void ff_h264_direct_dist_scale_factor(const H264Context *const h, H264SliceContext *sl) { const int poc = FIELD_PICTURE(h) ? h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD] : h->cur_pic_ptr->poc; const int poc1 = sl->ref_list[1][0].poc; int i, field; if (FRAME_MBAFF(h)) for (field = 0; field < 2; field++) { const int poc = h->cur_pic_ptr->field_poc[field]; const int poc1 = sl->ref_list[1][0].parent->field_poc[field]; for (i = 0; i < 2 * sl->ref_count[0]; i++) sl->dist_scale_factor_field[field][i ^ field] = get_scale_factor(sl, poc, poc1, i + 16); } for (i = 0; i < sl->ref_count[0]; i++) sl->dist_scale_factor[i] = get_scale_factor(sl, poc, poc1, i); }
int ff_h264_decode_ref_pic_marking(H264Context *h, GetBitContext *gb, int first_slice) { int i, ret; MMCO mmco_temp[MAX_MMCO_COUNT], *mmco = mmco_temp; int mmco_index = 0; if (h->nal_unit_type == NAL_IDR_SLICE) { // FIXME fields skip_bits1(gb); // broken_link if (get_bits1(gb)) { mmco[0].opcode = MMCO_LONG; mmco[0].long_arg = 0; mmco_index = 1; } } else { if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag for (i = 0; i < MAX_MMCO_COUNT; i++) { MMCOOpcode opcode = get_ue_golomb_31(gb); mmco[i].opcode = opcode; if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG) { mmco[i].short_pic_num = (h->curr_pic_num - get_ue_golomb(gb) - 1) & (h->max_pic_num - 1); #if 0 if (mmco[i].short_pic_num >= h->short_ref_count || h->short_ref[ mmco[i].short_pic_num ] == NULL){ av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control " "operation %d\n", mmco); return -1; } #endif } if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED || opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG) { unsigned int long_arg = get_ue_golomb_31(gb); if (long_arg >= 32 || (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG && long_arg == 16) && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE(h)))) { av_log(h->avctx, AV_LOG_ERROR, "illegal long ref in memory management control " "operation %d\n", opcode); return -1; } mmco[i].long_arg = long_arg; } if (opcode > (unsigned) MMCO_LONG) { av_log(h->avctx, AV_LOG_ERROR, "illegal memory management control operation %d\n", opcode); return -1; } if (opcode == MMCO_END) break; } mmco_index = i; } else { if (first_slice) { ret = ff_generate_sliding_window_mmcos(h, first_slice); if (ret < 0 && h->avctx->err_recognition & AV_EF_EXPLODE) return ret; } mmco_index = -1; } } if (first_slice && mmco_index != -1) { memcpy(h->mmco, mmco_temp, sizeof(h->mmco)); h->mmco_index = mmco_index; } else if (!first_slice && mmco_index >= 0 && (mmco_index != h->mmco_index || check_opcodes(h->mmco, mmco_temp, mmco_index))) { av_log(h->avctx, AV_LOG_ERROR, "Inconsistent MMCO state between slices [%d, %d]\n", mmco_index, h->mmco_index); return AVERROR_INVALIDDATA; } return 0; }
int ff_h264_decode_ref_pic_list_reordering(H264Context *h) { int list, index, pic_structure, i; print_short_term(h); print_long_term(h); for (list = 0; list < h->list_count; list++) { for (i = 0; i < h->ref_count[list]; i++) COPY_PICTURE(&h->ref_list[list][i], &h->default_ref_list[list][i]); if (get_bits1(&h->gb)) { int pred = h->curr_pic_num; for (index = 0; ; index++) { unsigned int reordering_of_pic_nums_idc = get_ue_golomb_31(&h->gb); unsigned int pic_id; int i; Picture *ref = NULL; if (reordering_of_pic_nums_idc == 3) break; if (index >= h->ref_count[list]) { av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n"); return -1; } if (reordering_of_pic_nums_idc < 3) { if (reordering_of_pic_nums_idc < 2) { const unsigned int abs_diff_pic_num = get_ue_golomb(&h->gb) + 1; int frame_num; if (abs_diff_pic_num > h->max_pic_num) { av_log(h->avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n"); return -1; } if (reordering_of_pic_nums_idc == 0) pred -= abs_diff_pic_num; else pred += abs_diff_pic_num; pred &= h->max_pic_num - 1; frame_num = pic_num_extract(h, pred, &pic_structure); for (i = h->short_ref_count - 1; i >= 0; i--) { ref = h->short_ref[i]; assert(ref->reference); assert(!ref->long_ref); if (ref->frame_num == frame_num && (ref->reference & pic_structure)) break; } if (i >= 0) ref->pic_id = pred; } else { int long_idx; pic_id = get_ue_golomb(&h->gb); //long_term_pic_idx long_idx = pic_num_extract(h, pic_id, &pic_structure); if (long_idx > 31) { av_log(h->avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); return -1; } ref = h->long_ref[long_idx]; assert(!(ref && !ref->reference)); if (ref && (ref->reference & pic_structure)) { ref->pic_id = pic_id; assert(ref->long_ref); i = 0; } else { i = -1; } } if (i < 0) { av_log(h->avctx, AV_LOG_ERROR, "reference picture missing during reorder\n"); memset(&h->ref_list[list][index], 0, sizeof(Picture)); //FIXME } else { for (i = index; i + 1 < h->ref_count[list]; i++) { if (ref->long_ref == h->ref_list[list][i].long_ref && ref->pic_id == h->ref_list[list][i].pic_id) break; } for (; i > index; i--) { COPY_PICTURE(&h->ref_list[list][i], &h->ref_list[list][i - 1]); } COPY_PICTURE(&h->ref_list[list][index], ref); if (FIELD_PICTURE(h)) { pic_as_field(&h->ref_list[list][index], pic_structure); } } } else { av_log(h->avctx, AV_LOG_ERROR, "illegal reordering_of_pic_nums_idc\n"); return -1; } } } } for (list = 0; list < h->list_count; list++) { for (index = 0; index < h->ref_count[list]; index++) { if ( !h->ref_list[list][index].f.buf[0] || (!FIELD_PICTURE(h) && (h->ref_list[list][index].reference&3) != 3)) { int i; av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref_list[list][0].poc); for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++) h->last_pocs[i] = INT_MIN; if (h->default_ref_list[list][0].f.buf[0] && !(!FIELD_PICTURE(h) && (h->default_ref_list[list][0].reference&3) != 3)) COPY_PICTURE(&h->ref_list[list][index], &h->default_ref_list[list][0]); else return -1; } av_assert0(av_buffer_get_ref_count(h->ref_list[list][index].f.buf[0]) > 0); } } return 0; }
int ff_h264_fill_default_ref_list(H264Context *h) { int i, len; if (h->slice_type_nos == AV_PICTURE_TYPE_B) { Picture *sorted[32]; int cur_poc, list; int lens[2]; if (FIELD_PICTURE(h)) cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD]; else cur_poc = h->cur_pic_ptr->poc; for (list = 0; list < 2; list++) { len = add_sorted(sorted, h->short_ref, h->short_ref_count, cur_poc, 1 ^ list); len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list); av_assert0(len <= 32); len = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]), sorted, len, 0, h->picture_structure); len += build_def_list(h->default_ref_list[list] + len, FF_ARRAY_ELEMS(h->default_ref_list[0]) - len, h->long_ref, 16, 1, h->picture_structure); av_assert0(len <= 32); if (len < h->ref_count[list]) memset(&h->default_ref_list[list][len], 0, sizeof(Picture) * (h->ref_count[list] - len)); lens[list] = len; } if (lens[0] == lens[1] && lens[1] > 1) { for (i = 0; i < lens[0] && h->default_ref_list[0][i].f.buf[0]->buffer == h->default_ref_list[1][i].f.buf[0]->buffer; i++); if (i == lens[0]) { Picture tmp; COPY_PICTURE(&tmp, &h->default_ref_list[1][0]); COPY_PICTURE(&h->default_ref_list[1][0], &h->default_ref_list[1][1]); COPY_PICTURE(&h->default_ref_list[1][1], &tmp); } } } else { len = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]), h->short_ref, h->short_ref_count, 0, h->picture_structure); len += build_def_list(h->default_ref_list[0] + len, FF_ARRAY_ELEMS(h->default_ref_list[0]) - len, h-> long_ref, 16, 1, h->picture_structure); av_assert0(len <= 32); if (len < h->ref_count[0]) memset(&h->default_ref_list[0][len], 0, sizeof(Picture) * (h->ref_count[0] - len)); } #ifdef TRACE for (i = 0; i < h->ref_count[0]; i++) { tprintf(h->avctx, "List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].f.data[0]); } if (h->slice_type_nos == AV_PICTURE_TYPE_B) { for (i = 0; i < h->ref_count[1]; i++) { tprintf(h->avctx, "List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[1][i].f.data[0]); } } #endif return 0; }
int ff_h264_decode_ref_pic_list_reordering(H264Context *h, H264SliceContext *sl) { int list, index, pic_structure; print_short_term(h); print_long_term(h); h264_initialise_ref_list(h, sl); for (list = 0; list < sl->list_count; list++) { if (get_bits1(&sl->gb)) { // ref_pic_list_modification_flag_l[01] int pred = h->curr_pic_num; for (index = 0; ; index++) { unsigned int modification_of_pic_nums_idc = get_ue_golomb_31(&sl->gb); unsigned int pic_id; int i; H264Picture *ref = NULL; if (modification_of_pic_nums_idc == 3) break; if (index >= sl->ref_count[list]) { av_log(h->avctx, AV_LOG_ERROR, "reference count overflow\n"); return -1; } switch (modification_of_pic_nums_idc) { case 0: case 1: { const unsigned int abs_diff_pic_num = get_ue_golomb_long(&sl->gb) + 1; int frame_num; if (abs_diff_pic_num > h->max_pic_num) { av_log(h->avctx, AV_LOG_ERROR, "abs_diff_pic_num overflow\n"); return AVERROR_INVALIDDATA; } if (modification_of_pic_nums_idc == 0) pred -= abs_diff_pic_num; else pred += abs_diff_pic_num; pred &= h->max_pic_num - 1; frame_num = pic_num_extract(h, pred, &pic_structure); for (i = h->short_ref_count - 1; i >= 0; i--) { ref = h->short_ref[i]; assert(ref->reference); assert(!ref->long_ref); if (ref->frame_num == frame_num && (ref->reference & pic_structure)) break; } if (i >= 0) ref->pic_id = pred; break; } case 2: { int long_idx; pic_id = get_ue_golomb(&sl->gb); // long_term_pic_idx long_idx = pic_num_extract(h, pic_id, &pic_structure); if (long_idx > 31U) { av_log(h->avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); return AVERROR_INVALIDDATA; } ref = h->long_ref[long_idx]; assert(!(ref && !ref->reference)); if (ref && (ref->reference & pic_structure) && !mismatches_ref(h, ref)) { ref->pic_id = pic_id; assert(ref->long_ref); i = 0; } else { i = -1; } break; } default: av_log(h->avctx, AV_LOG_ERROR, "illegal modification_of_pic_nums_idc %u\n", modification_of_pic_nums_idc); return AVERROR_INVALIDDATA; } if (i < 0) { av_log(h->avctx, AV_LOG_ERROR, "reference picture missing during reorder\n"); memset(&sl->ref_list[list][index], 0, sizeof(sl->ref_list[0][0])); // FIXME } else { for (i = index; i + 1 < sl->ref_count[list]; i++) { if (sl->ref_list[list][i].parent && ref->long_ref == sl->ref_list[list][i].parent->long_ref && ref->pic_id == sl->ref_list[list][i].pic_id) break; } for (; i > index; i--) { sl->ref_list[list][i] = sl->ref_list[list][i - 1]; } ref_from_h264pic(&sl->ref_list[list][index], ref); if (FIELD_PICTURE(h)) { pic_as_field(&sl->ref_list[list][index], pic_structure); } } } } } for (list = 0; list < sl->list_count; list++) { for (index = 0; index < sl->ref_count[list]; index++) { if ( !sl->ref_list[list][index].parent || (!FIELD_PICTURE(h) && (sl->ref_list[list][index].reference&3) != 3)) { int i; av_log(h->avctx, AV_LOG_ERROR, "Missing reference picture, default is %d\n", h->default_ref[list].poc); for (i = 0; i < FF_ARRAY_ELEMS(h->last_pocs); i++) h->last_pocs[i] = INT_MIN; if (h->default_ref[list].parent && !(!FIELD_PICTURE(h) && (h->default_ref[list].reference&3) != 3)) sl->ref_list[list][index] = h->default_ref[list]; else return -1; } av_assert0(av_buffer_get_ref_count(sl->ref_list[list][index].parent->f->buf[0]) > 0); } } return 0; }
static void h264_initialise_ref_list(H264Context *h, H264SliceContext *sl) { int i, len; int j; if (sl->slice_type_nos == AV_PICTURE_TYPE_B) { H264Picture *sorted[32]; int cur_poc, list; int lens[2]; if (FIELD_PICTURE(h)) cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD]; else cur_poc = h->cur_pic_ptr->poc; for (list = 0; list < 2; list++) { len = add_sorted(sorted, h->short_ref, h->short_ref_count, cur_poc, 1 ^ list); len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list); av_assert0(len <= 32); len = build_def_list(sl->ref_list[list], FF_ARRAY_ELEMS(sl->ref_list[0]), sorted, len, 0, h->picture_structure); len += build_def_list(sl->ref_list[list] + len, FF_ARRAY_ELEMS(sl->ref_list[0]) - len, h->long_ref, 16, 1, h->picture_structure); av_assert0(len <= 32); if (len < sl->ref_count[list]) memset(&sl->ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len)); lens[list] = len; } if (lens[0] == lens[1] && lens[1] > 1) { for (i = 0; i < lens[0] && sl->ref_list[0][i].parent->f->buf[0]->buffer == sl->ref_list[1][i].parent->f->buf[0]->buffer; i++); if (i == lens[0]) { FFSWAP(H264Ref, sl->ref_list[1][0], sl->ref_list[1][1]); } } } else { len = build_def_list(sl->ref_list[0], FF_ARRAY_ELEMS(sl->ref_list[0]), h->short_ref, h->short_ref_count, 0, h->picture_structure); len += build_def_list(sl->ref_list[0] + len, FF_ARRAY_ELEMS(sl->ref_list[0]) - len, h-> long_ref, 16, 1, h->picture_structure); av_assert0(len <= 32); if (len < sl->ref_count[0]) memset(&sl->ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len)); } for (j = 0; j<1+(sl->slice_type_nos == AV_PICTURE_TYPE_B); j++) { for (i = 0; i < sl->ref_count[j]; i++) { if (sl->ref_list[j][i].parent) { if (mismatches_ref(h, sl->ref_list[j][i].parent)) { av_log(h->avctx, AV_LOG_ERROR, "Discarding mismatching reference\n"); memset(&sl->ref_list[j][i], 0, sizeof(sl->ref_list[j][i])); } } } } for (i = 0; i < sl->list_count; i++) h->default_ref[i] = sl->ref_list[i][0]; }
int ff_h264_fill_default_ref_list(H264Context *h, H264SliceContext *sl) { int i, len; int j; if (sl->slice_type_nos == AV_PICTURE_TYPE_B) { H264Picture *sorted[32]; int cur_poc, list; int lens[2]; if (FIELD_PICTURE(h)) cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD]; else cur_poc = h->cur_pic_ptr->poc; for (list = 0; list < 2; list++) { len = add_sorted(sorted, h->short_ref, h->short_ref_count, cur_poc, 1 ^ list); len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list); av_assert0(len <= 32); len = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]), sorted, len, 0, h->picture_structure); len += build_def_list(h->default_ref_list[list] + len, FF_ARRAY_ELEMS(h->default_ref_list[0]) - len, h->long_ref, 16, 1, h->picture_structure); av_assert0(len <= 32); if (len < sl->ref_count[list]) memset(&h->default_ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len)); lens[list] = len; } if (lens[0] == lens[1] && lens[1] > 1) { for (i = 0; i < lens[0] && h->default_ref_list[0][i].parent->f->buf[0]->buffer == h->default_ref_list[1][i].parent->f->buf[0]->buffer; i++); if (i == lens[0]) { FFSWAP(H264Ref, h->default_ref_list[1][0], h->default_ref_list[1][1]); } } } else { len = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]), h->short_ref, h->short_ref_count, 0, h->picture_structure); len += build_def_list(h->default_ref_list[0] + len, FF_ARRAY_ELEMS(h->default_ref_list[0]) - len, h-> long_ref, 16, 1, h->picture_structure); av_assert0(len <= 32); if (len < sl->ref_count[0]) memset(&h->default_ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len)); } #ifdef TRACE for (i = 0; i < sl->ref_count[0]; i++) { ff_tlog(h->avctx, "List0: %s fn:%d 0x%p\n", h->default_ref_list[0][i].parent ? (h->default_ref_list[0][i].parent->long_ref ? "LT" : "ST") : "NULL", h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].parent ? h->default_ref_list[0][i].parent->f->data[0] : 0); } if (sl->slice_type_nos == AV_PICTURE_TYPE_B) { for (i = 0; i < sl->ref_count[1]; i++) { ff_tlog(h->avctx, "List1: %s fn:%d 0x%p\n", h->default_ref_list[1][i].parent ? (h->default_ref_list[1][i].parent->long_ref ? "LT" : "ST") : "NULL", h->default_ref_list[1][i].pic_id, h->default_ref_list[1][i].parent ? h->default_ref_list[1][i].parent->f->data[0] : 0); } } #endif for (j = 0; j<1+(sl->slice_type_nos == AV_PICTURE_TYPE_B); j++) { for (i = 0; i < sl->ref_count[j]; i++) { if (h->default_ref_list[j][i].parent) { if (mismatches_ref(h, h->default_ref_list[j][i].parent)) { av_log(h->avctx, AV_LOG_ERROR, "Discarding mismatching reference\n"); memset(&h->default_ref_list[j][i], 0, sizeof(h->default_ref_list[j][i])); } } } } return 0; }
static int cuvid_h264_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size) { const H264Context *h = avctx->priv_data; const PPS *pps = h->ps.pps; const SPS *sps = h->ps.sps; CUVIDContext *ctx = avctx->internal->hwaccel_priv_data; CUVIDPICPARAMS *pp = &ctx->pic_params; CUVIDH264PICPARAMS *ppc = &pp->CodecSpecific.h264; FrameDecodeData *fdd; CUVIDFrame *cf; int i, dpb_size, ret; ret = ff_cuvid_start_frame(avctx, h->cur_pic_ptr->f); if (ret < 0) return ret; fdd = (FrameDecodeData*)h->cur_pic_ptr->f->opaque_ref->data; cf = (CUVIDFrame*)fdd->hwaccel_priv; *pp = (CUVIDPICPARAMS) { .PicWidthInMbs = h->mb_width, .FrameHeightInMbs = h->mb_height, .CurrPicIdx = cf->idx, .field_pic_flag = FIELD_PICTURE(h), .bottom_field_flag = h->picture_structure == PICT_BOTTOM_FIELD, .second_field = FIELD_PICTURE(h) && !h->first_field, .ref_pic_flag = h->nal_ref_idc != 0, .intra_pic_flag = 0, .CodecSpecific.h264 = { .log2_max_frame_num_minus4 = sps->log2_max_frame_num - 4, .pic_order_cnt_type = sps->poc_type, .log2_max_pic_order_cnt_lsb_minus4 = FFMAX(sps->log2_max_poc_lsb - 4, 0), .delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag, .frame_mbs_only_flag = sps->frame_mbs_only_flag, .direct_8x8_inference_flag = sps->direct_8x8_inference_flag, .num_ref_frames = sps->ref_frame_count, .residual_colour_transform_flag = sps->residual_color_transform_flag, .bit_depth_luma_minus8 = sps->bit_depth_luma - 8, .bit_depth_chroma_minus8 = sps->bit_depth_chroma - 8, .qpprime_y_zero_transform_bypass_flag = sps->transform_bypass, .entropy_coding_mode_flag = pps->cabac, .pic_order_present_flag = pps->pic_order_present, .num_ref_idx_l0_active_minus1 = pps->ref_count[0] - 1, .num_ref_idx_l1_active_minus1 = pps->ref_count[1] - 1, .weighted_pred_flag = pps->weighted_pred, .weighted_bipred_idc = pps->weighted_bipred_idc, .pic_init_qp_minus26 = pps->init_qp - 26, .deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present, .redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present, .transform_8x8_mode_flag = pps->transform_8x8_mode, .MbaffFrameFlag = sps->mb_aff && !FIELD_PICTURE(h), .constrained_intra_pred_flag = pps->constrained_intra_pred, .chroma_qp_index_offset = pps->chroma_qp_index_offset[0], .second_chroma_qp_index_offset = pps->chroma_qp_index_offset[1], .ref_pic_flag = h->nal_ref_idc != 0, .frame_num = h->poc.frame_num, .CurrFieldOrderCnt[0] = h->cur_pic_ptr->field_poc[0], .CurrFieldOrderCnt[1] = h->cur_pic_ptr->field_poc[1], }, }; memcpy(ppc->WeightScale4x4, pps->scaling_matrix4, sizeof(ppc->WeightScale4x4)); memcpy(ppc->WeightScale8x8[0], pps->scaling_matrix8[0], sizeof(ppc->WeightScale8x8[0])); memcpy(ppc->WeightScale8x8[1], pps->scaling_matrix8[3], sizeof(ppc->WeightScale8x8[0])); dpb_size = 0; for (i = 0; i < h->short_ref_count; i++) dpb_add(h, &ppc->dpb[dpb_size++], h->short_ref[i], h->short_ref[i]->frame_num); for (i = 0; i < 16; i++) { if (h->long_ref[i]) dpb_add(h, &ppc->dpb[dpb_size++], h->long_ref[i], i); } for (i = dpb_size; i < FF_ARRAY_ELEMS(ppc->dpb); i++) ppc->dpb[i].PicIdx = -1; return 0; }
int ff_h264_decode_ref_pic_marking(H264SliceContext *sl, GetBitContext *gb, const H2645NAL *nal, void *logctx) { int i; MMCO *mmco = sl->mmco; int nb_mmco = 0; if (nal->type == H264_NAL_IDR_SLICE) { // FIXME fields skip_bits1(gb); // broken_link if (get_bits1(gb)) { mmco[0].opcode = MMCO_LONG; mmco[0].long_arg = 0; nb_mmco = 1; } sl->explicit_ref_marking = 1; } else { sl->explicit_ref_marking = get_bits1(gb); if (sl->explicit_ref_marking) { for (i = 0; i < MAX_MMCO_COUNT; i++) { MMCOOpcode opcode = get_ue_golomb_31(gb); mmco[i].opcode = opcode; if (opcode == MMCO_SHORT2UNUSED || opcode == MMCO_SHORT2LONG) { mmco[i].short_pic_num = (sl->curr_pic_num - get_ue_golomb_long(gb) - 1) & (sl->max_pic_num - 1); #if 0 if (mmco[i].short_pic_num >= h->short_ref_count || !h->short_ref[mmco[i].short_pic_num]) { av_log(s->avctx, AV_LOG_ERROR, "illegal short ref in memory management control " "operation %d\n", mmco); return -1; } #endif } if (opcode == MMCO_SHORT2LONG || opcode == MMCO_LONG2UNUSED || opcode == MMCO_LONG || opcode == MMCO_SET_MAX_LONG) { unsigned int long_arg = get_ue_golomb_31(gb); if (long_arg >= 32 || (long_arg >= 16 && !(opcode == MMCO_SET_MAX_LONG && long_arg == 16) && !(opcode == MMCO_LONG2UNUSED && FIELD_PICTURE(sl)))) { av_log(logctx, AV_LOG_ERROR, "illegal long ref in memory management control " "operation %d\n", opcode); return -1; } mmco[i].long_arg = long_arg; } if (opcode > (unsigned) MMCO_LONG) { av_log(logctx, AV_LOG_ERROR, "illegal memory management control operation %d\n", opcode); return -1; } if (opcode == MMCO_END) break; } nb_mmco = i; } } sl->nb_mmco = nb_mmco; return 0; }