[FFmpeg-devel] [PATCH v4 1/8] avcodec/startcode.h: create start_code_is_valid()

Scott Theisen scott.the.elm at gmail.com
Fri Sep 16 21:19:55 EEST 2022


This slightly changes what is considered valid in the following cases:
cavsdec.c:   0x000000XX is now considered invalid.
mpeg12dec.c: 0x000000XX is now considered invalid.
(where X is any value)

IS_MARKER is equivalent since VC1_CODE_RES0 = 0x00000100
---
 libavcodec/cavsdec.c               |  2 +-
 libavcodec/cbs_mpeg2.c             |  6 +++---
 libavcodec/extract_extradata_bsf.c |  2 +-
 libavcodec/mpeg12.c                |  2 +-
 libavcodec/mpeg12dec.c             |  2 +-
 libavcodec/mpegvideo_parser.c      |  2 +-
 libavcodec/remove_extradata_bsf.c  |  8 +++-----
 libavcodec/startcode.h             | 17 +++++++++++++++++
 libavcodec/vaapi_vc1.c             |  2 +-
 libavcodec/vc1_common.h            |  4 +---
 libavcodec/vc1dec.c                |  2 +-
 libavformat/avs2dec.c              |  4 ++--
 libavformat/avs3dec.c              |  4 ++--
 libavformat/cavsvideodec.c         |  2 +-
 libavformat/mpegvideodec.c         |  2 +-
 libavformat/rtpenc_mpv.c           |  2 +-
 16 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index 3e8be65968..0c19d0e3f6 100644
--- a/libavcodec/cavsdec.c
+++ b/libavcodec/cavsdec.c
@@ -1257,7 +1257,7 @@ static int cavs_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
     buf_end = buf + buf_size;
     for(;;) {
         buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &stc);
