blob: af40805b5da2f46341783405bd66eaa9544b24a3 [file] [log] [blame]
/*
* Copyright (c) 2015-2017, Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
//!
//! \file media_ddi_decode_vc1.cpp
//! \brief libva(and its extension) decoder implementation
//!
#include "media_libva_decoder.h"
#include "media_libva_util.h"
#include "media_ddi_decode_vc1.h"
#include "mos_solo_generic.h"
#include "codechal_memdecomp.h"
#include "media_ddi_decode_const.h"
#include "media_ddi_factory.h"
static const int32_t FractionToScaleFactor[21] = {
128, 85, 170, 64, 192,
51, 102, 153, 204, 43,
215, 37, 74, 111, 148,
185, 222, 32, 96, 160,
224,
};
void DdiDecodeVC1::CalculateQuantParams(
VAPictureParameterBufferVC1 *picParam,
uint32_t *outAltPquantConfig,
uint32_t *outAltPquantEdgeMask)
{
uint32_t dquant = picParam->pic_quantizer_fields.bits.dquant;
uint32_t dqFrame = picParam->pic_quantizer_fields.bits.dq_frame;
uint32_t dqProfile = picParam->pic_quantizer_fields.bits.dq_profile;
uint32_t dqDbedge = picParam->pic_quantizer_fields.bits.dq_db_edge;
uint32_t dqSbedge = picParam->pic_quantizer_fields.bits.dq_sb_edge;
uint32_t dqBilevel = picParam->pic_quantizer_fields.bits.dq_binary_level;
uint32_t altPquantConfig = 0;
uint32_t altPquantEdgeMask = 0;
if (dquant == 0)
{
altPquantConfig = 0;
altPquantEdgeMask = 0;
}
else if (dquant == 1)
{
if (dqFrame == 0)
{
altPquantConfig = 0;
altPquantEdgeMask = 0;
}
else if (dqFrame == 1)
{
altPquantConfig = 1;
altPquantEdgeMask = 0;
switch (dqProfile)
{
case 0: //all edge with altpquant
altPquantEdgeMask = 0xf;
break;
case 1: //double edge with altpquant
if (dqDbedge == 3)
{
altPquantEdgeMask = 0x9;
}
else
{
altPquantEdgeMask = (0x3 << dqDbedge);
}
break;
case 2: //single edge with altpquant
altPquantEdgeMask = (0x1 << dqSbedge);
break;
case 3: //all mbs
if (dqBilevel == 0)
{
altPquantConfig = 2;
altPquantEdgeMask = 0;
}
else
{
altPquantConfig = 3;
altPquantEdgeMask = 0;
}
break;
default:
break;
}
}
}
else
{
altPquantConfig = 1;
altPquantEdgeMask = 0xf;
}
*outAltPquantConfig = altPquantConfig;
*outAltPquantEdgeMask = altPquantEdgeMask;
}
static inline bool IsBIField(
bool isFirstField,
int16_t picType)
{
bool isBI = false;
if (picType == vc1BBIField)
{
isBI = (!isFirstField);
}
else if (picType == vc1BIBField)
{
isBI = isFirstField;
}
else if (picType == vc1BIBIField)
{
isBI = true;
}
return isBI;
}
static inline bool IsBField(
bool isFirstField,
int16_t picType)
{
bool isBottom = false;
if (picType == vc1BBIField)
{
isBottom = isFirstField;
}
else if (picType == vc1BIBField)
{
isBottom = (!isFirstField);
}
else if (picType == vc1BBField)
{
isBottom = true;
}
return isBottom;
}
static inline bool IsIField(
bool isFirstField,
int16_t picType)
{
bool isIF = false;
if (picType == vc1IPField)
{
isIF = isFirstField;
}
else if (picType == vc1PIField)
{
isIF = !isFirstField;
}
else if (picType == vc1IIField)
{
isIF = true;
}
return isIF;
}
VAStatus DdiDecodeVC1::ParsePicParams(
DDI_MEDIA_CONTEXT *mediaCtx,
VAPictureParameterBufferVC1 *picParam)
{
PCODEC_VC1_PIC_PARAMS codecPicParam = (PCODEC_VC1_PIC_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_picParams);
if ((codecPicParam == nullptr) ||
(picParam == nullptr))
{
DDI_ASSERTMESSAGE("nullptr pointer in Parsing VC1 Picture parameter\n");
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
uint32_t scaleFactor = 0;
// See spec, table 40 && Figure 70
if ((picParam->b_picture_fraction >= 0) && (picParam->b_picture_fraction < 21))
{
scaleFactor = FractionToScaleFactor[picParam->b_picture_fraction];
}
else
{
// Use one value for it if the picParam->b_picture_fraction is out of range.
// Since in some cases, although driver gets the invalid bFraction, HW still can handle this.
scaleFactor = FractionToScaleFactor[0];
}
uint32_t fwdRefDist = picParam->reference_fields.bits.reference_distance;
int32_t bwdRefDist = 0;
if (picParam->inloop_decoded_picture != DDI_CODEC_INVALID_FRAME_INDEX)
{
codecPicParam->DeblockedPicIdx = GetRenderTargetID(&(m_ddiDecodeCtx->RTtbl), m_ddiDecodeCtx->RTtbl.pCurrentRT);
DDI_CHK_RET(RegisterRTSurfaces(&m_ddiDecodeCtx->RTtbl, DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->inloop_decoded_picture)), "RegisterRTSurfaces failed!");
codecPicParam->CurrPic.FrameIdx = (uint16_t)GetRenderTargetID(&(m_ddiDecodeCtx->RTtbl),
DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->inloop_decoded_picture));
m_deblockPicIdx = codecPicParam->DeblockedPicIdx;
m_currPicIdx = codecPicParam->CurrPic.FrameIdx;
}
else
{
codecPicParam->CurrPic.FrameIdx = GetRenderTargetID(&(m_ddiDecodeCtx->RTtbl), m_ddiDecodeCtx->RTtbl.pCurrentRT);
codecPicParam->DeblockedPicIdx = codecPicParam->CurrPic.FrameIdx;
m_deblockPicIdx = DDI_CODEC_INVALID_FRAME_INDEX;
m_currPicIdx = codecPicParam->CurrPic.FrameIdx;
}
if (picParam->forward_reference_picture == DDI_CODEC_INVALID_FRAME_INDEX)
{
codecPicParam->ForwardRefIdx = codecPicParam->CurrPic.FrameIdx;
}
else
{
if (UpdateRegisteredRTSurfaceFlag(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->forward_reference_picture)) != VA_STATUS_SUCCESS)
{
DDI_CHK_RET(RegisterRTSurfaces(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->forward_reference_picture)), "RegisterRTSurfaces failed!");
}
codecPicParam->ForwardRefIdx = (uint16_t)GetRenderTargetID(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->forward_reference_picture));
}
if (picParam->backward_reference_picture == DDI_CODEC_INVALID_FRAME_INDEX)
{
codecPicParam->BackwardRefIdx = codecPicParam->CurrPic.FrameIdx;
}
else
{
if (UpdateRegisteredRTSurfaceFlag(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->backward_reference_picture)) != VA_STATUS_SUCCESS)
{
DDI_CHK_RET(RegisterRTSurfaces(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->backward_reference_picture)), "RegisterRTSurfaces failed!");
}
codecPicParam->BackwardRefIdx = (uint16_t)GetRenderTargetID(&(m_ddiDecodeCtx->RTtbl), DdiMedia_GetSurfaceFromVASurfaceID(mediaCtx, picParam->backward_reference_picture));
}
//add protection checking to prevent ref pic index larger than DPB size
if (codecPicParam->ForwardRefIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1)
{
codecPicParam->ForwardRefIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1 - 1;
}
if (codecPicParam->BackwardRefIdx >= CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1)
{
codecPicParam->BackwardRefIdx = CODECHAL_NUM_UNCOMPRESSED_SURFACE_VC1 - 1;
}
if (picParam->picture_fields.bits.frame_coding_mode == 0)
{
codecPicParam->CurrPic.PicFlags = PICTURE_FRAME;
}
else if (picParam->picture_fields.bits.frame_coding_mode == 1)
{
codecPicParam->CurrPic.PicFlags = PICTURE_INTERLACED_FRAME;
}
else
{
codecPicParam->CurrPic.PicFlags = (picParam->picture_fields.bits.is_first_field ^ picParam->picture_fields.bits.top_field_first) ? PICTURE_BOTTOM_FIELD : PICTURE_TOP_FIELD;
}
if (picParam->picture_fields.bits.frame_coding_mode < 2) //frame structure
{
codecPicParam->picture_fields.frame_coding_mode = picParam->picture_fields.bits.frame_coding_mode;
codecPicParam->luma_scale = (uint16_t)picParam->luma_scale;
codecPicParam->luma_shift = (uint16_t)picParam->luma_shift;
}
else
{
if (picParam->picture_fields.bits.top_field_first)
{
codecPicParam->picture_fields.frame_coding_mode = 2;
}
else
{
codecPicParam->picture_fields.frame_coding_mode = 3;
}
if (picParam->picture_fields.bits.picture_type >= vc1BBField) // B interlaced frames
{
fwdRefDist = (scaleFactor * picParam->reference_fields.bits.reference_distance) >> 8;
bwdRefDist = picParam->reference_fields.bits.reference_distance - fwdRefDist - 1;
if (bwdRefDist < 0)
{
bwdRefDist = 0;
}
}
codecPicParam->luma_scale = (uint16_t)(picParam->luma_scale2 + (picParam->luma_scale << 8));
codecPicParam->luma_shift = (uint16_t)(picParam->luma_shift2 + (picParam->luma_shift << 8));
}
codecPicParam->sequence_fields.AdvancedProfileFlag = (picParam->sequence_fields.bits.profile == 3) ? 1 : 0;
codecPicParam->picture_fields.picture_type = picParam->picture_fields.bits.picture_type;
if (codecPicParam->sequence_fields.AdvancedProfileFlag)
{
codecPicParam->sequence_fields.overlap = picParam->sequence_fields.bits.overlap;
}
else
{
// see 7.1.1.14 in VC spec
if ((picParam->b_picture_fraction == 0x7F) && (picParam->picture_fields.bits.picture_type == vc1IFrame))
{
codecPicParam->picture_fields.picture_type = vc1BIFrame;
}
codecPicParam->sequence_fields.overlap = picParam->sequence_fields.bits.overlap && (picParam->pic_quantizer_fields.bits.pic_quantizer_scale >= 9);
}
codecPicParam->coded_width = picParam->coded_width;
codecPicParam->coded_height = picParam->coded_height;
codecPicParam->sequence_fields.syncmarker = picParam->sequence_fields.bits.syncmarker;
codecPicParam->sequence_fields.pulldown = picParam->sequence_fields.bits.pulldown;
codecPicParam->sequence_fields.interlace = picParam->sequence_fields.bits.interlace;
codecPicParam->sequence_fields.tfcntrflag = picParam->sequence_fields.bits.tfcntrflag;
codecPicParam->sequence_fields.psf = picParam->sequence_fields.bits.psf;
codecPicParam->sequence_fields.multires = picParam->sequence_fields.bits.multires;
codecPicParam->sequence_fields.rangered = picParam->sequence_fields.bits.rangered;
codecPicParam->sequence_fields.max_b_frames = picParam->sequence_fields.bits.max_b_frames;
codecPicParam->entrypoint_fields.loopfilter = picParam->entrypoint_fields.bits.loopfilter;
codecPicParam->entrypoint_fields.broken_link = picParam->entrypoint_fields.bits.broken_link;
codecPicParam->entrypoint_fields.closed_entry = picParam->entrypoint_fields.bits.closed_entry;
codecPicParam->entrypoint_fields.panscan_flag = picParam->entrypoint_fields.bits.panscan_flag;
codecPicParam->picture_fields.is_first_field = picParam->picture_fields.bits.is_first_field;
codecPicParam->picture_fields.top_field_first = picParam->picture_fields.bits.top_field_first;
codecPicParam->picture_fields.intensity_compensation = picParam->picture_fields.bits.intensity_compensation;
if (picParam->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation)
{
codecPicParam->mv_fields.UnifiedMvMode = (picParam->mv_fields.bits.mv_mode2 + 1) & 0x3;
;
}
else
{
codecPicParam->mv_fields.UnifiedMvMode = (picParam->mv_fields.bits.mv_mode + 1) & 0x3;
}
if (picParam->mv_fields.bits.mv_mode == VAMvMode1MvHalfPelBilinear ||
(picParam->mv_fields.bits.mv_mode == VAMvModeIntensityCompensation && picParam->mv_fields.bits.mv_mode2 == VAMvMode1MvHalfPelBilinear))
{
codecPicParam->mv_fields.MvMode = picParam->fast_uvmc_flag ? 9 : 8;
}
else
{
codecPicParam->mv_fields.MvMode = picParam->fast_uvmc_flag ? 1 : 0;
}
uint32_t altPquantConfig = 0;
uint32_t altPquantEdgeMask = 0;
CalculateQuantParams(picParam, &altPquantConfig, &altPquantEdgeMask);
codecPicParam->pic_quantizer_fields.quantizer = picParam->pic_quantizer_fields.bits.quantizer;
codecPicParam->pic_quantizer_fields.pic_quantizer_scale = picParam->pic_quantizer_fields.bits.pic_quantizer_scale;
codecPicParam->pic_quantizer_fields.alt_pic_quantizer = picParam->pic_quantizer_fields.bits.alt_pic_quantizer;
codecPicParam->pic_quantizer_fields.pic_quantizer_type = picParam->pic_quantizer_fields.bits.pic_quantizer_type;
codecPicParam->pic_quantizer_fields.half_qp = picParam->pic_quantizer_fields.bits.half_qp;
codecPicParam->pic_quantizer_fields.AltPQuantConfig = altPquantConfig;
codecPicParam->pic_quantizer_fields.AltPQuantEdgeMask = altPquantEdgeMask;
codecPicParam->pic_quantizer_fields.dquant = picParam->pic_quantizer_fields.bits.dquant;
codecPicParam->mv_fields.extended_mv_flag = picParam->mv_fields.bits.extended_mv_flag;
codecPicParam->mv_fields.extended_dmv_flag = picParam->mv_fields.bits.extended_dmv_flag;
codecPicParam->mv_fields.extended_mv_range = picParam->mv_fields.bits.extended_mv_range;
codecPicParam->mv_fields.extended_dmv_range = picParam->mv_fields.bits.extended_dmv_range;
codecPicParam->mv_fields.four_mv_switch = picParam->mv_fields.bits.four_mv_switch;
codecPicParam->mv_fields.two_mv_block_pattern_table = picParam->mv_fields.bits.two_mv_block_pattern_table;
codecPicParam->mv_fields.four_mv_block_pattern_table = picParam->mv_fields.bits.four_mv_block_pattern_table;
codecPicParam->mv_fields.mv_table = picParam->mv_fields.bits.mv_table;
codecPicParam->reference_fields.reference_distance_flag = picParam->reference_fields.bits.reference_distance_flag;
codecPicParam->reference_fields.reference_distance = fwdRefDist; //picParam->reference_fields.bits.reference_distance;
codecPicParam->reference_fields.BwdReferenceDistance = bwdRefDist; //picParam->reference_fields.bits.reference_distance;
codecPicParam->reference_fields.num_reference_pictures = picParam->reference_fields.bits.num_reference_pictures;
codecPicParam->reference_fields.reference_field_pic_indicator = picParam->reference_fields.bits.reference_field_pic_indicator;
codecPicParam->raw_coding.value = 0xFE;
if (picParam->picture_fields.bits.frame_coding_mode < 2) //frame structure
{
if ((picParam->picture_fields.bits.picture_type == vc1IFrame) ||
(picParam->picture_fields.bits.picture_type == vc1BIFrame))
{
if (picParam->picture_fields.bits.frame_coding_mode == 1) //interlaced frame
{
codecPicParam->raw_coding.field_tx = !picParam->bitplane_present.flags.bp_field_tx;
}
codecPicParam->raw_coding.ac_pred = !picParam->bitplane_present.flags.bp_ac_pred;
codecPicParam->raw_coding.overflags = !picParam->bitplane_present.flags.bp_overflags;
}
else if (picParam->picture_fields.bits.picture_type == vc1PFrame)
{
codecPicParam->raw_coding.skip_mb = !picParam->bitplane_present.flags.bp_skip_mb;
if (picParam->picture_fields.bits.frame_coding_mode == 0) //progressive frame
{
codecPicParam->raw_coding.mv_type_mb = !picParam->bitplane_present.flags.bp_mv_type_mb;
}
}
else
{
codecPicParam->raw_coding.direct_mb = !picParam->bitplane_present.flags.bp_direct_mb;
codecPicParam->raw_coding.skip_mb = !picParam->bitplane_present.flags.bp_skip_mb;
}
}
else
{
if ((IsIField(picParam->picture_fields.bits.is_first_field, picParam->picture_fields.bits.picture_type)) ||
(IsBIField(picParam->picture_fields.bits.is_first_field, picParam->picture_fields.bits.picture_type)))
{
codecPicParam->raw_coding.ac_pred = !picParam->bitplane_present.flags.bp_ac_pred;
codecPicParam->raw_coding.overflags = !picParam->bitplane_present.flags.bp_overflags;
}
else if (IsBField(picParam->picture_fields.bits.is_first_field, picParam->picture_fields.bits.picture_type))
{
codecPicParam->raw_coding.forward_mb = !picParam->bitplane_present.flags.bp_forward_mb;
}
}
uint32_t rawCoding = codecPicParam->raw_coding.value & 0xFE;
codecPicParam->raw_coding.bitplane_present = (rawCoding == 0xFE) ? 0 : 1;
codecPicParam->transform_fields.intra_transform_dc_table = picParam->transform_fields.bits.intra_transform_dc_table;
codecPicParam->transform_fields.transform_ac_codingset_idx1 = picParam->transform_fields.bits.transform_ac_codingset_idx1;
codecPicParam->transform_fields.transform_ac_codingset_idx2 = picParam->transform_fields.bits.transform_ac_codingset_idx2;
codecPicParam->transform_fields.variable_sized_transform_flag = picParam->transform_fields.bits.variable_sized_transform_flag;
codecPicParam->transform_fields.mb_level_transform_type_flag = picParam->transform_fields.bits.mb_level_transform_type_flag;
codecPicParam->transform_fields.frame_level_transform_type = picParam->transform_fields.bits.frame_level_transform_type;
codecPicParam->conditional_overlap_flag = picParam->conditional_overlap_flag ? (picParam->conditional_overlap_flag + 1) : 0;
codecPicParam->fast_uvmc_flag = picParam->fast_uvmc_flag;
codecPicParam->cbp_table = picParam->cbp_table;
codecPicParam->mb_mode_table = picParam->mb_mode_table;
codecPicParam->b_picture_fraction = picParam->b_picture_fraction; //not used
codecPicParam->range_reduction_frame = picParam->range_reduction_frame;
codecPicParam->ScaleFactor = scaleFactor;
codecPicParam->post_processing = picParam->post_processing;
codecPicParam->picture_resolution_index = 0;
codecPicParam->rounding_control = picParam->rounding_control;
codecPicParam->UpsamplingFlag = picParam->sequence_fields.bits.multires ? (picParam->picture_resolution_index & 0x3) : 0;
//rangemap
if (codecPicParam->sequence_fields.AdvancedProfileFlag)
{
codecPicParam->range_mapping_fields.luma_flag = picParam->range_mapping_fields.bits.luma_flag;
codecPicParam->range_mapping_fields.luma = picParam->range_mapping_fields.bits.luma;
codecPicParam->range_mapping_fields.chroma_flag = picParam->range_mapping_fields.bits.chroma_flag;
codecPicParam->range_mapping_fields.chroma = picParam->range_mapping_fields.bits.chroma;
codecPicParam->range_mapping_fields.range_mapping_enabled = picParam->range_mapping_fields.value;
}
else
{
codecPicParam->range_mapping_fields.range_mapping_enabled = picParam->range_reduction_frame;
}
// Check if OLP is needed
// OLP output surface must be present
if ((m_deblockPicIdx != DDI_CODEC_INVALID_FRAME_INDEX) &&
((codecPicParam->DeblockedPicIdx != codecPicParam->CurrPic.FrameIdx) ||
codecPicParam->UpsamplingFlag ||
codecPicParam->range_mapping_fields.range_mapping_enabled))
{
m_olpNeeded = 1;
}
else
{
m_olpNeeded = 0;
}
return VA_STATUS_SUCCESS;
}
VAStatus DdiDecodeVC1::ParseSliceParams(
DDI_MEDIA_CONTEXT *mediaCtx,
VASliceParameterBufferVC1 *slcParam,
uint32_t numSlices)
{
PCODEC_VC1_SLICE_PARAMS codecSlcParam = (PCODEC_VC1_SLICE_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
codecSlcParam += m_ddiDecodeCtx->DecodeParams.m_numSlices;
if ((slcParam == nullptr) || (codecSlcParam == nullptr))
{
DDI_ASSERTMESSAGE("Null pointer for Parsing VC1 Slice parameter\n");
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
uint32_t sliceBaseOffset = GetBsBufOffset(m_groupIndex);
for (uint32_t slcCount = 0; slcCount < numSlices; slcCount++)
{
codecSlcParam[slcCount].slice_data_size = slcParam[slcCount].slice_data_size << 3;
codecSlcParam[slcCount].slice_data_offset = slcParam[slcCount].slice_data_offset +
sliceBaseOffset;
if (slcParam[slcCount].slice_data_flag)
{
DDI_NORMALMESSAGE("The whole slice is not in the bitstream buffer for this Execute call");
}
codecSlcParam[slcCount].macroblock_offset = slcParam[slcCount].macroblock_offset;
codecSlcParam[slcCount].slice_vertical_position = slcParam[slcCount].slice_vertical_position;
}
return VA_STATUS_SUCCESS;
}
VAStatus DdiDecodeVC1::AllocBitPlaneBuffer()
{
DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
DDI_CHK_NULL(bufMgr, "Null bufMgr in AllocBpBuffer", VA_STATUS_ERROR_INVALID_PARAMETER);
if (bufMgr->Codec_Param.Codec_Param_VC1.VC1BitPlane[bufMgr->Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex].bUsed)
{
// wait until decode complete
mos_bo_wait_rendering(bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[bufMgr->Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex]->bo);
}
bufMgr->Codec_Param.Codec_Param_VC1.VC1BitPlane[bufMgr->Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex].bUsed = true;
return VA_STATUS_SUCCESS;
}
VAStatus DdiDecodeVC1::AllocSliceParamContext(
uint32_t numSlices)
{
uint32_t baseSize = sizeof(CODEC_VC1_SLICE_PARAMS);
if (m_sliceParamBufNum < (m_ddiDecodeCtx->DecodeParams.m_numSlices + numSlices))
{
// in order to avoid that the buffer is reallocated multi-times,
// extra 10 slices are added.
uint32_t extraSlices = numSlices + 10;
m_ddiDecodeCtx->DecodeParams.m_sliceParams = realloc(m_ddiDecodeCtx->DecodeParams.m_sliceParams,
baseSize * (m_sliceParamBufNum + extraSlices));
if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
{
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
memset((void *)((uint8_t *)m_ddiDecodeCtx->DecodeParams.m_sliceParams + baseSize * m_sliceParamBufNum), 0, baseSize * extraSlices);
m_sliceParamBufNum += extraSlices;
}
return VA_STATUS_SUCCESS;
}
void DdiDecodeVC1::DestroyContext(
VADriverContextP ctx)
{
FreeResourceBuffer();
// explicitly call the base function to do the further clean-up
DdiMediaDecode::DestroyContext(ctx);
}
uint8_t* DdiDecodeVC1::GetPicParamBuf(
DDI_CODEC_COM_BUFFER_MGR *bufMgr)
{
return (uint8_t*)(&(bufMgr->Codec_Param.Codec_Param_VC1.PicParamVC1));
}
VAStatus DdiDecodeVC1::AllocSliceControlBuffer(
DDI_MEDIA_BUFFER *buf)
{
DDI_CODEC_COM_BUFFER_MGR *bufMgr;
uint32_t availSize;
uint32_t newSize;
bufMgr = &(m_ddiDecodeCtx->BufMgr);
availSize = m_sliceCtrlBufNum - bufMgr->dwNumSliceControl;
if(availSize < buf->uiNumElements)
{
newSize = sizeof(VASliceParameterBufferVC1) * (m_sliceCtrlBufNum - availSize + buf->uiNumElements);
bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 = (VASliceParameterBufferVC1 *)realloc(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1, newSize);
if(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 == nullptr)
{
return VA_STATUS_ERROR_ALLOCATION_FAILED;
}
MOS_ZeroMemory(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 + m_sliceCtrlBufNum, sizeof(VASliceParameterBufferVC1) * (buf->uiNumElements - availSize));
m_sliceCtrlBufNum = m_sliceCtrlBufNum - availSize + buf->uiNumElements;
}
buf->pData = (uint8_t*)bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1;
buf->uiOffset = sizeof(VASliceParameterBufferVC1) * bufMgr->dwNumSliceControl;
bufMgr->dwNumSliceControl += buf->uiNumElements;
return VA_STATUS_SUCCESS;
}
void DdiDecodeVC1::ContextInit(
int32_t picWidth,
int32_t picHeight)
{
// call the function in base class to initialize it.
DdiMediaDecode::ContextInit(picWidth, picHeight);
m_ddiDecodeCtx->wMode = CODECHAL_DECODE_MODE_VC1VLD;
m_olpNeeded = false;
m_currPicIdx = DDI_CODEC_INVALID_FRAME_INDEX;
m_deblockPicIdx = DDI_CODEC_INVALID_FRAME_INDEX;
if (m_ddiDecodeAttr->profile == VAProfileVC1Advanced)
{
int32_t alignedHeight = MOS_ALIGN_CEIL(picHeight, 32);
m_height = alignedHeight;
m_picHeightInMB = (int16_t)(DDI_CODEC_NUM_MACROBLOCKS_HEIGHT(alignedHeight));
}
}
VAStatus DdiDecodeVC1::BeginPicture(
VADriverContextP ctx,
VAContextID context,
VASurfaceID renderTarget)
{
VAStatus vaStatus = DdiMediaDecode::BeginPicture(ctx, context, renderTarget);
if (vaStatus != VA_STATUS_SUCCESS)
{
return vaStatus;
}
m_ddiDecodeCtx->DecodeParams.m_vc1BitplaneSize = 0;
return VA_STATUS_SUCCESS;
}
void DdiDecodeVC1::ParseBitPlane(
struct _DDI_MEDIA_BUFFER *bitPlaneBuffObject,
uint8_t *buf)
{
if (bitPlaneBuffObject->pData)
{
PCODEC_VC1_PIC_PARAMS picParam = (PCODEC_VC1_PIC_PARAMS)(m_ddiDecodeCtx->DecodeParams.m_picParams);
uint8_t *destBp = (uint8_t *)bitPlaneBuffObject->pData;
uint8_t *srcBp = (uint8_t *)buf;
uint32_t heightInMbs = MOS_ALIGN_CEIL(picParam->coded_height, CODECHAL_MACROBLOCK_HEIGHT) / CODECHAL_MACROBLOCK_HEIGHT;
uint32_t widthInMbs = MOS_ALIGN_CEIL(picParam->coded_width, CODECHAL_MACROBLOCK_WIDTH) / CODECHAL_MACROBLOCK_WIDTH;
uint32_t bitPlanePitch = MOS_ALIGN_CEIL(widthInMbs, 2) / 2;
uint32_t srcIdx, dstIdx;
uint32_t srcShift;
uint32_t i, j;
uint8_t srcValue = 0;
for (i = 0; i < heightInMbs; i++)
{
for (j = 0; j < widthInMbs; j++)
{
srcIdx = (i * widthInMbs + j) / 2;
dstIdx = j / 2;
srcShift = ((i * widthInMbs + j) & 1) ? 0 : 4;
srcValue = (srcBp[srcIdx] >> srcShift) & 0xf;
if (j % 2)
destBp[dstIdx] = destBp[dstIdx] + (srcValue << 4);
else
destBp[dstIdx] = srcValue;
}
destBp += bitPlanePitch;
}
}
}
VAStatus DdiDecodeVC1::RenderPicture(
VADriverContextP ctx,
VAContextID context,
VABufferID *buffers,
int32_t numBuffers)
{
DDI_FUNCTION_ENTER();
VAStatus va = VA_STATUS_SUCCESS;
PDDI_MEDIA_CONTEXT mediaCtx;
mediaCtx = DdiMedia_GetMediaContext(ctx);
void *data = nullptr;
for (int32_t i = 0; i < numBuffers; i++)
{
if (!buffers || (buffers[i] == VA_INVALID_ID))
{
return VA_STATUS_ERROR_INVALID_BUFFER;
}
DDI_MEDIA_BUFFER *buf = DdiMedia_GetBufferFromVABufferID(mediaCtx, buffers[i]);
if (nullptr == buf)
{
return VA_STATUS_ERROR_INVALID_BUFFER;
}
uint32_t dataSize = buf->iSize;
DdiMedia_MapBuffer(ctx, buffers[i], &data);
if (data == nullptr)
{
return VA_STATUS_ERROR_INVALID_BUFFER;
}
switch ((int32_t)buf->uiType)
{
case VABitPlaneBufferType:
{
int32_t index = m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex;
if (index == DDI_CODEC_INVALID_BUFFER_INDEX)
{
return VA_STATUS_ERROR_INVALID_BUFFER;
}
if (index >= DDI_CODEC_MAX_BITSTREAM_BUFFER)
{
return VA_STATUS_ERROR_INVALID_BUFFER;
}
DDI_CHK_RET(AllocBitPlaneBuffer(),"AllocBitPlaneBuffer failed!");
/* Before accessing it on CPU, Use the DdiMediaUtil_LockBuffer to map it into CPU */
DdiMediaUtil_LockBuffer(m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[index], MOS_LOCKFLAG_WRITEONLY);
ParseBitPlane(m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[index], (uint8_t *)data);
DdiMediaUtil_UnlockBuffer(m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[index]);
DdiMedia_MediaBufferToMosResource(m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[index], &m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.resBitPlaneBuffer);
m_ddiDecodeCtx->DecodeParams.m_vc1BitplaneSize = dataSize;
m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex++;
if (m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex >= DDI_CODEC_MAX_BITSTREAM_BUFFER)
{
m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.dwVC1BitPlaneIndex = 0;
}
break;
}
case VASliceDataBufferType:
{
int32_t index = GetBitstreamBufIndexFromBuffer(&m_ddiDecodeCtx->BufMgr, buf);
if (index == DDI_CODEC_INVALID_BUFFER_INDEX)
{
return VA_STATUS_ERROR_INVALID_BUFFER;
}
DdiMedia_MediaBufferToMosResource(m_ddiDecodeCtx->BufMgr.pBitStreamBuffObject[index], &m_ddiDecodeCtx->BufMgr.resBitstreamBuffer);
m_ddiDecodeCtx->DecodeParams.m_dataSize += dataSize;
break;
}
case VASliceParameterBufferType:
{
if (buf->uiNumElements == 0)
{
return VA_STATUS_ERROR_INVALID_BUFFER;
}
VASliceParameterBufferVC1 *slcInfo =
(VASliceParameterBufferVC1 *)data;
uint32_t numSlices = buf->uiNumElements;
DDI_CHK_RET(AllocSliceParamContext(numSlices),"AllocSliceParamContext failed!");
DDI_CHK_RET(ParseSliceParams(mediaCtx, slcInfo, numSlices),"ParseSliceParams failed!");
m_ddiDecodeCtx->DecodeParams.m_numSlices += numSlices;
m_groupIndex++;
break;
}
case VAPictureParameterBufferType:
{
VAPictureParameterBufferVC1 *picParam = (VAPictureParameterBufferVC1 *)data;
DDI_CHK_RET(ParsePicParams(mediaCtx, picParam),"ParsePicParams failed!");
break;
}
case VADecodeStreamoutBufferType:
{
DdiMedia_MediaBufferToMosResource(buf, &m_ddiDecodeCtx->BufMgr.resExternalStreamOutBuffer);
m_streamOutEnabled = true;
break;
}
default:
va = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE;
break;
}
DdiMedia_UnmapBuffer(ctx, buffers[i]);
}
DDI_FUNCTION_EXIT(va);
return va;
}
VAStatus DdiDecodeVC1::SetDecodeParams()
{
if ((&m_ddiDecodeCtx->DecodeParams)->m_numSlices == 0)
{
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
m_destSurface.dwOffset = 0;
MOS_FORMAT expectedFormat = Format_NV12;
DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
m_destSurface.Format = expectedFormat;
if (m_deblockPicIdx != DDI_CODEC_INVALID_FRAME_INDEX)
{
DdiMedia_MediaSurfaceToMosResource((&(m_ddiDecodeCtx->RTtbl))->pRT[m_currPicIdx], &(m_destSurface.OsResource));
}
else
{
DdiMedia_MediaSurfaceToMosResource((&(m_ddiDecodeCtx->RTtbl))->pCurrentRT, &(m_destSurface.OsResource));
}
if (m_destSurface.OsResource.Format != expectedFormat)
{
DDI_NORMALMESSAGE("Surface fomrat of decoded surface is inconsistent with Mpeg2 bitstream\n");
return VA_STATUS_ERROR_INVALID_PARAMETER;
}
(&m_ddiDecodeCtx->DecodeParams)->m_destSurface = &m_destSurface;
memset(&m_deblockSurface, 0, sizeof(MOS_SURFACE));
if (m_olpNeeded)
{
memset(&m_deblockSurface, 0, sizeof(MOS_SURFACE));
m_deblockSurface.Format = Format_NV12;
m_deblockSurface.dwOffset = 0;
DdiMedia_MediaSurfaceToMosResource((&(m_ddiDecodeCtx->RTtbl))->pRT[m_deblockPicIdx], &(m_deblockSurface.OsResource));
(&m_ddiDecodeCtx->DecodeParams)->m_deblockSurface = &m_deblockSurface;
}
else
{
(&m_ddiDecodeCtx->DecodeParams)->m_deblockSurface = nullptr;
}
(&m_ddiDecodeCtx->DecodeParams)->m_dataBuffer = &bufMgr->resBitstreamBuffer;
(&m_ddiDecodeCtx->DecodeParams)->m_bitStreamBufData = bufMgr->pBitstreamBuffer;
Mos_Solo_OverrideBufferSize((&m_ddiDecodeCtx->DecodeParams)->m_dataSize, (&m_ddiDecodeCtx->DecodeParams)->m_dataBuffer);
(&m_ddiDecodeCtx->DecodeParams)->m_bitplaneBuffer = &(m_ddiDecodeCtx->BufMgr.Codec_Param.Codec_Param_VC1.resBitPlaneBuffer);
if (m_streamOutEnabled)
{
(&m_ddiDecodeCtx->DecodeParams)->m_streamOutEnabled = true;
(&m_ddiDecodeCtx->DecodeParams)->m_externalStreamOutBuffer = &bufMgr->resExternalStreamOutBuffer;
}
else
{
(&m_ddiDecodeCtx->DecodeParams)->m_streamOutEnabled = false;
(&m_ddiDecodeCtx->DecodeParams)->m_externalStreamOutBuffer = nullptr;
}
m_olpNeeded = false;
m_currPicIdx = DDI_CODEC_INVALID_FRAME_INDEX;
m_deblockPicIdx = DDI_CODEC_INVALID_FRAME_INDEX;
return VA_STATUS_SUCCESS;
}
VAStatus DdiDecodeVC1::InitResourceBuffer(DDI_MEDIA_CONTEXT *mediaCtx)
{
VAStatus vaStatus = VA_STATUS_SUCCESS;
DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
bufMgr->pSliceData = nullptr;
bufMgr->ui64BitstreamOrder = 0;
bufMgr->dwMaxBsSize = m_width *
m_height * 3 / 2;
// minimal 10k bytes for some special case. Will refractor this later
if (bufMgr->dwMaxBsSize < DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE)
{
bufMgr->dwMaxBsSize = DDI_CODEC_MIN_VALUE_OF_MAX_BS_SIZE;
}
int32_t i;
// init decode bitstream buffer object
for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
{
bufMgr->pBitStreamBuffObject[i] = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
if (bufMgr->pBitStreamBuffObject[i] == nullptr)
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto finish;
}
bufMgr->pBitStreamBuffObject[i]->iSize = bufMgr->dwMaxBsSize;
bufMgr->pBitStreamBuffObject[i]->uiType = VASliceDataBufferType;
bufMgr->pBitStreamBuffObject[i]->format = Media_Format_Buffer;
bufMgr->pBitStreamBuffObject[i]->uiOffset = 0;
bufMgr->pBitStreamBuffObject[i]->bo = nullptr;
bufMgr->pBitStreamBase[i] = nullptr;
}
bufMgr->m_maxNumSliceData = m_picHeightInMB;
bufMgr->pSliceData = (DDI_CODEC_BITSTREAM_BUFFER_INFO *)MOS_AllocAndZeroMemory(sizeof(bufMgr->pSliceData[0]) *
bufMgr->m_maxNumSliceData);
if (bufMgr->pSliceData == nullptr)
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto finish;
}
for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
{
bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i] = (DDI_MEDIA_BUFFER *)MOS_AllocAndZeroMemory(sizeof(DDI_MEDIA_BUFFER));
if (bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i] == nullptr)
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto finish;
}
bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]->iSize = MOS_ALIGN_CEIL(m_width, CODECHAL_MACROBLOCK_WIDTH) * MOS_ALIGN_CEIL(m_height, CODECHAL_MACROBLOCK_HEIGHT) * 2 / (CODECHAL_MACROBLOCK_HEIGHT * CODECHAL_MACROBLOCK_WIDTH);
bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]->uiType = VABitPlaneBufferType;
bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]->format = Media_Format_Buffer;
bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]->uiOffset = 0;
bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]->pMediaCtx = mediaCtx;
vaStatus = DdiMediaUtil_CreateBuffer(bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i], mediaCtx->pDrmBufMgr);
if (vaStatus != VA_STATUS_SUCCESS)
{
goto finish;
}
bufMgr->Codec_Param.Codec_Param_VC1.VC1BitPlane[i].pBitPlaneBase = nullptr;
bufMgr->Codec_Param.Codec_Param_VC1.VC1BitPlane[i].bUsed = false;
}
bufMgr->dwNumSliceData = 0;
bufMgr->dwNumSliceControl = 0;
m_sliceCtrlBufNum = m_picHeightInMB;
bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 = (VASliceParameterBufferVC1 *)MOS_AllocAndZeroMemory(sizeof(VASliceParameterBufferVC1) * m_sliceCtrlBufNum);
if (bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 == nullptr)
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto finish;
}
bufMgr->Codec_Param.Codec_Param_VC1.pBitPlaneBuffer = (uint8_t *)MOS_AllocAndZeroMemory(m_picWidthInMB * m_picHeightInMB);
if (bufMgr->Codec_Param.Codec_Param_VC1.pBitPlaneBuffer == nullptr)
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto finish;
}
return VA_STATUS_SUCCESS;
finish:
FreeResourceBuffer();
return vaStatus;
}
void DdiDecodeVC1::FreeResourceBuffer()
{
DDI_CODEC_COM_BUFFER_MGR *bufMgr = &(m_ddiDecodeCtx->BufMgr);
int32_t i;
for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
{
if (bufMgr->pBitStreamBase[i])
{
DdiMediaUtil_UnlockBuffer(bufMgr->pBitStreamBuffObject[i]);
bufMgr->pBitStreamBase[i] = nullptr;
}
if (bufMgr->pBitStreamBuffObject[i])
{
DdiMediaUtil_FreeBuffer(bufMgr->pBitStreamBuffObject[i]);
MOS_FreeMemory(bufMgr->pBitStreamBuffObject[i]);
bufMgr->pBitStreamBuffObject[i] = nullptr;
}
}
if (bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1)
{
MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1);
bufMgr->Codec_Param.Codec_Param_VC1.pVASliceParaBufVC1 = nullptr;
}
if (bufMgr->Codec_Param.Codec_Param_VC1.pBitPlaneBuffer)
{
MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_VC1.pBitPlaneBuffer);
bufMgr->Codec_Param.Codec_Param_VC1.pBitPlaneBuffer = nullptr;
}
for (i = 0; i < DDI_CODEC_MAX_BITSTREAM_BUFFER; i++)
{
if (bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i])
{
DdiMediaUtil_UnlockBuffer(bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]);
DdiMediaUtil_FreeBuffer(bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]);
MOS_FreeMemory(bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i]);
bufMgr->Codec_Param.Codec_Param_VC1.pVC1BitPlaneBuffObject[i] = nullptr;
}
}
// free decode bitstream buffer object
MOS_FreeMemory(bufMgr->pSliceData);
bufMgr->pSliceData = nullptr;
return;
}
VAStatus DdiDecodeVC1::CodecHalInit(
DDI_MEDIA_CONTEXT *mediaCtx,
void *ptr)
{
VAStatus vaStatus = VA_STATUS_SUCCESS;
MOS_CONTEXT *mosCtx = (MOS_CONTEXT *)ptr;
CODECHAL_FUNCTION codecFunction = CODECHAL_FUNCTION_DECODE;
m_ddiDecodeCtx->pCpDdiInterface->SetCpParams(m_ddiDecodeAttr->uiEncryptionType, m_codechalSettings);
CODECHAL_STANDARD_INFO standardInfo;
memset(&standardInfo, 0, sizeof(standardInfo));
standardInfo.CodecFunction = codecFunction;
standardInfo.Mode = (CODECHAL_MODE)m_ddiDecodeCtx->wMode;
m_codechalSettings->codecFunction = codecFunction;
m_codechalSettings->width = m_width;
m_codechalSettings->height = m_height;
m_codechalSettings->lumaChromaDepth = CODECHAL_LUMA_CHROMA_DEPTH_8_BITS;
m_codechalSettings->shortFormatInUse = m_ddiDecodeCtx->bShortFormatInUse;
m_codechalSettings->mode = CODECHAL_DECODE_MODE_VC1VLD;
m_codechalSettings->standard = CODECHAL_VC1;
/* VC1 uses the Intel-specific Format */
m_codechalSettings->intelEntrypointInUse = true;
m_ddiDecodeCtx->DecodeParams.m_picParams = MOS_AllocAndZeroMemory(sizeof(CODEC_VC1_PIC_PARAMS));
if (m_ddiDecodeCtx->DecodeParams.m_picParams == nullptr)
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto CleanUpandReturn;
}
m_sliceParamBufNum = m_picHeightInMB;
m_ddiDecodeCtx->DecodeParams.m_sliceParams = MOS_AllocAndZeroMemory(m_sliceParamBufNum * sizeof(CODEC_VC1_SLICE_PARAMS));
if (m_ddiDecodeCtx->DecodeParams.m_sliceParams == nullptr)
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto CleanUpandReturn;
}
vaStatus = CreateCodecHal(mediaCtx,
ptr,
&standardInfo);
if (vaStatus != VA_STATUS_SUCCESS)
{
goto CleanUpandReturn;
}
if (InitResourceBuffer(mediaCtx) != VA_STATUS_SUCCESS)
{
vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
goto CleanUpandReturn;
}
return vaStatus;
CleanUpandReturn:
FreeResourceBuffer();
if (m_ddiDecodeCtx->pCodecHal)
{
m_ddiDecodeCtx->pCodecHal->Destroy();
MOS_Delete(m_ddiDecodeCtx->pCodecHal);
m_ddiDecodeCtx->pCodecHal = nullptr;
}
MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_picParams);
m_ddiDecodeCtx->DecodeParams.m_picParams = nullptr;
MOS_FreeMemory(m_ddiDecodeCtx->DecodeParams.m_sliceParams);
m_ddiDecodeCtx->DecodeParams.m_sliceParams = nullptr;
return vaStatus;
}
extern template class MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>;
static bool vc1Registered =
MediaDdiFactory<DdiMediaDecode, DDI_DECODE_CONFIG_ATTR>::RegisterCodec<DdiDecodeVC1>(DECODE_ID_VC1);