[FFmpeg-devel] [PATCH] avcodec: Use get_ue_golomb_long() when needed

Mark Harris mark.hsj at gmail.com
Tue Dec 29 08:04:08 CET 2015


get_ue_golomb() cannot decode values larger than 8190 (the maximum
value that can be golomb encoded in 25 bits) and produces the error
"Invalid UE golomb code" if a larger value is encountered.  Use
get_ue_golomb_long() instead (which supports 63 bits, up to 4294967294)
when valid h264/hevc values can exceed 8190.

This updates decoding of the following values:   (maximum)
  first_mb_in_slice                                36863* for level 5.2
  abs_diff_pic_num_minus1                         131071
  difference_of_pic_nums_minus1                   131071
  idr_pic_id                                       65535
  recovery_frame_cnt                               65535
  frame_packing_arrangement_id                4294967294
  frame_packing_arrangement_repetition_period      16384
  display_orientation_repetition_period            16384

An alternative would be to modify get_ue_golomb() to handle encoded
values of up to 49 bits as was done for get_se_golomb() in a92816c.
In that case get_ue_golomb() could continue to be used for all of
these except frame_packing_arrangement_id.
---
 libavcodec/golomb.h      |  2 +-
 libavcodec/h264.c        |  2 +-
 libavcodec/h264_parser.c |  6 +++---
 libavcodec/h264_refs.c   |  4 ++--
 libavcodec/h264_sei.c    | 10 +++++-----
 libavcodec/h264_slice.c  |  2 +-
 libavcodec/hevc_sei.c    |  2 +-
 7 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h
