2017-02-20 6:22 GMT+09:00 Martin Storsjö <[email protected]>:
> 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).
> ---
> libavformat/movenc.c | 24 ++++++++++++++++++++----
> libavformat/movenc.h | 2 ++
> 2 files changed, 22 insertions(+), 4 deletions(-)
>
> diff --git a/libavformat/movenc.c b/libavformat/movenc.c
> index 840190d..713c145 100644
> --- a/libavformat/movenc.c
> +++ b/libavformat/movenc.c
> @@ -62,6 +62,7 @@ static const AVOption options[] = {
> { "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" },
> { "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_INT, {.i64 = 0}, 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},
> @@ -1163,8 +1164,9 @@ static int mov_write_stsd_tag(AVFormatContext *s,
> AVIOContext *pb, MOVTrack *tra
> 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;
> @@ -1188,7 +1190,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 */
>
ctts ver. 1 is defined in iso4 or later isobmff brands.
> + 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);
> @@ -1273,7 +1279,7 @@ static int mov_write_stbl_tag(AVFormatContext *s,
> AVIOContext *pb, MOVTrack *tra
> mov_write_stss_tag(pb, track, MOV_PARTIAL_SYNC_SAMPLE);
> if (track->par->codec_type == AVMEDIA_TYPE_VIDEO &&
> track->flags & MOV_TRACK_CTTS && track->entry)
> - mov_write_ctts_tag(pb, track);
> + mov_write_ctts_tag(s, pb, track);
> mov_write_stsc_tag(pb, track);
> mov_write_stsz_tag(pb, track);
> mov_write_stco_tag(pb, track);
> @@ -2594,7 +2600,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 */
> @@ -3729,6 +3738,12 @@ static int mov_write_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;
>
Do you care about an issue of negative composition time offset on early
flush of movie fragments? Reordering of leading samples could confuse
demuxers due to the non-zero cts of the first sample and no examination
about subsequent samples. This can be occured when starting to remux from
Open-GOP boundary (also, don't forget that AVC and HEVC can output P or B
pictures before IDR picture).
> + pkt->dts += trk->dts_shift;
> + }
> +
> if (!pkt->size) {
> if (trk->start_dts == AV_NOPTS_VALUE && trk->frag_discont) {
> trk->start_dts = pkt->dts;
> @@ -4095,6 +4110,7 @@ static int mov_write_header(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 f4ed188..008f467 100644
> --- a/libavformat/movenc.h
> +++ b/libavformat/movenc.h
> @@ -107,6 +107,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 track
> describes
> @@ -195,6 +196,7 @@ typedef struct MOVMuxContext {
> #define FF_MOV_FLAG_DELAY_MOOV (1 << 13)
> #define FF_MOV_FLAG_GLOBAL_SIDX (1 << 14)
> #define FF_MOV_FLAG_SKIP_TRAILER (1 << 15)
> +#define FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS (1 << 16)
>
> int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
>
> --
> 2.10.1 (Apple Git-78)
>
> _______________________________________________
> libav-devel mailing list
> [email protected]
> https://lists.libav.org/mailman/listinfo/libav-devel
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel