Skip to content

Commit

Permalink
avformat/movenc: implement writing of the btrt box
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
jeeb committed Sep 22, 2020
1 parent 6475dc1 commit 3838e8f
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 27 deletions.
33 changes: 33 additions & 0 deletions libavformat/movenc.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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
Expand All @@ -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);
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion tests/fate/mov.mak
Expand Up @@ -113,7 +113,7 @@ fate-mov-spherical-mono: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries str

fate-mov-gpmf-remux: CMD = md5 -i $(TARGET_SAMPLES)/mov/fake-gp-media-with-real-gpmf.mp4 -map 0 -c copy -fflags +bitexact -f mp4
fate-mov-gpmf-remux: CMP = oneline
fate-mov-gpmf-remux: REF = 8f48e435ee1f6b7e173ea756141eabf3
fate-mov-gpmf-remux: REF = 6361cf3c2b9e6962c2eafbda138125f4

fate-mov-guess-delay-1: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=has_b_frames -select_streams v $(TARGET_SAMPLES)/h264/h264_3bf_nopyramid_nobsrestriction.mp4
fate-mov-guess-delay-2: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=has_b_frames -select_streams v $(TARGET_SAMPLES)/h264/h264_3bf_pyramid_nobsrestriction.mp4
Expand Down
4 changes: 2 additions & 2 deletions tests/ref/fate/copy-trac3074
@@ -1,5 +1,5 @@
f92a201033712bda262f1e071e25544a *tests/data/fate/copy-trac3074.mp4
333992 tests/data/fate/copy-trac3074.mp4
620e3ab4ee6241bec55ea2ec4ef42908 *tests/data/fate/copy-trac3074.mp4
334012 tests/data/fate/copy-trac3074.mp4
#tb 0: 1/48000
#media_type 0: audio
#codec_id 0: eac3
Expand Down
12 changes: 6 additions & 6 deletions tests/ref/fate/movenc
@@ -1,18 +1,18 @@
write_data len 36, time nopts, type header atom ftyp
write_data len 2389, time nopts, type header atom -
write_data len 2429, time nopts, type header atom -
write_data len 788, time 1000000, type sync atom moof
write_data len 110, time nopts, type trailer atom -
5f401347fc3c771b819e2449d69d4861 3323 non-empty-moov
6f06e338c71468d56580df40ff265066 3363 non-empty-moov
write_data len 36, time nopts, type header atom ftyp
write_data len 2721, 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 110, time nopts, type trailer atom -
4267feee527adf8cd4f7b36ac0fc0872 3775 non-empty-moov-elst
5b6e4211a45cd5dac99c8b90752a03d7 3815 non-empty-moov-elst
write_data len 36, time nopts, type header atom ftyp
write_data len 2629, 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 110, time nopts, type trailer atom -
44077b9ad45f3e16fafe4e5ada54e9b0 3683 non-empty-moov-no-elst
e106084014ed245ed7c4a30f1d11a3ac 3723 non-empty-moov-no-elst
write_data len 24, time nopts, type header atom ftyp
write_data len 1171, time nopts, type header atom -
write_data len 728, time 0, type sync atom moof
Expand Down
4 changes: 2 additions & 2 deletions tests/ref/lavf-fate/av1.mp4
@@ -1,3 +1,3 @@
1461be24bed65c04aab21659d6e7a3e1 *tests/data/lavf-fate/lavf.av1.mp4
55956 tests/data/lavf-fate/lavf.av1.mp4
d6afef355cf1bcf1a71b9cfb98c32fba *tests/data/lavf-fate/lavf.av1.mp4
55976 tests/data/lavf-fate/lavf.av1.mp4
tests/data/lavf-fate/lavf.av1.mp4 CRC=0x7c27cc15
4 changes: 2 additions & 2 deletions tests/ref/lavf-fate/h264.mp4
@@ -1,3 +1,3 @@
6d158b25efe7391c803f6f61c7a80aa0 *tests/data/lavf-fate/lavf.h264.mp4
547908 tests/data/lavf-fate/lavf.h264.mp4
fe299ea5205b71a48281f917b1256a5d *tests/data/lavf-fate/lavf.h264.mp4
547928 tests/data/lavf-fate/lavf.h264.mp4
tests/data/lavf-fate/lavf.h264.mp4 CRC=0x9da2c999
12 changes: 6 additions & 6 deletions tests/ref/lavf/mp4
@@ -1,9 +1,9 @@
ebca72c186a4f3ba9bb17d9cb5b74fef *tests/data/lavf/lavf.mp4
312457 tests/data/lavf/lavf.mp4
71c4ff2e747fe6f8169ff29244fe181d *tests/data/lavf/lavf.mp4
312477 tests/data/lavf/lavf.mp4
tests/data/lavf/lavf.mp4 CRC=0x9d9a638a
9944512475d82d2d601f3c96101bdf9c *tests/data/lavf/lavf.mp4
321343 tests/data/lavf/lavf.mp4
3c5734ad6d05e4afc2ccefef1385e882 *tests/data/lavf/lavf.mp4
321363 tests/data/lavf/lavf.mp4
tests/data/lavf/lavf.mp4 CRC=0xe8130120
7b3e71f294901067046c09f03a426bdc *tests/data/lavf/lavf.mp4
312001 tests/data/lavf/lavf.mp4
07348e31d11d92396e1eedc48ea14802 *tests/data/lavf/lavf.mp4
312021 tests/data/lavf/lavf.mp4
tests/data/lavf/lavf.mp4 CRC=0x9d9a638a
4 changes: 2 additions & 2 deletions tests/ref/vsynth/vsynth1-mpeg4
@@ -1,4 +1,4 @@
b4e8871c504a22c8c874c7e845b73da7 *tests/data/fate/vsynth1-mpeg4.mp4
540085 tests/data/fate/vsynth1-mpeg4.mp4
a7e57333c57e0f8a551374b063a41d9e *tests/data/fate/vsynth1-mpeg4.mp4
540105 tests/data/fate/vsynth1-mpeg4.mp4
f80ec173d37f2f91add031e95579a220 *tests/data/fate/vsynth1-mpeg4.out.rawvideo
stddev: 7.97 PSNR: 30.10 MAXDIFF: 105 bytes: 7603200/ 7603200
4 changes: 2 additions & 2 deletions tests/ref/vsynth/vsynth2-mpeg4
@@ -1,4 +1,4 @@
adbd883d1701beabd04522d003dafab6 *tests/data/fate/vsynth2-mpeg4.mp4
159310 tests/data/fate/vsynth2-mpeg4.mp4
b751a2d3b4e693ca39d4fafa0175fc9d *tests/data/fate/vsynth2-mpeg4.mp4
159330 tests/data/fate/vsynth2-mpeg4.mp4
2645405bc5350acc85ad72f3352f5135 *tests/data/fate/vsynth2-mpeg4.out.rawvideo
stddev: 6.02 PSNR: 32.53 MAXDIFF: 89 bytes: 7603200/ 7603200
4 changes: 2 additions & 2 deletions tests/ref/vsynth/vsynth3-mpeg4
@@ -1,4 +1,4 @@
ddcff996543900496f0b374a2d5cae74 *tests/data/fate/vsynth3-mpeg4.mp4
26017 tests/data/fate/vsynth3-mpeg4.mp4
7ca3bbb8bed55d558346d258f5bea440 *tests/data/fate/vsynth3-mpeg4.mp4
26037 tests/data/fate/vsynth3-mpeg4.mp4
fc0d8c1e58d254031e6207dfcae8f867 *tests/data/fate/vsynth3-mpeg4.out.rawvideo
stddev: 9.66 PSNR: 28.43 MAXDIFF: 79 bytes: 86700/ 86700
4 changes: 2 additions & 2 deletions tests/ref/vsynth/vsynth_lena-mpeg4
@@ -1,4 +1,4 @@
4a029747434d24d128b078a5e6aa1e88 *tests/data/fate/vsynth_lena-mpeg4.mp4
119722 tests/data/fate/vsynth_lena-mpeg4.mp4
a0d0edee19f6658d0e93d294e32a1a6f *tests/data/fate/vsynth_lena-mpeg4.mp4
119742 tests/data/fate/vsynth_lena-mpeg4.mp4
9a1e085d9e488c5ead0c940c9612a37a *tests/data/fate/vsynth_lena-mpeg4.out.rawvideo
stddev: 5.34 PSNR: 33.57 MAXDIFF: 83 bytes: 7603200/ 7603200

0 comments on commit 3838e8f

Please sign in to comment.