Merge commit 'a6e27f7add2698fdd89911632b570c3d0c3f2aaa'

* commit 'a6e27f7add2698fdd89911632b570c3d0c3f2aaa':
  h264: factor out parsing the reference count into a separate file

Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
This commit is contained in:
Derek Buitenhuis 2016-05-17 15:16:38 +01:00
commit 278dcec28d
6 changed files with 62 additions and 52 deletions

View File

@ -997,52 +997,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;
// 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) {
unsigned max[2];
max[0] = max[1] = h->picture_structure == PICT_FRAME ? 15 : 31;
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 (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
ref_count[1] = get_ue_golomb(&sl->gb) + 1;
} else
// full range is spec-ok in this case, even for frames
ref_count[1] = 1;
}
if (ref_count[0]-1 > max[0] || ref_count[1]-1 > max[1]){
av_log(h->avctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n", ref_count[0]-1, max[0], ref_count[1]-1, max[1]);
sl->ref_count[0] = sl->ref_count[1] = 0;
sl->list_count = 0;
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;
}
sl->ref_count[0] = ref_count[0];
sl->ref_count[1] = ref_count[1];
sl->list_count = list_count;
return 0;
}
#if FF_API_CAP_VDPAU
static const uint8_t start_code[] = { 0x00, 0x00, 0x01 };

View File

@ -1182,7 +1182,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);
#define SLICE_SINGLETHREAD 1

View File

@ -186,3 +186,51 @@ 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, void *logctx)
{
int list_count;
int num_ref_idx_active_override_flag;
// 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) {
unsigned max[2];
max[0] = max[1] = picture_structure == PICT_FRAME ? 15 : 31;
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 (slice_type_nos == AV_PICTURE_TYPE_B) {
ref_count[1] = get_ue_golomb(gb) + 1;
} else
// full range is spec-ok in this case, even for frames
ref_count[1] = 1;
}
if (ref_count[0] - 1 > max[0] || ref_count[1] - 1 > max[1]) {
av_log(logctx, AV_LOG_ERROR, "reference overflow %u > %u or %u > %u\n",
ref_count[0] - 1, max[0], ref_count[1] - 1, max[1]);
ref_count[0] = ref_count[1] = 0;
*plist_count = 0;
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;
}
*plist_count = list_count;
return 0;
}

View 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, void *logctx);
#endif /* AVCODEC_H264_PARSE_H */

View File

@ -144,6 +144,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;
@ -153,12 +154,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, h->avctx) < 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++) {
@ -174,7 +176,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;
@ -186,7 +188,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

View File

@ -1692,7 +1692,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, h->avctx);
if (ret < 0)
return ret;