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