movenc: Present durations in mvhd/tkhd/mdhd as they are after edits
If the edit lists remove parts of the output timeline, or add a delay to it, this should be included in the mvhd/tkhd/mdhd durations, which should correspond to the edit lists. For tracks starting with pts < 0, the edit list trims out the segment before pts=0. For tracks starting with pts > 0, a delay element is added in the edit list, delaying the start of the track data. In both cases, the practical effect is that the post-edit output is as if the track had started with pts = 0. Thus calculate the range from pts=0 to end_pts, for the purposes of mvhd/tkhd/mdhd, unless edit lists explicitly are disabled. mov_write_edts_tag needs to operate on the actual pts duration of the track samples, not the duration that already takes the edit list effect into account. Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
parent
d4902751cb
commit
c2424b1f35
|
@ -2904,21 +2904,50 @@ static int mov_write_minf_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
|
static void get_pts_range(MOVMuxContext *mov, MOVTrack *track,
|
||||||
|
int64_t *start, int64_t *end)
|
||||||
{
|
{
|
||||||
if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd) {
|
if (track->tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd) {
|
||||||
// tmcd tracks gets track_duration set in mov_write_moov_tag from
|
// tmcd tracks gets track_duration set in mov_write_moov_tag from
|
||||||
// another track's duration, while the end_pts may be left at zero.
|
// another track's duration, while the end_pts may be left at zero.
|
||||||
// Calculate the pts duration for that track instead.
|
// Calculate the pts duration for that track instead.
|
||||||
return av_rescale(calc_pts_duration(mov, &mov->tracks[track->src_track]),
|
get_pts_range(mov, &mov->tracks[track->src_track], start, end);
|
||||||
track->timescale, mov->tracks[track->src_track].timescale);
|
*start = av_rescale(*start, track->timescale,
|
||||||
|
mov->tracks[track->src_track].timescale);
|
||||||
|
*end = av_rescale(*end, track->timescale,
|
||||||
|
mov->tracks[track->src_track].timescale);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (track->end_pts != AV_NOPTS_VALUE &&
|
if (track->end_pts != AV_NOPTS_VALUE &&
|
||||||
track->start_dts != AV_NOPTS_VALUE &&
|
track->start_dts != AV_NOPTS_VALUE &&
|
||||||
track->start_cts != AV_NOPTS_VALUE) {
|
track->start_cts != AV_NOPTS_VALUE) {
|
||||||
return track->end_pts - (track->start_dts + track->start_cts);
|
*start = track->start_dts + track->start_cts;
|
||||||
|
*end = track->end_pts;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return track->track_duration;
|
*start = 0;
|
||||||
|
*end = track->track_duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int64_t calc_samples_pts_duration(MOVMuxContext *mov, MOVTrack *track)
|
||||||
|
{
|
||||||
|
int64_t start, end;
|
||||||
|
get_pts_range(mov, track, &start, &end);
|
||||||
|
return end - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the actual duration of the track, after edits.
|
||||||
|
// If it starts with a pts < 0, that is removed by the edit list.
|
||||||
|
// If it starts with a pts > 0, the edit list adds a delay before that.
|
||||||
|
// Thus, with edit lists enabled, the post-edit output of the file is
|
||||||
|
// starting with pts=0.
|
||||||
|
static int64_t calc_pts_duration(MOVMuxContext *mov, MOVTrack *track)
|
||||||
|
{
|
||||||
|
int64_t start, end;
|
||||||
|
get_pts_range(mov, track, &start, &end);
|
||||||
|
if (mov->use_editlist != 0)
|
||||||
|
start = 0;
|
||||||
|
return end - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mov_write_mdhd_tag(AVIOContext *pb, MOVMuxContext *mov,
|
static int mov_write_mdhd_tag(AVIOContext *pb, MOVMuxContext *mov,
|
||||||
|
@ -3145,7 +3174,7 @@ static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
|
||||||
static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov,
|
static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov,
|
||||||
MOVTrack *track)
|
MOVTrack *track)
|
||||||
{
|
{
|
||||||
int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track),
|
int64_t duration = av_rescale_rnd(calc_samples_pts_duration(mov, track),
|
||||||
MOV_TIMESCALE, track->timescale,
|
MOV_TIMESCALE, track->timescale,
|
||||||
AV_ROUND_UP);
|
AV_ROUND_UP);
|
||||||
int version = duration < INT32_MAX ? 0 : 1;
|
int version = duration < INT32_MAX ? 0 : 1;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
620e3ab4ee6241bec55ea2ec4ef42908 *tests/data/fate/copy-trac3074.mp4
|
da6122873fb83ce4340cf5d0ab8d475e *tests/data/fate/copy-trac3074.mp4
|
||||||
334012 tests/data/fate/copy-trac3074.mp4
|
334012 tests/data/fate/copy-trac3074.mp4
|
||||||
#tb 0: 1/48000
|
#tb 0: 1/48000
|
||||||
#media_type 0: audio
|
#media_type 0: audio
|
||||||
|
|
|
@ -5,7 +5,7 @@ duration_ts=103326
|
||||||
[/STREAM]
|
[/STREAM]
|
||||||
[FORMAT]
|
[FORMAT]
|
||||||
start_time=0.000000
|
start_time=0.000000
|
||||||
duration=2.367000
|
duration=2.344000
|
||||||
[/FORMAT]
|
[/FORMAT]
|
||||||
packet|pts=-1024|dts=-1024|duration=1024|flags=KDside_data|
|
packet|pts=-1024|dts=-1024|duration=1024|flags=KDside_data|
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ duration_ts=529200
|
||||||
[/STREAM]
|
[/STREAM]
|
||||||
[FORMAT]
|
[FORMAT]
|
||||||
start_time=0.000000
|
start_time=0.000000
|
||||||
duration=12.024000
|
duration=12.000000
|
||||||
[/FORMAT]
|
[/FORMAT]
|
||||||
packet|pts=-1024|dts=-1024|duration=1024|flags=KDside_data|
|
packet|pts=-1024|dts=-1024|duration=1024|flags=KDside_data|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ write_data len 36, time nopts, type header atom ftyp
|
||||||
write_data len 2761, time nopts, type header atom -
|
write_data len 2761, time nopts, type header atom -
|
||||||
write_data len 908, time 966667, type sync atom moof
|
write_data len 908, time 966667, type sync atom moof
|
||||||
write_data len 110, time nopts, type trailer atom -
|
write_data len 110, time nopts, type trailer atom -
|
||||||
5b6e4211a45cd5dac99c8b90752a03d7 3815 non-empty-moov-elst
|
caf0876986b5f033efc0958c338289cc 3815 non-empty-moov-elst
|
||||||
write_data len 36, time nopts, type header atom ftyp
|
write_data len 36, time nopts, type header atom ftyp
|
||||||
write_data len 2669, time nopts, type header atom -
|
write_data len 2669, time nopts, type header atom -
|
||||||
write_data len 908, time 1000000, type sync atom moof
|
write_data len 908, time 1000000, type sync atom moof
|
||||||
|
|
Loading…
Reference in New Issue