This will allow decoupling the parser from the decoder.tags/n3.1
| @@ -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; | |||
| @@ -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); | |||
| @@ -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; | |||
| } | |||
| @@ -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 */ | |||
| @@ -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 | |||
| @@ -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; | |||