Example #1
0
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;
}