h264: factor out parsing the reference count into a separate file
This will allow decoupling the parser from the decoder.
This commit is contained in:
parent
56b17a33f2
commit
a6e27f7add
@ -965,53 +965,6 @@ int ff_h264_get_profile(SPS *sps)
|
|||||||
return profile;
|
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)
|
static int get_last_needed_nal(H264Context *h)
|
||||||
{
|
{
|
||||||
int nals_needed = 0;
|
int nals_needed = 0;
|
||||||
|
@ -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);
|
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_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_decode_slice_header(H264Context *h, H264SliceContext *sl);
|
||||||
int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count);
|
int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count);
|
||||||
|
@ -176,3 +176,49 @@ int ff_h264_check_intra_pred_mode(void *logctx, int top_samples_available,
|
|||||||
|
|
||||||
return mode;
|
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;
|
||||||
|
}
|
||||||
|
@ -40,6 +40,7 @@ typedef struct H264PredWeightTable {
|
|||||||
} H264PredWeightTable;
|
} H264PredWeightTable;
|
||||||
|
|
||||||
struct SPS;
|
struct SPS;
|
||||||
|
struct PPS;
|
||||||
|
|
||||||
int ff_h264_pred_weight_table(GetBitContext *gb, const struct SPS *sps,
|
int ff_h264_pred_weight_table(GetBitContext *gb, const struct SPS *sps,
|
||||||
const int *ref_count, int slice_type_nos,
|
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 left_samples_available,
|
||||||
int mode, int is_chroma);
|
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 */
|
#endif /* AVCODEC_H264_PARSE_H */
|
||||||
|
@ -111,6 +111,7 @@ static int scan_mmco_reset(AVCodecParserContext *s)
|
|||||||
H264ParseContext *p = s->priv_data;
|
H264ParseContext *p = s->priv_data;
|
||||||
H264Context *h = &p->h;
|
H264Context *h = &p->h;
|
||||||
H264SliceContext *sl = &h->slice_ctx[0];
|
H264SliceContext *sl = &h->slice_ctx[0];
|
||||||
|
int list_count, ref_count[2];
|
||||||
|
|
||||||
sl->slice_type_nos = s->pict_type & 3;
|
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)
|
if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
|
||||||
get_bits1(&sl->gb); // direct_spatial_mv_pred
|
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;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
|
if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
|
||||||
int list;
|
int list;
|
||||||
for (list = 0; list < sl->list_count; list++) {
|
for (list = 0; list < list_count; list++) {
|
||||||
if (get_bits1(&sl->gb)) {
|
if (get_bits1(&sl->gb)) {
|
||||||
int index;
|
int index;
|
||||||
for (index = 0; ; index++) {
|
for (index = 0; ; index++) {
|
||||||
@ -141,7 +143,7 @@ static int scan_mmco_reset(AVCodecParserContext *s)
|
|||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (index >= sl->ref_count[list]) {
|
if (index >= ref_count[list]) {
|
||||||
av_log(h->avctx, AV_LOG_ERROR,
|
av_log(h->avctx, AV_LOG_ERROR,
|
||||||
"reference count %d overflow\n", index);
|
"reference count %d overflow\n", index);
|
||||||
return AVERROR_INVALIDDATA;
|
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) ||
|
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))
|
(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);
|
&sl->pwt);
|
||||||
|
|
||||||
if (get_bits1(&sl->gb)) { // adaptive_ref_pic_marking_mode_flag
|
if (get_bits1(&sl->gb)) { // adaptive_ref_pic_marking_mode_flag
|
||||||
|
@ -1457,7 +1457,9 @@ int ff_h264_decode_slice_header(H264Context *h, H264SliceContext *sl)
|
|||||||
if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
|
if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
|
||||||
sl->direct_spatial_mv_pred = get_bits1(&sl->gb);
|
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)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user