aboutsummaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--libavcodec/h264.c47
-rw-r--r--libavcodec/h264.h1
-rw-r--r--libavcodec/h264_parse.c46
-rw-r--r--libavcodec/h264_parse.h5
-rw-r--r--libavcodec/h264_parser.c10
-rw-r--r--libavcodec/h264_slice.c4
6 files changed, 60 insertions, 53 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index f1f9c7304b..e9dffa6b92 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -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;
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index cce973f42c..86625f3a13 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -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);
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;
+}
diff --git a/libavcodec/h264_parse.h b/libavcodec/h264_parse.h
index 9b96dc47a0..23676b36c7 100644
--- a/libavcodec/h264_parse.h
+++ b/libavcodec/h264_parse.h
@@ -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 */
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c
index 87f6fe6706..2d39ee4a04 100644
--- a/libavcodec/h264_parser.c
+++ b/libavcodec/h264_parser.c
@@ -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
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index d2c1f13f51..4b9c00c76b 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -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;