diff options
author | Derek Buitenhuis <derek.buitenhuis@gmail.com> | 2016-02-10 14:40:32 +0000 |
---|---|---|
committer | Derek Buitenhuis <derek.buitenhuis@gmail.com> | 2016-02-10 14:42:41 +0000 |
commit | bc9a5965c815cf7fd998d8ce14a18b8e861dd9ce (patch) | |
tree | 7011642746984633573c9a2d993d58dfd12ee44b | |
parent | d94b11a721385aa406187da8f49380f29be0fa7e (diff) | |
parent | 9f61abc8111c7c43f49ca012e957a108b9cc7610 (diff) | |
download | ffmpeg-bc9a5965c815cf7fd998d8ce14a18b8e861dd9ce.tar.gz |
Merge commit '9f61abc8111c7c43f49ca012e957a108b9cc7610'
This also deprecates our old duplicated callbacks.
* commit '9f61abc8111c7c43f49ca012e957a108b9cc7610':
lavf: allow custom IO for all files
Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
-rw-r--r-- | doc/APIchanges | 3 | ||||
-rw-r--r-- | libavformat/avformat.h | 40 | ||||
-rw-r--r-- | libavformat/dashenc.c | 8 | ||||
-rw-r--r-- | libavformat/hdsenc.c | 24 | ||||
-rw-r--r-- | libavformat/hls.c | 11 | ||||
-rw-r--r-- | libavformat/hlsenc.c | 40 | ||||
-rw-r--r-- | libavformat/img2dec.c | 11 | ||||
-rw-r--r-- | libavformat/img2enc.c | 11 | ||||
-rw-r--r-- | libavformat/internal.h | 6 | ||||
-rw-r--r-- | libavformat/mlvdec.c | 12 | ||||
-rw-r--r-- | libavformat/mov.c | 22 | ||||
-rw-r--r-- | libavformat/movenc.c | 4 | ||||
-rw-r--r-- | libavformat/options.c | 21 | ||||
-rw-r--r-- | libavformat/segment.c | 27 | ||||
-rw-r--r-- | libavformat/smoothstreamingenc.c | 18 | ||||
-rw-r--r-- | libavformat/tee.c | 17 | ||||
-rw-r--r-- | libavformat/utils.c | 15 | ||||
-rw-r--r-- | libavformat/version.h | 7 | ||||
-rw-r--r-- | libavformat/webm_chunk.c | 12 |
19 files changed, 177 insertions, 132 deletions
diff --git a/doc/APIchanges b/doc/APIchanges index 6fa2ef1004..d253a66280 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,6 +15,9 @@ libavutil: 2015-08-28 API changes, most recent first: +2016-xx-xx - xxxxxxx - lavf 57.25.0 - avformat.h + Add AVFormatContext.opaque, io_open and io_close, allowing custom IO + 2016-02-01 - xxxxxxx - lavf 57.24.100 Add protocol_whitelist to AVFormatContext, AVIOContext diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 273a6ae863..34bad436cd 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1780,7 +1780,6 @@ typedef struct AVFormatContext { /** * User data. * This is a place for some private data of the user. - * Mostly usable with control_message_cb or any future callbacks in device's context. */ void *opaque; @@ -1811,6 +1810,7 @@ typedef struct AVFormatContext { */ enum AVCodecID data_codec_id; +#if FF_API_OLD_OPEN_CALLBACKS /** * Called to open further IO contexts when needed for demuxing. * @@ -1825,8 +1825,12 @@ typedef struct AVFormatContext { * @See av_format_set_open_cb() * * Demuxing: Set by user. + * + * @deprecated Use io_open and io_close. */ + attribute_deprecated int (*open_cb)(struct AVFormatContext *s, AVIOContext **p, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options); +#endif /** * ',' separated list of allowed protocols. @@ -1834,6 +1838,34 @@ typedef struct AVFormatContext { * - decoding: set by user through AVOptions (NO direct access) */ char *protocol_whitelist; + + /* + * A callback for opening new IO streams. + * + * Certain muxers or demuxers (e.g. for various playlist-based formats) need + * to open additional files during muxing or demuxing. This callback allows + * the caller to provide custom IO in such cases. + * + * @param s the format context + * @param pb on success, the newly opened IO context should be returned here + * @param url the url to open + * @param flags a combination of AVIO_FLAG_* + * @param options a dictionary of additional options, with the same + * semantics as in avio_open2() + * @return 0 on success, a negative AVERROR code on failure + * + * @note Certain muxers and demuxers do nesting, i.e. they open one or more + * additional internal format contexts. Thus the AVFormatContext pointer + * passed to this callback may be different from the one facing the caller. + * It will, however, have the same 'opaque' field. + */ + int (*io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, + int flags, AVDictionary **options); + + /** + * A callback for closing the streams opened with AVFormatContext.io_open(). + */ + void (*io_close)(struct AVFormatContext *s, AVIOContext *pb); } AVFormatContext; int av_format_get_probe_score(const AVFormatContext *s); @@ -1851,8 +1883,10 @@ void * av_format_get_opaque(const AVFormatContext *s); void av_format_set_opaque(AVFormatContext *s, void *opaque); av_format_control_message av_format_get_control_message_cb(const AVFormatContext *s); void av_format_set_control_message_cb(AVFormatContext *s, av_format_control_message callback); -AVOpenCallback av_format_get_open_cb(const AVFormatContext *s); -void av_format_set_open_cb(AVFormatContext *s, AVOpenCallback callback); +#if FF_API_OLD_OPEN_CALLBACKS +attribute_deprecated AVOpenCallback av_format_get_open_cb(const AVFormatContext *s); +attribute_deprecated void av_format_set_open_cb(AVFormatContext *s, AVOpenCallback callback); +#endif /** * This function will cause global side data to be injected in the next packet diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index a1147398ef..1dd1a9d279 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -448,8 +448,7 @@ static int write_manifest(AVFormatContext *s, int final) AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0); snprintf(temp_filename, sizeof(temp_filename), "%s.tmp", s->filename); - ret = ffio_open_whitelist(&out, temp_filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist); + ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename); return ret; @@ -549,7 +548,7 @@ static int write_manifest(AVFormatContext *s, int final) avio_printf(out, "\t</Period>\n"); avio_printf(out, "</MPD>\n"); avio_flush(out); - avio_close(out); + ff_format_io_close(s, &out); return ff_rename(temp_filename, s->filename, s); } @@ -624,6 +623,9 @@ static int dash_write_header(AVFormatContext *s) os->ctx = ctx; ctx->oformat = oformat; ctx->interrupt_callback = s->interrupt_callback; + ctx->opaque = s->opaque; + ctx->io_close = s->io_close; + ctx->io_open = s->io_open; if (!(st = avformat_new_stream(ctx, NULL))) { ret = AVERROR(ENOMEM); diff --git a/libavformat/hdsenc.c b/libavformat/hdsenc.c index 93fa27f8b5..3e6e821a82 100644 --- a/libavformat/hdsenc.c +++ b/libavformat/hdsenc.c @@ -140,7 +140,8 @@ static void hds_free(AVFormatContext *s) return; for (i = 0; i < s->nb_streams; i++) { OutputStream *os = &c->streams[i]; - avio_closep(&os->out); + if (os->out) + ff_format_io_close(s, &os->out); if (os->ctx && os->ctx_inited) av_write_trailer(os->ctx); if (os->ctx) @@ -170,8 +171,7 @@ static int write_manifest(AVFormatContext *s, int final) snprintf(filename, sizeof(filename), "%s/index.f4m", s->filename); snprintf(temp_filename, sizeof(temp_filename), "%s/index.f4m.tmp", s->filename); - ret = ffio_open_whitelist(&out, temp_filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist); + ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename); return ret; @@ -189,7 +189,7 @@ static int write_manifest(AVFormatContext *s, int final) int b64_size = AV_BASE64_SIZE(os->metadata_size); char *base64 = av_malloc(b64_size); if (!base64) { - avio_close(out); + ff_format_io_close(s, &out); return AVERROR(ENOMEM); } av_base64_encode(base64, b64_size, os->metadata, os->metadata_size); @@ -202,7 +202,7 @@ static int write_manifest(AVFormatContext *s, int final) } avio_printf(out, "</manifest>\n"); avio_flush(out); - avio_close(out); + ff_format_io_close(s, &out); return ff_rename(temp_filename, filename, s); } @@ -239,8 +239,7 @@ static int write_abst(AVFormatContext *s, OutputStream *os, int final) "%s/stream%d.abst", s->filename, index); snprintf(temp_filename, sizeof(temp_filename), "%s/stream%d.abst.tmp", s->filename, index); - ret = ffio_open_whitelist(&out, temp_filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist); + ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename); return ret; @@ -283,15 +282,14 @@ static int write_abst(AVFormatContext *s, OutputStream *os, int final) } update_size(out, afrt_pos); update_size(out, 0); - avio_close(out); + ff_format_io_close(s, &out); return ff_rename(temp_filename, filename, s); } static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts) { int ret, i; - ret = ffio_open_whitelist(&os->out, os->temp_filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist); + ret = s->io_open(s, &os->out, os->temp_filename, AVIO_FLAG_WRITE, NULL); if (ret < 0) return ret; avio_wb32(os->out, 0); @@ -304,13 +302,13 @@ static int init_file(AVFormatContext *s, OutputStream *os, int64_t start_ts) return 0; } -static void close_file(OutputStream *os) +static void close_file(AVFormatContext *s, OutputStream *os) { int64_t pos = avio_tell(os->out); avio_seek(os->out, 0, SEEK_SET); avio_wb32(os->out, pos); avio_flush(os->out); - avio_closep(&os->out); + ff_format_io_close(s, &os->out); } static int hds_write_header(AVFormatContext *s) @@ -475,7 +473,7 @@ static int hds_flush(AVFormatContext *s, OutputStream *os, int final, avio_flush(os->ctx->pb); os->packets_written = 0; - close_file(os); + close_file(s, os); snprintf(target_filename, sizeof(target_filename), "%s/stream%dSeg1-Frag%d", s->filename, index, os->fragment_index); diff --git a/libavformat/hls.c b/libavformat/hls.c index e23eaf1657..fc1ff38e05 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -180,7 +180,7 @@ struct variant { typedef struct HLSContext { AVClass *class; - AVFormatContext *avfmt; + AVFormatContext *ctx; int n_variants; struct variant **variants; int n_playlists; @@ -635,7 +635,7 @@ static int open_url(HLSContext *c, URLContext **uc, const char *url, AVDictionar av_dict_copy(&tmp, c->avio_opts, 0); av_dict_copy(&tmp, opts, 0); - ret = ffurl_open_whitelist(uc, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp, c->avfmt->protocol_whitelist); + ret = ffurl_open_whitelist(uc, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp, c->ctx->protocol_whitelist); if( ret >= 0) { // update cookies on http response with setcookies. URLContext *u = *uc; @@ -680,8 +680,7 @@ static int parse_playlist(HLSContext *c, const char *url, av_dict_set(&opts, "headers", c->headers, 0); av_dict_set(&opts, "http_proxy", c->http_proxy, 0); - ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ, - c->interrupt_callback, &opts, c->avfmt->protocol_whitelist); + ret = c->ctx->io_open(c->ctx, &in, url, AVIO_FLAG_READ, &opts); av_dict_free(&opts); if (ret < 0) return ret; @@ -849,7 +848,7 @@ static int parse_playlist(HLSContext *c, const char *url, fail: av_free(new_url); if (close_in) - avio_close(in); + ff_format_io_close(c->ctx, &in); return ret; } @@ -1518,7 +1517,7 @@ static int hls_read_header(AVFormatContext *s) HLSContext *c = s->priv_data; int ret = 0, i, j, stream_offset = 0; - c->avfmt = s; + c->ctx = s; c->interrupt_callback = &s->interrupt_callback; c->strict_std_compliance = s->strict_std_compliance; diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index bc28e3cd85..9939276dad 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -210,8 +210,7 @@ static int hls_encryption_start(AVFormatContext *s) AVIOContext *pb; uint8_t key[KEYSIZE]; - if ((ret = ffio_open_whitelist(&pb, hls->key_info_file, AVIO_FLAG_READ, - &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { + if ((ret = s->io_open(s, &pb, hls->key_info_file, AVIO_FLAG_READ, NULL)) < 0) { av_log(hls, AV_LOG_ERROR, "error opening key info file %s\n", hls->key_info_file); return ret; @@ -226,7 +225,7 @@ static int hls_encryption_start(AVFormatContext *s) ff_get_line(pb, hls->iv_string, sizeof(hls->iv_string)); hls->iv_string[strcspn(hls->iv_string, "\r\n")] = '\0'; - avio_close(pb); + ff_format_io_close(s, &pb); if (!*hls->key_uri) { av_log(hls, AV_LOG_ERROR, "no key URI specified in key info file\n"); @@ -238,14 +237,13 @@ static int hls_encryption_start(AVFormatContext *s) return AVERROR(EINVAL); } - if ((ret = ffio_open_whitelist(&pb, hls->key_file, AVIO_FLAG_READ, - &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { + if ((ret = s->io_open(s, &pb, hls->key_file, AVIO_FLAG_READ, NULL)) < 0) { av_log(hls, AV_LOG_ERROR, "error opening key file %s\n", hls->key_file); return ret; } ret = avio_read(pb, key, sizeof(key)); - avio_close(pb); + ff_format_io_close(s, &pb); if (ret != sizeof(key)) { av_log(hls, AV_LOG_ERROR, "error reading key file %s\n", hls->key_file); if (ret >= 0 || ret == AVERROR_EOF) @@ -272,6 +270,9 @@ static int hls_mux_init(AVFormatContext *s) oc->oformat = hls->oformat; oc->interrupt_callback = s->interrupt_callback; oc->max_delay = s->max_delay; + oc->opaque = s->opaque; + oc->io_open = s->io_open; + oc->io_close = s->io_close; av_dict_copy(&oc->metadata, s->metadata, 0); if(hls->vtt_oformat) { @@ -395,8 +396,7 @@ static int hls_window(AVFormatContext *s, int last) set_http_options(&options, hls); snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", s->filename); - if ((ret = ffio_open_whitelist(&out, temp_filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, &options, s->protocol_whitelist)) < 0) + if ((ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL)) < 0) goto fail; for (en = hls->segments; en; en = en->next) { @@ -446,8 +446,7 @@ static int hls_window(AVFormatContext *s, int last) avio_printf(out, "#EXT-X-ENDLIST\n"); if( hls->vtt_m3u8_name ) { - if ((ret = ffio_open_whitelist(&sub_out, hls->vtt_m3u8_name, AVIO_FLAG_WRITE, - &s->interrupt_callback, &options, s->protocol_whitelist)) < 0) + if ((ret = s->io_open(s, &sub_out, hls->vtt_m3u8_name, AVIO_FLAG_WRITE, &options)) < 0) goto fail; avio_printf(sub_out, "#EXTM3U\n"); avio_printf(sub_out, "#EXT-X-VERSION:%d\n", version); @@ -477,8 +476,8 @@ static int hls_window(AVFormatContext *s, int last) fail: av_dict_free(&options); - avio_closep(&out); - avio_closep(&sub_out); + ff_format_io_close(s, &out); + ff_format_io_close(s, &sub_out); if (ret >= 0 && use_rename) ff_rename(temp_filename, s->filename, s); return ret; @@ -543,20 +542,17 @@ static int hls_start(AVFormatContext *s) err = AVERROR(ENOMEM); goto fail; } - err = ffio_open_whitelist(&oc->pb, filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, &options, s->protocol_whitelist); + err = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL); av_free(filename); av_dict_free(&options); if (err < 0) return err; } else - if ((err = ffio_open_whitelist(&oc->pb, oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, &options, s->protocol_whitelist)) < 0) + if ((err = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, &options)) < 0) goto fail; if (c->vtt_basename) { set_http_options(&options, c); - if ((err = ffio_open_whitelist(&vtt_oc->pb, vtt_oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, &options, s->protocol_whitelist)) < 0) + if ((err = s->io_open(s, &vtt_oc->pb, vtt_oc->filename, AVIO_FLAG_WRITE, &options)) < 0) goto fail; } av_dict_free(&options); @@ -795,9 +791,9 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) av_opt_set(hls->avf->priv_data, "mpegts_flags", "resend_headers", 0); hls->number++; } else { - avio_closep(&oc->pb); + ff_format_io_close(s, &oc->pb); if (hls->vtt_avf) - avio_close(hls->vtt_avf->pb); + ff_format_io_close(s, &hls->vtt_avf->pb); ret = hls_start(s); } @@ -828,7 +824,7 @@ static int hls_write_trailer(struct AVFormatContext *s) av_write_trailer(oc); if (oc->pb) { hls->size = avio_tell(hls->avf->pb) - hls->start_pos; - avio_closep(&oc->pb); + ff_format_io_close(s, &oc->pb); hls_append_segment(hls, hls->duration, hls->start_pos, hls->size); } @@ -836,7 +832,7 @@ static int hls_write_trailer(struct AVFormatContext *s) if (vtt_oc->pb) av_write_trailer(vtt_oc); hls->size = avio_tell(hls->vtt_avf->pb) - hls->start_pos; - avio_closep(&vtt_oc->pb); + ff_format_io_close(s, &vtt_oc->pb); } av_freep(&hls->basename); avformat_free_context(oc); diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index efd637b310..c353563610 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -377,10 +377,6 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) int size[3] = { 0 }, ret[3] = { 0 }; AVIOContext *f[3] = { NULL }; AVCodecContext *codec = s1->streams[0]->codec; - AVOpenCallback open_func = s1->open_cb; - - if (!open_func) - open_func = ffio_open2_wrapper; if (!s->is_pipe) { /* loop over input */ @@ -407,8 +403,7 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) !s->loop && !s->split_planes) { f[i] = s1->pb; - } else if (open_func(s1, &f[i], filename, AVIO_FLAG_READ, - &s1->interrupt_callback, NULL) < 0) { + } else if (s1->io_open(s1, &f[i], filename, AVIO_FLAG_READ, NULL) < 0) { if (i >= 1) break; av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n", @@ -496,7 +491,7 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) } } if (!s->is_pipe && f[i] != s1->pb) - avio_closep(&f[i]); + ff_format_io_close(s1, &f[i]); if (ret[i] > 0) pkt->size += ret[i]; } @@ -525,7 +520,7 @@ fail: if (!s->is_pipe) { for (i = 0; i < 3; i++) { if (f[i] != s1->pb) - avio_closep(&f[i]); + ff_format_io_close(s1, &f[i]); } } return res; diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c index 2f0aec1f02..a118e73ab2 100644 --- a/libavformat/img2enc.c +++ b/libavformat/img2enc.c @@ -111,8 +111,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) for (i = 0; i < 4; i++) { snprintf(img->tmp[i], sizeof(img->tmp[i]), "%s.tmp", filename); av_strlcpy(img->target[i], filename, sizeof(img->target[i])); - if (avio_open2(&pb[i], img->use_rename ? img->tmp[i] : filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL) < 0) { + if (s->io_open(s, &pb[i], img->use_rename ? img->tmp[i] : filename, AVIO_FLAG_WRITE, NULL) < 0) { av_log(s, AV_LOG_ERROR, "Could not open file : %s\n", img->use_rename ? img->tmp[i] : filename); return AVERROR(EIO); } @@ -137,11 +136,11 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) avio_write(pb[0], pkt->data , ysize); avio_write(pb[1], pkt->data + ysize , usize); avio_write(pb[2], pkt->data + ysize + usize, usize); - avio_closep(&pb[1]); - avio_closep(&pb[2]); + ff_format_io_close(s, &pb[1]); + ff_format_io_close(s, &pb[2]); if (desc->nb_components > 3) { avio_write(pb[3], pkt->data + ysize + 2*usize, ysize); - avio_closep(&pb[3]); + ff_format_io_close(s, &pb[3]); } } else if (img->muxer) { int ret; @@ -179,7 +178,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) } avio_flush(pb[0]); if (!img->is_pipe) { - avio_closep(&pb[0]); + ff_format_io_close(s, &pb[0]); for (i = 0; i < nb_renames; i++) { ff_rename(img->tmp[i], img->target[i], s); } diff --git a/libavformat/internal.h b/libavformat/internal.h index 2cb3481f8c..8e718058fd 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -548,4 +548,10 @@ int ffio_open2_wrapper(struct AVFormatContext *s, AVIOContext **pb, const char * */ #define FFERROR_REDO FFERRTAG('R','E','D','O') +/* + * A wrapper around AVFormatContext.io_close that should be used + * intead of calling the pointer directly. + */ +void ff_format_io_close(AVFormatContext *s, AVIOContext **pb); + #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/mlvdec.c b/libavformat/mlvdec.c index c003eab64e..288b2a1010 100644 --- a/libavformat/mlvdec.c +++ b/libavformat/mlvdec.c @@ -344,28 +344,24 @@ static int read_header(AVFormatContext *avctx) if (strlen(avctx->filename) > 2) { int i; char *filename = av_strdup(avctx->filename); - AVOpenCallback open_func = avctx->open_cb; if (!filename) return AVERROR(ENOMEM); - if (!open_func) - open_func = ffio_open2_wrapper; - for (i = 0; i < 100; i++) { snprintf(filename + strlen(filename) - 2, 3, "%02d", i); - if (open_func(avctx, &mlv->pb[i], filename, AVIO_FLAG_READ, &avctx->interrupt_callback, NULL) < 0) + if (avctx->io_open(avctx, &mlv->pb[i], filename, AVIO_FLAG_READ, NULL) < 0) break; if (check_file_header(mlv->pb[i], guid) < 0) { av_log(avctx, AV_LOG_WARNING, "ignoring %s; bad format or guid mismatch\n", filename); - avio_closep(&mlv->pb[i]); + ff_format_io_close(avctx, &mlv->pb[i]); continue; } av_log(avctx, AV_LOG_INFO, "scanning %s\n", filename); ret = scan_file(avctx, vst, ast, i); if (ret < 0) { av_log(avctx, AV_LOG_WARNING, "ignoring %s; %s\n", filename, av_err2str(ret)); - avio_closep(&mlv->pb[i]); + ff_format_io_close(avctx, &mlv->pb[i]); continue; } } @@ -466,7 +462,7 @@ static int read_close(AVFormatContext *s) int i; for (i = 0; i < 100; i++) if (mlv->pb[i]) - avio_closep(&mlv->pb[i]); + ff_format_io_close(s, &mlv->pb[i]); return 0; } diff --git a/libavformat/mov.c b/libavformat/mov.c index 299bee6f29..149e3b4a0e 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2922,14 +2922,8 @@ static int test_same_origin(const char *src, const char *ref) { return 1; } -static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref, - AVIOInterruptCB *int_cb) +static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref) { - AVOpenCallback open_func = c->fc->open_cb; - - if (!open_func) - open_func = ffio_open2_wrapper; - /* try relative path, we do not try the absolute because it can leak information about our system to an attacker */ if (ref->nlvl_to > 0 && ref->nlvl_from > 0) { @@ -2962,7 +2956,7 @@ static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDr av_strlcat(filename, "../", sizeof(filename)); av_strlcat(filename, ref->path + l + 1, sizeof(filename)); - if (!c->use_absolute_path && !c->fc->open_cb) { + if (!c->use_absolute_path) { int same_origin = test_same_origin(src, filename); if (!same_origin) { @@ -2982,16 +2976,13 @@ static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDr if (strlen(filename) + 1 == sizeof(filename)) return AVERROR(ENOENT); - if (!open_func(c->fc, pb, filename, AVIO_FLAG_READ, int_cb, NULL)) + if (!c->fc->io_open(c->fc, pb, filename, AVIO_FLAG_READ, NULL)) return 0; } } else if (c->use_absolute_path) { av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, " "this is a possible security issue\n"); - if (!open_func(c->fc, pb, ref->path, AVIO_FLAG_READ, int_cb, NULL)) - return 0; - } else if (c->fc->open_cb) { - if (!open_func(c->fc, pb, ref->path, AVIO_FLAG_READ, int_cb, NULL)) + if (!c->fc->io_open(c->fc, pb, ref->path, AVIO_FLAG_READ, NULL)) return 0; } else { av_log(c->fc, AV_LOG_ERROR, @@ -3052,8 +3043,7 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) { MOVDref *dref = &sc->drefs[sc->dref_id - 1]; if (c->enable_drefs) { - if (mov_open_dref(c, &sc->pb, c->fc->filename, dref, - &c->fc->interrupt_callback) < 0) + if (mov_open_dref(c, &sc->pb, c->fc->filename, dref) < 0) av_log(c->fc, AV_LOG_ERROR, "stream %d, error opening alias: path='%s', dir='%s', " "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n", @@ -4583,7 +4573,7 @@ static int mov_read_close(AVFormatContext *s) sc->drefs_count = 0; if (!sc->pb_is_copied) - avio_closep(&sc->pb); + ff_format_io_close(s, &sc->pb); sc->pb = NULL; av_freep(&sc->chunk_offsets); diff --git a/libavformat/movenc.c b/libavformat/movenc.c index c6fba21b04..799c26fd55 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -5534,7 +5534,7 @@ static int shift_data(AVFormatContext *s) * writing, so we re-open the same output, but for reading. It also avoids * a read/seek/write/seek back and forth. */ avio_flush(s->pb); - ret = ffio_open_whitelist(&read_pb, s->filename, AVIO_FLAG_READ, &s->interrupt_callback, NULL, s->protocol_whitelist); + ret = s->io_open(s, &read_pb, s->filename, AVIO_FLAG_READ, NULL); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for " "the second pass (faststart)\n", s->filename); @@ -5566,7 +5566,7 @@ static int shift_data(AVFormatContext *s) avio_write(s->pb, read_buf[read_buf_id], n); pos += n; } while (pos < pos_end); - avio_close(read_pb); + ff_format_io_close(s, &read_pb); end: av_free(buf); diff --git a/libavformat/options.c b/libavformat/options.c index 9918349703..8fe0017196 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -99,12 +99,33 @@ static const AVClass av_format_context_class = { .get_category = get_category, }; +static int io_open_default(AVFormatContext *s, AVIOContext **pb, + const char *url, int flags, AVDictionary **options) +{ +#if FF_API_OLD_OPEN_CALLBACKS +FF_DISABLE_DEPRECATION_WARNINGS + if (s->open_cb) + return s->open_cb(s, pb, url, flags, &s->interrupt_callback, options); +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist); +} + +static void io_close_default(AVFormatContext *s, AVIOContext *pb) +{ + avio_close(pb); +} + static void avformat_get_context_defaults(AVFormatContext *s) { memset(s, 0, sizeof(AVFormatContext)); s->av_class = &av_format_context_class; + s->io_open = io_open_default; + s->io_close = io_close_default; + av_opt_set_defaults(s); } diff --git a/libavformat/segment.c b/libavformat/segment.c index 90528f3aa8..f6df1759c3 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -156,6 +156,9 @@ static int segment_mux_init(AVFormatContext *s) oc->interrupt_callback = s->interrupt_callback; oc->max_delay = s->max_delay; av_dict_copy(&oc->metadata, s->metadata, 0); + oc->opaque = s->opaque; + oc->io_close = s->io_close; + oc->io_open = s->io_open; for (i = 0; i < s->nb_streams; i++) { AVStream *st; @@ -240,8 +243,7 @@ static int segment_start(AVFormatContext *s, int write_header) if ((err = set_segment_filename(s)) < 0) return err; - if ((err = ffio_open_whitelist(&oc->pb, oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { + if ((err = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL)) < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->filename); return err; } @@ -266,8 +268,7 @@ static int segment_list_open(AVFormatContext *s) int ret; snprintf(seg->temp_list_filename, sizeof(seg->temp_list_filename), seg->use_rename ? "%s.tmp" : "%s", seg->list); - ret = ffio_open_whitelist(&seg->list_pb, seg->temp_list_filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist); + ret = s->io_open(s, &seg->list_pb, seg->temp_list_filename, AVIO_FLAG_WRITE, NULL); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment list '%s'\n", seg->list); return ret; @@ -376,7 +377,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) segment_list_print_entry(seg->list_pb, seg->list_type, entry, s); if (seg->list_type == LIST_TYPE_M3U8 && is_last) avio_printf(seg->list_pb, "#EXT-X-ENDLIST\n"); - avio_closep(&seg->list_pb); + ff_format_io_close(s, &seg->list_pb); if (seg->use_rename) ff_rename(seg->temp_list_filename, seg->list, s); } else { @@ -390,7 +391,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) seg->segment_count++; end: - avio_closep(&oc->pb); + ff_format_io_close(oc, &oc->pb); return ret; } @@ -591,7 +592,7 @@ static int select_reference_stream(AVFormatContext *s) static void seg_free_context(SegmentContext *seg) { - avio_closep(&seg->list_pb); + ff_format_io_close(seg->avf, &seg->list_pb); avformat_free_context(seg->avf); seg->avf = NULL; } @@ -700,8 +701,7 @@ static int seg_write_header(AVFormatContext *s) goto fail; if (seg->write_header_trailer) { - if ((ret = ffio_open_whitelist(&oc->pb, seg->header_filename ? seg->header_filename : oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { + if ((ret = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL)) < 0) { av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", oc->filename); goto fail; } @@ -722,7 +722,7 @@ static int seg_write_header(AVFormatContext *s) } if (ret < 0) { - avio_closep(&oc->pb); + ff_format_io_close(oc, &oc->pb); goto fail; } seg->segment_frame_count = 0; @@ -740,12 +740,11 @@ static int seg_write_header(AVFormatContext *s) if (!seg->write_header_trailer || seg->header_filename) { if (seg->header_filename) { av_write_frame(oc, NULL); - avio_closep(&oc->pb); + ff_format_io_close(oc, &oc->pb); } else { close_null_ctxp(&oc->pb); } - if ((ret = ffio_open_whitelist(&oc->pb, oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) + if ((ret = oc->io_open(oc, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL)) < 0) goto fail; if (!seg->individual_header_trailer) oc->pb->seekable = 0; @@ -891,7 +890,7 @@ static int seg_write_trailer(struct AVFormatContext *s) } fail: if (seg->list) - avio_closep(&seg->list_pb); + ff_format_io_close(s, &seg->list_pb); av_dict_free(&seg->format_options); av_opt_free(seg); diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index cf7bb70e56..f36e5fee7b 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -223,7 +223,7 @@ static int write_manifest(AVFormatContext *s, int final) snprintf(filename, sizeof(filename), "%s/Manifest", s->filename); snprintf(temp_filename, sizeof(temp_filename), "%s/Manifest.tmp", s->filename); - ret = ffio_open_whitelist(&out, temp_filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist); + ret = s->io_open(s, &out, temp_filename, AVIO_FLAG_WRITE, NULL); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Unable to open %s for writing\n", temp_filename); return ret; @@ -285,7 +285,7 @@ static int write_manifest(AVFormatContext *s, int final) } avio_printf(out, "</SmoothStreamingMedia>\n"); avio_flush(out); - avio_close(out); + ff_format_io_close(s, &out); return ff_rename(temp_filename, filename, s); } @@ -412,7 +412,7 @@ static int parse_fragment(AVFormatContext *s, const char *filename, int64_t *sta AVIOContext *in; int ret; uint32_t len; - if ((ret = ffio_open_whitelist(&in, filename, AVIO_FLAG_READ, &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) + if ((ret = s->io_open(s, &in, filename, AVIO_FLAG_READ, NULL)) < 0) return ret; ret = AVERROR(EIO); *moof_size = avio_rb32(in); @@ -453,7 +453,7 @@ static int parse_fragment(AVFormatContext *s, const char *filename, int64_t *sta avio_seek(in, end, SEEK_SET); } fail: - avio_close(in); + ff_format_io_close(s, &in); return ret; } @@ -489,10 +489,10 @@ static int copy_moof(AVFormatContext *s, const char* infile, const char *outfile { AVIOContext *in, *out; int ret = 0; - if ((ret = ffio_open_whitelist(&in, infile, AVIO_FLAG_READ, &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) + if ((ret = s->io_open(s, &in, infile, AVIO_FLAG_READ, NULL)) < 0) return ret; - if ((ret = ffio_open_whitelist(&out, outfile, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL, s->protocol_whitelist)) < 0) { - avio_close(in); + if ((ret = s->io_open(s, &out, outfile, AVIO_FLAG_WRITE, NULL)) < 0) { + ff_format_io_close(s, &in); return ret; } while (size > 0) { @@ -507,8 +507,8 @@ static int copy_moof(AVFormatContext *s, const char* infile, const char *outfile size -= n; } avio_flush(out); - avio_close(out); - avio_close(in); + ff_format_io_close(s, &out); + ff_format_io_close(s, &in); return ret; } diff --git a/libavformat/tee.c b/libavformat/tee.c index 4993ca3714..139070556c 100644 --- a/libavformat/tee.c +++ b/libavformat/tee.c @@ -23,6 +23,7 @@ #include "libavutil/avutil.h" #include "libavutil/avstring.h" #include "libavutil/opt.h" +#include "internal.h" #include "avformat.h" #include "avio_internal.h" @@ -165,6 +166,9 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) if (ret < 0) goto end; av_dict_copy(&avf2->metadata, avf->metadata, 0); + avf2->opaque = avf->opaque; + avf2->io_open = avf->io_open; + avf2->io_close = avf->io_close; tee_slave->stream_map = av_calloc(avf->nb_streams, sizeof(*tee_slave->stream_map)); if (!tee_slave->stream_map) { @@ -227,9 +231,7 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) } if (!(avf2->oformat->flags & AVFMT_NOFILE)) { - if ((ret = ffio_open_whitelist(&avf2->pb, filename, AVIO_FLAG_WRITE, - &avf->interrupt_callback, NULL, - avf->protocol_whitelist)) < 0) { + if ((ret = avf2->io_open(avf2, &avf2->pb, filename, AVIO_FLAG_WRITE, NULL)) < 0) { av_log(avf, AV_LOG_ERROR, "Slave '%s': error opening: %s\n", slave, av_err2str(ret)); goto end; @@ -329,7 +331,7 @@ static void close_slaves(AVFormatContext *avf) av_freep(&tee->slaves[i].stream_map); av_freep(&tee->slaves[i].bsfs); - avio_closep(&avf2->pb); + ff_format_io_close(avf2, &avf2->pb); avformat_free_context(avf2); tee->slaves[i].avf = NULL; } @@ -420,11 +422,8 @@ static int tee_write_trailer(AVFormatContext *avf) if ((ret = av_write_trailer(avf2)) < 0) if (!ret_all) ret_all = ret; - if (!(avf2->oformat->flags & AVFMT_NOFILE)) { - if ((ret = avio_closep(&avf2->pb)) < 0) - if (!ret_all) - ret_all = ret; - } + if (!(avf2->oformat->flags & AVFMT_NOFILE)) + ff_format_io_close(avf2, &avf2->pb); } close_slaves(avf); return ret_all; diff --git a/libavformat/utils.c b/libavformat/utils.c index f8846b7115..ef9ea93aaa 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -112,7 +112,11 @@ MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, data_codec) MAKE_ACCESSORS(AVFormatContext, format, int, metadata_header_padding) MAKE_ACCESSORS(AVFormatContext, format, void *, opaque) MAKE_ACCESSORS(AVFormatContext, format, av_format_control_message, control_message_cb) +#if FF_API_OLD_OPEN_CALLBACKS +FF_DISABLE_DEPRECATION_WARNINGS MAKE_ACCESSORS(AVFormatContext, format, AVOpenCallback, open_cb) +FF_ENABLE_DEPRECATION_WARNINGS +#endif int64_t av_stream_get_end_pts(const AVStream *st) { @@ -356,9 +360,7 @@ static int init_input(AVFormatContext *s, const char *filename, (!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score)))) return score; - if ((ret = ffio_open_whitelist(&s->pb, filename, AVIO_FLAG_READ | s->avio_flags, - &s->interrupt_callback, options, - s->protocol_whitelist)) < 0) + if ((ret = s->io_open(s, &s->pb, filename, AVIO_FLAG_READ | s->avio_flags, options)) < 0) return ret; if (s->iformat) @@ -4742,3 +4744,10 @@ int av_apply_bitstream_filters(AVCodecContext *codec, AVPacket *pkt, } return ret; } + +void ff_format_io_close(AVFormatContext *s, AVIOContext **pb) +{ + if (*pb) + s->io_close(s, *pb); + *pb = NULL; +} diff --git a/libavformat/version.h b/libavformat/version.h index 0fdfee7a36..024ab9152f 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,8 +30,8 @@ #include "libavutil/version.h" #define LIBAVFORMAT_VERSION_MAJOR 57 -#define LIBAVFORMAT_VERSION_MINOR 24 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MINOR 25 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ @@ -71,6 +71,9 @@ #ifndef FF_API_COMPUTE_PKT_FIELDS2 #define FF_API_COMPUTE_PKT_FIELDS2 (LIBAVFORMAT_VERSION_MAJOR < 58) #endif +#ifndef FF_API_OLD_OPEN_CALLBACKS +#define FF_API_OLD_OPEN_CALLBACKS (LIBAVFORMAT_VERSION_MAJOR < 58) +#endif #ifndef FF_API_R_FRAME_RATE #define FF_API_R_FRAME_RATE 1 diff --git a/libavformat/webm_chunk.c b/libavformat/webm_chunk.c index 0ae6c3a659..063eb3beb8 100644 --- a/libavformat/webm_chunk.c +++ b/libavformat/webm_chunk.c @@ -126,8 +126,7 @@ static int webm_chunk_write_header(AVFormatContext *s) ret = get_chunk_filename(s, 1, oc->filename); if (ret < 0) return ret; - ret = ffio_open_whitelist(&oc->pb, oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist); + ret = s->io_open(s, &oc->pb, oc->filename, AVIO_FLAG_WRITE, NULL); if (ret < 0) return ret; @@ -135,7 +134,7 @@ static int webm_chunk_write_header(AVFormatContext *s) ret = oc->oformat->write_header(oc); if (ret < 0) return ret; - avio_close(oc->pb); + ff_format_io_close(s, &oc->pb); return 0; } @@ -170,14 +169,11 @@ static int chunk_end(AVFormatContext *s) ret = get_chunk_filename(s, 0, filename); if (ret < 0) goto fail; - ret = ffio_open_whitelist(&pb, filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL, s->protocol_whitelist); + ret = s->io_open(s, &pb, filename, AVIO_FLAG_WRITE, NULL); if (ret < 0) goto fail; avio_write(pb, buffer, buffer_size); - ret = avio_close(pb); - if (ret < 0) - goto fail; + ff_format_io_close(s, &pb); oc->pb = NULL; fail: av_free(buffer); |