int decode(void) { VAAPIContext * const vaapi = vaapi_get_context(); VAPictureParameterBufferMPEG4 *pic_param; VASliceParameterBufferMPEG4 *slice_param; VAIQMatrixBufferMPEG4 *iq_matrix; int i, slice_count; MPEG4PictureInfo mpeg4_pic_info; MPEG4SliceInfo mpeg4_slice_info; MPEG4IQMatrix mpeg4_iq_matrix; const uint8_t *mpeg4_slice_data; unsigned int mpeg4_slice_data_size; if (!vaapi) return -1; mpeg4_get_picture_info(&mpeg4_pic_info); if (vaapi_init_decoder(VAProfileMPEG4AdvancedSimple, VAEntrypointVLD, mpeg4_pic_info.width, mpeg4_pic_info.height) < 0) return -1; if ((pic_param = vaapi_alloc_picture(sizeof(*pic_param))) == NULL) return -1; #define COPY(field) \ pic_param->field = mpeg4_pic_info.field #define COPY_BFM(a,b,c) \ pic_param->BFM(a,b,c) = mpeg4_pic_info.a.b.c pic_param->vop_width = mpeg4_pic_info.width; pic_param->vop_height = mpeg4_pic_info.height; pic_param->forward_reference_picture = 0xffffffff; pic_param->backward_reference_picture = 0xffffffff; pic_param->BFV(vol_fields, value) = 0; /* reset all bits */ COPY_BFM(vol_fields, bits, short_video_header); COPY_BFM(vol_fields, bits, chroma_format); COPY_BFM(vol_fields, bits, interlaced); COPY_BFM(vol_fields, bits, obmc_disable); COPY_BFM(vol_fields, bits, sprite_enable); COPY_BFM(vol_fields, bits, sprite_warping_accuracy); COPY_BFM(vol_fields, bits, quant_type); COPY_BFM(vol_fields, bits, quarter_sample); COPY_BFM(vol_fields, bits, data_partitioned); COPY_BFM(vol_fields, bits, reversible_vlc); COPY(no_of_sprite_warping_points); for (i = 0; i < 3; i++) { COPY(sprite_trajectory_du[i]); COPY(sprite_trajectory_dv[i]); } COPY(quant_precision); pic_param->BFV(vop_fields, value) = 0; /* reset all bits */ COPY_BFM(vop_fields, bits, vop_coding_type); COPY_BFM(vop_fields, bits, backward_reference_vop_coding_type); COPY_BFM(vop_fields, bits, vop_rounding_type); COPY_BFM(vop_fields, bits, intra_dc_vlc_thr); COPY_BFM(vop_fields, bits, top_field_first); COPY_BFM(vop_fields, bits, alternate_vertical_scan_flag); COPY(vop_fcode_forward); COPY(vop_fcode_backward); COPY(num_gobs_in_vop); COPY(num_macroblocks_in_gob); COPY(TRB); COPY(TRD); #if (VA_CHECK_VERSION(0,31,1) /* XXX: update when changes are merged */ || \ (VA_CHECK_VERSION(0,31,0) && VA_SDS_VERSION >= 4)) COPY(vop_time_increment_resolution); COPY_BFM(vol_fields, bits, resync_marker_disable); #endif #undef COPY_BFM #undef COPY if (mpeg4_iq_matrix.load_intra_quant_mat || mpeg4_iq_matrix.load_non_intra_quant_mat) { if ((iq_matrix = vaapi_alloc_iq_matrix(sizeof(*iq_matrix))) == NULL) return -1; mpeg4_get_iq_matrix(&mpeg4_iq_matrix); #define COPY(field) iq_matrix->field = mpeg4_iq_matrix.field COPY(load_intra_quant_mat); COPY(load_non_intra_quant_mat); for (i = 0; i < 64; i++) { COPY(intra_quant_mat[i]); COPY(non_intra_quant_mat[i]); } #undef COPY } slice_count = mpeg4_get_slice_count(); for (i = 0; i < slice_count; i++) { if (mpeg4_get_slice_info(i, &mpeg4_slice_info) < 0) return -1; if (mpeg4_get_slice_data(i, &mpeg4_slice_data, &mpeg4_slice_data_size) < 0) return -1; if (mpeg4_slice_data_size != mpeg4_slice_info.slice_data_size) return -1; if ((slice_param = vaapi_alloc_slice(sizeof(*slice_param), mpeg4_slice_data, mpeg4_slice_data_size)) == NULL) return -1; #define COPY(field) slice_param->field = mpeg4_slice_info.field COPY(macroblock_offset); COPY(macroblock_number); COPY(quant_scale); #undef COPY } return vaapi_decode(); }
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; }