1 // Copyright (c) 2018-2020 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 #ifndef __MFX_H264_ENC_COMMON_HW_H__ 22 #define __MFX_H264_ENC_COMMON_HW_H__ 23 24 #if defined(AS_H264LA_PLUGIN) && defined(MFX_ENABLE_ENCTOOLS) 25 #undef MFX_ENABLE_ENCTOOLS 26 #endif 27 28 #include "mfx_common.h" 29 #include "mfxla.h" 30 31 #if defined (MFX_ENABLE_H264_VIDEO_ENCODE_HW) 32 33 #include <vector> 34 #include <assert.h> 35 #include <memory> 36 #include "mfx_ext_buffers.h" 37 #include "mfxfei.h" 38 #ifdef MFX_ENABLE_ENCTOOLS 39 #include "mfxenctools-int.h" 40 #else 41 #include "mfxbrc.h" 42 #endif 43 #include "mfx_h264_encode_struct_vaapi.h" 44 45 #if defined(MFX_VA_LINUX) 46 #include <va/va.h> 47 #include <va/va_enc_h264.h> 48 #endif 49 #include "mfxmvc.h" 50 51 #include "umc_defs.h" 52 53 #define ENABLE_APQ_LQ 54 55 56 #define D3DFMT_NV12 (D3DFORMAT)(MFX_MAKEFOURCC('N', 'V', '1', '2')) 57 #define D3DDDIFMT_NV12 (D3DDDIFORMAT)(MFX_MAKEFOURCC('N', 'V', '1', '2')) 58 #define D3DDDIFMT_YU12 (D3DDDIFORMAT)(MFX_MAKEFOURCC('Y', 'U', '1', '2')) 59 60 // this guid is used to identify that device creation is performed during Query or QueryIOSurf call 61 static const GUID MSDK_Private_Guid_Encode_AVC_Query = 62 { 0x32560c63, 0xe3dc, 0x43c9, { 0xa8, 0x16, 0xda, 0x73, 0x36, 0x45, 0x89, 0xe9 } }; 63 // this guid is used to identify device creation for MVC BD/AVCHD dependent view 64 static const GUID MSDK_Private_Guid_Encode_MVC_Dependent_View = 65 { 0x68bebcda, 0xefff, 0x4858, { 0x8d, 0x65, 0x92, 0x28, 0xab, 0xc5, 0x8c, 0x4e } }; 66 // this guid is used to identify that device creation is performed during for low power encoder 67 static const GUID MSDK_Private_Guid_Encode_AVC_LowPower_Query = 68 { 0x6815aa23, 0xc93e, 0x4a71, { 0xae, 0x66, 0xb, 0x60, 0x5d, 0x3b, 0xc4, 0xd7 } }; 69 70 namespace MfxHwH264Encode 71 { 72 class DdiTask; 73 class InputBitstream; 74 class OutputBitstream; 75 struct mfxExtSpsHeader; 76 struct mfxExtPpsHeader; 77 78 const mfxU16 CROP_UNIT_X[] = { 1, 2, 2, 1 }; 79 const mfxU16 CROP_UNIT_Y[] = { 1, 2, 1, 1 }; 80 81 static const mfxU16 MFX_PICSTRUCT_PART1 = MFX_PICSTRUCT_PROGRESSIVE | MFX_PICSTRUCT_FIELD_TFF | MFX_PICSTRUCT_FIELD_BFF; 82 static const mfxU16 MFX_PICSTRUCT_PART2 = MFX_PICSTRUCT_FIELD_REPEATED | MFX_PICSTRUCT_FRAME_DOUBLING | MFX_PICSTRUCT_FRAME_TRIPLING; 83 84 static const mfxU16 MFX_PICSTRUCT_FRAME_FLAGS = MFX_PICSTRUCT_FRAME_DOUBLING | MFX_PICSTRUCT_FRAME_TRIPLING; 85 static const mfxU16 MFX_PICSTRUCT_FIELD_FLAGS = MFX_PICSTRUCT_FIELD_REPEATED; 86 87 static const mfxU8 SEI_TYPE_BUFFERING_PERIOD = 0; 88 static const mfxU8 SEI_TYPE_PIC_TIMING = 1; 89 static const mfxU8 SEI_TYPE_FILLER_PAYLOAD = 3; 90 static const mfxU8 SEI_TYPE_RECOVERY_POINT = 6; 91 static const mfxU8 SEI_TYPE_DEC_REF_PIC_MARKING_REPETITION = 7; 92 static const mfxU8 SEI_TYPE_SCALABILITY_INFO = 24; 93 // MVC BD { 94 static const mfxU8 SEI_TYPE_MVC_SCALABLE_NESTING = 37; 95 // MVC BD } 96 97 static const mfxU16 MFX_RATECONTROL_WIDI_VBR = 100; 98 99 // internally used buffers 100 static const mfxU32 MFX_EXTBUFF_SPS_HEADER = MFX_MAKEFOURCC(0xff, 'S', 'P', 'S'); 101 static const mfxU32 MFX_EXTBUFF_PPS_HEADER = MFX_MAKEFOURCC(0xff, 'P', 'P', 'S'); 102 103 static const mfxU16 MFX_FRAMETYPE_IPB = MFX_FRAMETYPE_I | MFX_FRAMETYPE_P | MFX_FRAMETYPE_B; 104 static const mfxU16 MFX_FRAMETYPE_PB = MFX_FRAMETYPE_P | MFX_FRAMETYPE_B; 105 static const mfxU16 MFX_FRAMETYPE_PREF = MFX_FRAMETYPE_P | MFX_FRAMETYPE_REF; 106 static const mfxU16 MFX_FRAMETYPE_IREF = MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF; 107 static const mfxU16 MFX_FRAMETYPE_IREFIDR = MFX_FRAMETYPE_I | MFX_FRAMETYPE_REF | MFX_FRAMETYPE_IDR; 108 static const mfxU16 MFX_FRAMETYPE_xIPB = MFX_FRAMETYPE_xI | MFX_FRAMETYPE_xP | MFX_FRAMETYPE_xB; 109 static const mfxU16 MFX_FRAMETYPE_xPREF = MFX_FRAMETYPE_xP | MFX_FRAMETYPE_xREF; 110 static const mfxU16 MFX_FRAMETYPE_xIREF = MFX_FRAMETYPE_xI | MFX_FRAMETYPE_xREF; 111 static const mfxU16 MFX_FRAMETYPE_KEYPIC = 0x0020; 112 113 static const mfxU16 MFX_IOPATTERN_IN_MASK_SYS_OR_D3D = 114 MFX_IOPATTERN_IN_SYSTEM_MEMORY | MFX_IOPATTERN_IN_VIDEO_MEMORY; 115 116 static const mfxU16 MFX_IOPATTERN_IN_MASK = 117 MFX_IOPATTERN_IN_MASK_SYS_OR_D3D | MFX_IOPATTERN_IN_OPAQUE_MEMORY; 118 119 // masks for VideoParam.mfx.CodecProfile 120 static const mfxU16 MASK_PROFILE_IDC = (0xff); 121 static const mfxU16 MASK_CONSTRAINT_SET0_FLAG = (0x100 << 0); 122 static const mfxU16 MASK_CONSTRAINT_SET1_FLAG = (0x100 << 1); 123 static const mfxU16 MASK_CONSTRAINT_SET2_FLAG = (0x100 << 2); 124 static const mfxU16 MASK_CONSTRAINT_SET3_FLAG = (0x100 << 3); 125 static const mfxU16 MASK_CONSTRAINT_SET4_FLAG = (0x100 << 4); 126 static const mfxU16 MASK_CONSTRAINT_SET5_FLAG = (0x100 << 5); 127 static const mfxU16 MASK_CONSTRAINT_SET6_FLAG = (0x100 << 6); 128 static const mfxU16 MASK_CONSTRAINT_SET7_FLAG = (0x100 << 7); 129 static const mfxU16 MASK_CONSTRAINT_SET0123_FLAG = MASK_CONSTRAINT_SET0_FLAG | MASK_CONSTRAINT_SET1_FLAG | MASK_CONSTRAINT_SET2_FLAG | MASK_CONSTRAINT_SET3_FLAG; 130 SecondHalfOf(std::vector<T> & v)131 template<class T> inline T* SecondHalfOf(std::vector<T>& v) { return &v[v.size() / 2]; } 132 Zero(T & obj)133 template<class T> inline void Zero(T & obj) { memset(reinterpret_cast<void*>(&obj), 0, sizeof(obj)); } Zero(std::vector<T> & vec)134 template<class T> inline void Zero(std::vector<T> & vec) { if (vec.size() > 0) memset(&vec[0], 0, sizeof(T) * vec.size()); } Zero(T * first,size_t cnt)135 template<class T> inline void Zero(T * first, size_t cnt) { memset(first, 0, sizeof(T) * cnt); } 136 Equal(T const & lhs,T const & rhs)137 template<class T> inline bool Equal(T const & lhs, T const & rhs) { return memcmp(&lhs, &rhs, sizeof(T)) == 0; } 138 Copy(T & dst,U const & src)139 template<class T, class U> inline void Copy(T & dst, U const & src) 140 { 141 static_assert(sizeof(T) == sizeof(U), "copy_objects_of_different_size"); 142 MFX_INTERNAL_CPY(&dst, &src, sizeof(dst)); 143 } 144 RemoveConst(T const & t)145 template<class T> inline T & RemoveConst(T const & t) { return const_cast<T &>(t); } 146 RemoveConst(T const * t)147 template<class T> inline T * RemoveConst(T const * t) { return const_cast<T *>(t); } 148 Begin(T (& t)[N])149 template<class T, size_t N> inline T * Begin(T(& t)[N]) { return t; } 150 End(T (& t)[N])151 template<class T, size_t N> inline T * End(T(& t)[N]) { return t + N; } 152 SizeOf(T (&)[N])153 template<class T, size_t N> inline size_t SizeOf(T(&)[N]) { return N; } 154 Begin(std::vector<T> const & t)155 template<class T> inline T const * Begin(std::vector<T> const & t) { return &*t.begin(); } 156 End(std::vector<T> const & t)157 template<class T> inline T const * End(std::vector<T> const & t) { return &*t.begin() + t.size(); } 158 Begin(std::vector<T> & t)159 template<class T> inline T * Begin(std::vector<T> & t) { return &*t.begin(); } 160 End(std::vector<T> & t)161 template<class T> inline T * End(std::vector<T> & t) { return &*t.begin() + t.size(); } 162 163 template<class T> struct ExtBufTypeToId {}; 164 165 #define BIND_EXTBUF_TYPE_TO_ID(TYPE, ID) template<> struct ExtBufTypeToId<TYPE> { enum { id = ID }; } 166 BIND_EXTBUF_TYPE_TO_ID (mfxExtCodingOption, MFX_EXTBUFF_CODING_OPTION ); 167 BIND_EXTBUF_TYPE_TO_ID (mfxExtCodingOptionSPSPPS, MFX_EXTBUFF_CODING_OPTION_SPSPPS ); 168 BIND_EXTBUF_TYPE_TO_ID (mfxExtCodingOptionDDI, MFX_EXTBUFF_DDI ); 169 BIND_EXTBUF_TYPE_TO_ID (mfxExtVideoSignalInfo, MFX_EXTBUFF_VIDEO_SIGNAL_INFO ); 170 BIND_EXTBUF_TYPE_TO_ID (mfxExtOpaqueSurfaceAlloc, MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION); 171 BIND_EXTBUF_TYPE_TO_ID (mfxExtMVCSeqDesc, MFX_EXTBUFF_MVC_SEQ_DESC ); 172 BIND_EXTBUF_TYPE_TO_ID (mfxExtMVCTargetViews, MFX_EXTBUFF_MVC_TARGET_VIEWS ); 173 BIND_EXTBUF_TYPE_TO_ID (mfxExtPictureTimingSEI, MFX_EXTBUFF_PICTURE_TIMING_SEI ); 174 BIND_EXTBUF_TYPE_TO_ID (mfxExtSpsHeader, MFX_EXTBUFF_SPS_HEADER ); 175 BIND_EXTBUF_TYPE_TO_ID (mfxExtPpsHeader, MFX_EXTBUFF_PPS_HEADER ); 176 BIND_EXTBUF_TYPE_TO_ID (mfxExtAVCRefListCtrl, MFX_EXTBUFF_AVC_REFLIST_CTRL ); 177 #if defined MFX_ENABLE_H264_ROUNDING_OFFSET 178 BIND_EXTBUF_TYPE_TO_ID (mfxExtAVCRoundingOffset, MFX_EXTBUFF_AVC_ROUNDING_OFFSET ); 179 #endif 180 BIND_EXTBUF_TYPE_TO_ID (mfxExtAvcTemporalLayers, MFX_EXTBUFF_AVC_TEMPORAL_LAYERS ); 181 BIND_EXTBUF_TYPE_TO_ID (mfxExtVppAuxData, MFX_EXTBUFF_VPP_AUXDATA ); 182 BIND_EXTBUF_TYPE_TO_ID (mfxExtCodingOption2, MFX_EXTBUFF_CODING_OPTION2 ); 183 BIND_EXTBUF_TYPE_TO_ID (mfxExtAVCEncodedFrameInfo, MFX_EXTBUFF_ENCODED_FRAME_INFO ); 184 BIND_EXTBUF_TYPE_TO_ID (mfxExtEncoderResetOption, MFX_EXTBUFF_ENCODER_RESET_OPTION ); 185 BIND_EXTBUF_TYPE_TO_ID (mfxExtEncoderCapability, MFX_EXTBUFF_ENCODER_CAPABILITY ); 186 BIND_EXTBUF_TYPE_TO_ID (mfxExtEncoderROI, MFX_EXTBUFF_ENCODER_ROI ); 187 BIND_EXTBUF_TYPE_TO_ID (mfxExtLAFrameStatistics, MFX_EXTBUFF_LOOKAHEAD_STAT ); 188 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiParam, MFX_EXTBUFF_FEI_PARAM ); 189 BIND_EXTBUF_TYPE_TO_ID (mfxExtAVCRefLists, MFX_EXTBUFF_AVC_REFLISTS ); 190 BIND_EXTBUF_TYPE_TO_ID (mfxExtCodingOption3, MFX_EXTBUFF_CODING_OPTION3 ); 191 BIND_EXTBUF_TYPE_TO_ID (mfxExtMBQP, MFX_EXTBUFF_MBQP ); 192 #if MFX_VERSION >= 1023 193 BIND_EXTBUF_TYPE_TO_ID (mfxExtMBForceIntra, MFX_EXTBUFF_MB_FORCE_INTRA ); 194 #endif 195 BIND_EXTBUF_TYPE_TO_ID (mfxExtChromaLocInfo, MFX_EXTBUFF_CHROMA_LOC_INFO ); 196 BIND_EXTBUF_TYPE_TO_ID (mfxExtMBDisableSkipMap, MFX_EXTBUFF_MB_DISABLE_SKIP_MAP ); 197 BIND_EXTBUF_TYPE_TO_ID (mfxExtPredWeightTable, MFX_EXTBUFF_PRED_WEIGHT_TABLE ); 198 BIND_EXTBUF_TYPE_TO_ID (mfxExtDirtyRect, MFX_EXTBUFF_DIRTY_RECTANGLES ); 199 BIND_EXTBUF_TYPE_TO_ID (mfxExtMoveRect, MFX_EXTBUFF_MOVING_RECTANGLES ); 200 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiCodingOption, MFX_EXTBUFF_FEI_CODING_OPTION ); 201 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiEncMV, MFX_EXTBUFF_FEI_ENC_MV ); 202 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiEncMBStat, MFX_EXTBUFF_FEI_ENC_MB_STAT ); 203 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiPakMBCtrl, MFX_EXTBUFF_FEI_PAK_CTRL ); 204 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiEncFrameCtrl, MFX_EXTBUFF_FEI_ENC_CTRL ); 205 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiEncMVPredictors, MFX_EXTBUFF_FEI_ENC_MV_PRED ); 206 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiEncMBCtrl, MFX_EXTBUFF_FEI_ENC_MB ); 207 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiEncQP, MFX_EXTBUFF_FEI_ENC_QP ); 208 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiSPS, MFX_EXTBUFF_FEI_SPS ); 209 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiPPS, MFX_EXTBUFF_FEI_PPS ); 210 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiSliceHeader, MFX_EXTBUFF_FEI_SLICE ); 211 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiPreEncMV, MFX_EXTBUFF_FEI_PREENC_MV ); 212 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiPreEncMBStat, MFX_EXTBUFF_FEI_PREENC_MB ); 213 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiPreEncCtrl, MFX_EXTBUFF_FEI_PREENC_CTRL ); 214 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiPreEncMVPredictors,MFX_EXTBUFF_FEI_PREENC_MV_PRED ); 215 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiRepackCtrl, MFX_EXTBUFF_FEI_REPACK_CTRL ); 216 #if (MFX_VERSION >= 1025) 217 BIND_EXTBUF_TYPE_TO_ID (mfxExtFeiRepackStat, MFX_EXTBUFF_FEI_REPACK_STAT ); 218 #endif 219 #if defined (__MFXBRC_H__) 220 BIND_EXTBUF_TYPE_TO_ID (mfxExtBRC, MFX_EXTBUFF_BRC ); 221 #endif 222 223 #ifdef MFX_ENABLE_MFE 224 BIND_EXTBUF_TYPE_TO_ID (mfxExtMultiFrameControl, MFX_EXTBUFF_MULTI_FRAME_CONTROL ); 225 BIND_EXTBUF_TYPE_TO_ID (mfxExtMultiFrameParam, MFX_EXTBUFF_MULTI_FRAME_PARAM ); 226 #endif 227 #if defined (MFX_ENABLE_ENCTOOLS) 228 BIND_EXTBUF_TYPE_TO_ID(mfxEncTools, MFX_EXTBUFF_ENCTOOLS); 229 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsBRCFrameParams, MFX_EXTBUFF_ENCTOOLS_BRC_FRAME_PARAM); 230 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsBRCQuantControl, MFX_EXTBUFF_ENCTOOLS_BRC_QUANT_CONTROL); 231 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsBRCHRDPos, MFX_EXTBUFF_ENCTOOLS_BRC_HRD_POS); 232 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsBRCEncodeResult, MFX_EXTBUFF_ENCTOOLS_BRC_ENCODE_RESULT); 233 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsBRCStatus, MFX_EXTBUFF_ENCTOOLS_BRC_STATUS); 234 BIND_EXTBUF_TYPE_TO_ID(mfxExtEncToolsConfig, MFX_EXTBUFF_ENCTOOLS_CONFIG); 235 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsCtrlExtDevice, MFX_EXTBUFF_ENCTOOLS_DEVICE); 236 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsCtrlExtAllocator, MFX_EXTBUFF_ENCTOOLS_ALLOCATOR); 237 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsFrameToAnalyze, MFX_EXTBUFF_ENCTOOLS_FRAME_TO_ANALYZE); 238 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsHintPreEncodeSceneChange, MFX_EXTBUFF_ENCTOOLS_HINT_SCENE_CHANGE); 239 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsHintPreEncodeGOP, MFX_EXTBUFF_ENCTOOLS_HINT_GOP); 240 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsHintPreEncodeARefFrames, MFX_EXTBUFF_ENCTOOLS_HINT_AREF); 241 BIND_EXTBUF_TYPE_TO_ID(mfxEncToolsBRCBufferHint, MFX_EXTBUFF_ENCTOOLS_BRC_BUFFER_HINT); 242 243 #endif 244 245 #undef BIND_EXTBUF_TYPE_TO_ID 246 InitExtBufHeader(T & extBuf)247 template <class T> inline void InitExtBufHeader(T & extBuf) 248 { 249 Zero(extBuf); 250 extBuf.Header.BufferId = ExtBufTypeToId<T>::id; 251 extBuf.Header.BufferSz = sizeof(T); 252 } 253 254 template <> inline void InitExtBufHeader<mfxExtVideoSignalInfo>(mfxExtVideoSignalInfo & extBuf) 255 { 256 Zero(extBuf); 257 extBuf.Header.BufferId = ExtBufTypeToId<mfxExtVideoSignalInfo>::id; 258 extBuf.Header.BufferSz = sizeof(mfxExtVideoSignalInfo); 259 260 // set default values 261 extBuf.VideoFormat = 5; // unspecified video format 262 extBuf.VideoFullRange = 0; 263 extBuf.ColourDescriptionPresent = 0; 264 extBuf.ColourPrimaries = 2; // unspecified 265 extBuf.TransferCharacteristics = 2; // unspecified 266 extBuf.MatrixCoefficients = 2; // unspecified 267 } 268 269 template <> inline void InitExtBufHeader<mfxExtAVCRefListCtrl>(mfxExtAVCRefListCtrl & extBuf) 270 { 271 Zero(extBuf); 272 extBuf.Header.BufferId = ExtBufTypeToId<mfxExtAVCRefListCtrl>::id; 273 extBuf.Header.BufferSz = sizeof(mfxExtAVCRefListCtrl); 274 275 for (mfxU32 i = 0; i < 32; i++) 276 extBuf.PreferredRefList[i].FrameOrder = mfxU32(MFX_FRAMEORDER_UNKNOWN); 277 for (mfxU32 i = 0; i < 16; i++) 278 extBuf.RejectedRefList[i].FrameOrder = mfxU32(MFX_FRAMEORDER_UNKNOWN); 279 for (mfxU32 i = 0; i < 16; i++) 280 extBuf.LongTermRefList[i].FrameOrder = mfxU32(MFX_FRAMEORDER_UNKNOWN); 281 } 282 #if defined(MFX_ENABLE_ENCTOOLS) 283 template <> inline void InitExtBufHeader<mfxExtEncToolsConfig>(mfxExtEncToolsConfig & extBuf) 284 { 285 Zero(extBuf); 286 extBuf.Header.BufferId = ExtBufTypeToId<mfxExtEncToolsConfig>::id; 287 extBuf.Header.BufferSz = sizeof(mfxExtEncToolsConfig); 288 289 extBuf.AdaptiveI = 290 extBuf.AdaptiveB = 291 extBuf.AdaptiveRefP = 292 extBuf.AdaptiveRefB = 293 extBuf.SceneChange = 294 extBuf.AdaptiveLTR = 295 extBuf.AdaptivePyramidQuantP = 296 extBuf.AdaptivePyramidQuantB = 297 extBuf.AdaptiveQuantMatrices = 298 extBuf.BRCBufferHints = 299 extBuf.BRC = MFX_CODINGOPTION_OFF; 300 } 301 #endif 302 template <class T> struct GetPointedType {}; 303 template <class T> struct GetPointedType<T *> { typedef T Type; }; 304 template <class T> struct GetPointedType<T const *> { typedef T Type; }; 305 306 struct HrdParameters 307 { 308 mfxU8 cpbCntMinus1; 309 mfxU8 bitRateScale; 310 mfxU8 cpbSizeScale; 311 mfxU32 bitRateValueMinus1[32]; 312 mfxU32 cpbSizeValueMinus1[32]; 313 mfxU8 cbrFlag[32]; 314 mfxU8 initialCpbRemovalDelayLengthMinus1; 315 mfxU8 cpbRemovalDelayLengthMinus1; 316 mfxU8 dpbOutputDelayLengthMinus1; 317 mfxU8 timeOffsetLength; 318 }; 319 320 struct VuiParameters 321 { 322 struct 323 { 324 mfxU16 aspectRatioInfoPresent : 1; 325 mfxU16 overscanInfoPresent : 1; 326 mfxU16 overscanAppropriate : 1; 327 mfxU16 videoSignalTypePresent : 1; 328 mfxU16 videoFullRange : 1; 329 mfxU16 colourDescriptionPresent : 1; 330 mfxU16 chromaLocInfoPresent : 1; 331 mfxU16 timingInfoPresent : 1; 332 mfxU16 fixedFrameRate : 1; 333 mfxU16 nalHrdParametersPresent : 1; 334 mfxU16 vclHrdParametersPresent : 1; 335 mfxU16 lowDelayHrd : 1; 336 mfxU16 picStructPresent : 1; 337 mfxU16 bitstreamRestriction : 1; 338 mfxU16 motionVectorsOverPicBoundaries : 1; 339 mfxU16 reserved : 1; 340 } flags; 341 342 mfxU8 aspectRatioIdc; 343 mfxU16 sarWidth; 344 mfxU16 sarHeight; 345 mfxU8 videoFormat; 346 mfxU8 colourPrimaries; 347 mfxU8 transferCharacteristics; 348 mfxU8 matrixCoefficients; 349 mfxU8 chromaSampleLocTypeTopField; 350 mfxU8 chromaSampleLocTypeBottomField; 351 mfxU32 numUnitsInTick; 352 mfxU32 timeScale; 353 354 HrdParameters nalHrdParameters; 355 HrdParameters vclHrdParameters; 356 357 mfxU8 maxBytesPerPicDenom; 358 mfxU8 maxBitsPerMbDenom; 359 mfxU8 log2MaxMvLengthHorizontal; 360 mfxU8 log2MaxMvLengthVertical; 361 mfxU8 numReorderFrames; 362 mfxU8 maxDecFrameBuffering; 363 }; 364 365 struct mfxExtSpsHeader 366 { 367 mfxExtBuffer Header; 368 369 mfxU8 nalRefIdc; 370 mfxU8 nalUnitType; 371 mfxU8 profileIdc; 372 373 struct 374 { 375 mfxU8 set0 : 1; 376 mfxU8 set1 : 1; 377 mfxU8 set2 : 1; 378 mfxU8 set3 : 1; 379 mfxU8 set4 : 1; 380 mfxU8 set5 : 1; 381 mfxU8 set6 : 2; 382 mfxU8 set7 : 2; 383 } constraints; 384 385 mfxU8 levelIdc; 386 mfxU8 seqParameterSetId; 387 mfxU8 chromaFormatIdc; 388 mfxU8 separateColourPlaneFlag; 389 mfxU8 bitDepthLumaMinus8; 390 mfxU8 bitDepthChromaMinus8; 391 mfxU8 qpprimeYZeroTransformBypassFlag; 392 mfxU8 seqScalingMatrixPresentFlag; 393 mfxU8 seqScalingListPresentFlag[12]; 394 mfxU8 scalingList4x4[6][16]; 395 mfxU8 scalingList8x8[6][64]; 396 397 mfxU8 log2MaxFrameNumMinus4; 398 mfxU8 picOrderCntType; 399 mfxU8 log2MaxPicOrderCntLsbMinus4; 400 mfxU8 deltaPicOrderAlwaysZeroFlag; 401 mfxI32 offsetForNonRefPic; 402 mfxI32 offsetForTopToBottomField; 403 mfxU8 numRefFramesInPicOrderCntCycle; 404 mfxI32 offsetForRefFrame[256]; 405 406 mfxU8 maxNumRefFrames; 407 mfxU8 gapsInFrameNumValueAllowedFlag; 408 mfxU16 picWidthInMbsMinus1; 409 mfxU16 picHeightInMapUnitsMinus1; 410 mfxU8 frameMbsOnlyFlag; 411 mfxU8 mbAdaptiveFrameFieldFlag; 412 mfxU8 direct8x8InferenceFlag; 413 mfxU8 frameCroppingFlag; 414 mfxU32 frameCropLeftOffset; 415 mfxU32 frameCropRightOffset; 416 mfxU32 frameCropTopOffset; 417 mfxU32 frameCropBottomOffset; 418 mfxU8 vuiParametersPresentFlag; 419 420 VuiParameters vui; 421 }; 422 423 bool operator ==(mfxExtSpsHeader const & lhs, mfxExtSpsHeader const & rhs); 424 425 template <> inline bool Equal<mfxExtSpsHeader>(mfxExtSpsHeader const & lhs, mfxExtSpsHeader const & rhs) 426 { 427 return lhs == rhs; 428 } 429 430 struct mfxExtSpsSvcHeader 431 { 432 mfxExtBuffer Header; 433 434 mfxU8 interLayerDeblockingFilterControlPresentFlag; 435 mfxU8 extendedSpatialScalabilityIdc; 436 mfxU8 chromaPhaseXPlus1Flag; 437 mfxU8 chromaPhaseYPlus1; 438 mfxU8 seqRefLayerChromaPhaseXPlus1Flag; 439 mfxU8 seqRefLayerChromaPhaseYPlus1; 440 mfxI16 seqScaledRefLayerLeftOffset; 441 mfxI16 seqScaledRefLayerTopOffset; 442 mfxI16 seqScaledRefLayerRightOffset; 443 mfxI16 seqScaledRefLayerBottomOffset; 444 mfxU8 seqTcoeffLevelPredictionFlag; 445 mfxU8 adaptiveTcoeffLevelPredictionFlag; 446 mfxU8 sliceHeaderRestrictionFlag; 447 }; 448 449 450 union SliceGroupInfo 451 { 452 struct 453 { 454 mfxU32 runLengthMinus1[8]; 455 } t0; 456 457 struct 458 { 459 mfxU32 topLeft[7]; 460 mfxU32 bottomRight[7]; 461 } t2; 462 463 struct 464 { 465 mfxU8 sliceGroupChangeDirectionFlag; 466 mfxU32 sliceGroupChangeRate; 467 } t3; 468 469 struct 470 { 471 mfxU32 picSizeInMapUnitsMinus1; 472 } t6; 473 }; 474 475 template <> inline void InitExtBufHeader<mfxExtSpsHeader>(mfxExtSpsHeader & extBuf) 476 { 477 Zero(extBuf); 478 extBuf.Header.BufferId = ExtBufTypeToId<mfxExtSpsHeader>::id; 479 extBuf.Header.BufferSz = sizeof (mfxExtSpsHeader); 480 481 // set default non-zero values 482 extBuf.chromaFormatIdc = 1; 483 extBuf.vuiParametersPresentFlag = 1; 484 extBuf.vui.flags.nalHrdParametersPresent = 1; 485 extBuf.vui.flags.timingInfoPresent = 1; 486 extBuf.vui.flags.fixedFrameRate = 1; 487 } 488 489 struct mfxExtPpsHeader 490 { 491 mfxExtBuffer Header; 492 493 mfxU8 nalRefIdc; 494 mfxU8 picParameterSetId; 495 mfxU8 seqParameterSetId; 496 mfxU8 entropyCodingModeFlag; 497 mfxU8 bottomFieldPicOrderInframePresentFlag; 498 mfxU8 numSliceGroupsMinus1; 499 mfxU8 sliceGroupMapType; 500 501 SliceGroupInfo sliceGroupInfo; 502 503 mfxU8 numRefIdxL0DefaultActiveMinus1; 504 mfxU8 numRefIdxL1DefaultActiveMinus1; 505 mfxU8 weightedPredFlag; 506 mfxU8 weightedBipredIdc; 507 mfxI8 picInitQpMinus26; 508 mfxI8 picInitQsMinus26; 509 mfxI8 chromaQpIndexOffset; 510 mfxU8 deblockingFilterControlPresentFlag; 511 mfxU8 constrainedIntraPredFlag; 512 mfxU8 redundantPicCntPresentFlag; 513 mfxU8 transform8x8ModeFlag; 514 mfxU8 picScalingMatrixPresentFlag; 515 mfxI8 secondChromaQpIndexOffset; 516 bool moreRbspData; 517 518 mfxU8 scalingList4x4[6][16]; 519 mfxU8 scalingList8x8[6][64]; 520 bool picScalingListPresentFlag[12]; 521 }; 522 523 struct mfxRoiDesc{ 524 mfxU32 Left; 525 mfxU32 Top; 526 mfxU32 Right; 527 mfxU32 Bottom; 528 529 mfxI16 ROIValue; 530 }; 531 532 struct mfxRectDesc{ 533 mfxU32 Left; 534 mfxU32 Top; 535 mfxU32 Right; 536 mfxU32 Bottom; 537 }; 538 539 struct mfxMovingRectDesc{ 540 mfxU32 DestLeft; 541 mfxU32 DestTop; 542 mfxU32 DestRight; 543 mfxU32 DestBottom; 544 545 mfxU32 SourceLeft; 546 mfxU32 SourceTop; 547 }; 548 549 class MfxVideoParam : public mfxVideoParam 550 { 551 public: 552 MfxVideoParam(); 553 MfxVideoParam(MfxVideoParam const &); 554 MfxVideoParam(mfxVideoParam const &); 555 556 MfxVideoParam & operator = (MfxVideoParam const &); 557 MfxVideoParam & operator = (mfxVideoParam const &); 558 559 void SyncVideoToCalculableParam(); 560 561 void SyncCalculableToVideoParam(); 562 563 void AlignCalcWithBRCParamMultiplier(); 564 565 void ApplyDefaultsToMvcSeqDesc(); 566 567 568 protected: 569 void Construct(mfxVideoParam const & par); 570 571 void ConstructMvcSeqDesc(mfxExtMVCSeqDesc const & desc); 572 573 private: 574 #if defined(MFX_ENABLE_ENCTOOLS) 575 mfxExtBuffer * m_extParam[40]; 576 #else 577 mfxExtBuffer * m_extParam[32]; 578 #endif 579 // external, documented 580 mfxExtCodingOption m_extOpt; 581 mfxExtCodingOption2 m_extOpt2; 582 mfxExtCodingOption3 m_extOpt3; 583 mfxExtCodingOptionSPSPPS m_extOptSpsPps; 584 mfxExtVideoSignalInfo m_extVideoSignal; 585 mfxExtOpaqueSurfaceAlloc m_extOpaque; 586 mfxExtMVCSeqDesc m_extMvcSeqDescr; 587 mfxExtPictureTimingSEI m_extPicTiming; 588 mfxExtAvcTemporalLayers m_extTempLayers; 589 mfxExtEncoderResetOption m_extEncResetOpt; 590 mfxExtEncoderROI m_extEncRoi; 591 mfxExtFeiParam m_extFeiParam; 592 mfxExtChromaLocInfo m_extChromaLoc; 593 mfxExtPredWeightTable m_extPwt; 594 mfxExtDirtyRect m_extDirtyRect; 595 mfxExtMoveRect m_extMoveRect; 596 597 mfxExtCodingOptionDDI m_extOptDdi; 598 mfxExtSpsHeader m_extSps; 599 mfxExtPpsHeader m_extPps; 600 601 mfxExtFeiCodingOption m_extFeiOpt; 602 mfxExtFeiSliceHeader m_extFeiSlice[2]; 603 mfxExtFeiSPS m_extFeiSPS; 604 mfxExtFeiPPS m_extFeiPPS; 605 606 #if defined(__MFXBRC_H__) 607 mfxExtBRC m_extBRC; 608 #endif 609 #if defined(MFX_ENABLE_ENCTOOLS) 610 mfxEncTools m_encTools; 611 mfxExtEncToolsConfig m_encToolsConfig; 612 mfxEncToolsCtrlExtDevice m_extDevice; 613 mfxEncToolsCtrlExtAllocator m_extAllocator; 614 #endif 615 #if defined (MFX_ENABLE_MFE) 616 mfxExtMultiFrameParam m_MfeParam; 617 mfxExtMultiFrameControl m_MfeControl; 618 #endif 619 std::vector<mfxMVCViewDependency> m_storageView; 620 std::vector<mfxMVCOperationPoint> m_storageOp; 621 std::vector<mfxU16> m_storageViewId; 622 623 public: 624 struct CalculableParam 625 { 626 mfxU32 bufferSizeInKB; 627 mfxU32 initialDelayInKB; 628 mfxU32 targetKbps; 629 mfxU32 maxKbps; 630 mfxU32 WinBRCMaxAvgKbps; 631 632 mfxU32 numTemporalLayer; 633 mfxU32 tid[8]; 634 mfxU32 scale[8]; 635 636 // MVC BD { 637 struct 638 { 639 mfxU32 bufferSizeInKB; 640 mfxU32 initialDelayInKB; 641 mfxU32 targetKbps; 642 mfxU32 maxKbps; 643 mfxU16 codecLevel; 644 } mvcPerViewPar; 645 // MVC BD } 646 mfxU32 numDependencyLayer; 647 mfxU32 did[8]; 648 mfxU32 numLayersTotal; 649 mfxU32 numLayerOffset[8]; 650 mfxU32 dqId1Exists; 651 mfxU32 tempScalabilityMode; 652 mfxU32 cqpHrdMode; // special CQP mode in which HRD information is written into bitstreams: 0 - disabled, 1 -CBR, 2 - VBR 653 struct 654 { 655 mfxU32 bufferSizeInKB; 656 mfxU32 initialDelayInKB; 657 mfxU32 targetKbps; 658 mfxU32 maxKbps; 659 } decorativeHrdParam; // decorative HRD parameters for cqpHrdMode 660 661 mfxU16 widthLa; 662 mfxU16 heightLa; 663 mfxU32 TCBRCTargetFrameSize; 664 mfxU32 PPyrInterval; 665 } calcParam; 666 }; 667 668 bool isSWBRC (MfxVideoParam const & par); 669 bool isAdaptiveQP(MfxVideoParam const & par); 670 mfxU16 GetMaxNumSlices(MfxVideoParam const & par); 671 672 mfxU16 GetNumSurfInput(MfxVideoParam const & video); 673 674 mfxU8 GetNumReorderFrames(MfxVideoParam const & video); 675 676 mfxU32 CalcNumSurfRaw(MfxVideoParam const & video); 677 678 mfxU32 CalcNumSurfRecon(MfxVideoParam const & video); 679 680 mfxU32 CalcNumSurfBitstream(MfxVideoParam const & video); 681 682 mfxU32 CalcNumTasks(MfxVideoParam const & video); 683 684 mfxI64 CalcDTSFromPTS( 685 mfxFrameInfo const & info, 686 mfxU16 dpbOutputDelay, 687 mfxU64 timeStamp); 688 689 #define SCALE_FROM_DRIVER 4 // driver hardcodes scale 4. Need to use this value in MSDK. Otherwise BRC and MSDK HRD calculations will diverge. 690 691 mfxU32 GetMaxBitrateValue( 692 mfxU32 kbps, 693 mfxU32 scale = SCALE_FROM_DRIVER); 694 695 mfxU8 GetCabacInitIdc(mfxU32 targetUsage); 696 697 bool IsLookAheadSupported( 698 MfxVideoParam const & video, 699 eMFXHWType platform); 700 bool IsMctfSupported( 701 MfxVideoParam const & video); 702 703 mfxU32 GetPPyrSize( 704 MfxVideoParam const & video, 705 mfxU32 miniGopSize, 706 bool bEncToolsLA); 707 708 bool IsExtBrcSceneChangeSupported( 709 MfxVideoParam const & video); 710 711 bool IsCmNeededForSCD( 712 MfxVideoParam const & video); 713 714 bool IsAdaptiveLtrOn( 715 MfxVideoParam const & video); 716 717 mfxU8 DetermineQueryMode(mfxVideoParam * in); 718 719 mfxStatus SetLowPowerDefault( 720 MfxVideoParam& par, 721 const eMFXHWType& platform); 722 723 mfxStatus QueryHwCaps( 724 VideoCORE * core, 725 MFX_ENCODE_CAPS & hwCaps, 726 mfxVideoParam * par); 727 728 mfxStatus QueryMbProcRate( 729 VideoCORE* core, 730 mfxVideoParam const & out, 731 mfxU32 (&mbPerSec)[16], 732 const mfxVideoParam * in); 733 734 mfxStatus QueryGuid( 735 VideoCORE* core, 736 GUID guid); 737 738 mfxStatus ReadSpsPpsHeaders(MfxVideoParam & par); 739 740 mfxU16 GetFrameWidth(MfxVideoParam & par); 741 742 mfxU16 GetFrameHeight(MfxVideoParam & par); 743 744 mfxStatus CorrectCropping( 745 MfxVideoParam & par); 746 747 bool IsRunTimeOnlyExtBuffer( 748 mfxU32 id); 749 750 bool IsRunTimeExtBufferIdSupported( 751 MfxVideoParam const & video, mfxU32 id); 752 753 bool IsRuntimeOutputExtBufferIdSupported( 754 MfxVideoParam const & video, mfxU32 id); 755 756 bool IsRunTimeExtBufferPairAllowed( 757 MfxVideoParam const & video, mfxU32 id); 758 759 bool IsRunTimeExtBufferPairRequired( 760 MfxVideoParam const & video, mfxU32 id); 761 762 bool IsVideoParamExtBufferIdSupported( 763 mfxU32 id); 764 765 mfxStatus CheckExtBufferId( 766 mfxVideoParam const & par); 767 768 769 mfxStatus CheckWidthAndHeight( 770 MfxVideoParam const & par); 771 772 mfxStatus CopySpsPpsToVideoParam( 773 MfxVideoParam & par); 774 775 mfxStatus CheckForAllowedH264SpecViolations( 776 MfxVideoParam const & par); 777 778 mfxStatus CheckAndFixRectQueryLike( 779 MfxVideoParam const & par, 780 mfxRectDesc * rect); 781 782 mfxStatus CheckAndFixOpenRectQueryLike( 783 MfxVideoParam const & par, 784 mfxRectDesc * rect); 785 786 mfxStatus CheckAndFixRoiQueryLike( 787 MfxVideoParam const & par, 788 mfxRoiDesc * roi, 789 mfxU16 roiMode); 790 791 mfxStatus CheckAndFixMovingRectQueryLike( 792 MfxVideoParam const & par, 793 mfxMovingRectDesc * rect); 794 795 796 mfxStatus CheckVideoParam( 797 MfxVideoParam & par, 798 MFX_ENCODE_CAPS const & hwCaps, 799 bool setExtAlloc, 800 eMFXHWType platform = MFX_HW_UNKNOWN, 801 eMFXVAType vaType = MFX_HW_NO, 802 eMFXGTConfig config = MFX_GT_UNKNOWN, 803 bool bInit = false); 804 805 mfxStatus CheckVideoParamFEI( 806 MfxVideoParam & par); 807 808 mfxStatus CheckVideoParamQueryLike( 809 MfxVideoParam & par, 810 MFX_ENCODE_CAPS const & hwCaps, 811 eMFXHWType platform = MFX_HW_UNKNOWN, 812 eMFXVAType vaType = MFX_HW_NO, 813 eMFXGTConfig config = MFX_GT_UNKNOWN); 814 815 mfxStatus CheckVideoParamMvcQueryLike(MfxVideoParam & par); 816 817 mfxStatus CheckMVCSeqDescQueryLike(mfxExtMVCSeqDesc * mvcSeqDesc); 818 819 mfxStatus CheckAndFixMVCSeqDesc(mfxExtMVCSeqDesc * mvcSeqDesc, bool isViewOutput); 820 821 void SetDefaults( 822 MfxVideoParam & par, 823 MFX_ENCODE_CAPS const & hwCaps, 824 bool setExtAlloc, 825 eMFXHWType platform = MFX_HW_UNKNOWN, 826 eMFXVAType vaType = MFX_HW_NO, 827 eMFXGTConfig config = MFX_GT_UNKNOWN); 828 829 void InheritDefaultValues( 830 MfxVideoParam const & parInit, 831 MfxVideoParam & parReset, 832 MFX_ENCODE_CAPS const & hwCaps, 833 mfxVideoParam const * parResetIn = 0); 834 835 mfxStatus CheckPayloads( 836 mfxPayload const * const * payload, 837 mfxU16 numPayload); 838 839 mfxStatus CheckRunTimeExtBuffers( 840 MfxVideoParam const & video, 841 mfxEncodeCtrl * ctrl, 842 mfxFrameSurface1 * surface, 843 mfxBitstream * bs, 844 MFX_ENCODE_CAPS const & caps, 845 eMFXHWType platform = MFX_HW_UNKNOWN); 846 847 mfxStatus CheckFEIRunTimeExtBuffersContent( 848 MfxVideoParam const & video, 849 mfxEncodeCtrl * ctrl, 850 mfxFrameSurface1 * surface, 851 mfxBitstream * bs); 852 853 mfxStatus CheckRunTimePicStruct( 854 mfxU16 runtPicStruct, 855 mfxU16 initPicStruct); 856 857 bool IsRecoveryPointSeiMessagePresent( 858 mfxPayload const * const * payload, 859 mfxU16 numPayload, 860 mfxU32 payloadLayout); 861 862 mfxStatus CopyFrameDataBothFields( 863 VideoCORE * core, 864 mfxFrameData const & dst, 865 mfxFrameData const & src, 866 mfxFrameInfo const & info); 867 868 mfxExtBuffer * GetExtBuffer( 869 mfxExtBuffer ** extBuf, 870 mfxU32 numExtBuf, 871 mfxU32 id, 872 mfxU32 offset = 0); 873 struct mfxExtBufferProxy; 874 struct mfxExtBufferRefProxy; 875 template <typename T> mfxExtBufferProxy GetExtBuffer(const T & par, mfxU32 fieldId = 0); 876 template <typename T> mfxExtBufferProxy GetExtBufferFEI(const T & bs, mfxU32 fieldId = 0); 877 template <typename T> mfxExtBufferRefProxy GetExtBufferRef(const T & par, mfxU32 fieldId = 0); 878 879 struct mfxExtBufferProxy 880 { 881 public: 882 template <typename T> operator T() 883 { 884 mfxExtBuffer * p = MfxHwH264Encode::GetExtBuffer( 885 m_extParam, 886 m_numExtParam, 887 ExtBufTypeToId<typename GetPointedType<T>::Type>::id, 888 m_fieldId); 889 return reinterpret_cast<T>(p); 890 } 891 892 template <typename T> friend mfxExtBufferProxy GetExtBuffer(const T & par, mfxU32 fieldId) 893 { 894 return mfxExtBufferProxy(par.ExtParam, par.NumExtParam, fieldId); 895 } 896 template <typename T> friend mfxExtBufferProxy GetExtBufferFEI(const T & bs, mfxU32 fieldId) 897 { 898 return mfxExtBufferProxy(bs->ExtParam, bs->NumExtParam, fieldId); 899 } 900 901 protected: 902 mfxExtBufferProxy(mfxExtBuffer ** extParam, mfxU32 numExtParam, mfxU32 fieldId = 0) 903 : m_extParam(extParam) 904 , m_numExtParam(numExtParam) 905 , m_fieldId(fieldId) 906 { 907 } 908 909 private: 910 mfxExtBuffer ** m_extParam; 911 mfxU32 m_numExtParam; 912 mfxU32 m_fieldId; 913 }; 914 915 // version with assert, special for extract extBuffer from wrapper MfxVideoParam 916 struct mfxExtBufferRefProxy{ 917 public: 918 template <typename T> operator T&() 919 { 920 mfxExtBuffer * p = MfxHwH264Encode::GetExtBuffer( 921 m_extParam, 922 m_numExtParam, 923 ExtBufTypeToId<typename GetPointedType<T*>::Type>::id, 924 m_fieldId); 925 assert(p); 926 return *(reinterpret_cast<T*>(p)); 927 } 928 929 // Intention of GetExtBufferRef is to get ext buffers 930 // from MfxVideoParam structure which always has full set 931 // of extension buffers ("MfxHwH264Encode::GetExtBuffer" can't return zero). 932 // 933 // So, for MfxVideoParam it's better to use function GetExtBufferRef() 934 // instead GetExtBuffer(), we can wrap issues from static code analyze 935 // to one place (body of function GetExtBufferRef()) instead several 936 // places (every calling GetExtBuffer()) 937 template <typename T> friend mfxExtBufferRefProxy GetExtBufferRef(const T & par, mfxU32 fieldId) 938 { 939 return mfxExtBufferRefProxy(par.ExtParam, par.NumExtParam, fieldId); 940 } 941 942 protected: 943 mfxExtBufferRefProxy(mfxExtBuffer ** extParam, mfxU32 numExtParam, mfxU32 fieldId = 0) 944 : m_extParam(extParam) 945 , m_numExtParam(numExtParam) 946 , m_fieldId(fieldId) 947 { 948 } 949 950 private: 951 mfxExtBuffer ** m_extParam; 952 mfxU32 m_numExtParam; 953 mfxU32 m_fieldId; 954 }; 955 956 inline bool IsFieldCodingPossible(MfxVideoParam const & par) 957 { 958 return (par.mfx.FrameInfo.PicStruct & MFX_PICSTRUCT_PROGRESSIVE) == 0; 959 } 960 961 inline void ResetNumSliceIPB(mfxVideoParam &par) 962 { 963 mfxExtCodingOption3 * extOpt3 = GetExtBuffer(par); 964 if(extOpt3 != nullptr && (extOpt3->NumSliceI == 0 || extOpt3->NumSliceP == 0 || extOpt3->NumSliceB == 0)){ 965 extOpt3->NumSliceI = extOpt3->NumSliceP = extOpt3->NumSliceB = par.mfx.NumSlice; 966 } 967 } 968 969 inline mfxU32 GetAvgFrameSizeInBytes(const MfxVideoParam & par, bool bMaxKbps) 970 { 971 return mfxU32(1000.0 / 8.0*((par.mfx.MaxKbps && bMaxKbps) ? par.mfx.MaxKbps : par.mfx.TargetKbps) * std::max<mfxU32>(par.mfx.BRCParamMultiplier,1) / 972 (mfxF64(par.mfx.FrameInfo.FrameRateExtN) / par.mfx.FrameInfo.FrameRateExtD) ); 973 } 974 inline bool IsTCBRC(const MfxVideoParam & par, MFX_ENCODE_CAPS const & hwCaps) 975 { 976 mfxExtCodingOption3 &extOpt3 = GetExtBufferRef(par); 977 mfxExtCodingOption &extOpt = GetExtBufferRef(par); 978 return (IsOn(extOpt3.LowDelayBRC) && (hwCaps.ddi_caps.TCBRCSupport) && IsOff(extOpt.NalHrdConformance) && 979 (par.mfx.RateControlMethod == MFX_RATECONTROL_VBR || 980 par.mfx.RateControlMethod == MFX_RATECONTROL_QVBR || 981 par.mfx.RateControlMethod == MFX_RATECONTROL_VCM )); 982 } 983 984 inline mfxU8 GetPayloadLayout(mfxU32 fieldPicFlag, mfxU32 secondFieldPicFlag) 985 { 986 return fieldPicFlag == 0 987 ? 0 /* MFX_PAYLOAD_LAYOUT_ALL */ 988 : secondFieldPicFlag == 0 989 ? 1 /* MFX_PAYLOAD_LAYOUT_EVEN */ 990 : 2 /* MFX_PAYLOAD_LAYOUT_ODD */; 991 } 992 993 inline mfxU8 GetPayloadLayout(const mfxFrameParam& fp) 994 { 995 return GetPayloadLayout(fp.AVC.FieldPicFlag, fp.AVC.SecondFieldPicFlag); 996 } 997 998 inline bool IsDriverSliceSizeControlEnabled(const MfxVideoParam & par, MFX_ENCODE_CAPS const & hwCaps) 999 { 1000 return IsOn(par.mfx.LowPower) && hwCaps.ddi_caps.SliceLevelRateCtrl; 1001 } 1002 1003 mfxU8 ConvertFrameTypeMfx2Ddi(mfxU32 type); 1004 1005 mfxU8 ConvertMfxFrameType2SliceType(mfxU8 type); 1006 1007 ENCODE_FRAME_SIZE_TOLERANCE ConvertLowDelayBRCMfx2Ddi(mfxU16 type, bool bTCBRC); 1008 1009 enum class SliceDividerType 1010 { 1011 ONESLICE = 0, // Once slice for the whole frame 1012 ROW2ROW = 1, // Slices are power of 2 number of rows, all slices the same 1013 ROWSLICE = 2, // Slices are any number of rows, all slices the same 1014 ARBITRARY_ROW_SLICE = 3, // Slices are any number of rows, slices can be different 1015 ARBITRARY_MB_SLICE = 4, // Slices are any number of MBs, slices can be different 1016 }; 1017 1018 struct MfxMemId 1019 { 1020 public: 1021 MfxMemId() 1022 : mid(0) 1023 , external(false) 1024 {} 1025 1026 MfxMemId(mfxMemId mid_, bool external_) 1027 : mid(mid_) 1028 , external(external_) 1029 {} 1030 1031 mfxMemId mid; 1032 bool external; 1033 }; 1034 1035 inline mfxU32 CeilLog2(mfxU32 val) 1036 { 1037 mfxU32 res = 0; 1038 1039 while (val) 1040 { 1041 val >>= 1; 1042 res++; 1043 } 1044 1045 return res; 1046 } 1047 1048 inline mfxU32 ExpGolombCodeLength(mfxU32 val) 1049 { 1050 return 1051 CeilLog2(val + 1) * 2 - 1; 1052 } 1053 1054 // auto-lock for frames 1055 struct FrameLocker 1056 { 1057 FrameLocker(VideoCORE * core, mfxFrameData & data, bool external = false) 1058 : m_core(core) 1059 , m_data(data) 1060 , m_memId(data.MemId) 1061 , m_status(Lock(external)) 1062 { 1063 } 1064 1065 FrameLocker(VideoCORE * core, mfxFrameData & data, mfxMemId memId, bool external = false) 1066 : m_core(core) 1067 , m_data(data) 1068 , m_memId(memId) 1069 , m_status(Lock(external)) 1070 { 1071 } 1072 1073 ~FrameLocker() { Unlock(); } 1074 1075 mfxStatus Unlock() 1076 { 1077 mfxStatus mfxSts = MFX_ERR_NONE; 1078 1079 if (m_status == LOCK_INT) 1080 mfxSts = m_core->UnlockFrame(m_memId, &m_data); 1081 else if (m_status == LOCK_EXT) 1082 mfxSts = m_core->UnlockExternalFrame(m_memId, &m_data); 1083 1084 m_status = LOCK_NO; 1085 return mfxSts; 1086 } 1087 1088 1089 enum { LOCK_NO, LOCK_INT, LOCK_EXT }; 1090 1091 mfxU32 Lock(bool external) 1092 { 1093 mfxU32 status = LOCK_NO; 1094 1095 if (m_data.Y == 0) 1096 { 1097 status = external 1098 ? (m_core->LockExternalFrame(m_memId, &m_data) == MFX_ERR_NONE ? LOCK_EXT : LOCK_NO) 1099 : (m_core->LockFrame(m_memId, &m_data) == MFX_ERR_NONE ? LOCK_INT : LOCK_NO); 1100 } 1101 1102 return status; 1103 } 1104 1105 private: 1106 FrameLocker(FrameLocker const &); 1107 FrameLocker & operator =(FrameLocker const &); 1108 1109 VideoCORE * m_core; 1110 mfxFrameData & m_data; 1111 mfxMemId m_memId; 1112 mfxU32 m_status; 1113 }; 1114 1115 class FileHandle 1116 { 1117 public: 1118 FileHandle(FILE * file = 0) 1119 : m_file(file) 1120 { 1121 } 1122 1123 ~FileHandle() 1124 { 1125 Close(); 1126 } 1127 1128 void Close() 1129 { 1130 if (m_file != 0) 1131 { 1132 fclose(m_file); 1133 } 1134 } 1135 1136 FileHandle & operator =(FILE* file) 1137 { 1138 Close(); 1139 m_file = file; 1140 return *this; 1141 } 1142 1143 operator FILE *() 1144 { 1145 return m_file; 1146 } 1147 1148 private: 1149 FileHandle(FileHandle const &); // no impl 1150 FileHandle & operator =(FileHandle const &); // no impl 1151 FILE* m_file; 1152 }; 1153 1154 template <class T> 1155 class ScopedArray 1156 { 1157 public: 1158 ScopedArray(T * arr = 0) 1159 : m_arr(arr) 1160 { 1161 } 1162 1163 ~ScopedArray() 1164 { 1165 reset(0); 1166 } 1167 1168 T * reset(T * arr) 1169 { 1170 T * tmp(m_arr); 1171 delete [] m_arr; 1172 m_arr = arr; 1173 return tmp; 1174 } 1175 1176 T * cptr() 1177 { 1178 return m_arr; 1179 } 1180 1181 T const * cptr() const 1182 { 1183 return m_arr; 1184 } 1185 1186 T & operator [](size_t idx) 1187 { 1188 assert(m_arr); 1189 return m_arr[idx]; 1190 } 1191 1192 T const & operator [](size_t idx) const 1193 { 1194 assert(m_arr); 1195 return m_arr[idx]; 1196 } 1197 1198 private: 1199 ScopedArray(ScopedArray const &); 1200 ScopedArray & operator =(ScopedArray const &); 1201 1202 T * m_arr; 1203 }; 1204 1205 struct SliceDividerState 1206 { 1207 mfxU32 m_numSlice; 1208 mfxU32 m_numMbInRow; 1209 mfxU32 m_numMbRow; 1210 mfxU32 m_leftSlice; 1211 mfxU32 m_leftMbRow; 1212 mfxU32 m_currSliceFirstMbRow; 1213 mfxU32 m_currSliceNumMbRow; 1214 }; 1215 1216 struct SliceDivider : protected SliceDividerState 1217 { 1218 SliceDivider() : m_pfNext(0) {} 1219 1220 // 'False' means no more slices, object needs to be recreated 1221 bool Next() { return m_pfNext(*this); } 1222 1223 mfxU32 GetFirstMbInSlice() const; 1224 1225 mfxU32 GetNumMbInSlice() const; 1226 1227 mfxU32 GetNumSlice() const; 1228 1229 protected: 1230 bool (*m_pfNext)(SliceDividerState & state); 1231 }; 1232 1233 1234 struct SliceDividerOneSlice : SliceDivider 1235 { 1236 SliceDividerOneSlice( 1237 mfxU32 numSlice, 1238 mfxU32 widthInMbs, 1239 mfxU32 heightInMbs); 1240 1241 static bool Next(SliceDividerState & state); 1242 }; 1243 1244 1245 struct SliceDividerArbitraryRowSlice : SliceDivider 1246 { 1247 SliceDividerArbitraryRowSlice( 1248 mfxU32 numSlice, 1249 mfxU32 widthInMbs, 1250 mfxU32 heightInMbs); 1251 1252 static bool Next(SliceDividerState & state); 1253 }; 1254 1255 1256 struct SliceDividerRow2Row : SliceDivider 1257 { 1258 SliceDividerRow2Row( 1259 mfxU32 numSlice, 1260 mfxU32 widthInMbs, 1261 mfxU32 heightInMbs); 1262 1263 static bool Next(SliceDividerState & state); 1264 1265 static void Test(); 1266 }; 1267 1268 1269 struct SliceDividerRowSlice : SliceDivider 1270 { 1271 SliceDividerRowSlice( 1272 mfxU32 numSlice, 1273 mfxU32 widthInMbs, 1274 mfxU32 heightInMbs); 1275 1276 static bool Next(SliceDividerState & state); 1277 }; 1278 1279 struct SliceDividerTemporalScalability : SliceDivider 1280 { 1281 SliceDividerTemporalScalability( 1282 mfxU32 sliceSizeInMbs, 1283 mfxU32 widthInMbs, 1284 mfxU32 heightInMbs); 1285 1286 static bool Next(SliceDividerState & state); 1287 }; 1288 struct SliceDividerLowPower : SliceDivider 1289 { 1290 SliceDividerLowPower( 1291 mfxU32 numSlice, 1292 mfxU32 widthInMbs, 1293 mfxU32 heightInMbs); 1294 1295 static bool Next(SliceDividerState & state); 1296 }; 1297 struct SliceDividerLowPowerTemporalScalability : SliceDivider 1298 { 1299 SliceDividerLowPowerTemporalScalability( 1300 mfxU32 sliceSizeInMbs, 1301 mfxU32 widthInMbs, 1302 mfxU32 heightInMbs); 1303 1304 static bool Next(SliceDividerState & state); 1305 }; 1306 SliceDivider MakeSliceDivider( 1307 SliceDividerType sliceHwCaps, 1308 mfxU32 sliceSizeInMbs, 1309 mfxU32 numSlice, 1310 mfxU32 widthInMbs, 1311 mfxU32 heightInMbs, 1312 bool isLowPower = false); 1313 1314 1315 class AspectRatioConverter 1316 { 1317 public: 1318 AspectRatioConverter(mfxU16 sarw, mfxU16 sarh); 1319 AspectRatioConverter(mfxU8 sarIdc, mfxU16 sarw, mfxU16 sarh); 1320 mfxU8 GetSarIdc() const { return m_sarIdc; } 1321 mfxU16 GetSarWidth() const { return m_sarWidth; } 1322 mfxU16 GetSarHeight() const { return m_sarHeight; } 1323 1324 private: 1325 mfxU8 m_sarIdc; 1326 mfxU16 m_sarWidth; 1327 mfxU16 m_sarHeight; 1328 }; 1329 1330 class EndOfBuffer : public std::exception 1331 { 1332 public: 1333 EndOfBuffer() : std::exception() {} 1334 }; 1335 1336 class InvalidBitstream : public std::exception 1337 { 1338 public: 1339 InvalidBitstream() : std::exception() {} 1340 }; 1341 1342 void ReadSpsHeader( 1343 InputBitstream & reader, 1344 mfxExtSpsHeader & sps); 1345 1346 mfxU8 ReadSpsIdOfPpsHeader( 1347 InputBitstream reader); 1348 1349 void ReadPpsHeader( 1350 InputBitstream & reader, 1351 mfxExtSpsHeader const & sps, 1352 mfxExtPpsHeader & pps); 1353 1354 mfxU32 WriteSpsHeader( 1355 OutputBitstream & writer, 1356 mfxExtSpsHeader const & sps); 1357 1358 mfxU32 WriteSpsHeader( 1359 OutputBitstream & writer, 1360 mfxExtSpsHeader const & sps, 1361 mfxExtBuffer const & spsExt); 1362 1363 mfxU32 WritePpsHeader( 1364 OutputBitstream & writer, 1365 mfxExtPpsHeader const & pps); 1366 1367 void WriteScalingList( 1368 OutputBitstream & writer, 1369 const mfxU8* scalingList, 1370 mfxI32 sizeOfScalingList); 1371 1372 mfxU32 WriteAud( 1373 OutputBitstream & writer, 1374 mfxU32 frameType); 1375 1376 struct RefListMod; 1377 struct WeightTab; 1378 template<class T, mfxU32 N> struct FixedArray; 1379 typedef FixedArray<RefListMod, 32> ArrayRefListMod; 1380 typedef FixedArray<WeightTab, 32> ArrayWeightTab; 1381 1382 void WriteRefPicListModification( 1383 OutputBitstream & writer, 1384 ArrayRefListMod const & refListMod); 1385 1386 struct DecRefPicMarkingInfo; 1387 1388 void WriteDecRefPicMarking( 1389 OutputBitstream & writer, 1390 DecRefPicMarkingInfo const & marking, 1391 mfxU32 idrPicFlag); 1392 1393 bool IsAvcProfile(mfxU32 profile); 1394 1395 bool IsAvcBaseProfile(mfxU32 profile); 1396 1397 bool IsAvcHighProfile(mfxU32 profile); 1398 1399 bool IsMvcProfile(mfxU32 profile); 1400 1401 1402 inline mfxStatus Error(mfxStatus sts) 1403 { 1404 return sts; 1405 } 1406 1407 inline mfxStatus Warning(mfxStatus sts) 1408 { 1409 //__asm { int 3 } 1410 return sts; 1411 } 1412 1413 mfxU8 * PackPrefixNalUnitSvc( 1414 mfxU8 * begin, 1415 mfxU8 * end, 1416 bool emulationControl, 1417 DdiTask const & task, 1418 mfxU32 fieldId, 1419 mfxU32 nalUnitType = 0xe); 1420 1421 class HeaderPacker 1422 { 1423 public: 1424 void Init( 1425 MfxVideoParam const & par, 1426 MFX_ENCODE_CAPS const & hwCaps, 1427 bool emulPrev = true); // insert emualtion prevention bytes when possible (sps/pps/sei/aud) 1428 1429 std::vector<ENCODE_PACKEDHEADER_DATA> const & PackSlices( 1430 DdiTask const & task, 1431 mfxU32 fieldId); 1432 1433 1434 1435 ENCODE_PACKEDHEADER_DATA const & PackSkippedSlice( 1436 DdiTask const & task, 1437 mfxU32 fieldId); 1438 1439 ENCODE_PACKEDHEADER_DATA const & PackAud( 1440 DdiTask const & task, 1441 mfxU32 fieldId); 1442 1443 1444 ENCODE_PACKEDHEADER_DATA const & GetAud() const { return m_packedAud; } 1445 1446 std::vector<ENCODE_PACKEDHEADER_DATA> const & GetSps() const { return m_packedSps; } 1447 1448 std::vector<ENCODE_PACKEDHEADER_DATA> const & GetPps() const { return m_packedPps; } 1449 1450 std::vector<ENCODE_PACKEDHEADER_DATA> const & GetSlices() const { return m_packedSlices; } 1451 1452 bool isMVC() const { return m_isMVC; } 1453 bool isSvcPrefixUsed() const { return m_needPrefixNalUnit; } 1454 1455 void ResizeSlices(mfxU32 num); 1456 1457 #ifndef MFX_AVC_ENCODING_UNIT_DISABLE 1458 void GetHeadersInfo(std::vector<mfxEncodedUnitInfo> &HeadersMap, DdiTask const& task, mfxU32 fid); 1459 #endif 1460 1461 private: 1462 1463 mfxU32 WriteSlice( 1464 OutputBitstream & obs, 1465 DdiTask const & task, 1466 mfxU32 fieldId, 1467 mfxU32 sliceId); 1468 1469 mfxU32 WriteSlice( 1470 OutputBitstream & obs, 1471 DdiTask const & task, 1472 mfxU32 fieldId, 1473 mfxU32 firstMbInSlice, 1474 mfxU32 numMbInSlice); 1475 1476 // for header packing 1477 std::vector<mfxExtSpsHeader> m_sps; 1478 std::vector<mfxExtPpsHeader> m_pps; 1479 MFX_ENCODE_CAPS m_hwCaps; 1480 mfxU8 m_spsIdx[8][16]; // for lookup by did & qid 1481 mfxU8 m_ppsIdx[8][16]; // for lookup by did & qid 1482 mfxU8 m_refDqId[8]; // for lookup by did 1483 mfxU8 m_simulcast[8]; // for lookup by did 1484 mfxU16 m_cabacInitIdc; // same for all layers and slices 1485 mfxU16 m_directSpatialMvPredFlag; // same for all layers and slices 1486 mfxU16 m_numMbPerSlice; 1487 bool m_needPrefixNalUnit; 1488 bool m_emulPrev; // insert emualtion prevention bytes when possible (sps/pps/sei/aud) 1489 bool m_isMVC; 1490 bool m_longStartCodes; 1491 bool m_isLowPower; 1492 1493 ENCODE_PACKEDHEADER_DATA m_packedAud; 1494 std::vector<ENCODE_PACKEDHEADER_DATA> m_packedSps; 1495 std::vector<ENCODE_PACKEDHEADER_DATA> m_packedPps; 1496 std::vector<ENCODE_PACKEDHEADER_DATA> m_packedSlices; 1497 std::vector<mfxU8> m_headerBuffer; 1498 std::vector<mfxU8> m_sliceBuffer; 1499 1500 static const mfxU32 SPSPPS_BUFFER_SIZE = 1024; 1501 static const mfxU32 SLICE_BUFFER_SIZE = 2048; 1502 }; 1503 1504 inline mfxU16 LaDSenumToFactor(const mfxU16& LookAheadDS) 1505 { 1506 switch (LookAheadDS) 1507 { 1508 case MFX_LOOKAHEAD_DS_UNKNOWN: 1509 return 0; 1510 case MFX_LOOKAHEAD_DS_OFF: 1511 return 1; 1512 case MFX_LOOKAHEAD_DS_2x : 1513 return 2; 1514 case MFX_LOOKAHEAD_DS_4x : 1515 return 4; 1516 default: 1517 assert(0); 1518 return LookAheadDS; 1519 } 1520 } 1521 }; 1522 1523 #endif // MFX_ENABLE_H264_VIDEO_..._HW 1524 #endif // __MFX_H264_ENC_COMMON_HW_H__ 1525