From patchwork Sat Sep 10 04:37:16 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodger Combs X-Patchwork-Id: 514 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.140.134 with SMTP id o128csp631720vsd; Fri, 9 Sep 2016 21:38:19 -0700 (PDT) X-Received: by 10.28.167.151 with SMTP id q145mr712984wme.76.1473482299866; Fri, 09 Sep 2016 21:38:19 -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 e4si2116932wjc.142.2016.09.09.21.38.17; Fri, 09 Sep 2016 21:38:19 -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 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 DEE3F689E96; Sat, 10 Sep 2016 07:37:58 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oi0-f67.google.com (mail-oi0-f67.google.com [209.85.218.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2CB6B689D7E for ; Sat, 10 Sep 2016 07:37:52 +0300 (EEST) Received: by mail-oi0-f67.google.com with SMTP id s71so10256831oih.3 for ; Fri, 09 Sep 2016 21:38:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:subject:date:message-id:in-reply-to:references; bh=1urV7aMhm5hBi5/cncWp3D06NwDnFo7dNM4PM6ikdX0=; b=wsSsvp7O4GYf+nzJIlfzijmciWHbNsoeKSRnDQsHvH5LKLKhibQJyeg/4MwQBJfHG6 kGvjJVwchWL1fqR3Ny4HnFfw6OvKSdGOVuFbmjxJG4aShJFDqBe9VdB4oEX96UmBKs8t K7lsGiCRFvp4ZNYWlNkGWliZTycexyKypJyyo5Bo6rcwCyyhBHwq05cuZXeC3x0KuSUs lBogxFSrqI5cXQYOenpJJw9K6i9lDh87xSQO1WzN8d5tt0hzfFEqHbg/ADWD8fxXhHEc cMz/eD7YZKrypXDd67t24OMEjybJ/u15/tIYIk/EOg56kmRDnMbBMri8lMBVxyFcTLoy R2cA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=1urV7aMhm5hBi5/cncWp3D06NwDnFo7dNM4PM6ikdX0=; b=dvz/OZAcG6HvWH289ygxeiaKYRX0qSX6jd39mojnXiPfiHgxri4oI5B9aPNa/vYsHQ GButlx83w+33hw2q0WcN/P2a5IuW5w+TOUnggcV1ho9Pwn+Zjak65bb57srsrOfFs6i3 ct/3Gr0Avljgt9CS5FFIc4OcniTdJnEkdMwSx7mwn5E5sow0K5hMVKMT6Mn3cBsDjx4I +Fy5NcTJgO8Z5WxV9+SH/kl8Vq/GPmtVxvhDOMUO1qWemH8WHRK31ZSQpa0C9WwIFugq JFQccUFSU6ILuMtre2KTG23l97n1j4b0wHGsw7Kf2YrIQaDlN5FoCusgc8DtWgY6ZmPv EHfw== X-Gm-Message-State: AE9vXwMdwLaO8Ymg+l2FljlWJlVYBfYeeCZAYynLgLHi5oJzJPae2FbNGpawDwnl9lw38A== X-Received: by 10.202.71.80 with SMTP id u77mr10053210oia.153.1473482281648; Fri, 09 Sep 2016 21:38:01 -0700 (PDT) Received: from Rodgers-MacBook-Pro.local.net (c-73-209-137-129.hsd1.il.comcast.net. [73.209.137.129]) by smtp.gmail.com with ESMTPSA id s185sm3616106ita.21.2016.09.09.21.37.58 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 09 Sep 2016 21:38:01 -0700 (PDT) From: Rodger Combs To: ffmpeg-devel@ffmpeg.org Date: Fri, 9 Sep 2016 23:37:16 -0500 Message-Id: <20160910043725.98484-2-rodger.combs@gmail.com> X-Mailer: git-send-email 2.10.0 In-Reply-To: <20160910043725.98484-1-rodger.combs@gmail.com> References: <20160910043725.98484-1-rodger.combs@gmail.com> Subject: [FFmpeg-devel] [PATCH 02/11] lavf/mux: add avformat_init_output 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 allows a consumer to run the muxer's init function without actually writing the header, which is useful in chained muxers that support automatic bitstream filtering. --- libavformat/avformat.h | 34 +++++++++++++++++++++++-- libavformat/internal.h | 10 ++++++++ libavformat/mux.c | 68 +++++++++++++++++++++++++++++++++++++++----------- libavformat/version.h | 4 +-- 4 files changed, 98 insertions(+), 18 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 585f00b..7ac9127 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -618,6 +618,8 @@ typedef struct AVOutputFormat { * AVStream parameters that need to be set before packets are sent. * This method must not write output. * + * Return 0 if streams were fully configured, 1 if not, negative AVERROR on failure + * * Any allocations made here must be freed in deinit(). */ int (*init)(struct AVFormatContext *); @@ -2370,6 +2372,10 @@ void avformat_close_input(AVFormatContext **s); * @addtogroup lavf_encoding * @{ */ + +#define AVSTREAM_INIT_IN_WRITE_HEADER 0 ///< stream parameters initialized in avformat_write_header +#define AVSTREAM_INIT_IN_INIT_OUTPUT 1 ///< stream parameters initialized in avformat_init_output + /** * Allocate the stream private data and write the stream header to * an output media file. @@ -2381,14 +2387,38 @@ void avformat_close_input(AVFormatContext **s); * On return this parameter will be destroyed and replaced with a dict containing * options that were not found. May be NULL. * - * @return 0 on success, negative AVERROR on failure. + * @return AVSTREAM_INIT_IN_WRITE_HEADER on success if the codec had not already been fully initialized in avformat_init, + * AVSTREAM_INIT_IN_INIT_OUTPUT on success if the codec had already been fully initialized in avformat_init, + * negative AVERROR on failure. * - * @see av_opt_find, av_dict_set, avio_open, av_oformat_next. + * @see av_opt_find, av_dict_set, avio_open, av_oformat_next, avformat_init_output. */ av_warn_unused_result int avformat_write_header(AVFormatContext *s, AVDictionary **options); /** + * Allocate the stream private data and initialize the codec, but do not write the header. + * May optionally be used before avformat_write_header to initialize stream parameters + * before actually writing the header. + * If using this function, do not pass the same options to avformat_write_header. + * + * @param s Media file handle, must be allocated with avformat_alloc_context(). + * Its oformat field must be set to the desired output format; + * Its pb field must be set to an already opened AVIOContext. + * @param options An AVDictionary filled with AVFormatContext and muxer-private options. + * On return this parameter will be destroyed and replaced with a dict containing + * options that were not found. May be NULL. + * + * @return AVSTREAM_INIT_IN_WRITE_HEADER on success if the codec requires avformat_write_header to fully initialize, + * AVSTREAM_INIT_IN_INIT_OUTPUT on success if the codec has been fully initialized, + * negative AVERROR on failure. + * + * @see av_opt_find, av_dict_set, avio_open, av_oformat_next, avformat_write_header. + */ +av_warn_unused_result +int avformat_init_output(AVFormatContext *s, AVDictionary **options); + +/** * Write a packet to an output media file. * * This function passes the packet directly to the muxer, without any buffering diff --git a/libavformat/internal.h b/libavformat/internal.h index f9278c5..71bcf22 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -125,6 +125,16 @@ struct AVFormatInternal { */ int header_written; int write_header_ret; + + /** + * Whether or not avformat_init_output has already been called + */ + int initialized; + + /** + * Whether or not avformat_init_output fully initialized streams + */ + int streams_initialized; }; struct AVStreamInternal { diff --git a/libavformat/mux.c b/libavformat/mux.c index 10d2ba3..a8baee4e 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -423,10 +423,13 @@ FF_ENABLE_DEPRECATION_WARNINGS *options = tmp; } - if (s->oformat->init && (ret = s->oformat->init(s)) < 0) { - if (s->oformat->deinit) - s->oformat->deinit(s); - goto fail; + if (s->oformat->init) { + if ((ret = s->oformat->init(s)) < 0) { + if (s->oformat->deinit) + s->oformat->deinit(s); + return ret; + } + return ret == 0; } return 0; @@ -493,31 +496,64 @@ static int write_header_internal(AVFormatContext *s) return 0; } -int avformat_write_header(AVFormatContext *s, AVDictionary **options) +int avformat_init_output(AVFormatContext *s, AVDictionary **options) { int ret = 0; if ((ret = init_muxer(s, options)) < 0) return ret; + s->internal->initialized = 1; + s->internal->streams_initialized = ret; + + if (s->oformat->init && ret) { + if ((ret = init_pts(s)) < 0) + return ret; + + if (s->avoid_negative_ts < 0) { + av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO); + if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) { + s->avoid_negative_ts = 0; + } else + s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE; + } + + return AVSTREAM_INIT_IN_INIT_OUTPUT; + } + + return AVSTREAM_INIT_IN_WRITE_HEADER; +} + +int avformat_write_header(AVFormatContext *s, AVDictionary **options) +{ + int ret = 0; + int already_initialized = s->internal->initialized; + int streams_already_initialized = s->internal->streams_initialized; + + if (!already_initialized) + if ((ret = avformat_init_output(s, options)) < 0) + return ret; + if (!(s->oformat->check_bitstream && s->flags & AVFMT_FLAG_AUTO_BSF)) { ret = write_header_internal(s); if (ret < 0) goto fail; } - if ((ret = init_pts(s)) < 0) - goto fail; + if (!s->internal->streams_initialized) { + if ((ret = init_pts(s)) < 0) + goto fail; - if (s->avoid_negative_ts < 0) { - av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO); - if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) { - s->avoid_negative_ts = 0; - } else - s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE; + if (s->avoid_negative_ts < 0) { + av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO); + if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) { + s->avoid_negative_ts = 0; + } else + s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE; + } } - return 0; + return streams_already_initialized; fail: if (s->oformat->deinit) @@ -1253,6 +1289,10 @@ fail: if (s->oformat->deinit) s->oformat->deinit(s); + s->internal->header_written = + s->internal->initialized = + s->internal->streams_initialized = 0; + if (s->pb) avio_flush(s->pb); if (ret == 0) diff --git a/libavformat/version.h b/libavformat/version.h index 90ac534..34226ca 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,8 +32,8 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 57 -#define LIBAVFORMAT_VERSION_MINOR 48 -#define LIBAVFORMAT_VERSION_MICRO 103 +#define LIBAVFORMAT_VERSION_MINOR 49 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \