[FFmpeg-devel] [PATCH 08/17] avformat/avc: Add helper function to parse annex B NAL unit in one go

Andreas Rheinhardt andreas.rheinhardt at gmail.com
Thu Jul 9 22:17:55 EEST 2020


Up until now, a caller had no function to easily parse a single annex B
NAL unit. There was a "low-level" function that returned the position of
the beginning of the next start code, which could be used to get the
beginning and the end of NAL units. Yet using this function still
required calling the startcode function twice and actually getting the
start of the NAL unit data required a loop (because the offset from the
start of the unit might be three or four). In practice, several
functions that transformed from annex B to mp4 used the same scheme to
do so while other (the functions to write H.264/HEVC extradata) used the
former to at first transform the input into something more manageable.

This commit adds a helper function to easily parse one annex B NAL unit
in one go.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
---
 libavformat/avc.c | 30 +++++++++++++++++++++++++++++-
 libavformat/avc.h |  2 ++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/libavformat/avc.c b/libavformat/avc.c
index cc92fb1038..39078aa5be 100644
--- a/libavformat/avc.c
+++ b/libavformat/avc.c
@@ -79,15 +79,43 @@ rest:
             return p;
     }
 
-    return end;
+    return NULL;
 }
 
 const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end){
     const uint8_t *out = avc_find_startcode_internal(p, end);
+    out = out ? out : end;
     if(p<out && out<end && !out[-1]) out--;
     return out;
 }
 
+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;
+
+    if (!p)
+        return NULL;
+
+    if (!*nal_end) {
+        p = avc_find_startcode_internal(p, end);
+        if (!p)
+            return NULL;
+        p += 3;
+    }
+
+    next = avc_find_startcode_internal(p, end);
+
+    if (next) {
+        *nal_end = next > p && !next[-1] ? next - 1 : next;
+        next    += 3;
+    } else {
+        *nal_end = end;
+    }
+    *start = next;
+    return p;
+}
+
 int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size)
 {
     const uint8_t *p = buf_in;
diff --git a/libavformat/avc.h b/libavformat/avc.h
index 9792b77913..b3df0a7b6b 100644
--- a/libavformat/avc.h
+++ b/libavformat/avc.h
@@ -29,6 +29,8 @@ int ff_avc_parse_nal_units(AVIOContext *s, const uint8_t *buf, int size);
 int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size);
 int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len);
 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);
 int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size);
 const uint8_t *ff_avc_mp4_find_startcode(const uint8_t *start,
                                          const uint8_t *end,
-- 
2.20.1



More information about the ffmpeg-devel mailing list