From patchwork Sat Sep 23 15:44:44 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jan_Ekstr=C3=B6m?= X-Patchwork-Id: 5245 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.36.26 with SMTP id f26csp781479jaa; Sat, 23 Sep 2017 08:52:01 -0700 (PDT) X-Received: by 10.223.178.203 with SMTP id g69mr2034002wrd.258.1506181921774; Sat, 23 Sep 2017 08:52:01 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506181921; cv=none; d=google.com; s=arc-20160816; b=ZXkoVDot6KUg6mNJGJ/aInXm64u7ihsu7t6jJx2gtgIoh+PO8yrU0zEr+6Eh5UiUQ8 uF4aQW3faZWtg2fE3ZkTLXkf7lCURSBVjm/Bm0x1LFStacpW2eFmwQ4LZWRnn6uthcsI dtKCjPUu+SlixOSAxS2xkzDknOOL5t8MGDcNVLPZM8i7xgPn6sD6w5r+b72gZ+KzoDTj sFgOltGCg0AzCOjHoQXFtLOlzf1YJnhRHPztrT25VPlm01vRY1w25RISFPnyG4D1MAHk 90+sA4RUsonErmrYyzKCg2bs2JB+00Gi0IrQKtvtxVy1d9lMyHSef5mmiJiB2hL6ZM+l MEmg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to:arc-authentication-results; bh=UgIBDgnnRO1qIAfctOpmVRcTnR942vQmkLmKsz2Vkbs=; b=zoRevuqtjjHfAQjI2QkeGn7TKIK1icyNGHNY1dq9uXJIZi0zan9ubJIBxCjRUU/Efb v2e8RF+xr0WnmrgUlNn/Ovi5vB8dHXESgfzjZfF1eKz6N8t1EgAFIvQKPdcaklXDAYjP AVTqZBfIuLMqcvo4LNGekEWm5U2S0DBoRFYZxWG4en/VyU2IjEKDzmk9rq8luiCMhmaD JBZDcQTP+GeKM30AD8nKKuDgCeVVBl8s9PDlhn47n3s4bRBgD+TYr1yrwPGeYyBvb0gL N0jPwgDIcRGXTb28ixzklkzJPjuf3jF1m/H7T1ZoPNy/rfKva2g2xZOW5X4XPXir+7gj e8OQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=dW9mXQq6; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id f2si1686504wmd.40.2017.09.23.08.52.01; Sat, 23 Sep 2017 08:52:01 -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=dW9mXQq6; 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 05460680A27; Sat, 23 Sep 2017 18:51:50 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f195.google.com (mail-wr0-f195.google.com [209.85.128.195]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 41BBB68019C for ; Sat, 23 Sep 2017 18:51:44 +0300 (EEST) Received: by mail-wr0-f195.google.com with SMTP id n64so2018159wrb.2 for ; Sat, 23 Sep 2017 08:51:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=L1ICaq9QXLpGMg0Xpogw1k/I6kJBWUifxHqRSd1ZmJE=; b=dW9mXQq6aWVRLg8GCa5VNmCbatbse3mEpMmvdave3+WcZSTZafJ8yRBAY5L3iOb8RU O+9Tl2mw2tybxq+9Ur0csIH6yTjjsRgXxyYaoXlD8PwqXlIkRND+Fq36I3dhzQDW6fnb laZ3IhmrMKsayznAqBzZfkDY7wr2vgeVCKHNo5b9B/7XorZa+TJI+vv8/2eDxEktE/S9 FfiCUMii1i0DLOCmY4mYUOGsITiLaxCuE8Ve36l3r5sq27jJTYYS7yxEfcOuSV5soHUo mcIJCp6B1DN9vX4f8NHnloCxTxcRjb1Wt8sWmEx5R5Ao7IqEbfNqK243dASjraQGriZV kCgQ== 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:mime-version :content-transfer-encoding; bh=L1ICaq9QXLpGMg0Xpogw1k/I6kJBWUifxHqRSd1ZmJE=; b=nEcASax7tD2kLuO4AWcuwokaZ9J9GdvMTMVGqS4Xls5NSx56NeOdYrSlK/zky1D0O3 HWo1UTjXdreTZ4+PVZAr3bUMNrN87eZBsTIXhpJo2VuA2zrFBRHYQnQ/Bkj2Pgr1FG8m dBkDRSkq0DXiaaV700RtDbd6yo3L/mmgm3PD5aisaHHuwfsGpvpoLEO/a4SjVUVke2KO 5u2Yoy7vCO4+mT6MPM0o33VUFsxqUk4szqPDLJFSFu2axa6W0K1kJsXwocqDqVQSA1ze H/WYjpbg+PVccbnd1CDi+ecXLkvEHeA6F49uTQv4Fs4ifNJakQ6r7cDEuT1wg/Y2d6Xx pR2w== X-Gm-Message-State: AHPjjUjVqVyK81j8OlxW5LkZVRqmn04lxPMqiOc4iw/+EUkqkKPy6Erk l9Y9QHItFUMLqAAWYji0UL2m3w81 X-Google-Smtp-Source: AOwi7QCk0J0/nLLMrKcClinZSgcG897qSrUQ1ebjipZVXeuWScJP2Fq0/MPGrGutuw/zr+vGNjOoWg== X-Received: by 10.223.155.154 with SMTP id d26mr2154193wrc.149.1506181486857; Sat, 23 Sep 2017 08:44:46 -0700 (PDT) Received: from saten.42.fr ([62.210.32.10]) by smtp.gmail.com with ESMTPSA id q140sm2309045wmd.3.2017.09.23.08.44.45 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 23 Sep 2017 08:44:46 -0700 (PDT) From: =?UTF-8?q?Jan=20Ekstr=C3=B6m?= To: ffmpeg-devel@ffmpeg.org Date: Sat, 23 Sep 2017 18:44:44 +0300 Message-Id: <20170923154445.9716-1-jeebjp@gmail.com> X-Mailer: git-send-email 2.13.5 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] movenc: Add an option for enabling negative CTS offsets 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" From: Martin Storsjö This reduces the need for an edit list; streams that start with e.g. dts=-1, pts=0 can be encoded as dts=0, pts=0 (which is valid in mov/mp4) by shifting the dts values of all packets forward. This avoids the need for edit lists for such streams (while they still are needed for audio streams with encoder delay). This eases conformance with the DASH-IF interoperability guidelines. Signed-off-by: Martin Storsjö --- libavformat/movenc.c | 28 ++++++++++++++++++++++++---- libavformat/movenc.h | 2 ++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 10b959ad02..917486384a 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -77,6 +77,7 @@ static const AVOption options[] = { { "write_gama", "Write deprecated gama atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_WRITE_GAMA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "use_metadata_tags", "Use mdta atom for metadata.", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_USE_MDTA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, { "skip_trailer", "Skip writing the mfra/tfra/mfro trailer for fragmented files", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SKIP_TRAILER}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, + { "negative_cts_offsets", "Use negative CTS offsets (reducing the need for edit lists)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags), { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM}, { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM}, @@ -2094,8 +2095,9 @@ static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext return update_size(pb, pos); } -static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track) +static int mov_write_ctts_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track) { + MOVMuxContext *mov = s->priv_data; MOVStts *ctts_entries; uint32_t entries = 0; uint32_t atom_size; @@ -2119,7 +2121,11 @@ static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track) atom_size = 16 + (entries * 8); avio_wb32(pb, atom_size); /* size */ ffio_wfourcc(pb, "ctts"); - avio_wb32(pb, 0); /* version & flags */ + if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS) + avio_w8(pb, 1); /* version */ + else + avio_w8(pb, 0); /* version */ + avio_wb24(pb, 0); /* flags */ avio_wb32(pb, entries); /* entry count */ for (i = 0; i < entries; i++) { avio_wb32(pb, ctts_entries[i].count); @@ -2303,7 +2309,7 @@ static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext if (track->par->codec_type == AVMEDIA_TYPE_VIDEO && track->flags & MOV_TRACK_CTTS && track->entry) { - if ((ret = mov_write_ctts_tag(pb, track)) < 0) + if ((ret = mov_write_ctts_tag(s, pb, track)) < 0) return ret; } mov_write_stsc_tag(pb, track); @@ -4044,7 +4050,10 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov, avio_wb32(pb, 0); /* size placeholder */ ffio_wfourcc(pb, "trun"); - avio_w8(pb, 0); /* version */ + if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS) + avio_w8(pb, 1); /* version */ + else + avio_w8(pb, 0); /* version */ avio_wb24(pb, flags); avio_wb32(pb, end - first); /* sample count */ @@ -4489,6 +4498,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) ffio_wfourcc(pb, "MSNV"); else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) ffio_wfourcc(pb, "iso5"); // Required when using default-base-is-moof + else if (mov->mode == MODE_MP4 && mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS) + ffio_wfourcc(pb, "iso4"); else if (mov->mode == MODE_MP4) ffio_wfourcc(pb, "isom"); else if (mov->mode == MODE_IPOD) @@ -4759,6 +4770,8 @@ static int mov_flush_fragment(AVFormatContext *s, int force) if (!track->end_reliable) { AVPacket pkt; if (!ff_interleaved_peek(s, i, &pkt, 1)) { + if (track->dts_shift != AV_NOPTS_VALUE) + pkt.dts += track->dts_shift; track->track_duration = pkt.dts - track->start_dts; if (pkt.pts != AV_NOPTS_VALUE) track->end_pts = pkt.pts; @@ -5282,6 +5295,12 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt) mov->flags &= ~FF_MOV_FLAG_FRAG_DISCONT; } + if (mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS) { + if (trk->dts_shift == AV_NOPTS_VALUE) + trk->dts_shift = pkt->pts - pkt->dts; + pkt->dts += trk->dts_shift; + } + if (trk->par->codec_id == AV_CODEC_ID_MP4ALS || trk->par->codec_id == AV_CODEC_ID_AAC || trk->par->codec_id == AV_CODEC_ID_FLAC) { @@ -5922,6 +5941,7 @@ static int mov_init(AVFormatContext *s) track->start_dts = AV_NOPTS_VALUE; track->start_cts = AV_NOPTS_VALUE; track->end_pts = AV_NOPTS_VALUE; + track->dts_shift = AV_NOPTS_VALUE; if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') || track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') || diff --git a/libavformat/movenc.h b/libavformat/movenc.h index 4c4f3cdfc3..cc2a155d79 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -116,6 +116,7 @@ typedef struct MOVTrack { int64_t start_cts; int64_t end_pts; int end_reliable; + int64_t dts_shift; int hint_track; ///< the track that hints this track, -1 if no hint track is set int src_track; ///< the track that this hint (or tmcd) track describes @@ -241,6 +242,7 @@ typedef struct MOVMuxContext { #define FF_MOV_FLAG_WRITE_GAMA (1 << 16) #define FF_MOV_FLAG_USE_MDTA (1 << 17) #define FF_MOV_FLAG_SKIP_TRAILER (1 << 18) +#define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS (1 << 19) int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);