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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 4
0
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;
}