summaryrefslogtreecommitdiff
path: root/libavformat/movenc.c
diff options
context:
space:
mode:
authorJan Ekström <jeebjp@gmail.com>2020-09-20 15:26:42 +0300
committerJan Ekström <jeebjp@gmail.com>2020-09-22 18:21:31 +0300
commit3838e8fc210aa09a9f9058506c0ce80b6ad9b9c3 (patch)
tree47f37ed22d850c7700e70528674162c8ec24ec37 /libavformat/movenc.c
parent6475dc18cc4250b1d66e52a979eb71a3738d4716 (diff)
avformat/movenc: implement writing of the btrt box
This is utilized by various media ingests to figure out the bit rate of the content you are pushing towards it, so write it for video, audio and subtitle tracks in case at least one nonzero value is available. It is only mentioned for timed metadata sample descriptions in QTFF, so limit it only to ISOBMFF (MODE_MP4) mode. Updates the FATE tests which have their results changed due to the 20 extra bytes being written per track.
Diffstat (limited to 'libavformat/movenc.c')
-rw-r--r--libavformat/movenc.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index a4ec4d05c9..76fb251fa8 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1073,6 +1073,25 @@ static int get_samples_per_packet(MOVTrack *track)
return first_duration;
}
+static int mov_write_btrt_tag(AVIOContext *pb, MOVTrack *track)
+{
+ int64_t pos = avio_tell(pb);
+ struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
+ if (!bit_rates.max_bit_rate && !bit_rates.avg_bit_rate &&
+ !bit_rates.buffer_size)
+ // no useful data to be written, skip
+ return 0;
+
+ avio_wb32(pb, 0); /* size */
+ ffio_wfourcc(pb, "btrt");
+
+ avio_wb32(pb, bit_rates.buffer_size);
+ avio_wb32(pb, bit_rates.max_bit_rate);
+ avio_wb32(pb, bit_rates.avg_bit_rate);
+
+ return update_size(pb, pos);
+}
+
static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
{
int64_t pos = avio_tell(pb);
@@ -1221,6 +1240,10 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
return ret;
}
+ if (track->mode == MODE_MP4 &&
+ ((ret = mov_write_btrt_tag(pb, track)) < 0))
+ return ret;
+
ret = update_size(pb, pos);
return ret;
}
@@ -1736,6 +1759,7 @@ static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track, int field_order)
static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track)
{
+ int ret = AVERROR_BUG;
int64_t pos = avio_tell(pb);
avio_wb32(pb, 0); /* size */
avio_wl32(pb, track->tag); // store it byteswapped
@@ -1748,6 +1772,10 @@ static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track)
else if (track->par->extradata_size)
avio_write(pb, track->par->extradata, track->par->extradata_size);
+ if (track->mode == MODE_MP4 &&
+ ((ret = mov_write_btrt_tag(pb, track)) < 0))
+ return ret;
+
return update_size(pb, pos);
}
@@ -2051,6 +2079,7 @@ static void find_compressor(char * compressor_name, int len, MOVTrack *track)
static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track)
{
+ int ret = AVERROR_BUG;
int64_t pos = avio_tell(pb);
char compressor_name[32] = { 0 };
int avid = 0;
@@ -2231,6 +2260,10 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
ff_mov_cenc_write_sinf_tag(track, pb, mov->encryption_kid);
}
+ if (track->mode == MODE_MP4 &&
+ ((ret = mov_write_btrt_tag(pb, track)) < 0))
+ return ret;
+
/* extra padding for avid stsd */
/* https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-61112 */
if (avid)