From patchwork Sat Dec 21 18:02:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 16916 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 9AEB0448C81 for ; Sat, 21 Dec 2019 20:11:12 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 76FE168A9F3; Sat, 21 Dec 2019 20:11:12 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pf1-f193.google.com (mail-pf1-f193.google.com [209.85.210.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6F24168A88F for ; Sat, 21 Dec 2019 20:11:05 +0200 (EET) Received: by mail-pf1-f193.google.com with SMTP id i6so163200pfc.1 for ; Sat, 21 Dec 2019 10:11:05 -0800 (PST) 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:mime-version :content-transfer-encoding; bh=g4hCrP4wPSPx9D2CaDbJLzS0U6IZ8ZSXD6O1q54wBOY=; b=fJdfsQkZ2U119tn1h7Bb33N8jAWoF8aWyk9r0ObcbxTnx0ALzXXeQhmnsKDmqmHvZc TUwQfU6ZoAUSSmz2yPIrjnvqpw+u2yfAgfsX3yosflN4GfdIet4SInAHY3eK0Q+Jt5Ci ttGh5/n3B8ZKn9X9R2VufpA3lvV6Agfz2aQZUPUsBwIsCfpcHQEBa7YuivbxWwTIJkhT icEAr2Hob/5Yc9YNXj6QiM5g6SrWFmBlNOnCM/aFaYk/vjHmo8K9vGKo6UyJKpmSyMA1 o3jqcEnzyxmygM2F/dK+iJ26Po2hyg/i3U57S3spU0J6Eie2jeg57HSUACayY4r2SSnt JFLA== 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:mime-version:content-transfer-encoding; bh=g4hCrP4wPSPx9D2CaDbJLzS0U6IZ8ZSXD6O1q54wBOY=; b=cxGAAhEoczwz3lfClt4a0UY80knPKnADcNL0s3rhCvIVByorK18g6wbfrhmO9T2yf+ w384r3sSKGeuPE/aVwKHOCuHbnokt9cdWLUmbOeBuOiW2U2Fgttp0rdnylZoIhOaDJvM krZY+QGKUAk8x5JPLcasTkn34dAAZbe8l5g65H9G7rqoTAj8B+9viYMVzqixXS34gRuu W2RGf5VGs1xlGIsp0cuuW85gvoLMTwJqth70RDpz4lfV6CuLl66oG6gE3tnZ7gTEMhdv UXbEe0IqdsnSYRrxIQgFbAwiUlWYyH4PSY475qckkrqLhLAuKMwqbUeTPT4qhkb2XTln 3cmA== X-Gm-Message-State: APjAAAXyjndCw/tP07jfMTXxrw/gHKpREPZc7V2h8VluzHtqLMradmhR ZWZ0lC8LRmIDtjKap2su+QSKuNgC X-Google-Smtp-Source: APXvYqw1BiA9thLtapdeIYAYtMFiN+rrTbqeBcsDzLUBuc93OA5H97o1/FuVvxssb/Uy9nFwwTzPBA== X-Received: by 2002:a63:e17:: with SMTP id d23mr22241282pgl.173.1576951421177; Sat, 21 Dec 2019 10:03:41 -0800 (PST) Received: from localhost.localdomain ([191.83.216.116]) by smtp.gmail.com with ESMTPSA id s196sm18223564pfs.136.2019.12.21.10.03.40 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 21 Dec 2019 10:03:40 -0800 (PST) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Sat, 21 Dec 2019 15:02:48 -0300 Message-Id: <20191221180252.6091-11-jamrial@gmail.com> X-Mailer: git-send-email 2.24.1 In-Reply-To: <20191221180252.6091-1-jamrial@gmail.com> References: <20191221180252.6091-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 11/15] avformat/movenc: add a flag to enable CMAF compatability 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Sets some required constrains and reports compatibility with the relevant compatible brand. Signed-off-by: James Almer --- libavformat/movenc.c | 25 +++++++++++++++++++++++-- libavformat/movenc.h | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 5d3399071e..3c807d9270 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -72,6 +72,7 @@ static const AVOption options[] = { { "disable_chpl", "Disable Nero chapter atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DISABLE_CHPL}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "default_base_moof", "Set the default-base-is-moof flag in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DEFAULT_BASE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "dash", "Write DASH compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DASH}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, + { "cmaf", "Write CMAF compatible fragmented MP4", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_CMAF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "frag_discont", "Signal that the next fragment is discontinuous from earlier ones", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_DISCONT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "delay_moov", "Delay writing the initial moov until the first fragment is cut, or until the first fragment flush", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DELAY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "global_sidx", "Write a global sidx index at the start of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_GLOBAL_SIDX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, @@ -4210,6 +4211,9 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov, flags &= ~MOV_TFHD_BASE_DATA_OFFSET; flags |= MOV_TFHD_DEFAULT_BASE_IS_MOOF; } + /* CMAF requires all values to be explicit in tfhd atoms */ + if (mov->flags & FF_MOV_FLAG_CMAF) + flags |= MOV_TFHD_STSD_ID; /* Don't set a default sample size, the silverlight player refuses * to play files with that set. Don't set a default sample duration, @@ -4217,7 +4221,7 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov, * file format says it MUST NOT be set. */ if (track->mode == MODE_ISM) flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION | - MOV_TFHD_BASE_DATA_OFFSET); + MOV_TFHD_BASE_DATA_OFFSET | MOV_TFHD_STSD_ID); avio_wb32(pb, 0); /* size placeholder */ ffio_wfourcc(pb, "tfhd"); @@ -4227,6 +4231,9 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov, avio_wb32(pb, track->track_id); /* track-id */ if (flags & MOV_TFHD_BASE_DATA_OFFSET) avio_wb64(pb, moof_offset); + if (flags & MOV_TFHD_STSD_ID) { + avio_wb32(pb, 1); + } if (flags & MOV_TFHD_DEFAULT_DURATION) { track->default_duration = get_cluster_duration(track, 0); avio_wb32(pb, track->default_duration); @@ -4818,6 +4825,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) // brand, if not already the major brand. This is compatible with users that // don't understand tfdt. if (mov->mode == MODE_MP4) { + if (mov->flags & FF_MOV_FLAG_CMAF) + ffio_wfourcc(pb, "cmfc"); if (mov->flags & FF_MOV_FLAG_FRAGMENT && !(mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)) ffio_wfourcc(pb, "iso6"); } else { @@ -6183,6 +6192,9 @@ static int mov_init(AVFormatContext *s) if (mov->flags & FF_MOV_FLAG_DASH) mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_DEFAULT_BASE_MOOF; + if (mov->flags & FF_MOV_FLAG_CMAF) + mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV | + FF_MOV_FLAG_DEFAULT_BASE_MOOF | FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS; if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) { av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n"); @@ -6209,12 +6221,21 @@ static int mov_init(AVFormatContext *s) s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO) mov->use_editlist = 0; } + if (mov->flags & FF_MOV_FLAG_CMAF) { + // CMAF Track requires negative cts offsets without edit lists + mov->use_editlist = 0; + } } if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && !(mov->flags & FF_MOV_FLAG_DELAY_MOOV) && mov->use_editlist) av_log(s, AV_LOG_WARNING, "No meaningful edit list will be written when using empty_moov without delay_moov\n"); - if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO) + if (mov->flags & FF_MOV_FLAG_CMAF && mov->use_editlist) { + av_log(s, AV_LOG_WARNING, "Edit list enabled; Assuming writing CMAF Track File\n"); + mov->flags &= ~FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS; + } + if (!mov->use_editlist && s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO && + !(mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS)) s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_ZERO; /* Clear the omit_tfhd_offset flag if default_base_moof is set; diff --git a/libavformat/movenc.h b/libavformat/movenc.h index a3c6467c67..6ac106c653 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -259,6 +259,7 @@ typedef struct MOVMuxContext { #define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS (1 << 19) #define FF_MOV_FLAG_FRAG_EVERY_FRAME (1 << 20) #define FF_MOV_FLAG_SKIP_SIDX (1 << 21) +#define FF_MOV_FLAG_CMAF (1 << 22) int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);