From patchwork Fri Mar 24 22:31:47 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 3088 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.50.79 with SMTP id y76csp293539vsy; Fri, 24 Mar 2017 15:33:33 -0700 (PDT) X-Received: by 10.223.134.86 with SMTP id 22mr29193wrw.22.1490394813018; Fri, 24 Mar 2017 15:33:33 -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 z50si5219075wrz.218.2017.03.24.15.33.32; Fri, 24 Mar 2017 15:33:32 -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 5F94B689777; Sat, 25 Mar 2017 00:32:24 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt0-f195.google.com (mail-qt0-f195.google.com [209.85.216.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3799D688370 for ; Sat, 25 Mar 2017 00:32:17 +0200 (EET) Received: by mail-qt0-f195.google.com with SMTP id x35so520032qtc.1 for ; Fri, 24 Mar 2017 15:32:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=YU1M/tIvUU7dPSNzljfok7LERIzfC0vLJkDL+qRUmZo=; b=UG0vt63yMwso6myp5+U9prC12Rxr72XZrEzptsB+H6v/+E5liB8XQ+OZr3wbuRn/Za 3eDiP+vN5nnqbB4QIiwZq5Kb7sEHfIcl1T19GVn8edDhO17fW/y+mGilB+bpQi+0+z8u RD2CIHoYuCu8X2f3Irc9ZF0yAYA/I6GJyTLWXB65MDilb86Lv0DZZJUVA3tK35kkBZEr HW4QGOlOQGuBw1YWogaifqAxqg+BTEWY2eT2qlkXFiXaEl+EePlJlvc9ujxxEFzyv8Jn TXExXKnF15EYNS1r5S9SfXsjolpwp+TQNBKVkxqxMjLV8h59wqGcmlDoC8NCYkYD2FHi LXLg== 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:in-reply-to :references; bh=YU1M/tIvUU7dPSNzljfok7LERIzfC0vLJkDL+qRUmZo=; b=ElLP/lTeIOxoOIEHhoYWJBWz3KvgnptGJff9aDclrhTRChZSlPakdXITcrY2JaeFF4 59RJyKjuOykh/j+QygMJrqrUU19mP+J1vA6uleaCUc9KUcoY9yoq+6p1lxHhVdCHTflN mZfPjX4sQfqbIxht+mysHyg/ttJze3izeGQze7HpJeDws+fJbCvPa6lS1FM0QiccHTCG GzWfVQaL4degp2a4AVZMlaTUhi2N2VV/PhlwGvetRVszvhJjPptmlXrP6Lb6IR+Kh3EM /23ol02aRQdcffNDRbrdqTXrHMwGu19p/UCWtS/iZT80xK8ChGxuIdCPIlcIh8i4zxWd xGOw== X-Gm-Message-State: AFeK/H0lqO36WkNI8dzquL7Dc1tWl4xVKXLPC6EE9FvbeiBzFLfGSjMFLyMYd3HDZ6pGOA== X-Received: by 10.237.37.229 with SMTP id y34mr10474634qtc.30.1490394756735; Fri, 24 Mar 2017 15:32:36 -0700 (PDT) Received: from localhost.localdomain ([181.231.62.139]) by smtp.gmail.com with ESMTPSA id e19sm2414824qta.68.2017.03.24.15.32.35 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 24 Mar 2017 15:32:36 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Fri, 24 Mar 2017 19:31:47 -0300 Message-Id: <20170324223147.2692-7-jamrial@gmail.com> X-Mailer: git-send-email 2.12.0 In-Reply-To: <20170324223147.2692-1-jamrial@gmail.com> References: <20170324223147.2692-1-jamrial@gmail.com> Subject: [FFmpeg-devel] [PATCH 6/6] 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 checks. Signed-off-by: James Almer --- libavformat/internal.h | 9 +++ libavformat/utils.c | 147 ++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 143 insertions(+), 13 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..f643db4a41 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3370,6 +3370,128 @@ 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; + + /* check that the codec id is supported */ + 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 +3651,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 +3804,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 +4067,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 +4256,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);