* [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata @ 2023-04-15 22:05 Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 2/6] avformat/mov: restrict unix timestamp hack to version 0 mdhd/mvhd Marton Balint ` (5 more replies) 0 siblings, 6 replies; 7+ messages in thread From: Marton Balint @ 2023-04-15 22:05 UTC (permalink / raw) To: ffmpeg-devel; +Cc: Marton Balint Signed-off-by: Marton Balint <cus@passwd.hu> --- libavformat/mov.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 057fd872b1..5d00ff6e8b 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1515,14 +1515,22 @@ static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom) return mov_read_default(c, pb, atom); } -static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx) +static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version) { + int64_t time; + if (version == 1) { + time = avio_rb64(pb); + avio_rb64(pb); + } else { + time = avio_rb32(pb); + avio_rb32(pb); /* modification time */ + } if (time) { if (time >= 2082844800) time -= 2082844800; /* seconds between 1904-01-01 and Epoch */ if ((int64_t)(time * 1000000ULL) / 1000000 != time) { - av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n"); + av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n"); return; } @@ -1537,7 +1545,6 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) int version; char language[4] = {0}; unsigned lang; - int64_t creation_time; if (c->fc->nb_streams < 1) return 0; @@ -1555,14 +1562,7 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR_PATCHWELCOME; } avio_rb24(pb); /* flags */ - if (version == 1) { - creation_time = avio_rb64(pb); - avio_rb64(pb); - } else { - creation_time = avio_rb32(pb); - avio_rb32(pb); /* modification time */ - } - mov_metadata_creation_time(&st->metadata, creation_time, c->fc); + mov_metadata_creation_time(c, pb, &st->metadata, version); sc->time_scale = avio_rb32(pb); if (sc->time_scale <= 0) { @@ -1587,18 +1587,10 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) { int i; - int64_t creation_time; int version = avio_r8(pb); /* version */ avio_rb24(pb); /* flags */ - if (version == 1) { - creation_time = avio_rb64(pb); - avio_rb64(pb); - } else { - creation_time = avio_rb32(pb); - avio_rb32(pb); /* modification time */ - } - mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc); + mov_metadata_creation_time(c, pb, &c->fc->metadata, version); c->time_scale = avio_rb32(pb); /* time scale */ if (c->time_scale <= 0) { av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale); -- 2.35.3 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 7+ messages in thread
* [FFmpeg-devel] [PATCH 2/6] avformat/mov: restrict unix timestamp hack to version 0 mdhd/mvhd 2023-04-15 22:05 [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata Marton Balint @ 2023-04-15 22:05 ` Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 3/6] avformat/movenc: factorize determining mdhd/mvhd/tkhd version Marton Balint ` (4 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Marton Balint @ 2023-04-15 22:05 UTC (permalink / raw) To: ffmpeg-devel; +Cc: Marton Balint Commit 23eeffcd48a15e73fb2649b712870b6d101c5471 added a hack to support invalid files where the creation date was encoded as a classic unix timestamp. Let's reduce the scope of the hack by only applying it to version 0 mdhd/mvhd atoms. Also warn the user of such possibly broken files. Signed-off-by: Marton Balint <cus@passwd.hu> --- libavformat/mov.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 5d00ff6e8b..1b3c1d7683 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1524,10 +1524,13 @@ static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDiction } else { time = avio_rb32(pb); avio_rb32(pb); /* modification time */ + if (time > 0 && time < 2082844800) { + av_log(c->fc, AV_LOG_WARNING, "Detected creation time before 1970, parsing as unix timestamp.\n"); + time += 2082844800; + } } if (time) { - if (time >= 2082844800) - time -= 2082844800; /* seconds between 1904-01-01 and Epoch */ + time -= 2082844800; /* seconds between 1904-01-01 and Epoch */ if ((int64_t)(time * 1000000ULL) / 1000000 != time) { av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n"); -- 2.35.3 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 7+ messages in thread
* [FFmpeg-devel] [PATCH 3/6] avformat/movenc: factorize determining mdhd/mvhd/tkhd version 2023-04-15 22:05 [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 2/6] avformat/mov: restrict unix timestamp hack to version 0 mdhd/mvhd Marton Balint @ 2023-04-15 22:05 ` Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 4/6] avformat/smoothstreamingenc: do not override movflag defaults Marton Balint ` (3 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Marton Balint @ 2023-04-15 22:05 UTC (permalink / raw) To: ffmpeg-devel; +Cc: Marton Balint Also make duration check for mvhd more consistent with the others, write version 1 of mvhd if duration is at least INT32_MAX instead of UINT32_MAX. Signed-off-by: Marton Balint <cus@passwd.hu> --- libavformat/movenc.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index c370922c7d..32a675b285 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -3269,14 +3269,20 @@ static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track) return end - start; } +static int mov_mdhd_mvhd_tkhd_version(MOVMuxContext *mov, MOVTrack *track, int64_t duration) +{ + if (track && track->mode == MODE_ISM) + return 1; + if (duration < INT32_MAX) + return 0; + return 1; +} + static int mov_write_mdhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track) { int64_t duration = calc_samples_pts_duration(mov, track); - int version = duration < INT32_MAX ? 0 : 1; - - if (track->mode == MODE_ISM) - version = 1; + int version = mov_mdhd_mvhd_tkhd_version(mov, track, duration); (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */ ffio_wfourcc(pb, "mdhd"); @@ -3362,8 +3368,6 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov, else duration *= mov->avif_loop_count; - version = duration < INT32_MAX ? 0 : 1; - if (st) { if (mov->per_stream_grouping) group = st->index; @@ -3379,8 +3383,7 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov, if (track->flags & MOV_TRACK_ENABLED) flags |= MOV_TKHD_FLAG_ENABLED; - if (track->mode == MODE_ISM) - version = 1; + version = mov_mdhd_mvhd_tkhd_version(mov, track, duration); (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */ ffio_wfourcc(pb, "tkhd"); @@ -3863,7 +3866,7 @@ static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov) max_track_id = 1; } - version = max_track_len < UINT32_MAX ? 0 : 1; + version = mov_mdhd_mvhd_tkhd_version(mov, NULL, max_track_len); avio_wb32(pb, version == 1 ? 120 : 108); /* size */ ffio_wfourcc(pb, "mvhd"); -- 2.35.3 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 7+ messages in thread
* [FFmpeg-devel] [PATCH 4/6] avformat/smoothstreamingenc: do not override movflag defaults 2023-04-15 22:05 [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 2/6] avformat/mov: restrict unix timestamp hack to version 0 mdhd/mvhd Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 3/6] avformat/movenc: factorize determining mdhd/mvhd/tkhd version Marton Balint @ 2023-04-15 22:05 ` Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 5/6] tests: do not override movflags defaults Marton Balint ` (2 subsequent siblings) 5 siblings, 0 replies; 7+ messages in thread From: Marton Balint @ 2023-04-15 22:05 UTC (permalink / raw) To: ffmpeg-devel; +Cc: Marton Balint Signed-off-by: Marton Balint <cus@passwd.hu> --- libavformat/smoothstreamingenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c index 66e6313934..3c050ca54e 100644 --- a/libavformat/smoothstreamingenc.c +++ b/libavformat/smoothstreamingenc.c @@ -340,7 +340,7 @@ static int ism_write_header(AVFormatContext *s) } av_dict_set_int(&opts, "ism_lookahead", c->lookahead_count, 0); - av_dict_set(&opts, "movflags", "frag_custom", 0); + av_dict_set(&opts, "movflags", "+frag_custom", 0); ret = avformat_write_header(ctx, &opts); av_dict_free(&opts); if (ret < 0) { -- 2.35.3 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 7+ messages in thread
* [FFmpeg-devel] [PATCH 5/6] tests: do not override movflags defaults 2023-04-15 22:05 [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata Marton Balint ` (2 preceding siblings ...) 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 4/6] avformat/smoothstreamingenc: do not override movflag defaults Marton Balint @ 2023-04-15 22:05 ` Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 6/6] doc/muxers: reorder and cleanup mov muxer options Marton Balint 2023-04-23 18:46 ` [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata Marton Balint 5 siblings, 0 replies; 7+ messages in thread From: Marton Balint @ 2023-04-15 22:05 UTC (permalink / raw) To: ffmpeg-devel; +Cc: Marton Balint It does not matter if the default is 0, but still it is cleaner that way. Signed-off-by: Marton Balint <cus@passwd.hu> --- libavformat/tests/movenc.c | 54 +++++++++++++++++++------------------- tests/fate/subtitles.mak | 2 +- tests/fate/vcodec.mak | 2 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/libavformat/tests/movenc.c b/libavformat/tests/movenc.c index 6f9d381927..fca3213285 100644 --- a/libavformat/tests/movenc.c +++ b/libavformat/tests/movenc.c @@ -389,7 +389,7 @@ int main(int argc, char **argv) // samples. One moov+mdat with 1 second of data and one moof+mdat with 1 // second of data. init_out("non-empty-moov"); - av_dict_set(&opts, "movflags", "frag_keyframe", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe", 0); init(0, 0); mux_gops(2); finish(); @@ -398,7 +398,7 @@ int main(int argc, char **argv) // Write a similar file, but with B-frames and audio preroll, handled // via an edit list. init_out("non-empty-moov-elst"); - av_dict_set(&opts, "movflags", "frag_keyframe", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe", 0); av_dict_set(&opts, "use_editlist", "1", 0); init(1, 1); mux_gops(2); @@ -410,7 +410,7 @@ int main(int argc, char **argv) // of the first audio packet is > 0, but it is set to zero since edit // lists aren't used, increasing the duration of the first packet instead. init_out("non-empty-moov-no-elst"); - av_dict_set(&opts, "movflags", "frag_keyframe", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe", 0); av_dict_set(&opts, "use_editlist", "0", 0); init(1, 0); mux_gops(2); @@ -420,7 +420,7 @@ int main(int argc, char **argv) format = "ismv"; // Write an ISMV, with B-frames and audio preroll. init_out("ismv"); - av_dict_set(&opts, "movflags", "frag_keyframe", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe", 0); init(1, 1); mux_gops(2); finish(); @@ -430,7 +430,7 @@ int main(int argc, char **argv) // An initial moov that doesn't contain any samples, followed by two // moof+mdat pairs. init_out("empty-moov"); - av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+empty_moov", 0); av_dict_set(&opts, "use_editlist", "0", 0); init(0, 0); mux_gops(2); @@ -442,7 +442,7 @@ int main(int argc, char **argv) // pts/dts 0. avoid_negative_ts behaves in the same way as // in non-empty-moov-no-elst above. init_out("empty-moov-no-elst"); - av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+empty_moov", 0); init(1, 0); mux_gops(2); finish(); @@ -454,7 +454,7 @@ int main(int argc, char **argv) // This should trigger a warning - we check that the warning is produced. init_count_warnings(); init_out("empty-moov-no-elst-no-adjust"); - av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+empty_moov", 0); av_dict_set(&opts, "avoid_negative_ts", "disabled", 0); init(1, 0); mux_gops(2); @@ -467,7 +467,7 @@ int main(int argc, char **argv) // Verify that delay_moov produces the same as empty_moov for // simple input init_out("delay-moov"); - av_dict_set(&opts, "movflags", "frag_keyframe+delay_moov", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+delay_moov", 0); av_dict_set(&opts, "use_editlist", "0", 0); init(0, 0); mux_gops(2); @@ -477,7 +477,7 @@ int main(int argc, char **argv) // Test writing content that requires an edit list using delay_moov init_out("delay-moov-elst"); - av_dict_set(&opts, "movflags", "frag_keyframe+delay_moov", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+delay_moov", 0); init(1, 1); mux_gops(2); finish(); @@ -486,7 +486,7 @@ int main(int argc, char **argv) // Test writing a file with one track lacking packets, with delay_moov. skip_write_audio = 1; init_out("delay-moov-empty-track"); - av_dict_set(&opts, "movflags", "frag_keyframe+delay_moov", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+delay_moov", 0); init(0, 0); mux_gops(2); // The automatic flushing shouldn't output anything, since we're still @@ -501,7 +501,7 @@ int main(int argc, char **argv) // Check that manually flushing still outputs things as expected. This // produces two fragments, while the one above produces only one. init_out("delay-moov-empty-track-flush"); - av_dict_set(&opts, "movflags", "frag_custom+delay_moov", 0); + av_dict_set(&opts, "movflags", "+frag_custom+delay_moov", 0); init(0, 0); mux_gops(1); av_write_frame(ctx, NULL); // Force writing the moov @@ -519,7 +519,7 @@ int main(int argc, char **argv) // Verify that the header written by delay_moov when manually flushed // is identical to the one by empty_moov. init_out("empty-moov-header"); - av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+empty_moov", 0); av_dict_set(&opts, "use_editlist", "0", 0); init(0, 0); close_out(); @@ -542,7 +542,7 @@ int main(int argc, char **argv) finish(); init_out("delay-moov-header"); - av_dict_set(&opts, "movflags", "frag_custom+delay_moov", 0); + av_dict_set(&opts, "movflags", "+frag_custom+delay_moov", 0); av_dict_set(&opts, "use_editlist", "0", 0); init(0, 0); check(out_size == 0, "Output written during init with delay_moov"); @@ -563,7 +563,7 @@ int main(int argc, char **argv) // Verify that we can produce an identical second fragment without // writing the first one. First write the reference fragments that // we want to reproduce. - av_dict_set(&opts, "movflags", "frag_custom+empty_moov+dash", 0); + av_dict_set(&opts, "movflags", "+frag_custom+empty_moov+dash", 0); init(0, 0); mux_gops(1); av_write_frame(ctx, NULL); // Output the first fragment @@ -576,7 +576,7 @@ int main(int argc, char **argv) // Produce the same second fragment without actually writing the first // one before. - av_dict_set(&opts, "movflags", "frag_custom+empty_moov+dash+frag_discont", 0); + av_dict_set(&opts, "movflags", "+frag_custom+empty_moov+dash+frag_discont", 0); av_dict_set(&opts, "fragment_index", "2", 0); av_dict_set(&opts, "avoid_negative_ts", "disabled", 0); av_dict_set(&opts, "use_editlist", "0", 0); @@ -591,7 +591,7 @@ int main(int argc, char **argv) // Produce the same thing by using delay_moov, which requires a slightly // different call sequence. - av_dict_set(&opts, "movflags", "frag_custom+delay_moov+dash+frag_discont", 0); + av_dict_set(&opts, "movflags", "+frag_custom+delay_moov+dash+frag_discont", 0); av_dict_set(&opts, "fragment_index", "2", 0); init(0, 0); skip_gops(1); @@ -607,7 +607,7 @@ int main(int argc, char **argv) // Test discontinuously written fragments with B-frames (where the // assumption of starting at pts=0 works) but not with audio preroll // (which can't be guessed). - av_dict_set(&opts, "movflags", "frag_custom+delay_moov+dash", 0); + av_dict_set(&opts, "movflags", "+frag_custom+delay_moov+dash", 0); init(1, 0); mux_gops(1); init_out("delay-moov-elst-init"); @@ -622,7 +622,7 @@ int main(int argc, char **argv) memcpy(content, hash, HASH_SIZE); finish(); - av_dict_set(&opts, "movflags", "frag_custom+delay_moov+dash+frag_discont", 0); + av_dict_set(&opts, "movflags", "+frag_custom+delay_moov+dash+frag_discont", 0); av_dict_set(&opts, "fragment_index", "2", 0); init(1, 0); skip_gops(1); @@ -640,7 +640,7 @@ int main(int argc, char **argv) // Test discontinuously written fragments with B-frames and audio preroll, // properly signaled. - av_dict_set(&opts, "movflags", "frag_custom+delay_moov+dash", 0); + av_dict_set(&opts, "movflags", "+frag_custom+delay_moov+dash", 0); init(1, 1); mux_gops(1); init_out("delay-moov-elst-signal-init"); @@ -655,7 +655,7 @@ int main(int argc, char **argv) memcpy(content, hash, HASH_SIZE); finish(); - av_dict_set(&opts, "movflags", "frag_custom+delay_moov+dash+frag_discont", 0); + av_dict_set(&opts, "movflags", "+frag_custom+delay_moov+dash+frag_discont", 0); av_dict_set(&opts, "fragment_index", "2", 0); init(1, 1); signal_init_ts(); @@ -673,7 +673,7 @@ int main(int argc, char **argv) // Test muxing discontinuous fragments with very large (> (1<<31)) timestamps. - av_dict_set(&opts, "movflags", "frag_custom+delay_moov+dash+frag_discont", 0); + av_dict_set(&opts, "movflags", "+frag_custom+delay_moov+dash+frag_discont", 0); av_dict_set(&opts, "fragment_index", "2", 0); init(1, 1); signal_init_ts(); @@ -700,7 +700,7 @@ int main(int argc, char **argv) // match - the input stream starts at pts=-2048, but that part is excluded // by the edit list. init_out("vfr"); - av_dict_set(&opts, "movflags", "frag_keyframe+delay_moov+dash", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+delay_moov+dash", 0); init_fps(1, 1, 3); mux_frames(gop_size/2, 0); duration /= 10; @@ -719,7 +719,7 @@ int main(int argc, char **argv) init_count_warnings(); clear_duration = 1; init_out("vfr-noduration"); - av_dict_set(&opts, "movflags", "frag_keyframe+delay_moov+dash", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+delay_moov+dash", 0); init_fps(1, 1, 3); mux_frames(gop_size/2, 0); duration /= 10; @@ -735,7 +735,7 @@ int main(int argc, char **argv) // this will cause write_data_type to be called with the type unknown. force_iobuf_size = 1500; init_out("large_frag"); - av_dict_set(&opts, "movflags", "frag_keyframe+delay_moov", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+delay_moov", 0); init_fps(1, 1, 3); mux_gops(2); finish(); @@ -748,7 +748,7 @@ int main(int argc, char **argv) // the expected, but we simulate dropped frames at one point. do_interleave = 1; init_out("vfr-noduration-interleave"); - av_dict_set(&opts, "movflags", "frag_keyframe+delay_moov", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+delay_moov", 0); av_dict_set(&opts, "frag_duration", "650000", 0); init_fps(1, 1, 30); mux_frames(gop_size/2, 0); @@ -771,7 +771,7 @@ int main(int argc, char **argv) // with negative cts values, removing the edit list for the // video track. init_out("delay-moov-elst-neg-cts"); - av_dict_set(&opts, "movflags", "frag_keyframe+delay_moov+negative_cts_offsets", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+delay_moov+negative_cts_offsets", 0); init(1, 1); mux_gops(2); finish(); @@ -781,7 +781,7 @@ int main(int argc, char **argv) // with negative cts values, avoiding any edit lists, allowing // to use empty_moov instead of delay_moov. init_out("empty-moov-neg-cts"); - av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov+negative_cts_offsets", 0); + av_dict_set(&opts, "movflags", "+frag_keyframe+empty_moov+negative_cts_offsets", 0); init(1, 0); mux_gops(2); finish(); diff --git a/tests/fate/subtitles.mak b/tests/fate/subtitles.mak index e6684a814b..59595b9cc1 100644 --- a/tests/fate/subtitles.mak +++ b/tests/fate/subtitles.mak @@ -39,7 +39,7 @@ FATE_SUBTITLES_ASS-$(call DEMDEC, MOV, MOVTEXT) += fate-sub-movtext fate-sub-movtext: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/MovText_capability_tester.mp4 FATE_SUBTITLES-$(call ENCDEC, MOVTEXT, MOV) += fate-binsub-movtextenc -fate-binsub-movtextenc: CMD = md5 -i $(TARGET_SAMPLES)/sub/MovText_capability_tester.mp4 -map 0 -scodec mov_text -f mp4 -flags +bitexact -fflags +bitexact -movflags frag_keyframe+empty_moov +fate-binsub-movtextenc: CMD = md5 -i $(TARGET_SAMPLES)/sub/MovText_capability_tester.mp4 -map 0 -scodec mov_text -f mp4 -flags +bitexact -fflags +bitexact -movflags +frag_keyframe+empty_moov FATE_SUBTITLES_ASS-$(call DEMDEC, MPL2, MPL2) += fate-sub-mpl2 fate-sub-mpl2: CMD = fmtstdout ass -i $(TARGET_SAMPLES)/sub/MPL2_capability_tester.txt diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak index bf9de0327a..fbee264a9d 100644 --- a/tests/fate/vcodec.mak +++ b/tests/fate/vcodec.mak @@ -111,7 +111,7 @@ fate-vsynth%-dnxhd-1080i-10bit: ENCOPTS = -s hd1080 -b 185M -flags +ildct \ -pix_fmt yuv422p10 -frames 5 -qmax 8 fate-vsynth%-dnxhd-1080i-10bit: DECOPTS = -sws_flags area+accurate_rnd+bitexact -fate-vsynth%-dnxhd-1080i-colr: ENCOPTS = -s hd1080 -b 120M -flags +ildct -movflags write_colr \ +fate-vsynth%-dnxhd-1080i-colr: ENCOPTS = -s hd1080 -b 120M -flags +ildct -movflags +write_colr \ -pix_fmt yuv422p -frames 5 -qmax 8 fate-vsynth%-dnxhd-1080i-colr: DECOPTS = -sws_flags area+accurate_rnd+bitexact -- 2.35.3 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 7+ messages in thread
* [FFmpeg-devel] [PATCH 6/6] doc/muxers: reorder and cleanup mov muxer options 2023-04-15 22:05 [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata Marton Balint ` (3 preceding siblings ...) 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 5/6] tests: do not override movflags defaults Marton Balint @ 2023-04-15 22:05 ` Marton Balint 2023-04-23 18:46 ` [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata Marton Balint 5 siblings, 0 replies; 7+ messages in thread From: Marton Balint @ 2023-04-15 22:05 UTC (permalink / raw) To: ffmpeg-devel; +Cc: Marton Balint Make various movflags grouped together similar to how it is done for other options. Signed-off-by: Marton Balint <cus@passwd.hu> --- doc/muxers.texi | 88 +++++++++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 79dd864182..d1e825eec5 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -1630,8 +1630,10 @@ MOV/MP4/ISMV (Smooth Streaming) muxer. The mov/mp4/ismv muxer supports fragmentation. Normally, a MOV/MP4 file has all the metadata about all packets stored in one location (written at the end of the file, it can be moved to the start for -better playback by adding @var{faststart} to the @var{movflags}, or -using the @command{qt-faststart} tool). A fragmented +better playback by adding @code{+faststart} to the @code{-movflags}, or +using the @command{qt-faststart} tool). + +A fragmented file consists of a number of fragments, where packets and metadata about these packets are stored together. Writing a fragmented file has the advantage that the file is decodable even if the @@ -1641,40 +1643,34 @@ very long files (since writing normal MOV/MP4 files stores info about every single packet in memory until the file is closed). The downside is that it is less compatible with other applications. -@subsection Options +Fragmentation is enabled by setting one of the options that define +how to cut the file into fragments: @code{-frag_duration}, @code{-frag_size}, +@code{-min_frag_duration}, @code{-movflags +frag_keyframe} and +@code{-movflags +frag_custom}. If more than one condition is specified, +fragments are cut when one of the specified conditions is fulfilled. The +exception to this is @code{-min_frag_duration}, which has to be fulfilled for +any of the other conditions to apply. -Fragmentation is enabled by setting one of the AVOptions that define -how to cut the file into fragments: +@subsection Options @table @option -@item -moov_size @var{bytes} -Reserves space for the moov atom at the beginning of the file instead of placing the -moov atom at the end. If the space reserved is insufficient, muxing will fail. -@item -movflags frag_keyframe -Start a new fragment at each video keyframe. -@item -frag_duration @var{duration} +@item frag_duration @var{duration} Create fragments that are @var{duration} microseconds long. -@item -frag_size @var{size} +@item frag_size @var{size} Create fragments that contain up to @var{size} bytes of payload data. -@item -movflags frag_custom +@item min_frag_duration @var{duration} +Don't create fragments that are shorter than @var{duration} microseconds long. +@item movflags @var{flags} +Set various muxing switches. The following flags can be used: +@table @samp +@item frag_keyframe +Start a new fragment at each video keyframe. +@item frag_custom Allow the caller to manually choose when to cut fragments, by calling @code{av_write_frame(ctx, NULL)} to write a fragment with the packets written so far. (This is only useful with other applications integrating libavformat, not from @command{ffmpeg}.) -@item -min_frag_duration @var{duration} -Don't create fragments that are shorter than @var{duration} microseconds long. -@end table - -If more than one condition is specified, fragments are cut when -one of the specified conditions is fulfilled. The exception to this is -@code{-min_frag_duration}, which has to be fulfilled for any of the other -conditions to apply. - -Additionally, the way the output file is written can be adjusted -through a few other options: - -@table @option -@item -movflags empty_moov +@item empty_moov Write an initial moov atom directly at the start of the file, without describing any samples in it. Generally, an mdat/moov pair is written at the start of the file, as a normal MOV/MP4 file, containing only @@ -1683,43 +1679,40 @@ mdat atom, and the moov atom only describes the tracks but has a zero duration. This option is implicitly set when writing ismv (Smooth Streaming) files. -@item -movflags separate_moof +@item separate_moof Write a separate moof (movie fragment) atom for each track. Normally, packets for all tracks are written in a moof atom (which is slightly more efficient), but with this option set, the muxer writes one moof/mdat pair for each track, making it easier to separate tracks. This option is implicitly set when writing ismv (Smooth Streaming) files. -@item -movflags skip_sidx +@item skip_sidx Skip writing of sidx atom. When bitrate overhead due to sidx atom is high, this option could be used for cases where sidx atom is not mandatory. When global_sidx flag is enabled, this option will be ignored. -@item -movflags faststart +@item faststart Run a second pass moving the index (moov atom) to the beginning of the file. This operation can take a while, and will not work in various situations such as fragmented output, thus it is not enabled by default. -@item -movflags rtphint +@item rtphint Add RTP hinting tracks to the output file. -@item -movflags disable_chpl +@item disable_chpl Disable Nero chapter markers (chpl atom). Normally, both Nero chapters and a QuickTime chapter track are written to the file. With this option set, only the QuickTime chapter track will be written. Nero chapters can cause failures when the file is reprocessed with certain tagging programs, like mp3Tag 2.61a and iTunes 11.3, most likely other versions are affected as well. -@item -movflags omit_tfhd_offset +@item omit_tfhd_offset Do not write any absolute base_data_offset in tfhd atoms. This avoids tying fragments to absolute byte positions in the file/streams. -@item -movflags default_base_moof +@item default_base_moof Similarly to the omit_tfhd_offset, this flag avoids writing the absolute base_data_offset field in tfhd atoms, but does so by using the new default-base-is-moof flag instead. This flag is new from 14496-12:2012. This may make the fragments easier to parse in certain circumstances (avoiding basing track fragment location calculations on the implicit end of the previous track fragment). -@item -write_tmcd -Specify @code{on} to force writing a timecode track, @code{off} to disable it -and @code{auto} to write a timecode track only for mov and mp4 output (default). -@item -movflags negative_cts_offsets +@item negative_cts_offsets Enables utilization of version 1 of the CTTS box, in which the CTS offsets can be negative. This enables the initial sample to have DTS/CTS of zero, and reduces the need for edit lists for some cases such as video tracks with @@ -1727,15 +1720,24 @@ B-frames. Additionally, eases conformance with the DASH-IF interoperability guidelines. This option is implicitly set when writing ismv (Smooth Streaming) files. +@end table + +@item moov_size @var{bytes} +Reserves space for the moov atom at the beginning of the file instead of placing the +moov atom at the end. If the space reserved is insufficient, muxing will fail. + +@item write_tmcd +Specify @code{on} to force writing a timecode track, @code{off} to disable it +and @code{auto} to write a timecode track only for mov and mp4 output (default). -@item -write_btrt @var{bool} +@item write_btrt @var{bool} Force or disable writing bitrate box inside stsd box of a track. The box contains decoding buffer size (in bytes), maximum bitrate and average bitrate for the track. The box will be skipped if none of these values can be computed. Default is @code{-1} or @code{auto}, which will write the box only in MP4 mode. -@item -write_prft +@item write_prft Write producer time reference box (PRFT) with a specified time source for the NTP field in the PRFT box. Set value as @samp{wallclock} to specify timesource as wallclock time and @samp{pts} to specify timesource as input packets' PTS @@ -1746,15 +1748,15 @@ where PTS values are set as as wallclock time at the source. For example, an encoding use case with decklink capture source where @option{video_pts} and @option{audio_pts} are set to @samp{abs_wallclock}. -@item -empty_hdlr_name @var{bool} +@item empty_hdlr_name @var{bool} Enable to skip writing the name inside a @code{hdlr} box. Default is @code{false}. -@item -movie_timescale @var{scale} +@item movie_timescale @var{scale} Set the timescale written in the movie header box (@code{mvhd}). Range is 1 to INT_MAX. Default is 1000. -@item -video_track_timescale @var{scale} +@item video_track_timescale @var{scale} Set the timescale used for video tracks. Range is 0 to INT_MAX. If set to @code{0}, the timescale is automatically set based on the native stream time base. Default is 0. -- 2.35.3 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata 2023-04-15 22:05 [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata Marton Balint ` (4 preceding siblings ...) 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 6/6] doc/muxers: reorder and cleanup mov muxer options Marton Balint @ 2023-04-23 18:46 ` Marton Balint 5 siblings, 0 replies; 7+ messages in thread From: Marton Balint @ 2023-04-23 18:46 UTC (permalink / raw) To: FFmpeg development discussions and patches On Sun, 16 Apr 2023, Marton Balint wrote: > Signed-off-by: Marton Balint <cus@passwd.hu> > --- > libavformat/mov.c | 32 ++++++++++++-------------------- > 1 file changed, 12 insertions(+), 20 deletions(-) Will apply the series soon. Regards, Marton > > diff --git a/libavformat/mov.c b/libavformat/mov.c > index 057fd872b1..5d00ff6e8b 100644 > --- a/libavformat/mov.c > +++ b/libavformat/mov.c > @@ -1515,14 +1515,22 @@ static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom) > return mov_read_default(c, pb, atom); > } > > -static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx) > +static void mov_metadata_creation_time(MOVContext *c, AVIOContext *pb, AVDictionary **metadata, int version) > { > + int64_t time; > + if (version == 1) { > + time = avio_rb64(pb); > + avio_rb64(pb); > + } else { > + time = avio_rb32(pb); > + avio_rb32(pb); /* modification time */ > + } > if (time) { > if (time >= 2082844800) > time -= 2082844800; /* seconds between 1904-01-01 and Epoch */ > > if ((int64_t)(time * 1000000ULL) / 1000000 != time) { > - av_log(logctx, AV_LOG_DEBUG, "creation_time is not representable\n"); > + av_log(c->fc, AV_LOG_DEBUG, "creation_time is not representable\n"); > return; > } > > @@ -1537,7 +1545,6 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) > int version; > char language[4] = {0}; > unsigned lang; > - int64_t creation_time; > > if (c->fc->nb_streams < 1) > return 0; > @@ -1555,14 +1562,7 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) > return AVERROR_PATCHWELCOME; > } > avio_rb24(pb); /* flags */ > - if (version == 1) { > - creation_time = avio_rb64(pb); > - avio_rb64(pb); > - } else { > - creation_time = avio_rb32(pb); > - avio_rb32(pb); /* modification time */ > - } > - mov_metadata_creation_time(&st->metadata, creation_time, c->fc); > + mov_metadata_creation_time(c, pb, &st->metadata, version); > > sc->time_scale = avio_rb32(pb); > if (sc->time_scale <= 0) { > @@ -1587,18 +1587,10 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) > static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) > { > int i; > - int64_t creation_time; > int version = avio_r8(pb); /* version */ > avio_rb24(pb); /* flags */ > > - if (version == 1) { > - creation_time = avio_rb64(pb); > - avio_rb64(pb); > - } else { > - creation_time = avio_rb32(pb); > - avio_rb32(pb); /* modification time */ > - } > - mov_metadata_creation_time(&c->fc->metadata, creation_time, c->fc); > + mov_metadata_creation_time(c, pb, &c->fc->metadata, version); > c->time_scale = avio_rb32(pb); /* time scale */ > if (c->time_scale <= 0) { > av_log(c->fc, AV_LOG_ERROR, "Invalid mvhd time scale %d, defaulting to 1\n", c->time_scale); > -- > 2.35.3 > > _______________________________________________ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe". ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2023-04-23 18:47 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2023-04-15 22:05 [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 2/6] avformat/mov: restrict unix timestamp hack to version 0 mdhd/mvhd Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 3/6] avformat/movenc: factorize determining mdhd/mvhd/tkhd version Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 4/6] avformat/smoothstreamingenc: do not override movflag defaults Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 5/6] tests: do not override movflags defaults Marton Balint 2023-04-15 22:05 ` [FFmpeg-devel] [PATCH 6/6] doc/muxers: reorder and cleanup mov muxer options Marton Balint 2023-04-23 18:46 ` [FFmpeg-devel] [PATCH 1/6] avformat/mov: factorize reading creation time metadata Marton Balint
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git