diff mbox series

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

Message ID 20200709191805.21648-1-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
Related show

Checks

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:17 p.m. UTC
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@gmail.com>
---
 libavformat/avc.c | 30 +++++++++++++++++++++++++++++-
 libavformat/avc.h |  2 ++
 2 files changed, 31 insertions(+), 1 deletion(-)
diff mbox series

Patch

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,