bool VaapiDecoderH264::fillSlice(VaapiSliceH264 * slice, H264NalUnit * nalu) { H264SliceHdr *const sliceHdr = &slice->m_sliceHdr; VaapiBufObject *sliceParamObj = slice->m_param; VASliceParameterBufferH264 *sliceParam = (VASliceParameterBufferH264 *) sliceParamObj->map(); /* Fill in VASliceParameterBufferH264 */ sliceParam->slice_data_bit_offset = getSliceDataBitOffset(sliceHdr, nalu); sliceParam->first_mb_in_slice = sliceHdr->first_mb_in_slice; sliceParam->slice_type = sliceHdr->type % 5; sliceParam->direct_spatial_mv_pred_flag = sliceHdr->direct_spatial_mv_pred_flag; sliceParam->cabac_init_idc = sliceHdr->cabac_init_idc; sliceParam->slice_qp_delta = sliceHdr->slice_qp_delta; sliceParam->disable_deblocking_filter_idc = sliceHdr->disable_deblocking_filter_idc; sliceParam->slice_alpha_c0_offset_div2 = sliceHdr->slice_alpha_c0_offset_div2; sliceParam->slice_beta_offset_div2 = sliceHdr->slice_beta_offset_div2; sliceParamObj->unmap(); if (!fillRefPicList(slice)) return false; if (!fillPredWeightTable(slice)) return false; return true; }
bool VaapiDecoderVP8::fillSliceParam(VaapiSliceVP8 * slice) { VaapiBufObject *sliceParamObj = slice->m_param; VASliceParameterBufferVP8 *sliceParam = (VASliceParameterBufferVP8 *) sliceParamObj->map(); int32 lastPartitionSize, i; if (m_frameHdr.key_frame == VP8_KEY_FRAME) sliceParam->slice_data_offset = VP8_UNCOMPRESSED_DATA_SIZE_KEY_FRAME; else sliceParam->slice_data_offset = VP8_UNCOMPRESSED_DATA_SIZE_NON_KEY_FRAME; // XXX, the buf start address m_buffer sliceParam->macroblock_offset = (m_frameHdr.rangedecoder_state.buffer - m_buffer - sliceParam->slice_data_offset) * 8 - m_frameHdr.rangedecoder_state.remaining_bits; sliceParam->num_of_partitions = (1 << m_frameHdr.log2_nbr_of_dct_partitions) + 1; // +1 for the frame header partition // first_part_size doesn't include the uncompress data(frame-tage/magic-number/frame-width/height) at the begining of the frame. // partition_size[0] refer to 'first_part_size - parsed-bytes-by-range-decoder' sliceParam->partition_size[0] = m_frameHdr.first_part_size - ((sliceParam->macroblock_offset + 7) >> 3); #if __PLATFORM_BYT__ sliceParam->slice_data_offset = 0; sliceParam->macroblock_offset = 8 - m_frameHdr.rangedecoder_state.remaining_bits; #endif if (m_frameHdr.key_frame == VP8_KEY_FRAME) lastPartitionSize = m_frameSize - VP8_UNCOMPRESSED_DATA_SIZE_KEY_FRAME; else lastPartitionSize = m_frameSize - VP8_UNCOMPRESSED_DATA_SIZE_NON_KEY_FRAME; lastPartitionSize -= m_frameHdr.first_part_size; for (i = 1; i < sliceParam->num_of_partitions - 1; i++) { sliceParam->partition_size[i] = m_frameHdr.partition_size[i - 1]; lastPartitionSize -= (m_frameHdr.partition_size[i - 1] + 3); } sliceParam->partition_size[sliceParam->num_of_partitions - 1] = lastPartitionSize; sliceParamObj->unmap(); return true; }
bool VaapiDecoderH264::fillRefPicList(VaapiSliceH264 * slice) { uint32_t i, numRefLists = 0; VaapiDecPicBufLayer *DPBLayer = m_DPBManager->DPBLayer; H264SliceHdr *const sliceHdr = &slice->m_sliceHdr; VaapiBufObject *sliceParamObj = slice->m_param; VASliceParameterBufferH264 *sliceParam = (VASliceParameterBufferH264 *) sliceParamObj->map(); sliceParam->num_ref_idx_l0_active_minus1 = 0; sliceParam->num_ref_idx_l1_active_minus1 = 0; if (H264_IS_B_SLICE(sliceHdr)) numRefLists = 2; else if (H264_IS_I_SLICE(sliceHdr)) numRefLists = 0; else numRefLists = 1; if (numRefLists < 1) goto out; sliceParam->num_ref_idx_l0_active_minus1 = sliceHdr->num_ref_idx_l0_active_minus1; for (i = 0; i < DPBLayer->refPicList0Count && DPBLayer->refPicList0[i]; i++) vaapiFillPicture(&sliceParam->RefPicList0[i], DPBLayer->refPicList0[i], 0); for (; i <= sliceParam->num_ref_idx_l0_active_minus1; i++) vaapiInitPicture(&sliceParam->RefPicList0[i]); if (numRefLists < 2) goto out; sliceParam->num_ref_idx_l1_active_minus1 = sliceHdr->num_ref_idx_l1_active_minus1; for (i = 0; i < DPBLayer->refPicList1Count && DPBLayer->refPicList1[i]; i++) vaapiFillPicture(&sliceParam->RefPicList1[i], DPBLayer->refPicList1[i], 0); for (; i <= sliceParam->num_ref_idx_l1_active_minus1; i++) vaapiInitPicture(&sliceParam->RefPicList1[i]); out: sliceParamObj->unmap(); return true; }
bool VaapiDecoderVP8::fillPictureParam(VaapiPictureVP8 * picture) { int32 i, n; VaapiBufObject *picParamObj = picture->m_picParam; VAPictureParameterBufferVP8 *picParam = (VAPictureParameterBufferVP8 *) picParamObj->map(); /* Fill in VAPictureParameterBufferVP8 */ VASliceParameterBufferVP8 *sliceParam = NULL; Vp8Segmentation *seg = &m_frameHdr.multi_frame_data->segmentation; memset(picParam, 0, sizeof(*picParam)); /* Fill in VAPictureParameterBufferVP8 */ if (m_frameHdr.key_frame == VP8_KEY_FRAME) { if (m_frameHdr.horizontal_scale || m_frameHdr.vertical_scale) WARNING ("horizontal_scale or vertical_scale in VP8 isn't supported yet"); } picParam->frame_width = m_frameWidth; picParam->frame_height = m_frameHeight; if (m_frameHdr.key_frame == VP8_KEY_FRAME) { picParam->last_ref_frame = VA_INVALID_SURFACE; picParam->golden_ref_frame = VA_INVALID_SURFACE; picParam->alt_ref_frame = VA_INVALID_SURFACE; } else { picParam->last_ref_frame = m_lastPicture ? m_lastPicture->m_surfaceID : VA_INVALID_SURFACE; picParam->golden_ref_frame = m_goldenRefPicture ? m_goldenRefPicture->m_surfaceID : VA_INVALID_SURFACE; picParam->alt_ref_frame = m_altRefPicture ? m_altRefPicture->m_surfaceID : VA_INVALID_SURFACE; } picParam->out_of_loop_frame = VA_INVALID_SURFACE; // not used currently picParam->pic_fields.bits.key_frame = m_frameHdr.key_frame; picParam->pic_fields.bits.version = m_frameHdr.version; picParam->pic_fields.bits.segmentation_enabled = seg->segmentation_enabled; picParam->pic_fields.bits.update_mb_segmentation_map = seg->update_mb_segmentation_map; picParam->pic_fields.bits.update_segment_feature_data = seg->update_segment_feature_data; picParam->pic_fields.bits.filter_type = m_frameHdr.filter_type; picParam->pic_fields.bits.sharpness_level = m_frameHdr.sharpness_level; picParam->pic_fields.bits.loop_filter_adj_enable = m_frameHdr.multi_frame_data->mb_lf_adjust.loop_filter_adj_enable; picParam->pic_fields.bits.mode_ref_lf_delta_update = m_frameHdr.multi_frame_data->mb_lf_adjust.mode_ref_lf_delta_update; picParam->pic_fields.bits.sign_bias_golden = m_frameHdr.sign_bias_golden; picParam->pic_fields.bits.sign_bias_alternate = m_frameHdr.sign_bias_alternate; picParam->pic_fields.bits.mb_no_coeff_skip = m_frameHdr.mb_no_skip_coeff; for (i = 0; i < 3; i++) { picParam->mb_segment_tree_probs[i] = seg->segment_prob[i]; } for (i = 0; i < 4; i++) { if (seg->segmentation_enabled) { picParam->loop_filter_level[i] = seg->lf_update_value[i]; if (!seg->segment_feature_mode) picParam->loop_filter_level[i] += m_frameHdr.loop_filter_level; } else picParam->loop_filter_level[i] = m_frameHdr.loop_filter_level; picParam->loop_filter_deltas_ref_frame[i] = m_frameHdr.multi_frame_data->mb_lf_adjust.ref_frame_delta[i]; picParam->loop_filter_deltas_mode[i] = m_frameHdr.multi_frame_data->mb_lf_adjust.mb_mode_delta[i]; } if ((picParam->pic_fields.bits.version == 0) || (picParam->pic_fields.bits.version == 1)) { picParam->pic_fields.bits.loop_filter_disable = picParam->loop_filter_level[0] == 0; } picParam->prob_skip_false = m_frameHdr.prob_skip_false; picParam->prob_intra = m_frameHdr.prob_intra; picParam->prob_last = m_frameHdr.prob_last; picParam->prob_gf = m_frameHdr.prob_gf; if (m_frameHdr.key_frame == VP8_KEY_FRAME) { // key frame use fixed prob table memcpy(picParam->y_mode_probs, keyFrameYModeProbs, 4); memcpy(picParam->uv_mode_probs, keyFrameUVModeProbs, 3); // prepare for next frame which may be not a key frame memcpy(m_yModeProbs, nonKeyFrameDefaultYModeProbs, 4); memcpy(m_uvModeProbs, nonKeyFrameDefaultUVModeProbs, 3); } else { if (m_frameHdr.intra_16x16_prob_update_flag) { memcpy(picParam->y_mode_probs, m_frameHdr.intra_16x16_prob, 4); } else { memcpy(picParam->y_mode_probs, m_yModeProbs, 4); } if (m_frameHdr.intra_chroma_prob_update_flag) { memcpy(picParam->uv_mode_probs, m_frameHdr.intra_chroma_prob, 3); } else { memcpy(picParam->uv_mode_probs, m_uvModeProbs, 3); } } memcpy(picParam->mv_probs, m_frameHdr.multi_frame_data->mv_prob_update.prob, sizeof picParam->mv_probs); picParam->bool_coder_ctx.range = m_frameHdr.rangedecoder_state.range; picParam->bool_coder_ctx.value = m_frameHdr.rangedecoder_state.code_word; picParam->bool_coder_ctx.count = m_frameHdr.rangedecoder_state.remaining_bits; picParamObj->unmap(); return true; }
bool VaapiDecoderH264::fillPredWeightTable(VaapiSliceH264 * slice) { int32_t i, j; uint32_t numWeightTables = 0; H264SliceHdr *const sliceHdr = &slice->m_sliceHdr; H264PPS *const pps = sliceHdr->pps; H264SPS *const sps = pps->sequence; H264PredWeightTable *const w = &sliceHdr->pred_weight_table; VaapiBufObject *sliceParamObj = slice->m_param; VASliceParameterBufferH264 *sliceParam = (VASliceParameterBufferH264 *) sliceParamObj->map(); if (pps->weighted_pred_flag && (H264_IS_P_SLICE(sliceHdr) || H264_IS_SP_SLICE(sliceHdr))) numWeightTables = 1; else if (pps->weighted_bipred_idc == 1 && H264_IS_B_SLICE(sliceHdr)) numWeightTables = 2; else numWeightTables = 0; sliceParam->luma_log2_weight_denom = w->luma_log2_weight_denom; sliceParam->chroma_log2_weight_denom = w->chroma_log2_weight_denom; sliceParam->luma_weight_l0_flag = 0; sliceParam->chroma_weight_l0_flag = 0; sliceParam->luma_weight_l1_flag = 0; sliceParam->chroma_weight_l1_flag = 0; if (numWeightTables < 1) goto out; sliceParam->luma_weight_l0_flag = 1; for (i = 0; i <= sliceParam->num_ref_idx_l0_active_minus1; i++) { sliceParam->luma_weight_l0[i] = w->luma_weight_l0[i]; sliceParam->luma_offset_l0[i] = w->luma_offset_l0[i]; } sliceParam->chroma_weight_l0_flag = sps->chroma_array_type != 0; if (sliceParam->chroma_weight_l0_flag) { for (i = 0; i <= sliceParam->num_ref_idx_l0_active_minus1; i++) { for (j = 0; j < 2; j++) { sliceParam->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j]; sliceParam->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j]; } } } if (numWeightTables < 2) goto out; sliceParam->luma_weight_l1_flag = 1; for (i = 0; i <= sliceParam->num_ref_idx_l1_active_minus1; i++) { sliceParam->luma_weight_l1[i] = w->luma_weight_l1[i]; sliceParam->luma_offset_l1[i] = w->luma_offset_l1[i]; } sliceParam->chroma_weight_l1_flag = sps->chroma_array_type != 0; if (sliceParam->chroma_weight_l1_flag) { for (i = 0; i <= sliceParam->num_ref_idx_l1_active_minus1; i++) { for (j = 0; j < 2; j++) { sliceParam->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j]; sliceParam->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j]; } } } out: sliceParamObj->unmap(); return true; }
bool VaapiDecoderH264::fillPicture(VaapiPictureH264 * picture, H264SliceHdr * sliceHdr, H264NalUnit * nalu) { uint32_t i, n; H264PPS *const pps = picture->m_pps; H264SPS *const sps = pps->sequence; VaapiDecPicBufLayer *DPBLayer = m_DPBManager->DPBLayer; VaapiBufObject *picParamObj = picture->m_picParam; VAPictureParameterBufferH264 *picParam = (VAPictureParameterBufferH264 *) picParamObj->map(); /* Fill in VAPictureParameterBufferH264 */ vaapiFillPicture(&picParam->CurrPic, picture, 0); for (i = 0, n = 0; i < DPBLayer->DPBCount; i++) { VaapiFrameStore *const frameStore = DPBLayer->DPB[i]; if (frameStore && frameStore->hasReference()) vaapiFillPicture(&picParam->ReferenceFrames[n++], frameStore->m_buffers[0], frameStore->m_structure); } for (; n < N_ELEMENTS(picParam->ReferenceFrames); n++) vaapiInitPicture(&picParam->ReferenceFrames[n]); #define COPY_FIELD(s, f) \ picParam->f = (s)->f #define COPY_BFM(a, s, f) \ picParam->a.bits.f = (s)->f picParam->picture_width_in_mbs_minus1 = m_mbWidth - 1; picParam->picture_height_in_mbs_minus1 = m_mbHeight - 1; picParam->frame_num = m_frameNum; COPY_FIELD(sps, bit_depth_luma_minus8); COPY_FIELD(sps, bit_depth_chroma_minus8); COPY_FIELD(sps, num_ref_frames); COPY_FIELD(pps, num_slice_groups_minus1); COPY_FIELD(pps, slice_group_map_type); COPY_FIELD(pps, slice_group_change_rate_minus1); COPY_FIELD(pps, pic_init_qp_minus26); COPY_FIELD(pps, pic_init_qs_minus26); COPY_FIELD(pps, chroma_qp_index_offset); COPY_FIELD(pps, second_chroma_qp_index_offset); picParam->seq_fields.value = 0; /* reset all bits */ picParam->seq_fields.bits.residual_colour_transform_flag = sps->separate_colour_plane_flag; picParam->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */ COPY_BFM(seq_fields, sps, chroma_format_idc); COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag); COPY_BFM(seq_fields, sps, frame_mbs_only_flag); COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag); COPY_BFM(seq_fields, sps, direct_8x8_inference_flag); COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4); COPY_BFM(seq_fields, sps, pic_order_cnt_type); COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4); COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag); picParam->pic_fields.value = 0; /* reset all bits */ picParam->pic_fields.bits.field_pic_flag = sliceHdr->field_pic_flag; picParam->pic_fields.bits.reference_pic_flag = VAAPI_PICTURE_IS_REFERENCE(picture); COPY_BFM(pic_fields, pps, entropy_coding_mode_flag); COPY_BFM(pic_fields, pps, weighted_pred_flag); COPY_BFM(pic_fields, pps, weighted_bipred_idc); COPY_BFM(pic_fields, pps, transform_8x8_mode_flag); COPY_BFM(pic_fields, pps, constrained_intra_pred_flag); COPY_BFM(pic_fields, pps, pic_order_present_flag); COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag); COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag); picParamObj->unmap(); return true; }