h264: factor out parsing the reference count into a separate file
authorAnton Khirnov <anton@khirnov.net>
Mon, 21 Mar 2016 15:14:31 +0000 (16:14 +0100)
committerAnton Khirnov <anton@khirnov.net>
Sun, 24 Apr 2016 08:06:23 +0000 (10:06 +0200)
This will allow decoupling the parser from the decoder.

libavcodec/h264.c
libavcodec/h264.h
libavcodec/h264_parse.c
libavcodec/h264_parse.h
libavcodec/h264_parser.c
libavcodec/h264_slice.c

index f1f9c73..e9dffa6 100644 (file)
@@ -965,53 +965,6 @@ int ff_h264_get_profile(SPS *sps)
     return profile;
 }
 
-int ff_set_ref_count(H264Context *h, H264SliceContext *sl)
-{
-    int ref_count[2], list_count;
-    int num_ref_idx_active_override_flag, max_refs;
-
-    // set defaults, might be overridden a few lines later
-    ref_count[0] = h->pps.ref_count[0];
-    ref_count[1] = h->pps.ref_count[1];
-
-    if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
-        num_ref_idx_active_override_flag = get_bits1(&sl->gb);
-
-        if (num_ref_idx_active_override_flag) {
-            ref_count[0] = get_ue_golomb(&sl->gb) + 1;
-            if (ref_count[0] < 1)
-                return AVERROR_INVALIDDATA;
-            if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
-                ref_count[1] = get_ue_golomb(&sl->gb) + 1;
-                if (ref_count[1] < 1)
-                    return AVERROR_INVALIDDATA;
-            }
-        }
-
-        if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
-            list_count = 2;
-        else
-            list_count = 1;
-    } else {
-        list_count   = 0;
-        ref_count[0] = ref_count[1] = 0;
-    }
-
-    max_refs = h->picture_structure == PICT_FRAME ? 16 : 32;
-
-    if (ref_count[0] > max_refs || ref_count[1] > max_refs) {
-        av_log(h->avctx, AV_LOG_ERROR, "reference overflow\n");
-        sl->ref_count[0] = sl->ref_count[1] = 0;
-        return AVERROR_INVALIDDATA;
-    }
-
-    sl->ref_count[0] = ref_count[0];
-    sl->ref_count[1] = ref_count[1];
-    sl->list_count   = list_count;
-
-    return 0;
-}
-
 static int get_last_needed_nal(H264Context *h)
 {
     int nals_needed = 0;
index cce973f..86625f3 100644 (file)
@@ -1054,7 +1054,6 @@ int ff_h264_slice_context_init(H264Context *h, H264SliceContext *sl);
 
 void ff_h264_draw_horiz_band(const H264Context *h, H264SliceContext *sl, int y, int height);
 int ff_init_poc(H264Context *h, int pic_field_poc[2], int *pic_poc);
-int ff_set_ref_count(H264Context *h, H264SliceContext *sl);
 
 int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl);
 int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count);
index 50b1118..6230d67 100644 (file)
@@ -176,3 +176,49 @@ int ff_h264_check_intra_pred_mode(void *logctx, int top_samples_available,
 
     return mode;
 }
+
+int ff_h264_parse_ref_count(int *plist_count, int ref_count[2],
+                            GetBitContext *gb, const PPS *pps,
+                            int slice_type_nos, int picture_structure)
+{
+    int list_count;
+    int num_ref_idx_active_override_flag, max_refs;
+
+    // set defaults, might be overridden a few lines later
+    ref_count[0] = pps->ref_count[0];
+    ref_count[1] = pps->ref_count[1];
+
+    if (slice_type_nos != AV_PICTURE_TYPE_I) {
+        num_ref_idx_active_override_flag = get_bits1(gb);
+
+        if (num_ref_idx_active_override_flag) {
+            ref_count[0] = get_ue_golomb(gb) + 1;
+            if (ref_count[0] < 1)
+                return AVERROR_INVALIDDATA;
+            if (slice_type_nos == AV_PICTURE_TYPE_B) {
+                ref_count[1] = get_ue_golomb(gb) + 1;
+                if (ref_count[1] < 1)
+                    return AVERROR_INVALIDDATA;
+            }
+        }
+
+        if (slice_type_nos == AV_PICTURE_TYPE_B)
+            list_count = 2;
+        else
+            list_count = 1;
+    } else {
+        list_count   = 0;
+        ref_count[0] = ref_count[1] = 0;
+    }
+
+    max_refs = picture_structure == PICT_FRAME ? 16 : 32;
+
+    if (ref_count[0] > max_refs || ref_count[1] > max_refs) {
+        ref_count[0] = ref_count[1] = 0;
+        return AVERROR_INVALIDDATA;
+    }
+
+    *plist_count = list_count;
+
+    return 0;
+}
index 9b96dc4..23676b3 100644 (file)
@@ -40,6 +40,7 @@ typedef struct H264PredWeightTable {
 } H264PredWeightTable;
 
 struct SPS;
