From patchwork Wed Mar 14 06:24:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rodger Combs X-Patchwork-Id: 7983 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.1.70 with SMTP id c67csp1636304jad; Tue, 13 Mar 2018 23:25:45 -0700 (PDT) X-Google-Smtp-Source: AG47ELugqPfmCMxI4SoJBHiA4IvrhizRcX2xah0S7HPXCFd5ryfJQJSNRWfZY2eQQ1oaFNR6gR0J X-Received: by 10.28.108.7 with SMTP id h7mr549931wmc.35.1521008745806; Tue, 13 Mar 2018 23:25:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521008745; cv=none; d=google.com; s=arc-20160816; b=ARE//wol2Pk3KUbQrhanWKuN8DFH8uROFLX6QIYCeaC4IhtCkzqcw8YmJZgxliBLiS eD3KksunwLUvcusyH1r7A+tKwEE2MAiJdofOTedgKzwGZlTRX0QlZsofNBt3Je7J5U69 ELI6O3d9RW47cxkHa0nxx2zZBzntY/ZjlM+4DWeKCArQA7WzXZEVb3S3FVaSMGyWCC0J GFK7A6v+Q622xtJdjsnBLIn+3OT7LUQBERwzm6HcufNyFJJv/j/FMTz7zmLXWn5VQ400 K6E5wzMBoFBnfTdBJXD/TRvznU/Iq/m/Oji6af7c4/sS0LXmO5v4a6dP1PeDAGTMAjNM dZoA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=9gEHGMDZDryVNsmAPdpy6E3bABhFzDM1wnPAqin0quw=; b=gSKjkRfm1k0w5UsVbPQI+rAQFyvanonLth1UIeQsSgS0A3QpKAlxfv/VhdygA5WLcX SqeEIS5yG53jr4Lx/N+S3NFQ+t8/0BahbdBfyEIJQ0O8bWeMFS0knOKYVqgusELJ6DPi SmV6GXGe/+Z93RWQxdvtB7lEKp7/9Irvj0W7vCG5Lrn8JsCg/5MFXf2tpFnWyRclesB3 CnOH5NXNdauNGVvenrGKh+qfvGVTFqLoy/TSjD3z0NYNXayqslr0ZRH3ZnRZw1AtCg+A 57yDUS5WA8ROw9dRcKAFwBXKDGSh2JMO1SBHfoO11biRbHT91bQ/46/A2y++vVZWe9t+ rk6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=jYgpsWaA; 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=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id m21si375979wmi.8.2018.03.13.23.25.45; Tue, 13 Mar 2018 23:25:45 -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 header.s=20161025 header.b=jYgpsWaA; 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=QUARANTINE 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 78E0668A123; Wed, 14 Mar 2018 08:24:52 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-it0-f51.google.com (mail-it0-f51.google.com [209.85.214.51]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C77A1689F29 for ; Wed, 14 Mar 2018 08:24:44 +0200 (EET) Received: by mail-it0-f51.google.com with SMTP id w63-v6so3150300ita.3 for ; Tue, 13 Mar 2018 23:24:56 -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=Y2K9a+wIY1lizxYflP5LYgUzOWLabbu6KK+AO+GWivg=; b=jYgpsWaAGYj5kmq8FeuUaIJONORMQ5xaNpRc9ty9sHfa3MzFwdflg9y9T3K/SawIxj 4z/93Ta7lJzYifHLxeshe5ONm+l5Nv+48g0mTQV8yvnOSMrrtvsLxRyUmjQLbzqdCL/s 1nXHyyC2nKAOrKrqWDtExGJ0Ckn4InY6TzeyCRpxmWfoJ35pDlL5CyBRQTGQjZILaRY9 Woq9IO7MioZr82dj9Tetqw8/jHRfQTCSjdG4uY4Wibf+MH85bcdMzGRbTdfLCv2n6q2R Xj6uvPVdB1cmVruBh58RyS3xY2xFxVU9Vm8B0k0xPNq+hOstv2fPV/9K40AZYJifndHa xgZg== 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=Y2K9a+wIY1lizxYflP5LYgUzOWLabbu6KK+AO+GWivg=; b=M9yFt7/aNFvfJKU6K7vxraF7CqdglbL0D/yF4wfQwnjaA3Ru4HVP/j44zrxem5HKcx Gu7PjI6LUyAL36kqaEQpXtE2Ag07TSYz78uiRcM0lI6lC5+CxNF+PrtRTITxRsB+WZMh bwRMM3FZCCQvHkgmOQqEKYEZN+jcsHPR6cAFGjumKJ6fbeHQ06Pz+hF1ydV/UXSr+AFS em4TDrybooDWVQK4u2t6XazspHd3/9rIIIOSZnhfGrhG20crPJYFvHmTHyaRmoJZhVED Sd5M1bT1DKalWoLAn/Bt6Z8yT5cwe2XYCwrisIGZa/Wk+xOBa/Xr8bvQOxbL9v6+R3fC P2FQ== X-Gm-Message-State: AElRT7Gm//9+vavVh216jb2P/DdKXeMp4geGfjARsnocrar+emXObROy Xsgjc0UlHKOBCs495IzUkpzUR6Bm X-Received: by 10.36.145.199 with SMTP id i190mr770850ite.50.1521008694415; Tue, 13 Mar 2018 23:24:54 -0700 (PDT) Received: from Rodgers-MBP.localdomain ([71.201.155.37]) by smtp.gmail.com with ESMTPSA id v134-v6sm394596ith.27.2018.03.13.23.24.53 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 13 Mar 2018 23:24:53 -0700 (PDT) From: Rodger Combs To: ffmpeg-devel@ffmpeg.org Date: Wed, 14 Mar 2018 01:24:41 -0500 Message-Id: <20180314062445.89909-6-rodger.combs@gmail.com> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180314062445.89909-1-rodger.combs@gmail.com> References: <20180314062445.89909-1-rodger.combs@gmail.com> Subject: [FFmpeg-devel] [PATCH 06/10] Revert "avformat/mux: stop delaying writing the header" 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 reverts commit d6d605eb05c3ca32f591016c345eb2ad9e81c554. --- libavformat/avformat.h | 2 +- libavformat/internal.h | 6 +++++ libavformat/mux.c | 52 ++++++++++++++++++++++++++++++++++-------- libavformat/options_table.h | 2 +- libavformat/tests/fifo_muxer.c | 52 ++++++++++++++++++++++++++++++++++++++++++ tests/ref/fate/fifo-muxer-tst | 1 + tests/ref/fate/rgb24-mkv | 4 ++-- 7 files changed, 105 insertions(+), 14 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index a2fe7c6bb2..9e87d6cdac 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1482,7 +1482,7 @@ typedef struct AVFormatContext { #endif #define AVFMT_FLAG_FAST_SEEK 0x80000 ///< Enable fast, but inaccurate seeks for some formats #define AVFMT_FLAG_SHORTEST 0x100000 ///< Stop muxing when the shortest stream stops. -#define AVFMT_FLAG_AUTO_BSF 0x200000 ///< Add bitstream filters as requested by the muxer +#define AVFMT_FLAG_AUTO_BSF 0x200000 ///< Wait for packet data before writing a header, and add bitstream filters as requested by the muxer /** * Maximum size of the data read from input for determining diff --git a/libavformat/internal.h b/libavformat/internal.h index a020b1b417..666e2054a7 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -120,6 +120,12 @@ struct AVFormatInternal { int avoid_negative_ts_use_pts; + /** + * Whether or not a header has already been written + */ + int header_written; + int write_header_ret; + /** * Timestamp of the end of the shortest stream. */ diff --git a/libavformat/mux.c b/libavformat/mux.c index a13f0e3a1b..5fdc9275cc 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -485,6 +485,25 @@ static void flush_if_needed(AVFormatContext *s) } } +static int write_header_internal(AVFormatContext *s) +{ + if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb) + avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_HEADER); + if (s->oformat->write_header) { + int ret = s->oformat->write_header(s); + if (ret >= 0 && s->pb && s->pb->error < 0) + ret = s->pb->error; + s->internal->write_header_ret = ret; + if (ret < 0) + return ret; + flush_if_needed(s); + } + s->internal->header_written = 1; + if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb) + avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_UNKNOWN); + return 0; +} + int avformat_init_output(AVFormatContext *s, AVDictionary **options) { int ret = 0; @@ -515,18 +534,11 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) if ((ret = avformat_init_output(s, options)) < 0) return ret; - if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb) - avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_HEADER); - if (s->oformat->write_header) { - ret = s->oformat->write_header(s); - if (ret >= 0 && s->pb && s->pb->error < 0) - ret = s->pb->error; + if (!(s->oformat->check_bitstream && s->flags & AVFMT_FLAG_AUTO_BSF)) { + ret = write_header_internal(s); if (ret < 0) goto fail; - flush_if_needed(s); } - if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb) - avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_UNKNOWN); if (!s->internal->streams_initialized) { if ((ret = init_pts(s)) < 0) @@ -738,6 +750,12 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) } } + if (!s->internal->header_written) { + ret = s->internal->write_header_ret ? s->internal->write_header_ret : write_header_internal(s); + if (ret < 0) + goto fail; + } + if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) { AVFrame *frame = (AVFrame *)pkt->data; av_assert0(pkt->size == UNCODED_FRAME_PACKET_SIZE); @@ -753,6 +771,8 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) ret = s->pb->error; } +fail: + if (ret < 0) { pkt->pts = pts_backup; pkt->dts = dts_backup; @@ -885,6 +905,11 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt) if (!pkt) { if (s->oformat->flags & AVFMT_ALLOW_FLUSH) { + if (!s->internal->header_written) { + ret = s->internal->write_header_ret ? s->internal->write_header_ret : write_header_internal(s); + if (ret < 0) + return ret; + } ret = s->oformat->write_packet(s, NULL); flush_if_needed(s); if (ret >= 0 && s->pb && s->pb->error < 0) @@ -1268,8 +1293,14 @@ int av_write_trailer(AVFormatContext *s) goto fail; } + if (!s->internal->header_written) { + ret = s->internal->write_header_ret ? s->internal->write_header_ret : write_header_internal(s); + if (ret < 0) + goto fail; + } + fail: - if (s->oformat->write_trailer) { + if (s->internal->header_written && s->oformat->write_trailer) { if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb) avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER); if (ret >= 0) { @@ -1282,6 +1313,7 @@ fail: if (s->oformat->deinit) s->oformat->deinit(s); + s->internal->header_written = s->internal->initialized = s->internal->streams_initialized = 0; diff --git a/libavformat/options_table.h b/libavformat/options_table.h index b8fa47c6fd..b60d031f67 100644 --- a/libavformat/options_table.h +++ b/libavformat/options_table.h @@ -57,7 +57,7 @@ static const AVOption avformat_options[] = { {"seek2any", "allow seeking to non-keyframes on demuxer level when supported", OFFSET(seek2any), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, D}, {"bitexact", "do not write random/volatile data", 0, AV_OPT_TYPE_CONST, { .i64 = AVFMT_FLAG_BITEXACT }, 0, 0, E, "fflags" }, {"shortest", "stop muxing with the shortest stream", 0, AV_OPT_TYPE_CONST, { .i64 = AVFMT_FLAG_SHORTEST }, 0, 0, E, "fflags" }, -{"autobsf", "add needed bsfs automatically", 0, AV_OPT_TYPE_CONST, { .i64 = AVFMT_FLAG_AUTO_BSF }, 0, 0, E, "fflags" }, +{"autobsf", "add needed bsfs automatically (delays header until each stream's first packet is written)", 0, AV_OPT_TYPE_CONST, { .i64 = AVFMT_FLAG_AUTO_BSF }, 0, 0, E, "fflags" }, {"analyzeduration", "specify how many microseconds are analyzed to probe the input", OFFSET(max_analyze_duration), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, D}, {"cryptokey", "decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D}, {"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), AV_OPT_TYPE_INT, {.i64 = 1<<20 }, 0, INT_MAX, D}, diff --git a/libavformat/tests/fifo_muxer.c b/libavformat/tests/fifo_muxer.c index 5127a8aadb..13a55db3a9 100644 --- a/libavformat/tests/fifo_muxer.c +++ b/libavformat/tests/fifo_muxer.c @@ -130,6 +130,54 @@ fail: return ret; } +static int fifo_write_header_err_tst(AVFormatContext *oc, AVDictionary **opts, + const FailingMuxerPacketData *pkt_data) +{ + int ret = 0, i; + AVPacket pkt; + + av_init_packet(&pkt); + + ret = avformat_write_header(oc, opts); + if (ret) { + fprintf(stderr, "Unexpected write_header failure: %s\n", + av_err2str(ret)); + goto fail; + } + + for (i = 0; i < MAX_TST_PACKETS; i++ ) { + ret = prepare_packet(&pkt, pkt_data, i); + if (ret < 0) { + fprintf(stderr, "Failed to prepare test packet: %s\n", + av_err2str(ret)); + goto write_trailer_and_fail; + } + ret = av_write_frame(oc, &pkt); + av_packet_unref(&pkt); + if (ret < 0) { + break; + } + } + + if (!ret) { + fprintf(stderr, "write_packet not failed when supposed to.\n"); + goto fail; + } else if (ret != -1) { + fprintf(stderr, "Unexpected write_packet error: %s\n", av_err2str(ret)); + goto fail; + } + + ret = av_write_trailer(oc); + if (ret < 0) + fprintf(stderr, "Unexpected write_trailer error: %s\n", av_err2str(ret)); + + return ret; +write_trailer_and_fail: + av_write_trailer(oc); +fail: + return ret; +} + static int fifo_overflow_drop_test(AVFormatContext *oc, AVDictionary **opts, const FailingMuxerPacketData *data) { @@ -247,6 +295,10 @@ const TestCase tests[] = { * exactly what was on input */ {fifo_basic_test, "nonfail test", NULL,1, 0, 0, {0, 0, 0}}, + /* Test that we receive delayed write_header error from one of the write_packet + * calls. */ + {fifo_write_header_err_tst, "write header error test", NULL, 0, -1, 0, {0, 0, 0}}, + /* Each write_packet will fail 3 times before operation is successful. If recovery * Since recovery is on, fifo muxer should not return any errors. */ {fifo_basic_test, "recovery test", "attempt_recovery=1:recovery_wait_time=0", diff --git a/tests/ref/fate/fifo-muxer-tst b/tests/ref/fate/fifo-muxer-tst index e1139ee0a8..ca7e294860 100644 --- a/tests/ref/fate/fifo-muxer-tst +++ b/tests/ref/fate/fifo-muxer-tst @@ -2,6 +2,7 @@ flush count: 1 pts seen nr: 15 pts seen: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 nonfail test: ok +write header error test: ok recovery test: ok flush count: 1 pts seen nr: 15 diff --git a/tests/ref/fate/rgb24-mkv b/tests/ref/fate/rgb24-mkv index 439b2bc5e9..4c357accaf 100644 --- a/tests/ref/fate/rgb24-mkv +++ b/tests/ref/fate/rgb24-mkv @@ -1,5 +1,5 @@ -09ee413b2d92a6be5e3b18e9e20a1f74 *tests/data/fate/rgb24-mkv.matroska -58342 tests/data/fate/rgb24-mkv.matroska +55270be3b5d393d770a1dfcb19b68271 *tests/data/fate/rgb24-mkv.matroska +58345 tests/data/fate/rgb24-mkv.matroska #tb 0: 1/10 #media_type 0: video #codec_id 0: rawvideo