1 // Copyright (c) 2018-2019 Intel Corporation 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in all 11 // copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 // SOFTWARE. 20 21 #pragma once 22 23 #include "mfx_common.h" 24 #if defined MFX_VA_LINUX 25 #include "mfx_h264_encode_struct_vaapi.h" 26 #endif 27 #include "mfx_vp9_encode_hw_utils.h" 28 #include "mfx_platform_headers.h" 29 30 namespace MfxHwVP9Encode 31 { 32 33 static const GUID DXVA2_Intel_Encode_VP9_Profile0 = 34 { 0x464bdb3c, 0x91c4, 0x4e9b, { 0x89, 0x6f, 0x22, 0x54, 0x96, 0xac, 0x4e, 0xd6 } }; 35 static const GUID DXVA2_Intel_Encode_VP9_Profile1 = 36 { 0xafe4285c, 0xab63, 0x4b2d, { 0x82, 0x78, 0xe6, 0xba, 0xac, 0xea, 0x2c, 0xe9 } }; 37 static const GUID DXVA2_Intel_Encode_VP9_10bit_Profile2 = 38 { 0x4c5ba10, 0x4e9a, 0x4b8e, { 0x8d, 0xbf, 0x4f, 0x4b, 0x48, 0xaf, 0xa2, 0x7c } }; 39 static const GUID DXVA2_Intel_Encode_VP9_10bit_Profile3 = 40 { 0x24d19fca, 0xc5a2, 0x4b8e, { 0x9f, 0x93, 0xf8, 0xf6, 0xef, 0x15, 0xc8, 0x90 } }; 41 42 static const GUID DXVA2_Intel_LowpowerEncode_VP9_Profile0 = 43 { 0x9b31316b, 0xf204, 0x455d, { 0x8a, 0x8c, 0x93, 0x45, 0xdc, 0xa7, 0x7c, 0x1 } }; 44 static const GUID DXVA2_Intel_LowpowerEncode_VP9_Profile1 = 45 { 0x277de9c5, 0xed83, 0x48dd, {0xab, 0x8f, 0xac, 0x2d, 0x24, 0xb2, 0x29, 0x43 } }; 46 static const GUID DXVA2_Intel_LowpowerEncode_VP9_10bit_Profile2 = 47 { 0xacef8bc, 0x285f, 0x415d, {0xab, 0x22, 0x7b, 0xf2, 0x52, 0x7a, 0x3d, 0x2e } }; 48 static const GUID DXVA2_Intel_LowpowerEncode_VP9_10bit_Profile3 = 49 { 0x353aca91, 0xd945, 0x4c13, {0xae, 0x7e, 0x46, 0x90, 0x60, 0xfa, 0xc8, 0xd8 } }; 50 51 GUID GetGuid(VP9MfxVideoParam const & par); 52 53 #define DDI_FROM_MAINLINE_DRIVER 54 55 typedef struct tagENCODE_CAPS_VP9 56 { 57 union 58 { 59 struct 60 { 61 UINT CodingLimitSet : 1; 62 UINT Color420Only : 1; 63 UINT ForcedSegmentationSupport : 1; 64 UINT FrameLevelRateCtrl : 1; 65 UINT BRCReset : 1; 66 UINT AutoSegmentationSupport : 1; 67 UINT TemporalLayerRateCtrl : 3; 68 UINT DynamicScaling : 1; 69 UINT TileSupport : 1; 70 UINT NumScalablePipesMinus1 : 3; 71 UINT YUV422ReconSupport : 1; 72 UINT YUV444ReconSupport : 1; 73 UINT MaxEncodedBitDepth : 2; 74 UINT UserMaxFrameSizeSupport : 1; 75 UINT SegmentFeatureSupport : 4; 76 UINT DirtyRectSupport : 1; 77 UINT MoveRectSupport : 1; 78 UINT : 7; 79 80 }; 81 82 UINT CodingLimits; 83 }; 84 85 union 86 { 87 struct 88 { 89 UCHAR EncodeFunc : 1; // CHV+ 90 UCHAR HybridPakFunc : 1; // HSW/BDW hybrid ENC & PAK 91 UCHAR EncFunc : 1; // BYT enc only mode 92 UCHAR: 5; 93 }; 94 95 UCHAR CodingFunction; 96 }; 97 98 UINT MaxPicWidth; 99 UINT MaxPicHeight; 100 USHORT MaxNumOfDirtyRect; 101 USHORT MaxNumOfMoveRect; 102 103 104 } ENCODE_CAPS_VP9; 105 106 class DriverEncoder; 107 108 mfxStatus QueryCaps(VideoCORE * pCore, ENCODE_CAPS_VP9 & caps, GUID guid, VP9MfxVideoParam const & par); 109 110 DriverEncoder* CreatePlatformVp9Encoder(VideoCORE * pCore); 111 112 class DriverEncoder 113 { 114 public: 115 ~DriverEncoder()116 virtual ~DriverEncoder(){} 117 118 virtual mfxStatus CreateAuxilliaryDevice( 119 VideoCORE * pCore, 120 GUID guid, 121 VP9MfxVideoParam const & par) = 0; 122 123 virtual 124 mfxStatus CreateAccelerationService( 125 VP9MfxVideoParam const & par) = 0; 126 127 virtual 128 mfxStatus Reset( 129 VP9MfxVideoParam const & par) = 0; 130 131 virtual 132 mfxStatus Register( 133 mfxFrameAllocResponse & response, 134 D3DDDIFORMAT type) = 0; 135 136 virtual 137 mfxStatus Execute( 138 Task const &task, 139 mfxHDLPair pair) = 0; 140 141 virtual 142 mfxStatus QueryCompBufferInfo( 143 D3DDDIFORMAT type, 144 mfxFrameAllocRequest & request, 145 mfxU32 frameWidth, 146 mfxU32 frameHeight) = 0; 147 148 virtual 149 mfxStatus QueryEncodeCaps( 150 ENCODE_CAPS_VP9 & caps) = 0; 151 152 virtual 153 mfxStatus QueryStatus( 154 Task & task ) = 0; 155 156 virtual 157 mfxU32 GetReconSurfFourCC() = 0; 158 159 virtual 160 mfxStatus Destroy() = 0; 161 }; 162 163 #define VP9_MAX_UNCOMPRESSED_HEADER_SIZE 1000 164 #define SWITCHABLE 4 /* should be the last one */ 165 166 enum { 167 LAST_FRAME = 0, 168 GOLDEN_FRAME = 1, 169 ALTREF_FRAME = 2 170 }; 171 172 struct BitOffsets 173 { 174 mfxU16 BitOffsetUncompressedHeader; 175 mfxU16 BitOffsetForLFRefDelta; 176 mfxU16 BitOffsetForLFModeDelta; 177 mfxU16 BitOffsetForLFLevel; 178 mfxU16 BitOffsetForQIndex; 179 mfxU16 BitOffsetForFirstPartitionSize; 180 mfxU16 BitOffsetForSegmentation; 181 mfxU16 BitSizeForSegmentation; 182 }; 183 AddSeqHeader(mfxU32 width,mfxU32 height,mfxU32 FrameRateN,mfxU32 FrameRateD,mfxU32 numFramesInFile,mfxU8 * pBitstream,mfxU32 bufferSize)184 inline mfxStatus AddSeqHeader(mfxU32 width, 185 mfxU32 height, 186 mfxU32 FrameRateN, 187 mfxU32 FrameRateD, 188 mfxU32 numFramesInFile, 189 mfxU8* pBitstream, 190 mfxU32 bufferSize) 191 { 192 mfxU32 ivf_file_header[8] = { 0x46494B44, 0x00200000, 0x30395056, width + (height << 16), FrameRateN, FrameRateD, numFramesInFile, 0x00000000 }; 193 if (bufferSize < sizeof(ivf_file_header)) 194 return MFX_ERR_MORE_DATA; 195 196 std::copy(std::begin(ivf_file_header),std::end(ivf_file_header), reinterpret_cast<mfxU32*>(pBitstream)); 197 198 return MFX_ERR_NONE; 199 }; 200 AddPictureHeader(mfxU8 * pBitstream,mfxU32 bufferSize)201 inline mfxStatus AddPictureHeader(mfxU8* pBitstream, mfxU32 bufferSize) 202 { 203 mfxU32 number_of_zero_bytes = 3*sizeof(mfxU32); 204 205 if (bufferSize < number_of_zero_bytes) 206 return MFX_ERR_MORE_DATA; 207 208 std::fill_n(pBitstream, number_of_zero_bytes, 0); 209 210 return MFX_ERR_NONE; 211 }; 212 MakePackedByteBuffer(mfxU8 * data,mfxU32 size)213 inline ENCODE_PACKEDHEADER_DATA MakePackedByteBuffer(mfxU8 * data, mfxU32 size) 214 { 215 ENCODE_PACKEDHEADER_DATA desc = {}; 216 desc.pData = data; 217 desc.BufferSize = size; 218 desc.DataLength = size; 219 return desc; 220 } 221 222 struct BitBuffer { 223 mfxU8 *pBuffer; 224 mfxU16 bitOffset; 225 }; 226 227 mfxU16 WriteUncompressedHeader(BitBuffer &buffer, 228 Task const &task, 229 VP9SeqLevelParam const &seqPar, 230 BitOffsets &offsets); 231 232 mfxU16 PrepareFrameHeader(VP9MfxVideoParam const &par, 233 mfxU8 *pBuf, 234 mfxU32 bufferSizeBytes, 235 Task const& task, 236 VP9SeqLevelParam const &seqPar, 237 BitOffsets &offsets); 238 } // MfxHwVP9Encode 239