+struct PPS;
 
 int ff_h264_pred_weight_table(GetBitContext *gb, const struct SPS *sps,
                               const int *ref_count, int slice_type_nos,
@@ -60,4 +61,8 @@ int ff_h264_check_intra_pred_mode(void *logctx, int top_samples_available,
                                   int left_samples_available,
                                   int mode, int is_chroma);
 
+int ff_h264_parse_ref_count(int *plist_count, int ref_count[2],
+                            GetBitContext *gb, const struct PPS *pps,
+                            int slice_type_nos, int picture_structure);
+
 #endif /* AVCODEC_H264_PARSE_H */
index 87f6fe6..2d39ee4 100644 (file)
@@ -111,6 +111,7 @@ static int scan_mmco_reset(AVCodecParserContext *s)
     H264ParseContext *p = s->priv_data;
     H264Context      *h = &p->h;
     H264SliceContext *sl = &h->slice_ctx[0];
+    int list_count, ref_count[2];
 
     sl->slice_type_nos = s->pict_type & 3;
 
@@ -120,12 +121,13 @@ static int scan_mmco_reset(AVCodecParserContext *s)
     if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
         get_bits1(&sl->gb); // direct_spatial_mv_pred
 
-    if (ff_set_ref_count(h, sl) < 0)
+    if (ff_h264_parse_ref_count(&list_count, ref_count, &sl->gb, &h->pps,
+                                sl->slice_type_nos, h->picture_structure) < 0)
         return AVERROR_INVALIDDATA;
 
     if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
         int list;
-        for (list = 0; list < sl->list_count; list++) {
+        for (list = 0; list < list_count; list++) {
             if (get_bits1(&sl->gb)) {
                 int index;
                 for (index = 0; ; index++) {
@@ -141,7 +143,7 @@ static int scan_mmco_reset(AVCodecParserContext *s)
                     } else
                         break;
 
-                    if (index >= sl->ref_count[list]) {
+                    if (index >= ref_count[list]) {
                         av_log(h->avctx, AV_LOG_ERROR,
                                "reference count %d overflow\n", index);
                         return AVERROR_INVALIDDATA;
@@ -153,7 +155,7 @@ static int scan_mmco_reset(AVCodecParserContext *s)
 
     if ((h->pps.weighted_pred && sl->slice_type_nos == AV_PICTURE_TYPE_P) ||
         (h->pps.weighted_bipred_idc == 1 && sl->slice_type_nos == AV_PICTURE_TYPE_B))
-        ff_h264_pred_weight_table(&sl->gb, &h->sps, sl->ref_count, sl->slice_type_nos,
+        ff_h264_pred_weight_table(&sl->gb, &h->sps, ref_count, sl->slice_type_nos,
                                   &sl->pwt);
 
     if (get_bits1(&sl->gb)) { // adaptive_ref_pic_marking_mode_flag
index d2c1f13..4b9c00c 100644 (file)
@@ -1457,7 +1457,9 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
     if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
         sl->direct_spatial_mv_pred = get_bits1(&sl->gb);
 
-    ret = ff_set_ref_count(h, sl);
+    ret = ff_h264_parse_ref_count(&sl->list_count, sl->ref_count,
+                                  &sl->gb, &h->pps, sl->slice_type_nos,
+                                  h->picture_structure);
     if (ret < 0)
         return ret;