diff options
author | Gil Pedersen <gil@cmi.aau.dk> | 2011-05-02 19:25:28 +0200 |
---|---|---|
committer | Alex Converse <alex.converse@gmail.com> | 2011-05-31 08:16:18 -0700 |
commit | c16919487ec4acc861401d0e2ad2bbdb5cb251d1 (patch) | |
tree | 33f481933550d26c0a721e6549fec0fe1e90bfd6 /libavformat/movenc.c | |
parent | 6f1ec38ce2193d3d4cacd87edb452c6d7ba751ec (diff) | |
download | ffmpeg-c16919487ec4acc861401d0e2ad2bbdb5cb251d1.tar.gz |
improved 'edts' atom writing support
The 'edts' write function can now generate an initial empty edit resulting in a track-specific presentation delay.
This is automatically calculated and inserted for any track where the initial DTS != 0.
Added support for long (version==1) timecodes.
Diffstat (limited to 'libavformat/movenc.c')
-rw-r--r-- | libavformat/movenc.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 2b6539d140..67d39f4aef 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -1279,20 +1279,49 @@ static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track) // This box seems important for the psp playback ... without it the movie seems to hang static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track) { - avio_wb32(pb, 0x24); /* size */ + int64_t duration = av_rescale_rnd(track->trackDuration, MOV_TIMESCALE, + track->timescale, AV_ROUND_UP); + int version = duration < INT32_MAX ? 0 : 1; + int entry_size, entry_count, size; + int64_t delay, start_ct = track->cluster[0].cts; + delay = av_rescale_rnd(track->cluster[0].dts + start_ct, MOV_TIMESCALE, + track->timescale, AV_ROUND_DOWN); + version |= delay < INT32_MAX ? 0 : 1; + + entry_size = (version == 1) ? 20 : 12; + entry_count = 1 + (delay > 0); + size = 24 + entry_count * entry_size; + + /* write the atom data */ + avio_wb32(pb, size); ffio_wfourcc(pb, "edts"); - avio_wb32(pb, 0x1c); /* size */ + avio_wb32(pb, size - 8); ffio_wfourcc(pb, "elst"); - avio_wb32(pb, 0x0); - avio_wb32(pb, 0x1); + avio_w8(pb, version); + avio_wb24(pb, 0); /* flags */ - /* duration ... doesn't seem to effect psp */ - avio_wb32(pb, av_rescale_rnd(track->trackDuration, MOV_TIMESCALE, - track->timescale, AV_ROUND_UP)); + avio_wb32(pb, entry_count); + if (delay > 0) { /* add an empty edit to delay presentation */ + if (version == 1) { + avio_wb64(pb, delay); + avio_wb64(pb, -1); + } else { + avio_wb32(pb, delay); + avio_wb32(pb, -1); + } + avio_wb32(pb, 0x00010000); + } - avio_wb32(pb, track->cluster[0].cts); /* first pts is cts since dts is 0 */ + /* duration */ + if (version == 1) { + avio_wb64(pb, duration); + avio_wb64(pb, start_ct); + } else { + avio_wb32(pb, duration); + avio_wb32(pb, start_ct); + } avio_wb32(pb, 0x00010000); - return 0x24; + return size; } static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track) @@ -1349,7 +1378,7 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVTrack *track, AVStream *st) avio_wb32(pb, 0); /* size */ ffio_wfourcc(pb, "trak"); mov_write_tkhd_tag(pb, track, st); - if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS) + if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS || track->cluster[0].dts) mov_write_edts_tag(pb, track); // PSP Movies require edts box if (track->tref_tag) mov_write_tref_tag(pb, track); |