From patchwork Sun Apr 2 00:03:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 3238 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.44.195 with SMTP id s186csp2631302vss; Sat, 1 Apr 2017 17:04:17 -0700 (PDT) X-Received: by 10.223.161.132 with SMTP id u4mr8624150wru.203.1491091457348; Sat, 01 Apr 2017 17:04:17 -0700 (PDT) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id m184si9294448wmd.35.2017.04.01.17.04.16; Sat, 01 Apr 2017 17:04:17 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2DA5A689A99; Sun, 2 Apr 2017 03:04:13 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt0-f196.google.com (mail-qt0-f196.google.com [209.85.216.196]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7B45A689A5D for ; Sun, 2 Apr 2017 03:04:06 +0300 (EEST) Received: by mail-qt0-f196.google.com with SMTP id n37so14799592qtb.3 for ; Sat, 01 Apr 2017 17:04:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id; bh=u6u7isH/wXqM23pkZ6y9KxMNeOMJtg6b/OkYUOqFPUo=; b=j1aV7MK56w70thiKTNRXOT6MwMFrF/Kz3CE6zVCdFg2X5Y/6PJwqY8CjVUV7d67IGe GeP9WNPbNDkPcA/Daz1RMa9mgkjBjCo9t71NKNQm+fmCMsk7YZf1qLNV/KJpa0UyBQOC Pw5UctMu4fTTa0sOYw1pVAaiTRVz4gtMgBLnWNvGJ/cwXTiyxa5khHg8ITKpbgASqoql FXHubwwiPZyEDkV9tY5HSDwTbXmtWj5PhZ2ChuaJTU7DTtpDFy1RcWh6RDEYIVU1ayg0 lT6gtPyxMdQCXdsUBhxklYoQNGd0GBl7QsHNiixzSqCXN32fsykwR8aMGe1K7CPqV8hB Blog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=u6u7isH/wXqM23pkZ6y9KxMNeOMJtg6b/OkYUOqFPUo=; b=L/gimNgdagHQNrcRuqveqUDgsezzpA5TAT9wk+M5WSSFyijV2JzxylhY6GaxOMeFhV Ohy+9gl5D6dL14+vkhY54deHqAW/h9j9bYwivzxMHX8lf340Df8SsK342vzjPfUo6tIa ww5fQKZbkpQWkFzTqdc/83JhZRvqkY3+PaNxNgtDF9tV3tkckWn1mNtxiyR0o6M6n2d8 FGbn2HIhxLGuHCNdsUVUUmxwzKyJpgZH6LpRSX9HQdV6zgd90METxaSUQEzo5AyOOLwM JOY2nCcRakPt653HpANpSs6r1U9y+/vokOoQXEqAOWDPXKH0IsG6oNGnrovg9PSpg8HP 5Pzw== X-Gm-Message-State: AFeK/H3mrb9XU5n8U2L5PuY+z7lojvmFQiz2w+0C87OpMq9sYNjySchGnUZvCodI6f7mgw== X-Received: by 10.237.57.164 with SMTP id m33mr10664303qte.293.1491091446133; Sat, 01 Apr 2017 17:04:06 -0700 (PDT) Received: from localhost.localdomain ([181.231.62.139]) by smtp.gmail.com with ESMTPSA id p19sm6537610qtp.36.2017.04.01.17.04.04 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 01 Apr 2017 17:04:05 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Sat, 1 Apr 2017 21:03:39 -0300 Message-Id: <20170402000339.6180-1-jamrial@gmail.com> X-Mailer: git-send-email 2.12.1 Subject: [FFmpeg-devel] [PATCH v2] lavf: use the new bitstream filter for extracting extradata X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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 --- 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 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