aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2013-09-10 15:24:24 +0300
committerMartin Storsjö <martin@martin.st>2015-03-16 13:23:19 +0200
commit50ff0c05b691524d1fd044a2f2eefb706932fc98 (patch)
tree05ed1f2cfc9e4feef3304200e807bb77e92b687c
parentfaab8f9fcb4ffeb967dc6872c0f1e9da719106ce (diff)
downloadffmpeg-50ff0c05b691524d1fd044a2f2eefb706932fc98.tar.gz
movenc: Support writing multiple trun atoms
This is needed if all the data for one track isn't continuous within the mdat. Normally we make sure all the data for one track is continuous, but in new cases we will need to have the samples interleaved. Signed-off-by: Martin Storsjö <martin@martin.st>
-rw-r--r--libavformat/movenc.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index c326999327..40de25c785 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -2476,18 +2476,19 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov,
}
static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov,
- MOVTrack *track, int moof_size)
+ MOVTrack *track, int moof_size,
+ int first, int end)
{
int64_t pos = avio_tell(pb);
uint32_t flags = MOV_TRUN_DATA_OFFSET;
int i;
- for (i = 0; i < track->entry; i++) {
+ for (i = first; i < end; i++) {
if (get_cluster_duration(track, i) != track->default_duration)
flags |= MOV_TRUN_SAMPLE_DURATION;
if (track->cluster[i].size != track->default_size)
flags |= MOV_TRUN_SAMPLE_SIZE;
- if (i > 0 && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
+ if (i > first && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
flags |= MOV_TRUN_SAMPLE_FLAGS;
}
if (!(flags & MOV_TRUN_SAMPLE_FLAGS) && track->entry > 0 &&
@@ -2501,18 +2502,18 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov,
avio_w8(pb, 0); /* version */
avio_wb24(pb, flags);
- avio_wb32(pb, track->entry); /* sample count */
+ avio_wb32(pb, end - first); /* sample count */
if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
!(mov->flags & FF_MOV_FLAG_DEFAULT_BASE_MOOF) &&
!mov->first_trun)
avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
else
avio_wb32(pb, moof_size + 8 + track->data_offset +
- track->cluster[0].pos); /* data offset */
+ track->cluster[first].pos); /* data offset */
if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
- avio_wb32(pb, get_sample_flags(track, &track->cluster[0]));
+ avio_wb32(pb, get_sample_flags(track, &track->cluster[first]));
- for (i = 0; i < track->entry; i++) {
+ for (i = first; i < end; i++) {
if (flags & MOV_TRUN_SAMPLE_DURATION)
avio_wb32(pb, get_cluster_duration(track, i));
if (flags & MOV_TRUN_SAMPLE_SIZE)
@@ -2652,13 +2653,20 @@ static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
int moof_size)
{
int64_t pos = avio_tell(pb);
+ int i, start = 0;
avio_wb32(pb, 0); /* size placeholder */
ffio_wfourcc(pb, "traf");
mov_write_tfhd_tag(pb, mov, track, moof_offset);
if (mov->mode != MODE_ISM)
mov_write_tfdt_tag(pb, track);
- mov_write_trun_tag(pb, mov, track, moof_size);
+ for (i = 1; i < track->entry; i++) {
+ if (track->cluster[i].pos != track->cluster[i - 1].pos + track->cluster[i - 1].size) {
+ mov_write_trun_tag(pb, mov, track, moof_size, start, i);
+ start = i;
+ }
+ }
+ mov_write_trun_tag(pb, mov, track, moof_size, start, track->entry);
if (mov->mode == MODE_ISM) {
mov_write_tfxd_tag(pb, track);