blob: c5b6cbad8f459afe75dae8b7fc6a978c3f9cfaad [file] [log] [blame]
/*
* Copyright (c) 2012-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 codechal_decode_vp8.h
//! \brief Defines the decode interface extension for VP8.
//! \details Defines all types, macros, and functions required by CodecHal for VP8 decoding.
//! Definitions are not externally facing.
//!
#ifndef __CODECHAL_DECODER_VP8_H__
#define __CODECHAL_DECODER_VP8_H__
#include "codechal.h"
#include "codechal_hw.h"
#include "codechal_decoder.h"
//*------------------------------------------------------------------------------
//* Codec Definitions
//*------------------------------------------------------------------------------
//!
//! \enum VP8_MB_LVL_FEATURES
//! VP8 MB Level Features
//!
typedef enum
{
VP8_MB_LVL_ALT_Q = 0,
VP8_MB_LVL_ALT_LF = 1,
VP8_MB_LVL_MAX = 2
} VP8_MB_LVL_FEATURES;
//!
//! \enum VP8_MB_PREDICTION_MODE
//! VP8 MB Prediction Mode
//!
typedef enum
{
VP8_DC_PRED,
VP8_V_PRED,
VP8_H_PRED,
VP8_TM_PRED,
VP8_B_PRED,
VP8_NEARESTMV,
VP8_NEARMV,
VP8_ZEROMV,
VP8_NEWMV,
SPLITMV,
VP8_MB_MODE_COUNT
} VP8_MB_PREDICTION_MODE;
//!
//! \enum VP8_LF_TYPE
//! VP8 LF Type
//!
typedef enum
{
VP8_NORMAL_LF = 0,
VP8_SIMPLE_LF = 1
} VP8_LF_TYPE;
//!
//! \enum VP8_TOKEN_PARTITION
//! VP8 Token Partition
//!
typedef enum
{
VP8_ONE_PARTITION = 0,
VP8_TWO_PARTITION = 1,
VP8_FOUR_PARTITION = 2,
VP8_EIGHT_PARTITION = 3
} VP8_TOKEN_PARTITION;
//!
//! \enum VP8_MV_REFERENCE_FRAME
//! VP8 MV Reference Frame
//!
typedef enum
{
VP8_NONE = -1,
VP8_INTRA_FRAME = 0,
VP8_LAST_FRAME = 1,
VP8_GOLDEN_FRAME = 2,
VP8_ALTREF_FRAME = 3,
VP8_MAX_REF_FRAMES = 4
} VP8_MV_REFERENCE_FRAME;
//!
//! \def VP8_Y_MODES
//! VP8 Y Mode Max Index
//!
#define VP8_Y_MODES (VP8_B_PRED + 1)
//!
//! \def VP8_UV_MODES
//! VP8 UV Mode Max Index
//!
#define VP8_UV_MODES (VP8_TM_PRED + 1)
//!
//! \def VP8_MAX_MB_SEGMENTS
//! Max Index of VP8 MB Segment
//!
#define VP8_MAX_MB_SEGMENTS 4
//!
//! \def VP8_MB_SEGMENT_TREE_PROBS
//! Max Index of Prob Tree for MB Segment Id
//!
#define VP8_MB_SEGMENT_TREE_PROBS 3
//!
//! \def VP8_MAX_REF_LF_DELTAS
//! Max Index of VP8 Ref LF Deltas
//!
#define VP8_MAX_REF_LF_DELTAS 4
//!
//! \def VP8_MAX_MODE_LF_DELTAS
//! Max Index of VP8 Mode LF Deltas
//!
#define VP8_MAX_MODE_LF_DELTAS 4
//!
//! \def VP8_MAX_Q
//! VP8 Max Q Index
//!
#define VP8_MAX_Q 127
//!
//! \def VP8_Q_INDEX_RANGE
//! VP8 Q Index range
//!
#define VP8_Q_INDEX_RANGE (VP8_MAX_Q + 1)
//!
//! \def VP8_BLOCK_TYPES
//! VP8 Block Types Max Index
//!
#define VP8_BLOCK_TYPES 4
//!
//! \def VP8_COEF_BANDS
//! VP8 Coef Bands Max Index
//!
#define VP8_COEF_BANDS 8
//!
//! \def VP8_PREV_COEF_CONTEXTS
//! VP8 Prev Coef Context Max Index
//!
#define VP8_PREV_COEF_CONTEXTS 3
//!
//! \def VP8_ENTROPY_NODES
//! VP8 Entropy Nodes Max Index
//!
#define VP8_ENTROPY_NODES 11
//!
//! \struct _VP8_FRAME_CONTEXT
//! \brief Define variables for VP8 Frame Context
//!
typedef struct _VP8_FRAME_CONTEXT
{
uint8_t YModeProb[VP8_Y_MODES - 1];
uint8_t UVModeProb[VP8_UV_MODES - 1];
uint8_t CoefProbs[VP8_BLOCK_TYPES][VP8_COEF_BANDS][VP8_PREV_COEF_CONTEXTS][VP8_ENTROPY_NODES];
MV_CONTEXT MvContext[2];
} VP8_FRAME_CONTEXT;
typedef struct _CODECHAL_DECODE_VP8_FRAME_HEAD CODECHAL_DECODE_VP8_FRAME_HEAD, *PCODECHAL_DECODE_VP8_FRAME_HEAD;
//!
//! \struct _CODECHAL_DECODE_VP8_FRAME_HEAD
//! \brief Define variables for VP8 Frame Head
//!
struct _CODECHAL_DECODE_VP8_FRAME_HEAD
{
int16_t Y1DeQuant[VP8_Q_INDEX_RANGE][2];
int16_t Y2DeQuant[VP8_Q_INDEX_RANGE][2];
int16_t UVDeQuant[VP8_Q_INDEX_RANGE][2];
int32_t iNewFrameBufferIdx, iLastFrameBufferIdx, iGoldenFrameBufferIdx, iAltFrameBufferIdx;
int32_t iLastFrameBufferCurrIdx, iGoldenFrameBufferCurrIdx, iAltFrameBufferCurrIdx;
int32_t iFrameType;
int32_t iShowframe;
int32_t iMbNoCoeffSkip;
int32_t iProbSkipFalse;
int32_t iBaseQIndex;
int32_t iY1DcDeltaQ;
int32_t iY2DcDeltaQ;
int32_t iY2AcDeltaQ;
int32_t iUVDcDeltaQ;
int32_t iUVAcDeltaQ;
VP8_LF_TYPE FilterType;
int32_t iFilterLevel;
int32_t iSharpnessLevel;
int32_t iRefreshLastFrame;
int32_t iRefreshGoldenFrame;
int32_t iRefreshAltFrame;
int32_t iCopyBufferToGolden; //!< 0 - None, 1 - Last to Golden, 2 - ALT to Golden
int32_t iCopyBufferToAlt; //!< 0 - None, 1 - Last to ALT, 2 - Golden to ALT
int32_t iRefreshEntropyProbs;
int32_t RefFrameSignBias[VP8_MAX_REF_FRAMES];
VP8_FRAME_CONTEXT LastFrameContext;
VP8_FRAME_CONTEXT FrameContext;
int32_t iVersion;
VP8_TOKEN_PARTITION MultiTokenPartition;
uint8_t u8SegmentationEnabled;
uint8_t u8UpdateMbSegmentationMap;
uint8_t u8UpdateMbSegmentationData;
uint8_t u8MbSegementAbsDelta;
uint8_t MbSegmentTreeProbs[VP8_MB_SEGMENT_TREE_PROBS]; //!< Prob Tree for MB Segment Id
int8_t SegmentFeatureData[VP8_MB_LVL_MAX][VP8_MAX_MB_SEGMENTS];
int8_t LoopFilterLevel[VP8_MAX_MB_SEGMENTS];
uint8_t u8ModeRefLfDeltaEnabled;
uint8_t u8ModeRefLfDeltaUpdate;
int8_t RefLFDeltas[VP8_MAX_REF_LF_DELTAS]; //!< Intra, Last, Golden, ALT
int8_t ModeLFDeltas[VP8_MAX_MODE_LF_DELTAS]; //!< BPRED, ZERO_MV, MV, SPLIT
uint32_t uiFirstPartitionLengthInBytes;
uint8_t YModeProbs[4];
uint8_t UVModeProbs[3];
uint8_t ProbIntra;
uint8_t ProbLast;
uint8_t ProbGf;
bool bNotFirstCall;
};
//!
//! \class Vp8EntropyState
//! \brief This class defines the member fields, functions etc used by VP8 entropy decoder to parse frame head.
//!
class Vp8EntropyState
{
public:
const uint8_t m_keyFrame = 0; //!< VP8 Key Frame Flag
const uint8_t m_interFrame = 1; //!< VP8 Inter Frame Flag
const uint32_t m_bdValueSize = ((uint32_t)sizeof(uint32_t) * CHAR_BIT); // VP8 BD Value Size
const uint32_t m_lotsOfBits = 0x40000000; //!< Offset for parsing frame head
const uint8_t m_probHalf = 128; //!< VP8 Half Probability
//!
//! \brief Constructor
//!
Vp8EntropyState() {};
//!
//! \brief Destructor
//!
~Vp8EntropyState() {};
//!
//! \brief Initialize VP8 entropy state
//! \details Initialize VP8 bitstream buffer and related index
//! \param [in] vp8FrameHeadIn
//! Pointer to VP8 Frame Head
//! \param [in] bitstreamBufferIn
//! Pointer to VP8 bitstream buffer
//! \param [in] bitstreamBufferSizeIn
//! VP8 bitstream buffer size
//! \return void
//!
void Initialize(
PCODECHAL_DECODE_VP8_FRAME_HEAD vp8FrameHeadIn,
uint8_t* bitstreamBufferIn,
uint32_t bitstreamBufferSizeIn);
//!
//! \brief Parse VP8 Frame Head
//! \details Parse VP8 Frame Head based on VP8 Pic Params
//! \param [in] vp8PicParams
//! Pointer to VP8 Pic Params
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS ParseFrameHead(
PCODEC_VP8_PIC_PARAMS vp8PicParams);
//!
//! \brief Update Quant Index in VP8 Frame Head
//! \details Update Quant Index in VP8 Frame Head for
//! Y/UV based on DeltaQ in VP8 Pic Params
//! \param [in] vp8PicParams
//! Pointer to VP8 Pic Params
//! \return void
//!
void FrameHeadQuantUpdate(
PCODEC_VP8_PIC_PARAMS vp8PicParams);
protected:
//!
//! \brief Initialize Frame Head in VP8 Entropy State class
//! \details Initialize Frame Head for VP8 Frame Head Parser
//! \return void
//!
void ParseFrameHeadInit();
//!
//! \brief Start Entropy Decode
//! \return int32_t
//! 1 if Buffer is empty or pointer is nullptr, else call DecodeFill and return 0
//!
int32_t StartEntropyDecode();
//!
//! \brief Update Segmentation Info in Frame Head
//! \details Parse bitstream to update frame head segmentation info
//! \return void
//!
void SegmentationEnabled();
//!
//! \brief Update Mv Contexts in Frame Head
//! \details Parse bitstream to update Mv Contexts Info
//! \param [out] mvContext
//! Pointer to Mv Contexts
//! \return void
//!
void ReadMvContexts(MV_CONTEXT *mvContext);
PCODECHAL_DECODE_VP8_FRAME_HEAD m_frameHead = nullptr; //!< Pointer to VP8 Frame Head
uint8_t * m_bitstreamBuffer = nullptr; //!< Pointer to Bitstream Buffer
uint32_t m_bitstreamBufferSize = 0; //!< Size of Bitstream Buffer
uint8_t * m_dataBuffer = nullptr; //!< Pointer to Data Buffer
uint8_t * m_dataBufferEnd = nullptr; //<! Pointer to Data Buffer End
private:
//!
//! \brief Update Entropy Decode State Info
//! \details Calculate left bitstream size to update pointer info
//! \return void
//!
void DecodeFill();
//!
//! \brief Update Entropy Decode State according to probability
//! \param [in] probability
//! Probability to do entropy decode
//! \return uint32_t
//! return 1 if entropy decode value meets the requirement of probability, else 0
//!
uint32_t DecodeBool(int32_t probability);
//!
//! \brief Update Entropy Decode State according to Bits Number
//! \param [in] bits
//! Bits to do entropy decode
//! \return int32_t
//! return value calculated by DecodeBool using 0x80 as probability
//!
int32_t DecodeValue(int32_t bits);
//!
//! \brief Update Loop Filter Info in VP8 Frame Header
//! \param [in] defaultFilterLvl
//! Default Segmentation Level
//! \return void
//!
void LoopFilterInit(int32_t defaultFilterLvl);
//!
//! \brief Update Loop Filter Deltas and Default Loop Filter Level
//! \details Parse Loop Filter Deltas and Default Loop Filter Level Info to
//! Initialize Loop Filter
//! \return void
//!
void LoopFilterEnabled();
//!
//! \brief Get DeltaQ from Frame Header
//! \details Parse Frame Header to Get DeltaQ value Based on
//! Current DeltaQ Value and Update info
//! \param [in] prevVal
//! Previous DeltaQ Value
//! \param [in] qupdate
//! Pointer to DeltaQ Update Value
//! \return int32_t
//! Return Calculated DeltaQ Value
//!
int32_t GetDeltaQ(int32_t prevVal, int32_t * qupdate);
//!
//! \brief Get DC Quant Value from Lookup Table
//! \param [in] qindex
//! Quant Index
//! \param [in] delta
//! Quant Index Offset
//! \return int32_t
//! Return DC Quant Value in Lookup Table with Index and Offset
//!
int32_t DcQuant(int32_t qindex, int32_t delta);
//!
//! \brief Get Double DC Quant Value from Lookup Table
//! \param [in] qindex
//! Quant Index
//! \param [in] delta
//! Quant Index Offset
//! \return int32_t
//! Return Double DC Quant Value in Lookup Table with Index and Offset
//!
int32_t Dc2Quant(int32_t qindex, int32_t delta);
//!
//! \brief Get DC Quant Value from Lookup Table for UV
//! \param [in] qindex
//! Quant Index
//! \param [in] delta
//! Quant Index Offset
//! \return int32_t
//! Return DC Quant Value in Lookup Table with Index and Offset for UV
//!
int32_t DcUVQuant(int32_t qindex, int32_t delta);
//!
//! \brief Get AC Quant Value from Lookup Table for Y
//! \param [in] qindex
//! Quant Index
//! \return int32_t
//! Return AC Quant Value in Lookup Table with Index and Offset for Y
//!
int32_t AcYQuant(int32_t qindex);
//!
//! \brief Get ~Double AC Quant Value from Lookup Table
//! \param [in] qindex
//! Quant Index
//! \param [in] delta
//! Quant Index Offset
//! \return int32_t
//! Return AC Quant Value in Lookup Table with Index and Offset
//! Multiplied by 101581 and Then Devided by 2^16 (About 1.55)
//!
int32_t Ac2Quant(int32_t qindex, int32_t delta);
//!
//! \brief Get AC Quant Value from Lookup Table for UV
//! \param [in] qindex
//! Quant Index
//! \param [in] delta
//! Quant Index Offset
//! \return int32_t
//! Return AC Quant Value in Lookup Table with Index and Offset for UV
//!
int32_t AcUVQuant(int32_t qindex, int32_t delta);
//!
//! \brief Initialize Quant Table for Y/UV in Frame Head
//! \return void
//!
void QuantInit();
//!
//! \brief Initialize DC/AC DeltaQ Value in Frame Head for Y/UV
//! \return void
//!
void QuantSetup();
const uint8_t *m_bufferEnd = nullptr; //!< Pointer to Data Buffer End
const uint8_t *m_buffer = nullptr; //!< Pointer to Data Buffer
int32_t m_count = 0; //!< Bits Count for Bitstream Buffer
uint32_t m_value = 0; //!< Entropy Value
uint32_t m_range = 0; //!< Entropy Range
};
using PVP8_ENTROPY_STATE = Vp8EntropyState*;
//!
//! \class CodechalDecodeVp8
//! \brief This class defines the member fields, functions etc used by VP8 decoder.
//!
class CodechalDecodeVp8 : public CodechalDecode
{
public:
const int32_t m_codechalDecodeVp8CoeffprobTableSize = 4 * 8 * 3 * 11;
//!
//! \brief Constructor
//! \param [in] hwInterface
//! Hardware interface
//! \param [in] debugInterface
//! Debug interface
//! \param [in] standardInfo
//! The information of decode standard for this instance
//!
CodechalDecodeVp8(
CodechalHwInterface *hwInterface,
CodechalDebugInterface* debugInterface,
PCODECHAL_STANDARD_INFO standardInfo);
//!
//! \brief Destructor
//!
~CodechalDecodeVp8();
//!
//! \brief Allocate and initialize VP8 decoder standard
//! \param [in] settings
//! Pointer to CodechalSetting
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS AllocateStandard(
CodechalSetting * settings) override;
//!
//! \brief Set states for each frame to prepare for VP8 decode
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS SetFrameStates() override;
//!
//! \brief VP8 decoder state level function
//! \details State level function for VP8 decoder
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS DecodeStateLevel() override;
//!
//! \brief VP9 decoder primitive level function
//! \details Primitive level function for GEN specific VP8 decoder
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS DecodePrimitiveLevel() override;
MOS_STATUS InitMmcState() override;
//!
//! \brief Allocate fixed sized resources
//! \details Allocate fixed sized resources VP8 decode driver
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS AllocateResourcesFixedSizes();
//!
//! \brief Allocate variable sized resources
//! \details Allocate variable sized resources in VP8 decode driver
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS AllocateResourcesVariableSizes();
// Parameters passed by application
uint16_t m_picWidthInMbLastMaxAlloced; //!< Max Picture Width in MB used for buffer allocation in past frames
uint16_t m_picHeightInMbLastMaxAlloced; //!< Max Picture Height in MB used for buffer allocation in past frames
bool m_shortFormatInUse; //!< Short Format Indicator
uint32_t m_dataSize; //!< Data Size in Decode Params
uint32_t m_dataOffset; //!< Data Offset in Decode Params
PCODEC_VP8_PIC_PARAMS m_vp8PicParams; //!< Pointer to VP8 Pic Params
PCODEC_VP8_IQ_MATRIX_PARAMS m_vp8IqMatrixParams; //!< Pointer to VP8 IQ Matrix Params
MOS_SURFACE m_destSurface; //!< Pointer to MOS_SURFACE of render surface
PMOS_RESOURCE m_presLastRefSurface; //!< Pointer to resource of Last Reference Surface
PMOS_RESOURCE m_presGoldenRefSurface; //!< Pointer to resource of Golden Reference Surface
PMOS_RESOURCE m_presAltRefSurface; //!< Pointer to resource of Alternate Reference Surface
MOS_RESOURCE m_resDataBuffer; //!< Graphics resource of bitstream data surface
MOS_RESOURCE m_resCoefProbBuffer; //!< Graphics resource of Coefficient Probability data surface
// Track for several row store buffer's max picture width in MB used for buffer allocation in past frames
uint16_t m_mfdDeblockingFilterRowStoreScratchBufferPicWidthInMb;
uint16_t m_mfdIntraRowStoreScratchBufferPicWidthInMb;
uint16_t m_bsdMpcRowStoreScratchBufferPicWidthInMb;
// Internally maintained
MOS_RESOURCE m_resTmpBitstreamBuffer; //!< Graphics resource of Bitstream data surface
MOS_RESOURCE m_resMfdIntraRowStoreScratchBuffer; //!< Graphics resource of MFD Intra Row Store Scratch data surface
MOS_RESOURCE m_resMfdDeblockingFilterRowStoreScratchBuffer; //!< Graphics resource of MFD Deblocking Filter Row Store Scratch data surface
MOS_RESOURCE m_resBsdMpcRowStoreScratchBuffer; //!< Graphics resource of BSD/MPC Row Store Scratch data surface
MOS_RESOURCE m_resMprRowStoreScratchBuffer; //!< Graphics resource of MPR Row Store Scratch data surface
MOS_RESOURCE m_resSegmentationIdStreamBuffer; //!< Graphics resource of Segmentation ID Stream data surface
PCODEC_REF_LIST m_vp8RefList[CODECHAL_NUM_UNCOMPRESSED_SURFACE_VP8]; //!< VP8 Reference List
MOS_RESOURCE m_resSyncObject; //!< Graphics resource of Sync Object
MOS_RESOURCE m_resPrivateInputBuffer; //!< Graphics resource of private surface for bitstream and coeff prob table
uint32_t m_privateInputBufferSize; //!< Size of private surface
uint32_t m_coeffProbTableOffset; //!< Coefficient Probability Table Offset
bool m_deblockingEnabled; //!< VP8 Loop Filter Enable Indicator
// VP8 Frame Head
Vp8EntropyState m_vp8EntropyState; //!< VP8 Entropy State class to parse frame head
CODECHAL_DECODE_VP8_FRAME_HEAD m_vp8FrameHead; //!< VP8 Frame Head
// HuC copy related
bool m_huCCopyInUse; //!< a sync flag used when huc copy and decoder run in the different VDBOX
MOS_RESOURCE m_resSyncObjectWaContextInUse; //!< signals on the video WA context
MOS_RESOURCE m_resSyncObjectVideoContextInUse; //!< signals on the video context
protected:
//!
//! \brief Parse Frame Head
//! \details Parse Frame Head from Bitstream Buffer for VP8
//!
//! \param [in] bitstreamBuffer
//! Pointer to input Bitstream Buffer
//! \param [in] bitstreamBufferSize
//! Size of Input Bitstream Buffer
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS ParseFrameHead(
uint8_t* bitstreamBuffer,
uint32_t bitstreamBufferSize);
//!
//! \brief Copy Bitstream Buffer
//! \details Copy Bitstream Buffer from Source to Destiny
//!
//! \param [in] srcBitstreamBuffer
//! Resource of Source Bitstream Buffer
//! \param [in] dstBitstreamBuffer
//! Pointer to Resource of Destiny Bitstream Buffer
//! \param [in] size
//! Size of Bitstream Buffer
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS CopyBitstreamBuffer(
MOS_RESOURCE srcBitstreamBuffer,
PMOS_RESOURCE dstBitstreamBuffer,
uint32_t size);
#if USE_CODECHAL_DEBUG_TOOL
MOS_STATUS DumpPicParams(
PCODEC_VP8_PIC_PARAMS picParams);
MOS_STATUS DumpIQParams(
PCODEC_VP8_IQ_MATRIX_PARAMS matrixData);
#endif
};
#endif // __CODECHAL_DECODER_VP8_H__