index 5136a04..d4df0b3 100644
--- a/libavcodec/golomb.h
+++ b/libavcodec/golomb.h
@@ -48,7 +48,7 @@ extern const  int8_t ff_interleaved_se_golomb_vlc_code[256];
 extern const uint8_t ff_interleaved_dirac_golomb_vlc_code[256];
 
 /**
- * read unsigned exp golomb code.
+ * Read an unsigned Exp-Golomb code in the range 0 to 8190.
  */
 static inline int get_ue_golomb(GetBitContext *gb)
 {
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 089a86f..139011b 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -1365,7 +1365,7 @@ static int get_last_needed_nal(H264Context *h, const uint8_t *buf, int buf_size)
         case NAL_IDR_SLICE:
         case NAL_SLICE:
             init_get_bits(&gb, ptr, bit_length);
-            if (!get_ue_golomb(&gb) ||
+            if (!get_ue_golomb_long(&gb) ||  // first_mb_in_slice
                 !first_slice ||
                 first_slice != h->nal_unit_type)
                 nals_needed = nal_index;
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 19d1aa3..12d6397 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -152,7 +152,7 @@ static int scan_mmco_reset(AVCodecParserContext *s)
                     unsigned int reordering_of_pic_nums_idc = get_ue_golomb_31(&sl->gb);
 
                     if (reordering_of_pic_nums_idc < 3)
-                        get_ue_golomb(&sl->gb);
+                        get_ue_golomb_long(&sl->gb);
                     else if (reordering_of_pic_nums_idc > 3) {
                         av_log(h->avctx, AV_LOG_ERROR,
                                "illegal reordering_of_pic_nums_idc %d\n",
@@ -191,7 +191,7 @@ static int scan_mmco_reset(AVCodecParserContext *s)
                 return 1;
 
             if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG)
-                get_ue_golomb(&sl->gb);
+                get_ue_golomb_long(&sl->gb); // difference_of_pic_nums_minus1
             if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED ||
                 opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG)
                 get_ue_golomb_31(&sl->gb);
@@ -373,7 +373,7 @@ static inline int parse_nal_units(AVCodecParserContext *s,
             }
 
             if (h->nal_unit_type == NAL_IDR_SLICE)
-                get_ue_golomb(&sl->gb); /* idr_pic_id */
+                get_ue_golomb_long(&sl->gb); /* idr_pic_id */
             if (h->sps.poc_type == 0) {
                 h->poc_lsb = get_bits(&sl->gb, h->sps.log2_max_poc_lsb);
 
diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c
index fbdcbd6..52fedc1 100644
--- a/libavcodec/h264_refs.c
+++ b/libavcodec/h264_refs.c
@@ -266,7 +266,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl)
                 switch (modification_of_pic_nums_idc) {
                 case 0:
                 case 1: {
-                    const unsigned int abs_diff_pic_num = get_ue_golomb(&sl->gb) + 1;
+                    const unsigned int abs_diff_pic_num = get_ue_golomb_long(&sl->gb) + 1;
                     int frame_num;
 
                     if (abs_diff_pic_num > h->max_pic_num) {
@@ -843,7 +843,7 @@ int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb,
                 mmco[i].opcode = opcode;
                 if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG) {
                     mmco[i].short_pic_num =
-                        (h->curr_pic_num - get_ue_golomb(gb) - 1) &
+                        (h->curr_pic_num - get_ue_golomb_long(gb) - 1) &
                             (h->max_pic_num - 1);
 #if 0
                     if (mmco[i].short_pic_num >= h->short_ref_count ||
diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c
index 0411b87..77dd7b2 100644
--- a/libavcodec/h264_sei.c
+++ b/libavcodec/h264_sei.c
@@ -253,7 +253,7 @@ static int decode_unregistered_user_data(H264Context *h, int size)
 
 static int decode_recovery_point(H264Context *h)
 {
-    h->sei_recovery_frame_cnt = get_ue_golomb(&h->gb);
+    h->sei_recovery_frame_cnt = get_ue_golomb_long(&h->gb);
 
     /* 1b exact_match_flag,
      * 1b broken_link_flag,
@@ -306,7 +306,7 @@ static int decode_buffering_period(H264Context *h)
 
 static int decode_frame_packing_arrangement(H264Context *h)
 {
-    h->sei_fpa.frame_packing_arrangement_id          = get_ue_golomb(&h->gb);
+    h->sei_fpa.frame_packing_arrangement_id          = get_ue_golomb_long(&h->gb);
     h->sei_fpa.frame_packing_arrangement_cancel_flag = get_bits1(&h->gb);
     h->sei_frame_packing_present = !h->sei_fpa.frame_packing_arrangement_cancel_flag;
 
@@ -326,7 +326,7 @@ static int decode_frame_packing_arrangement(H264Context *h)
         if (!h->quincunx_subsampling && h->frame_packing_arrangement_type != 5)
             skip_bits(&h->gb, 16);      // frame[01]_grid_position_[xy]
         skip_bits(&h->gb, 8);           // frame_packing_arrangement_reserved_byte
-        h->sei_fpa.frame_packing_arrangement_repetition_period = get_ue_golomb(&h->gb) /* frame_packing_arrangement_repetition_period */;
+        h->sei_fpa.frame_packing_arrangement_repetition_period = get_ue_golomb_long(&h->gb);
     }
     skip_bits1(&h->gb);                 // frame_packing_arrangement_extension_flag
 
@@ -351,8 +351,8 @@ static int decode_display_orientation(H264Context *h)
         h->sei_vflip = get_bits1(&h->gb);     // ver_flip
 
         h->sei_anticlockwise_rotation = get_bits(&h->gb, 16);
-        get_ue_golomb(&h->gb);  // display_orientation_repetition_period
-        skip_bits1(&h->gb);     // display_orientation_extension_flag
+        get_ue_golomb_long(&h->gb);  // display_orientation_repetition_period
+        skip_bits1(&h->gb);          // display_orientation_extension_flag
     }
 
     return 0;
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 2db7ca2..318302f 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -1688,7 +1688,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
     }
 
     if (h->nal_unit_type == NAL_IDR_SLICE)
-        get_ue_golomb(&sl->gb); /* idr_pic_id */
+        get_ue_golomb_long(&sl->gb); /* idr_pic_id */
 
     if (h->sps.poc_type == 0) {
         int poc_lsb = get_bits(&sl->gb, h->sps.log2_max_poc_lsb);
diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c
index 46cd06b..07856f2 100644
--- a/libavcodec/hevc_sei.c
+++ b/libavcodec/hevc_sei.c
@@ -82,7 +82,7 @@ static int decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
 {
     GetBitContext *gb = &s->HEVClc->gb;
 
-    get_ue_golomb(gb);                  // frame_packing_arrangement_id
+    get_ue_golomb_long(gb);             // frame_packing_arrangement_id
     s->sei_frame_packing_present = !get_bits1(gb);
 
     if (s->sei_frame_packing_present) {
-- 
2.6.4



More information about the ffmpeg-devel mailing list