]> git.sesse.net Git - ffmpeg/commitdiff
avformat/movenc: implement writing of the btrt box
authorJan Ekström <jeebjp@gmail.com>
Sun, 20 Sep 2020 12:26:42 +0000 (15:26 +0300)
committerJan Ekström <jeebjp@gmail.com>
Tue, 22 Sep 2020 15:21:31 +0000 (18:21 +0300)
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.

libavformat/movenc.c
tests/fate/mov.mak
tests/ref/fate/copy-trac3074
tests/ref/fate/movenc
tests/ref/lavf-fate/av1.mp4
tests/ref/lavf-fate/h264.mp4
tests/ref/lavf/mp4
tests/ref/vsynth/vsynth1-mpeg4
tests/ref/vsynth/vsynth2-mpeg4
tests/ref/vsynth/vsynth3-mpeg4
tests/ref/vsynth/vsynth_lena-mpeg4

index a4ec4d05c9d48cd395a83f1afb4f374dd6b59326..76fb251fa86b1a3c0484b5bad287f5d1cd9ac96f 100644 (file)
@@ -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)
index 8d3b6c7224949a6a0d7c535cbc8693751011b339..0fd20fef9624d32663fc40ef6f425729762b105e 100644 (file)
@@ -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
index ff66900253f88f8e8f7b5bbbae6610940524c564..b5b0b6a60b07f6c1f19e04f132e308d865676d72 100644 (file)
@@ -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
index fb39b98165fa8f74a12c464cb1ea8e8a7860504f..602639106d5fa9dbc7e13ee5c05d302f3e2e37d2 100644 (file)
@@ -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
index 470c7671117f97ddd40e11143311dc777b7e952c..ef174589baf0975be970c64b4ded67d204751780 100644 (file)
@@ -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
index bb52f45758a383c777873e3055c80329e73714fb..a9c3823c2c2a1933f58b3792bf2bb0bbf4c6d0a6 100644 (file)
@@ -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
index 8482812380961c59dbfca2ef54f43ece053ce42c..0becfd34f5814bf09dd73261b3d1dd7b5b968df1 100644 (file)
@@ -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
index 4e9b4bd03a90ab73332fe4739162dbe98fc53185..e5abc146bc962487bf9a92c6813f02d7747f1f60 100644 (file)
@@ -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
index 85899ff88e7a5a592e2f6b886f5fdefcec269c59..7857d458033739ac7d671d1999da38780f131aed 100644 (file)
@@ -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
index 02cf68d55d26aef90582cefef15b21e4ae5c6178..a241e929c65dcd9526b71bad1557b345a6530f22 100644 (file)
@@ -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
index 8d8cccef4070b6615ac5ddbb70c12203688cfaec..375c3fc659d913b55da5706842f7559b19c800e5 100644 (file)
@@ -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