[FFmpeg-cvslog] lavf: use the new bitstream filter for extracting extradata
James Almer
git at videolan.org
Fri Apr 7 23:20:23 EEST 2017
ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Fri Mar 24 18:42:19 2017 -0300| [b8f26779d615dfb466e90627323b1a4e40639f76] | committer: James Almer
lavf: use the new bitstream filter for extracting extradata
This merges commits 8e2ea691351c5079cdab245ff7bfa5c0f3e3bfe4 and
096a8effa3f8f3455292c958c3ed07e798def7bd by Anton Khirnov, with the
following change:
- extract_extradata_check() is added to know if the codec is supported
by the bsf before trying to initialize it. This behaviour is similar to
the old AVCodecParser.split checks.
The FATE reference changes are due to the filtered out NAL units that
the old AVCodecParser.split implementation left alone.
Decoding is unchanged as the functions that parse extradata simply
ignored said unnecessary NAL units.
Signed-off-by: James Almer <jamrial at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=b8f26779d615dfb466e90627323b1a4e40639f76
---
libavformat/internal.h | 9 ++
libavformat/utils.c | 146 ++++++++++++++++++++++++---
tests/ref/fate/copy-trac2211-avi | 4 +-
tests/ref/fate/h264_mp4toannexb_ticket2991 | 2 +-
tests/ref/fate/h264_mp4toannexb_ticket5927 | 2 +-
tests/ref/fate/h264_mp4toannexb_ticket5927_2 | 2 +-
tests/ref/fate/segment-mp4-to-ts | 2 +-
7 files changed, 148 insertions(+), 19 deletions(-)
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 63a1724..c856945 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 a059046..ba82a76 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 c22ca3d..007349e 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 4c73d7d..76bdf3c 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 60a1deb..95e35c4 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 b5f11e3..8db6a7e 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 8513027..847c1a2 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
More information about the ffmpeg-cvslog
mailing list