-        if ((stc & 0xFFFFFE00) || buf_ptr == buf_end) {
+        if (!start_code_is_valid(stc) || buf_ptr == buf_end) {
             if (!h->stc)
                 av_log(h->avctx, AV_LOG_WARNING, "no frame decoded\n");
             return FFMAX(0, buf_ptr - buf);
diff --git a/libavcodec/cbs_mpeg2.c b/libavcodec/cbs_mpeg2.c
index 04b0c7f87d..23839ca47b 100644
--- a/libavcodec/cbs_mpeg2.c
+++ b/libavcodec/cbs_mpeg2.c
@@ -150,7 +150,7 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
 
     start = avpriv_find_start_code(frag->data, frag->data + frag->data_size,
                                    &start_code);
-    if (start_code >> 8 != 0x000001) {
+    if (!start_code_is_valid(start_code)) {
         // No start code found.
         return AVERROR_INVALIDDATA;
     }
@@ -172,7 +172,7 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
         // (may be the last byte of fragment->data); end points to the byte
         // following the byte containing the start code identifier (or to
         // the end of fragment->data).
-        if (start_code >> 8 == 0x000001) {
+        if (start_code_is_valid(start_code)) {
             // Unit runs from start to the beginning of the start code
             // pointed to by end (including any padding zeroes).
             unit_size = (end - 4) - start;
@@ -189,7 +189,7 @@ static int cbs_mpeg2_split_fragment(CodedBitstreamContext *ctx,
         start = end;
 
         // Do we have a further unit to add to the fragment?
-    } while ((start_code >> 8) == 0x000001);
+    } while (start_code_is_valid(start_code));
 
     return 0;
 }
diff --git a/libavcodec/extract_extradata_bsf.c b/libavcodec/extract_extradata_bsf.c
index 329b1a6174..e698a2632e 100644
--- a/libavcodec/extract_extradata_bsf.c
+++ b/libavcodec/extract_extradata_bsf.c
@@ -239,7 +239,7 @@ static int extract_extradata_vc1(AVBSFContext *ctx, AVPacket *pkt,
         ptr = avpriv_find_start_code(ptr, end, &state);
         if (state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT) {
             has_extradata = 1;
-        } else if (has_extradata && IS_MARKER(state)) {
+        } else if (has_extradata && start_code_is_valid(state)) {
             extradata_size = ptr - 4 - pkt->data;
             break;
         }
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c
index d78e25a777..5ff1830496 100644
--- a/libavcodec/mpeg12.c
+++ b/libavcodec/mpeg12.c
@@ -214,7 +214,7 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size,
                 pc->frame_start_found = 0;
             if (pc->frame_start_found  < 4 && state == EXT_START_CODE)
                 pc->frame_start_found++;
-            if (pc->frame_start_found == 4 && (state & 0xFFFFFF00) == 0x100) {
+            if (pc->frame_start_found == 4 && start_code_is_valid(state)) {
                 if (state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE) {
                     pc->frame_start_found = 0;
                     pc->state             = -1;
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 7133696f3c..b857353ab8 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -2446,7 +2446,7 @@ static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
         /* find next start code */
         uint32_t start_code = -1;
         buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &start_code);
-        if (start_code > 0x1ff) {
+        if (!start_code_is_valid(start_code)) {
             if (!skip_frame) {
                 if (HAVE_THREADS &&
                     (avctx->active_thread_type & FF_THREAD_SLICE) &&
diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c
index ac6efb6909..f5afa95981 100644
--- a/libavcodec/mpegvideo_parser.c
+++ b/libavcodec/mpegvideo_parser.c
@@ -83,7 +83,7 @@ static int mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf,
                 pc->frame_start_found = 0;
             if (pc->frame_start_found  < 4 && state == EXT_START_CODE)
                 pc->frame_start_found++;
-            if (pc->frame_start_found == 4 && (state & 0xFFFFFF00) == 0x100) {
+            if (pc->frame_start_found == 4 && start_code_is_valid(state)) {
                 if (state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE) {
                     pc->frame_start_found = 0;
                     pc->state             = -1;
diff --git a/libavcodec/remove_extradata_bsf.c b/libavcodec/remove_extradata_bsf.c
index 66b7d00bd8..1914cf19d5 100644
--- a/libavcodec/remove_extradata_bsf.c
+++ b/libavcodec/remove_extradata_bsf.c
@@ -35,8 +35,6 @@ enum RemoveFreq {
     REMOVE_FREQ_NONKEYFRAME,
 };
 
-#define START_CODE 0x000001
-
 typedef struct RemoveExtradataContext {
     const AVClass *class;
     int freq;
@@ -73,7 +71,7 @@ static int h264_split(const uint8_t *buf, int buf_size)
 
     while (ptr < end) {
         ptr = avpriv_find_start_code(ptr, end, &state);
-        if ((state & 0xFFFFFF00) != 0x100)
+        if (!start_code_is_valid(state))
             break;
         nalu_type = state & 0x1F;
         if (nalu_type == H264_NAL_SPS) {
@@ -111,7 +109,7 @@ static int hevc_split(const uint8_t *buf, int buf_size)
 
     while (ptr < end) {
         ptr = avpriv_find_start_code(ptr, end, &state);
-        if ((state >> 8) != START_CODE)
+        if (!start_code_is_valid(state))
             break;
         nut = (state >> 1) & 0x3F;
         if (nut == HEVC_NAL_VPS)
@@ -171,7 +169,7 @@ static int vc1_split(const uint8_t *buf, int buf_size)
         ptr = avpriv_find_start_code(ptr, end, &state);
         if (state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT) {
             charged = 1;
-        } else if (charged && IS_MARKER(state))
+        } else if (charged && start_code_is_valid(state))
             return ptr - 4 - buf;
     }
 
diff --git a/libavcodec/startcode.h b/libavcodec/startcode.h
index 8b75832aaf..833754af09 100644
--- a/libavcodec/startcode.h
+++ b/libavcodec/startcode.h
@@ -27,6 +27,23 @@
 
 #include <stdint.h>
 
+#include "libavutil/attributes.h"
+
+/**
+ * @brief Test whether a start code found by avpriv_find_start_code() is valid.
+ *
+ * Use this to test the validity of a start code especially if a start code can
+ * be at the end of the buffer, where testing the return value of avpriv_find_start_code()
+ * would incorrectly imply that the start code is invalid (since the returned value
+ * equals <b>@c end </b>).
+ *
+ * @param[in] start_code The start code to test.
+ * @return A boolean that is true if and only if <b>@p start_code</b> is valid
+ */
+static av_always_inline int start_code_is_valid(uint32_t start_code) {
+    return (start_code & 0xFFFFFF00) == 0x100;
+}
+
 const uint8_t *avpriv_find_start_code(const uint8_t *p,
                                       const uint8_t *end,
                                       uint32_t *state);
diff --git a/libavcodec/vaapi_vc1.c b/libavcodec/vaapi_vc1.c
index d82336a3b3..33de4a63c8 100644
--- a/libavcodec/vaapi_vc1.c
+++ b/libavcodec/vaapi_vc1.c
@@ -473,7 +473,7 @@ static int vaapi_vc1_decode_slice(AVCodecContext *avctx, const uint8_t *buffer,
     int err;
 
     /* Current bit buffer is beyond any marker for VC-1, so skip it */
-    if (avctx->codec_id == AV_CODEC_ID_VC1 && IS_MARKER(AV_RB32(buffer))) {
+    if (avctx->codec_id == AV_CODEC_ID_VC1 && start_code_is_valid(AV_RB32(buffer))) {
         buffer += 4;
         size -= 4;
     }
diff --git a/libavcodec/vc1_common.h b/libavcodec/vc1_common.h
index c0f0c8c2eb..8ff9802a51 100644
--- a/libavcodec/vc1_common.h
+++ b/libavcodec/vc1_common.h
@@ -41,8 +41,6 @@ enum VC1Code {
 };
 //@}
 
-#define IS_MARKER(x) (((x) & ~0xFF) == VC1_CODE_RES0)
-
 /** Available Profiles */
 //@{
 enum Profile {
@@ -61,7 +59,7 @@ static av_always_inline const uint8_t* find_next_marker(const uint8_t *src, cons
     if (end - src >= 4) {
         uint32_t mrk = 0xFFFFFFFF;
         src = avpriv_find_start_code(src, end, &mrk);
-        if (IS_MARKER(mrk))
+        if (start_code_is_valid(mrk))
             return src - 4;
     }
     return end;
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
index 9f32e82f9e..d98c15f2e4 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -667,7 +667,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, AVFrame *pict,
         if (!buf2)
             return AVERROR(ENOMEM);
 
-        if (IS_MARKER(AV_RB32(buf))) { /* frame starts with marker and needs to be parsed */
+        if (start_code_is_valid(AV_RB32(buf))) { /* frame starts with marker and needs to be parsed */
             const uint8_t *start, *end, *next;
             int size;
 
diff --git a/libavformat/avs2dec.c b/libavformat/avs2dec.c
index 0d5b23b65e..a5a7cee7d0 100644
--- a/libavformat/avs2dec.c
+++ b/libavformat/avs2dec.c
@@ -42,8 +42,8 @@ static int avs2_probe(const AVProbeData *p)
 
     while (ptr < end) {
         ptr = avpriv_find_start_code(ptr, end, &code);
-        state = code & 0xFF;
-        if ((code & 0xffffff00) == 0x100) {
+        if (start_code_is_valid(code)) {
+            state = code & 0xFF;
             if (AVS2_ISUNIT(state)) {
                 if (sqb && !hds) {
                     hds = ptr - sqb;
diff --git a/libavformat/avs3dec.c b/libavformat/avs3dec.c
index 2395df171b..112b28efa8 100644
--- a/libavformat/avs3dec.c
+++ b/libavformat/avs3dec.c
@@ -36,8 +36,8 @@ static int avs3video_probe(const AVProbeData *p)
 
     while (ptr < end) {
         ptr = avpriv_find_start_code(ptr, end, &code);
-        state = code & 0xFF;
-        if ((code & 0xFFFFFF00) == 0x100) {
+        if (start_code_is_valid(code)) {
+            state = code & 0xFF;
             if (state < AVS3_SEQ_START_CODE) {
                 if (code < slice_pos)
                     return 0;
diff --git a/libavformat/cavsvideodec.c b/libavformat/cavsvideodec.c
index b89851fbbb..398f1192dd 100644
--- a/libavformat/cavsvideodec.c
+++ b/libavformat/cavsvideodec.c
@@ -39,7 +39,7 @@ static int cavsvideo_probe(const AVProbeData *p)
 
     while (ptr < end) {
         ptr = avpriv_find_start_code(ptr, end, &code);
-        if ((code & 0xffffff00) == 0x100) {
+        if (start_code_is_valid(code)) {
             if(code < CAVS_SEQ_START_CODE) {
                 /* slices have to be consecutive */
                 if(code < slice_pos)
diff --git a/libavformat/mpegvideodec.c b/libavformat/mpegvideodec.c
index 33c5d79794..88966af72a 100644
--- a/libavformat/mpegvideodec.c
+++ b/libavformat/mpegvideodec.c
@@ -44,7 +44,7 @@ static int mpegvideo_probe(const AVProbeData *p)
 
     while (ptr < end) {
         ptr = avpriv_find_start_code(ptr, end, &code);
-        if ((code & 0xffffff00) == 0x100) {
+        if (start_code_is_valid(code)) {
             switch(code){
             case     SEQ_START_CODE:
                 if (!(ptr[3 + 1 + 2] & 0x20))
diff --git a/libavformat/rtpenc_mpv.c b/libavformat/rtpenc_mpv.c
index c18c75082f..8b6987b7f2 100644
--- a/libavformat/rtpenc_mpv.c
+++ b/libavformat/rtpenc_mpv.c
@@ -57,7 +57,7 @@ void ff_rtp_send_mpegvideo(AVFormatContext *s1, const uint8_t *buf1, int size)
             while (1) {
                 start_code = -1;
                 r = avpriv_find_start_code(r1, end, &start_code);
-                if((start_code & 0xFFFFFF00) == 0x100) {
+                if (start_code_is_valid(start_code)) {
                     /* New start code found */
                     if (start_code == 0x100) {
                         frame_type = (r[1] & 0x38) >> 3;
-- 
2.34.1



More information about the ffmpeg-devel mailing list