diff mbox series

[FFmpeg-devel,13/17] avformat/avc: Remove trailing zero bytes during annex B->mp4 conversion

Message ID 20200709192022.9412-5-andreas.rheinhardt@gmail.com
State New
Headers show
Series [FFmpeg-devel,1/7] avformat/avc: Fix undefined shift and assert when reading exp-golomb num | expand


Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Andreas Rheinhardt July 9, 2020, 7:20 p.m. UTC
The annex B format of H.264 and HEVC allows there to be trailing zero
bytes in byte stream NAL units; this means that there can be trailing
zero bytes after the actual NAL units (besides start codes
prepended to them).

Samples in mp4 contain a sequence of length-prefixed NAL units and not
byte stream NAL units; as such, the trailing zero bytes are actually
not allowed. Therefore this commit strips them away.

Two fate-tests needed to be updated: hevc-bsf-mp4toannexb because the
HEVC parser does not properly check for four byte startcodes and instead
assigns the leading zero to the end of the preceding packet (it is now
stripped away) and lavf-fate-h264.mp4 because of an oddity of
ff_h2645_extract_rbsp: It also assigns the first byte of a four-byte
startcode to the preceding unit and this meant that the extradata (from
the extract extradata bsf) has a trailing zero at the end which is now

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
 libavformat/avc.c            | 11 +++++++----
 tests/fate/hevc.mak          |  2 +-
 tests/ref/lavf-fate/h264.mp4 |  4 ++--
 3 files changed, 10 insertions(+), 7 deletions(-)
diff mbox series


diff --git a/libavformat/avc.c b/libavformat/avc.c
index 17fcd1e73f..9f375ca992 100644
--- a/libavformat/avc.c
+++ b/libavformat/avc.c
@@ -92,7 +92,7 @@  const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end){
 const uint8_t *ff_avc_parse_nalu(const uint8_t **start, const uint8_t **nal_end,
                                  const uint8_t *end)
-    const uint8_t *p = *start, *next;
+    const uint8_t *p = *start, *next, *end_temp;
     if (!p)
         return NULL;
@@ -108,18 +108,21 @@  search_again:
     next = avc_find_startcode_internal(p, end);
     if (next) {
-        *nal_end = next > p && !next[-1] ? next - 1 : next;
+        end_temp = next;
         next    += 3;
     } else {
-        *nal_end = end;
+        end_temp = end;
-    if (*nal_end == p) {
+    while (end_temp > p && !end_temp[-1])
+        end_temp--;
+    if (end_temp == p) {
         if (!next)
             return NULL;
         p = next;
         goto search_again;
     *start = next;
+    *nal_end = end_temp;
     return p;
diff --git a/tests/fate/hevc.mak b/tests/fate/hevc.mak
index 65c5a262e9..bd94cc6cff 100644
--- a/tests/fate/hevc.mak
+++ b/tests/fate/hevc.mak
 fate-hevc-bsf-mp4toannexb: tests/data/hevc-mp4.mov
 fate-hevc-bsf-mp4toannexb: CMD = md5 -i $(TARGET_PATH)/tests/data/hevc-mp4.mov -c:v copy -fflags +bitexact -f hevc
 fate-hevc-bsf-mp4toannexb: CMP = oneline
-fate-hevc-bsf-mp4toannexb: REF = 1873662a3af1848c37e4eb25722c8df9
+fate-hevc-bsf-mp4toannexb: REF = 73019329ed7f81c24f9af67c34c640c0
 fate-hevc-skiploopfilter: CMD = framemd5 -skip_loop_filter nokey -i $(TARGET_SAMPLES)/hevc-conformance/SAO_D_Samsung_5.bit -sws_flags bitexact
 FATE_HEVC += fate-hevc-skiploopfilter
diff --git a/tests/ref/lavf-fate/h264.mp4 b/tests/ref/lavf-fate/h264.mp4
index bb52f45758..7a84b7a983 100644
--- a/tests/ref/lavf-fate/h264.mp4
+++ b/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
+aaf8b3d9340ab1fdebced54ada2447d5 *tests/data/lavf-fate/lavf.h264.mp4
+547907 tests/data/lavf-fate/lavf.h264.mp4
 tests/data/lavf-fate/lavf.h264.mp4 CRC=0x9da2c999