static void rtsp_cmd_interrupt(RTSPContext *c, const char *url, RTSPMessageHeader *h, int pause_only) { RTSPContext *rtp_c; rtp_c = find_rtp_session_with_url(url, h->session_id); if (!rtp_c) { rtsp_reply_error(c, RTSP_STATUS_SESSION); return; } if (pause_only) { if (rtp_c->state != RTPSTATE_SEND_DATA) { rtsp_reply_error(c, RTSP_STATUS_STATE); return; } rtp_c->state = HTTPSTATE_READY; c->ntp_start_time = 0.0; } rtsp_reply_header(c, RTSP_STATUS_OK); /* session ID */ avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id); avio_printf(c->pb, "\r\n"); if (!pause_only) close_connection(rtp_c); }
static void json_print_integer(const char *key, int64_t value) { if (octx.prefix[octx.level -1].nb_elems) avio_printf(probe_out, ",\n"); AVP_INDENT(); avio_printf(probe_out, "\"%s\" : %"PRId64"", key, value); }
static void json_print_array_header(const char *name, int plain_values) { if (octx.prefix[octx.level -1].nb_elems) avio_printf(probe_out, ",\n"); AVP_INDENT(); avio_printf(probe_out, "\"%s\" : ", name); avio_printf(probe_out, "[\n"); }
/* RTSP Handle Function */ static void rtsp_cmd_options(RTSPContext *c, const char *url) { rtsp_reply_header(c, RTSP_STATUS_OK); avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK"); avio_printf(c->pb, "CSeq: %d\r\n", c->seq); avio_printf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE"); avio_printf(c->pb, "\r\n"); }
static void show_format_entry_string(const char *key, const char *value) { if (key && av_dict_get(fmt_entries_to_show, key, NULL, 0)) { if (nb_fmt_entries_to_show > 1) avio_printf(probe_out, "%s=", key); avio_printf(probe_out, "%s\n", value); } }
static void show_format_entry_integer(const char *key, int64_t value) { if (key && av_dict_get(fmt_entries_to_show, key, NULL, 0)) { if (nb_fmt_entries_to_show > 1) avio_printf(probe_out, "%s=", key); avio_printf(probe_out, "%"PRId64"\n", value); } }
static void json_print_object_header(const char *name) { if (octx.prefix[octx.level -1].nb_elems) avio_printf(probe_out, ",\n"); AVP_INDENT(); if (octx.prefix[octx.level -1].type == OBJECT) avio_printf(probe_out, "\"%s\" : ", name); avio_printf(probe_out, "{\n"); }
static int lrc_write_packet(AVFormatContext *s, AVPacket *pkt) { if(pkt->pts != AV_NOPTS_VALUE) { char *data = av_malloc(pkt->size + 1); char *line; char *delim; if(!data) { return AVERROR(ENOMEM); } memcpy(data, pkt->data, pkt->size); data[pkt->size] = '\0'; for(delim = data + pkt->size - 1; delim >= data && (delim[0] == '\n' || delim[0] == '\r'); delim--) { delim[0] = '\0'; // Strip last empty lines } line = data; while(line[0] == '\n' || line[0] == '\r') { line++; // Skip first empty lines } while(line) { delim = strchr(line, '\n'); if(delim) { if(delim > line && delim[-1] == '\r') { delim[-1] = '\0'; } delim[0] = '\0'; delim++; } if(line[0] == '[') { av_log(s, AV_LOG_WARNING, "Subtitle starts with '[', may cause problems with LRC format.\n"); } if(pkt->pts >= 0) { avio_printf(s->pb, "[%02"PRId64":%02"PRId64".%02"PRId64"]", (pkt->pts / 6000), ((pkt->pts / 100) % 60), (pkt->pts % 100)); } else { /* Offset feature of LRC can easily make pts negative, * we just output it directly and let the player drop it. */ avio_printf(s->pb, "[-%02"PRId64":%02"PRId64".%02"PRId64"]", (-pkt->pts) / 6000, ((-pkt->pts) / 100) % 60, (-pkt->pts) % 100); } avio_printf(s->pb, "%s\n", line); line = delim; } av_free(data); } return 0; }
static int microdvd_write_packet(AVFormatContext *avf, AVPacket *pkt) { avio_printf(avf->pb, "{%"PRId64"}", pkt->pts); if (pkt->duration < 0) avio_write(avf->pb, "{}", 2); else avio_printf(avf->pb, "{%"PRId64"}", pkt->pts + pkt->duration); avio_write(avf->pb, pkt->data, pkt->size); avio_write(avf->pb, "\n", 1); return 0; }
static void show_stream_entry_integer(const char *key, int64_t value) { if (!key) key = header_key; if (key && av_dict_get(stream_entries_to_show, key, NULL, 0)) { if (nb_stream_entries_to_show > 1) avio_printf(probe_out, "%s=", key); avio_printf(probe_out, "%"PRId64"\n", value); } }
static void json_print_string(const char *key, const char *value) { if (octx.prefix[octx.level -1].nb_elems) avio_printf(probe_out, ",\n"); AVP_INDENT(); avio_w8(probe_out, '\"'); json_escape_print(key); avio_printf(probe_out, "\" : \""); json_escape_print(value); avio_w8(probe_out, '\"'); }
static void ini_print_integer(const char *key, int64_t value) { if (key) { ini_escape_print(key); avio_printf(probe_out, "=%"PRId64"\n", value); } else { if (octx.prefix[octx.level -1].nb_elems) avio_printf(probe_out, ","); avio_printf(probe_out, "%"PRId64, value); } }
static int framehash_write_header(struct AVFormatContext *s) { struct HashContext *c = s->priv_data; int res = av_hash_alloc(&c->hash, c->hash_name); if (res < 0) return res; avio_printf(s->pb, "#format: frame checksums\n"); avio_printf(s->pb, "#version: %d\n", c->format_version); avio_printf(s->pb, "#hash: %s\n", av_hash_get_name(c->hash)); ff_framehash_write_header(s, c->format_version); avio_printf(s->pb, "#stream#, dts, pts, duration, size, hash\n"); return 0; }
int ff_framehash_write_header(AVFormatContext *s) { int i; if (s->nb_streams && !(s->flags & AVFMT_FLAG_BITEXACT)) avio_printf(s->pb, "#software: %s\n", LIBAVFORMAT_IDENT); for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den); avio_printf(s->pb, "#tb %d: %d/%d\n", i, st->time_base.num, st->time_base.den); avio_flush(s->pb); } return 0; }
static void rtsp_cmd_play(RTSPContext *c, const char *url, RTSPMessageHeader *h) { RTSPContext *rtp_c; rtp_c = find_rtp_session_with_url(url, h->session_id); if (!rtp_c) { printf("can't find rtp session %s with url %s \n", h->session_id, url); rtsp_reply_error(c, RTSP_STATUS_SESSION); return; } rtp_c->start_time = cur_time; // set start time // pos * 188이 offset! int64_t last_offset = rtp_c->cur_offset; printf("cmd play! cur_offset = %lld\n", rtp_c->cur_offset); if (c->ntp_start_time != 0.0) { // set start time for seek! printf("find start time by ntp time!!! seek request! seek time = %lfs \n", c->ntp_start_time); rtp_c->ntp_start_time = c->ntp_start_time; rtp_c->cur_idx = get_closest_iframe_by_time(rtp_c->stream->first_idx, rtp_c->ntp_start_time); if (rtp_c->cur_idx != NULL) rtp_c->cur_offset = rtp_c->cur_idx->pos * 188; // play time이 바뀐 경우, buffer도 비워줘야 함. if (rtp_c->buffer_ptr >= rtp_c->buffer_end) { printf("no need to reset rtp_c->buffer ptr \n"); } else { printf("need to reset rtp_c->buffer ptr \n"); rtp_c->buffer_ptr = rtp_c->buffer_end; av_free(c->pb_buffer); } } else { rtp_c->cur_idx = NULL; } printf("cmd play! after find iframe cur_offset = %lld\n", rtp_c->cur_offset); // reset served bytes for restart from pause state rtp_c->served_bytes = 0; rtp_c->state = RTPSTATE_SEND_DATA; /* now everything is OK, so we can send the connection parameters */ rtsp_reply_header(c, RTSP_STATUS_OK); /* session ID */ avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id); if (rtp_c->cur_idx != NULL) { avio_printf(c->pb, "Range: npt=%.3lf-\r\n", get_iIndex_PCR(rtp_c->cur_idx)); printf("range response! Range: npt=%.3lf-\n", get_iIndex_PCR(rtp_c->cur_idx)); avio_printf(c->pb, "RTP-Info: seq=%d\r\n", rtp_c->cur_seq); printf("RTP info: seq=%d\n", rtp_c->cur_seq); } avio_printf(c->pb, "\r\n"); }
static int lrc_write_header(AVFormatContext *s) { const AVDictionaryEntry *metadata_item; if(s->nb_streams != 1 || s->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) { av_log(s, AV_LOG_ERROR, "LRC supports only a single subtitle stream.\n"); return AVERROR(EINVAL); } if(s->streams[0]->codecpar->codec_id != AV_CODEC_ID_SUBRIP && s->streams[0]->codecpar->codec_id != AV_CODEC_ID_TEXT) { av_log(s, AV_LOG_ERROR, "Unsupported subtitle codec: %s\n", avcodec_get_name(s->streams[0]->codecpar->codec_id)); return AVERROR(EINVAL); } avpriv_set_pts_info(s->streams[0], 64, 1, 100); ff_standardize_creation_time(s); ff_metadata_conv_ctx(s, ff_lrc_metadata_conv, NULL); if(!(s->flags & AVFMT_FLAG_BITEXACT)) { // avoid breaking regression tests /* LRC provides a metadata slot for specifying encoder version * in addition to encoder name. We will store LIBAVFORMAT_VERSION * to it. */ av_dict_set(&s->metadata, "ve", AV_STRINGIFY(LIBAVFORMAT_VERSION), 0); } else { av_dict_set(&s->metadata, "ve", NULL, 0); } for(metadata_item = NULL; (metadata_item = av_dict_get(s->metadata, "", metadata_item, AV_DICT_IGNORE_SUFFIX));) { char *delim; if(!metadata_item->value[0]) { continue; } while((delim = strchr(metadata_item->value, '\n'))) { *delim = ' '; } while((delim = strchr(metadata_item->value, '\r'))) { *delim = ' '; } avio_printf(s->pb, "[%s:%s]\n", metadata_item->key, metadata_item->value); } avio_printf(s->pb, "\n"); return 0; }
static void ini_print_string(const char *key, const char *value) { ini_escape_print(key); avio_printf(probe_out, "="); ini_escape_print(value); avio_w8(probe_out, '\n'); }
static void purge_dialogues(AVFormatContext *s, int force) { int n = 0; ASSContext *ass = s->priv_data; DialogueLine *dialogue = ass->dialogue_cache; while (dialogue && (dialogue->readorder == ass->expected_readorder || force)) { DialogueLine *next = dialogue->next; if (dialogue->readorder != ass->expected_readorder) { av_log(s, AV_LOG_WARNING, "ReadOrder gap found between %d and %d\n", ass->expected_readorder, dialogue->readorder); ass->expected_readorder = dialogue->readorder; } avio_printf(s->pb, "Dialogue: %s\r\n", dialogue->line); if (dialogue == ass->last_added_dialogue) ass->last_added_dialogue = next; av_free(dialogue->line); av_free(dialogue); if (next) next->prev = NULL; dialogue = ass->dialogue_cache = next; ass->expected_readorder++; n++; } ass->cache_size -= n; if (n > 1) av_log(s, AV_LOG_DEBUG, "wrote %d ASS lines, cached dialogues: %d, waiting for event id %d\n", n, ass->cache_size, ass->expected_readorder); }
static int write_header(AVFormatContext *s) { ASSContext *ass = s->priv_data; AVCodecContext *avctx= s->streams[0]->codec; if (s->nb_streams != 1 || (avctx->codec_id != AV_CODEC_ID_SSA && avctx->codec_id != AV_CODEC_ID_ASS)) { av_log(s, AV_LOG_ERROR, "Exactly one ASS/SSA stream is needed.\n"); return AVERROR(EINVAL); } ass->write_ts = avctx->codec_id == AV_CODEC_ID_ASS; avpriv_set_pts_info(s->streams[0], 64, 1, 100); if (avctx->extradata_size > 0) { avio_write(s->pb, avctx->extradata, avctx->extradata_size); if (avctx->extradata[avctx->extradata_size - 1] != '\n') avio_write(s->pb, "\r\n", 2); ass->ssa_mode = !strstr(avctx->extradata, "\n[V4+ Styles]"); if (!strstr(avctx->extradata, "\n[Events]")) avio_printf(s->pb, "[Events]\r\nFormat: %s, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r\n", ass->ssa_mode ? "Marked" : "Layer"); } avio_flush(s->pb); return 0; }
static int write_packet(AVFormatContext *s, AVPacket *pkt) { ASSContext *ass = s->priv_data; if (ass->write_ts) { long int layer; char *p; int64_t start = pkt->pts; int64_t end = start + pkt->duration; int hh1, mm1, ss1, ms1; int hh2, mm2, ss2, ms2; p = pkt->data + strcspn(pkt->data, ",") + 1; // skip ReadOrder layer = strtol(p, &p, 10); if (*p == ',') p++; hh1 = (int)(start / 360000); mm1 = (int)(start / 6000) % 60; hh2 = (int)(end / 360000); mm2 = (int)(end / 6000) % 60; ss1 = (int)(start / 100) % 60; ms1 = (int)(start % 100); ss2 = (int)(end / 100) % 60; ms2 = (int)(end % 100); if (hh1 > 9) hh1 = 9, mm1 = 59, ss1 = 59, ms1 = 99; if (hh2 > 9) hh2 = 9, mm2 = 59, ss2 = 59, ms2 = 99; avio_printf(s->pb, "Dialogue: %ld,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s\r\n", layer, hh1, mm1, ss1, ms1, hh2, mm2, ss2, ms2, p); } else { avio_write(s->pb, pkt->data, pkt->size); } return 0; }
static int srt_write_packet(AVFormatContext *avf, AVPacket *pkt) { SRTContext *srt = avf->priv_data; int write_ts = avf->streams[0]->codec->codec_id != AV_CODEC_ID_SRT; srt->index++; if (write_ts) { int64_t s = pkt->pts, e, d = pkt->duration; if (d <= 0) /* For backward compatibility, fallback to convergence_duration. */ d = pkt->convergence_duration; if (s == AV_NOPTS_VALUE || d < 0) { av_log(avf, AV_LOG_ERROR, "Insufficient timestamps.\n"); return AVERROR(EINVAL); } e = s + d; avio_printf(avf->pb, "%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\n", srt->index, (int)(s / 3600000), (int)(s / 60000) % 60, (int)(s / 1000) % 60, (int)(s % 1000), (int)(e / 3600000), (int)(e / 60000) % 60, (int)(e / 1000) % 60, (int)(e % 1000)); } avio_write(avf->pb, pkt->data, pkt->size); if (write_ts) avio_write(avf->pb, "\n\n", 2); avio_flush(avf->pb); return 0; }
static void rtsp_cmd_describe(RTSPContext *c, const char *url) { iStream *stream; char path1[1024]; const char *path; uint8_t *content; int content_length = 0; socklen_t len; struct sockaddr_in my_addr; /* find which URL is asked */ av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url); int l = strlen(path1); if (path1[l-1] == '/') { path1[l-1] = '\0'; } path = path1; if (*path == '/') path++; for(stream = first_stream; stream != NULL; stream = stream->next) { if (!strcmp(path, stream->name)) { goto found; } } /* no stream found */ rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */ return; found: /* prepare the media description in SDP format */ content = av_mallocz(1024); /* get the host IP */ len = sizeof(my_addr); getsockname(c->fd, (struct sockaddr *)&my_addr, &len); rtsp_reply_header(c, RTSP_STATUS_OK); avio_printf(c->pb, "Content-Base: %s/\r\n", url); avio_printf(c->pb, "Content-Type: application/sdp\r\n"); int added_length = 0; // 여기에 sdp정보 추가 해야 함. content_length = generate_sdp_context(stream, &content); avio_printf(c->pb, "Content-Length: %d\r\n", content_length + added_length); avio_printf(c->pb, "\r\n"); // content added avio_write(c->pb, content, content_length + added_length); av_free(content); }
static int srt_write_packet(AVFormatContext *avf, AVPacket *pkt) { SRTContext *srt = avf->priv_data; int write_ts = avf->streams[0]->codec->codec_id != AV_CODEC_ID_SRT; if (write_ts) { int64_t s = pkt->pts, e, d = pkt->duration; int size, x1 = -1, y1 = -1, x2 = -1, y2 = -1; const uint8_t *p; p = av_packet_get_side_data(pkt, AV_PKT_DATA_SUBTITLE_POSITION, &size); if (p && size == 16) { x1 = AV_RL32(p ); y1 = AV_RL32(p + 4); x2 = AV_RL32(p + 8); y2 = AV_RL32(p + 12); } if (d <= 0) /* For backward compatibility, fallback to convergence_duration. */ d = pkt->convergence_duration; if (s == AV_NOPTS_VALUE || d < 0) { av_log(avf, AV_LOG_WARNING, "Insufficient timestamps in event number %d.\n", srt->index); return 0; } e = s + d; avio_printf(avf->pb, "%d\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d", srt->index, (int)(s / 3600000), (int)(s / 60000) % 60, (int)(s / 1000) % 60, (int)(s % 1000), (int)(e / 3600000), (int)(e / 60000) % 60, (int)(e / 1000) % 60, (int)(e % 1000)); if (p) avio_printf(avf->pb, " X1:%03d X2:%03d Y1:%03d Y2:%03d", x1, x2, y1, y2); avio_printf(avf->pb, "\n"); } avio_write(avf->pb, pkt->data, pkt->size); if (write_ts) avio_write(avf->pb, "\n\n", 2); avio_flush(avf->pb); srt->index++; return 0; }
static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) { SegmentContext *seg = s->priv_data; AVFormatContext *oc = seg->avf; AVStream *st = s->streams[pkt->stream_index]; int64_t end_pts = seg->recording_time * seg->number; int ret, can_split = 1; if (!oc) return AVERROR(EINVAL); if (seg->has_video) { can_split = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && pkt->flags & AV_PKT_FLAG_KEY; } if (can_split && av_compare_ts(pkt->pts, st->time_base, end_pts, AV_TIME_BASE_Q) >= 0) { av_log(s, AV_LOG_DEBUG, "Next segment starts at %d %"PRId64"\n", pkt->stream_index, pkt->pts); ret = segment_end(oc, seg->individual_header_trailer); if (!ret) ret = segment_start(s, seg->individual_header_trailer); if (ret) goto fail; oc = seg->avf; if (seg->list) { if (seg->list_type == LIST_HLS) { if ((ret = segment_hls_window(s, 0)) < 0) goto fail; } else { avio_printf(seg->pb, "%s\n", oc->filename); avio_flush(seg->pb); if (seg->size && !(seg->number % seg->size)) { ff_format_io_close(s, &seg->pb); if ((ret = s->io_open(s, &seg->pb, seg->list, AVIO_FLAG_WRITE, NULL)) < 0) goto fail; } } } } ret = ff_write_chained(oc, pkt->stream_index, pkt, s); fail: if (ret < 0) seg_free_context(seg); return ret; }
static char *choose_pix_fmts(OutputStream *ost) { AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0); if(strict_dict) // used by choose_pixel_fmt() and below { av_opt_set(ost->enc_ctx, "strict", strict_dict->value, 0); } if(ost->keep_pix_fmt) { if(ost->filter) avfilter_graph_set_auto_convert(ost->filter->graph->graph, AVFILTER_AUTO_CONVERT_NONE); if(ost->enc_ctx->pix_fmt == AV_PIX_FMT_NONE) { return NULL; } return av_strdup(av_get_pix_fmt_name(ost->enc_ctx->pix_fmt)); } if(ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) { return av_strdup(av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc_ctx, ost->enc, ost->enc_ctx->pix_fmt))); } else if(ost->enc && ost->enc->pix_fmts) { const enum AVPixelFormat *p; AVIOContext *s = NULL; uint8_t *ret; int len; if(avio_open_dyn_buf(&s) < 0) { exit_program(1); } p = ost->enc->pix_fmts; if(ost->enc_ctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) { p = get_compliance_unofficial_pix_fmts(ost->enc_ctx->codec_id, p); } for(; *p != AV_PIX_FMT_NONE; p++) { const char *name = av_get_pix_fmt_name(*p); avio_printf(s, "%s|", name); } len = avio_close_dyn_buf(s, &ret); ret[len - 1] = 0; return ret; } else { return NULL; } }
int ff_framehash_write_header(AVFormatContext *s) { int i; for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den); avio_printf(s->pb, "#tb %d: %d/%d\n", i, st->time_base.num, st->time_base.den); avio_flush(s->pb); } return 0; }
static void framehash_print_extradata(struct AVFormatContext *s) { int i; for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; AVCodecParameters *par = st->codecpar; if (par->extradata) { struct HashContext *c = s->priv_data; char buf[AV_HASH_MAX_SIZE*2+1]; avio_printf(s->pb, "#extradata %d, %31d, ", i, par->extradata_size); av_hash_init(c->hash); av_hash_update(c->hash, par->extradata, par->extradata_size); av_hash_final_hex(c->hash, buf, sizeof(buf)); avio_write(s->pb, buf, strlen(buf)); avio_printf(s->pb, "\n"); } } }
static void ini_print_array_header(const char *name, int plain_values) { if (!plain_values) { /* Add a new line if we create a new full group */ if (octx.prefix[octx.level -1].nb_elems) avio_printf(probe_out, "\n"); } else { ini_escape_print(name); avio_w8(probe_out, '='); } }
/* RTSP 관련 처리 */ static void rtsp_reply_header(RTSPContext *c, enum RTSPStatusCode error_number) { const char *str; time_t ti; struct tm *tm; char buf2[32]; str = RTSP_STATUS_CODE2STRING(error_number); //str = "OK"; if (!str) str = "Unknown Error"; avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str); avio_printf(c->pb, "CSeq: %d\r\n", c->seq); /* output GMT time */ ti = time(NULL); tm = gmtime(&ti); strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm); avio_printf(c->pb, "Date: %s GMT\r\n", buf2); }
static void ini_escape_print(const char *s) { int i = 0; char c = 0; while (c = s[i++]) { switch (c) { case '\r': avio_printf(probe_out, "%s", "\\r"); break; case '\n': avio_printf(probe_out, "%s", "\\n"); break; case '\f': avio_printf(probe_out, "%s", "\\f"); break; case '\b': avio_printf(probe_out, "%s", "\\b"); break; case '\t': avio_printf(probe_out, "%s", "\\t"); break; case '\\': case '#' : case '=' : case ':' : avio_w8(probe_out, '\\'); default: if ((unsigned char)c < 32) avio_printf(probe_out, "\\x00%02x", c & 0xff); else avio_w8(probe_out, c); break; } } }