summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavformat/internal.h9
-rw-r--r--libavformat/utils.c146
-rw-r--r--tests/ref/fate/copy-trac2211-avi4
-rw-r--r--tests/ref/fate/h264_mp4toannexb_ticket29912
-rw-r--r--tests/ref/fate/h264_mp4toannexb_ticket59272
-rw-r--r--tests/ref/fate/h264_mp4toannexb_ticket5927_22
-rw-r--r--tests/ref/fate/segment-mp4-to-ts2
7 files changed, 148 insertions, 19 deletions
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 63a1724cfa..c856945ce9 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -178,6 +178,15 @@ struct AVStreamInternal {
enum AVCodecID orig_codec_id;
+ /* the context for extracting extradata in find_stream_info()
+ * inited=1/bsf=NULL signals that extracting is not possible (codec not
+ * supported) */
+ struct {
+ AVBSFContext *bsf;
+ AVPacket *pkt;
+ int inited;
+ } extract_extradata;
+
/**
* Whether the internal avctx needs to be updated from codecpar (after a late change to codecpar)
*/
diff --git a/libavformat/utils.c b/libavformat/utils.c
index a059046a2c..ba82a766dc 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3370,6 +3370,127 @@ void ff_rfps_calculate(AVFormatContext *ic)
}
}
+static int extract_extradata_check(AVStream *st)
+{
+ const AVBitStreamFilter *f;
+
+ f = av_bsf_get_by_name("extract_extradata");
+ if (!f)
+ return 0;
+
+ if (f->codec_ids) {
+ const enum AVCodecID *ids;
+ for (ids = f->codec_ids; *ids != AV_CODEC_ID_NONE; ids++)
+ if (*ids == st->codecpar->codec_id)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int extract_extradata_init(AVStream *st)
+{
+ AVStreamInternal *i = st->internal;
+ const AVBitStreamFilter *f;
+ int ret;
+
+ f = av_bsf_get_by_name("extract_extradata");
+ if (!f)
+ goto finish;
+
+ /* check that the codec id is supported */
+ ret = extract_extradata_check(st);
+ if (!ret)
+ goto finish;
+
+ i->extract_extradata.pkt = av_packet_alloc();
+ if (!i->extract_extradata.pkt)
+ return AVERROR(ENOMEM);
+
+ ret = av_bsf_alloc(f, &i->extract_extradata.bsf);
+ if (ret < 0)
+ goto fail;
+
+ ret = avcodec_parameters_copy(i->extract_extradata.bsf->par_in,
+ st->codecpar);
+ if (ret < 0)
+ goto fail;
+
+ i->extract_extradata.bsf->time_base_in = st->time_base;
+
+ /* if init fails here, we assume extracting extradata is just not
+ * supported for this codec, so we return success */
+ ret = av_bsf_init(i->extract_extradata.bsf);
+ if (ret < 0) {
+ av_bsf_free(&i->extract_extradata.bsf);
+ ret = 0;
+ }
+
+finish:
+ i->extract_extradata.inited = 1;
+
+ return 0;
+fail:
+ av_bsf_free(&i->extract_extradata.bsf);
+ av_packet_free(&i->extract_extradata.pkt);
+ return ret;
+}
+
+static int extract_extradata(AVStream *st, AVPacket *pkt)
+{
+ AVStreamInternal *i = st->internal;
+ AVPacket *pkt_ref;
+ int ret;
+
+ if (!i->extract_extradata.inited) {
+ ret = extract_extradata_init(st);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (i->extract_extradata.inited && !i->extract_extradata.bsf)
+ return 0;
+
+ pkt_ref = i->extract_extradata.pkt;
+ ret = av_packet_ref(pkt_ref, pkt);
+ if (ret < 0)
+ return ret;
+
+ ret = av_bsf_send_packet(i->extract_extradata.bsf, pkt_ref);
+ if (ret < 0) {
+ av_packet_unref(pkt_ref);
+ return ret;
+ }
+
+ while (ret >= 0 && !i->avctx->extradata) {
+ int extradata_size;
+ uint8_t *extradata;
+
+ ret = av_bsf_receive_packet(i->extract_extradata.bsf, pkt_ref);
+ if (ret < 0) {
+ if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
+ return ret;
+ continue;
+ }
+
+ extradata = av_packet_get_side_data(pkt_ref, AV_PKT_DATA_NEW_EXTRADATA,
+ &extradata_size);
+
+ if (extradata) {
+ i->avctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!i->avctx->extradata) {
+ av_packet_unref(pkt_ref);
+ return AVERROR(ENOMEM);
+ }
+ memcpy(i->avctx->extradata, extradata, extradata_size);
+ i->avctx->extradata_size = extradata_size;
+ }
+ av_packet_unref(pkt_ref);
+ }
+
+ return 0;
+}
+
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
{
int i, count = 0, ret = 0, j;
@@ -3529,8 +3650,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (count < fps_analyze_framecount)
break;
}
- if (st->parser && st->parser->parser->split &&
- !st->internal->avctx->extradata)
+ if (!st->internal->avctx->extradata &&
+ (!st->internal->extract_extradata.inited ||
+ st->internal->extract_extradata.bsf) &&
+ extract_extradata_check(st))
break;
if (st->first_dts == AV_NOPTS_VALUE &&
!(ic->iformat->flags & AVFMT_NOTIMESTAMPS) &&
@@ -3680,17 +3803,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
ff_rfps_add_frame(ic, st, pkt->dts);
#endif
- if (st->parser && st->parser->parser->split && !avctx->extradata) {
- int i = st->parser->parser->split(avctx, pkt->data, pkt->size);
- if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {
- avctx->extradata_size = i;
- avctx->extradata = av_mallocz(avctx->extradata_size +
- AV_INPUT_BUFFER_PADDING_SIZE);
- if (!avctx->extradata)
- return AVERROR(ENOMEM);
- memcpy(avctx->extradata, pkt->data,
- avctx->extradata_size);
- }
+ if (!st->internal->avctx->extradata) {
+ ret = extract_extradata(st, pkt);
+ if (ret < 0)
+ goto find_stream_info_err;
}
/* If still no information, we try to open the codec and to
@@ -3950,6 +4066,8 @@ find_stream_info_err:
if (st->info)
av_freep(&st->info->duration_error);
av_freep(&ic->streams[i]->info);
+ av_bsf_free(&ic->streams[i]->internal->extract_extradata.bsf);
+ av_packet_free(&ic->streams[i]->internal->extract_extradata.pkt);
}
if (ic->pb)
av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n",
@@ -4137,6 +4255,8 @@ static void free_stream(AVStream **pst)
av_bsf_free(&st->internal->bsfcs[i]);
av_freep(&st->internal->bsfcs);
}
+ av_bsf_free(&st->internal->extract_extradata.bsf);
+ av_packet_free(&st->internal->extract_extradata.pkt);
}
av_freep(&st->internal);
diff --git a/tests/ref/fate/copy-trac2211-avi b/tests/ref/fate/copy-trac2211-avi
index c22ca3d4da..007349e572 100644
--- a/tests/ref/fate/copy-trac2211-avi
+++ b/tests/ref/fate/copy-trac2211-avi
@@ -1,5 +1,5 @@
-dd199ecb167b2fa0fc0c17638a655e1c *tests/data/fate/copy-trac2211-avi.avi
-1777926 tests/data/fate/copy-trac2211-avi.avi
+6f6b211cbc8de9871e8e09e64048e2f9 *tests/data/fate/copy-trac2211-avi.avi
+1777924 tests/data/fate/copy-trac2211-avi.avi
#tb 0: 1/14
#media_type 0: video
#codec_id 0: rawvideo
diff --git a/tests/ref/fate/h264_mp4toannexb_ticket2991 b/tests/ref/fate/h264_mp4toannexb_ticket2991
index 4c73d7da44..76bdf3cae7 100644
--- a/tests/ref/fate/h264_mp4toannexb_ticket2991
+++ b/tests/ref/fate/h264_mp4toannexb_ticket2991
@@ -1,6 +1,6 @@
05d66e60ab22ee004720e0051af0fe74 *tests/data/fate/h264_mp4toannexb_ticket2991.h264
1985815 tests/data/fate/h264_mp4toannexb_ticket2991.h264
-#extradata 0: 79, 0x1ec61105
+#extradata 0: 47, 0x3a590d55
#tb 0: 1/1200000
#media_type 0: video
#codec_id 0: h264
diff --git a/tests/ref/fate/h264_mp4toannexb_ticket5927 b/tests/ref/fate/h264_mp4toannexb_ticket5927
index 60a1deb8e1..95e35c4d80 100644
--- a/tests/ref/fate/h264_mp4toannexb_ticket5927
+++ b/tests/ref/fate/h264_mp4toannexb_ticket5927
@@ -1,6 +1,6 @@
a3b02fd09392e01619cebc959d4d9ff2 *tests/data/fate/h264_mp4toannexb_ticket5927.h264
595583 tests/data/fate/h264_mp4toannexb_ticket5927.h264
-#extradata 0: 59, 0xf10e1136
+#extradata 0: 33, 0x84fe08f8
#tb 0: 1/1200000
#media_type 0: video
#codec_id 0: h264
diff --git a/tests/ref/fate/h264_mp4toannexb_ticket5927_2 b/tests/ref/fate/h264_mp4toannexb_ticket5927_2
index b5f11e3432..8db6a7e54a 100644
--- a/tests/ref/fate/h264_mp4toannexb_ticket5927_2
+++ b/tests/ref/fate/h264_mp4toannexb_ticket5927_2
@@ -1,6 +1,6 @@
a3b02fd09392e01619cebc959d4d9ff2 *tests/data/fate/h264_mp4toannexb_ticket5927_2.h264
595583 tests/data/fate/h264_mp4toannexb_ticket5927_2.h264
-#extradata 0: 59, 0xf10e1136
+#extradata 0: 33, 0x84fe08f8
#tb 0: 1/1200000
#media_type 0: video
#codec_id 0: h264
diff --git a/tests/ref/fate/segment-mp4-to-ts b/tests/ref/fate/segment-mp4-to-ts
index 8513027b9f..847c1a297d 100644
--- a/tests/ref/fate/segment-mp4-to-ts
+++ b/tests/ref/fate/segment-mp4-to-ts
@@ -1,4 +1,4 @@
-#extradata 0: 795, 0x395101dc
+#extradata 0: 50, 0x4f1b0df9
#tb 0: 1/90000
#media_type 0: video
#codec_id 0: h264