blob: d1d434d5383a26c2be738258b9a447eb78e41bd4 [file] [log] [blame]
/*
* Copyright (c) 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_kernel_hme.h
//! \brief Defines the hme kernel base
//! \details Hme kernel base includes all common functions and definitions for HME on all platforms
//!
#ifndef __CODECHAL_KERNEL_HME_H__
#define __CODECHAL_KERNEL_HME_H__
#include "codechal_kernel_base.h"
// clang-format off
static uint8_t genericBMEMethod[NUM_TARGET_USAGE_MODES + 1] =
{
0, 4, 4, 6, 6, 6, 6, 4, 7
};
static uint8_t genericMEMethod[NUM_TARGET_USAGE_MODES + 1] =
{
0, 4, 4, 6, 6, 6, 6, 4, 7
};
static uint32_t SuperCombineDist[NUM_TARGET_USAGE_MODES + 1] =
{
0, 1, 1, 5, 5, 5, 9, 9, 0
};
// SearchPath Table, index [CodingType][MEMethod][]
static uint32_t codechalEncodeSearchPath[2][8][16] =
{
// I-Frame & P-Frame
{
// MEMethod: 0
{
0x120FF10F, 0x1E22E20D, 0x20E2FF10, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x4EF1F1F1, 0xF1F21211,
0x0DFFFFE0, 0x11201F1F, 0x1105F1CF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
},
// MEMethod: 1
{
0x120FF10F, 0x1E22E20D, 0x20E2FF10, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x4EF1F1F1, 0xF1F21211,
0x0DFFFFE0, 0x11201F1F, 0x1105F1CF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
},
// MEMethod: 2
{
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
},
// MEMethod: 3
{
0x01010101, 0x11010101, 0x01010101, 0x11010101, 0x01010101, 0x11010101, 0x01010101, 0x11010101,
0x01010101, 0x11010101, 0x01010101, 0x00010101, 0x00000000, 0x00000000, 0x00000000, 0x00000000
},
// MEMethod: 4
{
0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
},
// MEMethod: 5
{
0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
},
// MEMethod: 6
{
0x120FF10F, 0x1E22E20D, 0x20E2FF10, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x4EF1F1F1, 0xF1F21211,
0x0DFFFFE0, 0x11201F1F, 0x1105F1CF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
},
// MEMethod: 7 used for mpeg2 encoding P frames
{
0x1F11F10F, 0x2E22E2FE, 0x20E220DF, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x02F1F1F1, 0x1F201111,
0xF1EFFF0C, 0xF01104F1, 0x10FF0A50, 0x000FF1C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000
}
},
// B-Frame
{
// MEMethod: 0
{
0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
},
// MEMethod: 1
{
0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
},
// MEMethod: 2
{
0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
},
// MEMethod: 3
{
0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
},
// MEMethod: 4
{
0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
},
// MEMethod: 5
{
0x0101F00F, 0x0F0F1010, 0xF0F0F00F, 0x01010101, 0x10101010, 0x0F0F0F0F, 0xF0F0F00F, 0x0101F0F0,
0x01010101, 0x10101010, 0x0F0F1010, 0x0F0F0F0F, 0xF0F0F00F, 0xF0F0F0F0, 0x00000000, 0x00000000
},
// MEMethod: 6
{
0x120FF10F, 0x1E22E20D, 0x20E2FF10, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x4EF1F1F1, 0xF1F21211,
0x0DFFFFE0, 0x11201F1F, 0x1105F1CF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000
},
// MEMethod: 7 used for mpeg2 encoding B frames
{
0x1F11F10F, 0x2E22E2FE, 0x20E220DF, 0x2EDD06FC, 0x11D33FF1, 0xEB1FF33D, 0x02F1F1F1, 0x1F201111,
0xF1EFFF0C, 0xF01104F1, 0x10FF0A50, 0x000FF1C0, 0x00000000, 0x00000000, 0x00000000, 0x00000000
}
}
};
// clang-format on
//!
//! \class CodechalKernelHme
//! \brief Codechal kernel hme
//!
class CodechalKernelHme : public CodechalKernelBase
{
public:
//!
//! \enum HmeLevel
//! \brief Hme level
//!
enum HmeLevel
{
hmeLevelNone = 0,
hmeLevel4x = 1,
hmeLevel16x = 1 << 1,
hmeLevel32x = 1 << 2
};
//!
//! \enum KernelIndex
//! \brief Kernel index
//!
enum KernelIndex
{
hmeP = 0,
hmeB = 1
};
//!
//! \enum SurfaceId
//! \brief SurfaceI id
//!
enum SurfaceId
{
me4xMvDataBuffer = 0,
me16xMvDataBuffer = 1,
me32xMvDataBuffer = 2,
me4xDistortionBuffer = 3
};
//!
//! \enum BindingTableOffset
//! \brief Binding table offset
//!
enum BindingTableOffset
{
meOutputMvDataSurface = 0,
meInputMvDataSurface = 1,
meDistortionSurface = 2,
meBrcDistortion = 3,
meCurrForFwdRef = 5,
meFwdRefIdx0 = 6,
meFwdRefIdx1 = 8,
meFwdRefIdx2 = 10,
meFwdRefIdx3 = 12,
meFwdRefIdx4 = 14,
meFwdRefIdx5 = 16,
meFwdRefIdx6 = 18,
meFwdRefIdx7 = 20,
meCurrForBwdRef = 22,
meBwdRefIdx0 = 23,
meBwdRefIdx1 = 25,
meSurfaceNum = 27
};
//!
//! \struct CurbeParam
//! \brief Curbe parameter
//!
struct CurbeParam
{
bool brcEnable = false;
uint8_t subPelMode = 3;
uint8_t sumMVThreshold = 0;
CODEC_PICTURE currOriginalPic;
uint32_t qpPrimeY;
uint32_t targetUsage;
uint32_t maxMvLen;
uint32_t numRefIdxL1Minus1;
uint32_t numRefIdxL0Minus1;
uint8_t* meMethodTable = nullptr;
uint8_t* bmeMethodTable = nullptr;
uint32_t list0RefID0FieldParity : MOS_BITFIELD_BIT(0);
uint32_t list0RefID1FieldParity : MOS_BITFIELD_BIT(1);
uint32_t list0RefID2FieldParity : MOS_BITFIELD_BIT(2);
uint32_t list0RefID3FieldParity : MOS_BITFIELD_BIT(3);
uint32_t list0RefID4FieldParity : MOS_BITFIELD_BIT(4);
uint32_t list0RefID5FieldParity : MOS_BITFIELD_BIT(5);
uint32_t list0RefID6FieldParity : MOS_BITFIELD_BIT(6);
uint32_t list0RefID7FieldParity : MOS_BITFIELD_BIT(7);
uint32_t list1RefID0FieldParity : MOS_BITFIELD_BIT(8);
uint32_t list1RefID1FieldParity : MOS_BITFIELD_BIT(9);
};
//!
//! \struct SurfaceParams
//! \brief Surface parameters
//!
struct SurfaceParams
{
bool mbaffEnabled;
bool vdencStreamInEnabled;
uint32_t numRefIdxL0ActiveMinus1;
uint32_t numRefIdxL1ActiveMinus1;
uint32_t downScaledWidthInMb;
uint32_t downScaledHeightInMb;
uint32_t downScaledBottomFieldOffset;
uint32_t vdencStreamInSurfaceSize;
uint32_t verticalLineStride;
uint32_t verticalLineStrideOffset;
uint32_t meBrcDistortionBottomFieldOffset;
PCODEC_REF_LIST * refList;
PCODEC_PIC_ID picIdx;
PCODEC_PICTURE currOriginalPic;
PCODEC_PICTURE refL0List;
PCODEC_PICTURE refL1List;
PMOS_SURFACE meBrcDistortionBuffer;
PMOS_RESOURCE meVdencStreamInBuffer;
CODECHAL_ENCODE_BUFFER meSumMvandDistortionBuffer;
CmSurface2D *meBrcDistortionSurface;
};
//!
//! \brief Constructor
//!
//! \param [in] encoder
//! Codechal encoder state
//! \param [in] me4xDistBufferSupported
//! flag to support 4x Distortion buffer
//!
CodechalKernelHme(
CodechalEncoderState *encoder,
bool me4xDistBufferSupported);
virtual ~CodechalKernelHme();
//!
//! \brief Execute HME kernel
//!
//! \param [in] curbeParam
//! Reference to CurbeParam
//! \param [in] surfaceParam
//! Reference to SurfaceParams
//! \param [in] hmeLevel
//! current Hme level to run the kernel
//!
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success
//!
virtual MOS_STATUS Execute(CurbeParam &curbeParam, SurfaceParams &surfaceParam, HmeLevel hmeLevel);
virtual MOS_STATUS AllocateResources() override;
virtual MOS_STATUS ReleaseResources() override;
uint32_t GetBTCount() override { return BindingTableOffset::meSurfaceNum; }
inline bool Is4xMeEnabled()
{
return m_4xMeSupported && (m_pictureCodingType != I_TYPE);
}
inline bool Is16xMeEnabled()
{
return m_16xMeSupported && (m_pictureCodingType != I_TYPE);
}
inline bool Is32xMeEnabled()
{
return m_32xMeSupported && (m_pictureCodingType != I_TYPE);
}
inline uint32_t Get4xMeMvBottomFieldOffset()
{
return m_4xMeMvBottomFieldOffset;
}
inline void Set4xMeMvBottomFieldOffset(uint32_t offset)
{
m_4xMeMvBottomFieldOffset = offset;
}
inline uint32_t GetDistortionBottomFieldOffset()
{
return m_meDistortionBottomFieldOffset;
}
inline void SetDistortionBottomFieldOffset(uint32_t offset)
{
m_meDistortionBottomFieldOffset = offset;
}
inline uint32_t Get16xMeMvBottomFieldOffset()
{
return m_16xMeMvBottomFieldOffset;
}
inline void Set16xMeMvBottomFieldOffset(uint32_t offset)
{
m_16xMeMvBottomFieldOffset = offset;
}
inline uint32_t Get32xMeMvBottomFieldOffset()
{
return m_32xMeMvBottomFieldOffset;
}
inline void Set32xMeMvBottomFieldOffset(uint32_t offset)
{
m_32xMeMvBottomFieldOffset = offset;
}
inline void setnoMEKernelForPFrame(bool flag)
{
m_noMEKernelForPFrame = flag;
}
#if USE_CODECHAL_DEBUG_TOOL
MOS_STATUS DumpKernelOutput() override;
#endif
protected:
MOS_STATUS AddPerfTag() override;
MHW_KERNEL_STATE * GetActiveKernelState() override;
CODECHAL_MEDIA_STATE_TYPE GetMediaStateType() override;
MOS_STATUS SendSurfaces(PMOS_COMMAND_BUFFER cmd, MHW_KERNEL_STATE *kernelState) override;
MOS_STATUS InitWalkerCodecParams(CODECHAL_WALKER_CODEC_PARAMS &walkerParam) override;
protected:
bool &m_4xMeSupported;
bool &m_16xMeSupported;
bool &m_32xMeSupported;
bool &m_noMEKernelForPFrame;
bool &m_useNonLegacyStreamIn;
bool m_4xMeDistortionBufferSupported = false; //!< 4x Me Distortion buffer supported
bool m_4xMeInUse = false; //!< 4x Me is in use
bool m_16xMeInUse = false; //!< 16x Me is in use
bool m_32xMeInUse = false; //!< 32x Me is in use
uint32_t m_4xMeMvBottomFieldOffset = 0; //!< 4x ME mv bottom field offset
uint32_t m_16xMeMvBottomFieldOffset = 0; //!< 16x ME mv bottom field offset
uint32_t m_32xMeMvBottomFieldOffset = 0; //!< 32x ME mv bottom field offset
uint32_t m_meDistortionBottomFieldOffset = 0; //!< ME distortion bottom field offset
uint8_t * m_bmeMethodTable = genericBMEMethod; //!< pointer to BME method table
uint8_t * m_meMethodTable = genericMEMethod; //!< pointer to ME method table
CurbeParam m_curbeParam; //!< curbe paramters
SurfaceParams m_surfaceParam; //! surface parameters
static const uint32_t scalingFactor4X = 4;
static const uint32_t scalingFactor16X = 16;
static const uint32_t scalingFactor32X = 32;
};
#endif /* __CODECHAL_KERNEL_HME_H__ */