aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/h264_parse.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2016-03-21 16:14:31 +0100
committerAnton Khirnov <anton@khirnov.net>2016-04-24 10:06:23 +0200
commita6e27f7add2698fdd89911632b570c3d0c3f2aaa (patch)
tree8e345bf225e923c9c8fc0e68809dd28b8aa27ad7 /libavcodec/h264_parse.c
parent56b17a33f231859cbccbd741b4763617cb4ecf03 (diff)
downloadffmpeg-a6e27f7add2698fdd89911632b570c3d0c3f2aaa.tar.gz
h264: factor out parsing the reference count into a separate file
This will allow decoupling the parser from the decoder.
Diffstat (limited to 'libavcodec/h264_parse.c')
-rw-r--r--libavcodec/h264_parse.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c
index 50b111820f..6230d677b5 100644
--- a/libavcodec/h264_parse.c
+++ b/libavcodec/h264_parse.c
@@ -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;
+}