1 // Copyright (c) 2017 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_MPEG2_ENCODE_HW_UTILS_H__ 22 #define __MFX_MPEG2_ENCODE_HW_UTILS_H__ 23 24 #include "mfx_common.h" 25 26 27 #if defined (MFX_ENABLE_MPEG2_VIDEO_ENCODE) 28 29 #include "mfxvideo++int.h" 30 #include "mfx_frames.h" 31 #include "mfx_mpeg2_enc_common_hw.h" 32 #include "umc_mpeg2_brc.h" 33 #include "mfx_brc_common.h" 34 #include "umc_video_brc.h" 35 #include "mfx_enc_common.h" 36 37 namespace MPEG2EncoderHW 38 { 39 enum HW_MODE 40 { 41 FULL_ENCODE, 42 HYBRID_ENCODE, 43 UNSUPPORTED 44 }; 45 class EncoderBase 46 { 47 public: 48 // Destructor 49 virtual ~EncoderBase(void)50 ~EncoderBase(void) {} 51 52 virtual 53 mfxStatus Init(mfxVideoParam *par) = 0; 54 virtual 55 mfxStatus Reset(mfxVideoParam *par) = 0; 56 virtual 57 mfxStatus Close(void) = 0; 58 59 virtual 60 mfxStatus GetVideoParam(mfxVideoParam *par) = 0; 61 virtual 62 mfxStatus GetEncodeStat(mfxEncodeStat *stat) = 0; 63 virtual 64 mfxStatus EncodeFrameCheck(mfxEncodeCtrl *ctrl, 65 mfxFrameSurface1 *surface, 66 mfxBitstream *bs, 67 mfxFrameSurface1 **reordered_surface, 68 mfxEncodeInternalParams *pInternalParams, 69 MFX_ENTRY_POINT *pEntryPoint) = 0; 70 virtual EncodeFrameCheck(mfxEncodeCtrl * ctrl,mfxFrameSurface1 * surface,mfxBitstream * bs,mfxFrameSurface1 ** reordered_surface,mfxEncodeInternalParams * pInternalParams,MFX_ENTRY_POINT pEntryPoints[],mfxU32 & numEntryPoints)71 mfxStatus EncodeFrameCheck(mfxEncodeCtrl *ctrl, 72 mfxFrameSurface1 *surface, 73 mfxBitstream *bs, 74 mfxFrameSurface1 **reordered_surface, 75 mfxEncodeInternalParams *pInternalParams, 76 MFX_ENTRY_POINT pEntryPoints[], 77 mfxU32 &numEntryPoints) 78 { 79 mfxStatus mfxRes; 80 81 // call the overweighted version 82 mfxRes = EncodeFrameCheck(ctrl, surface, bs, reordered_surface, pInternalParams, pEntryPoints); 83 numEntryPoints = 1; 84 85 return mfxRes; 86 } 87 virtual 88 mfxStatus EncodeFrameCheck(mfxEncodeCtrl *ctrl, mfxFrameSurface1 *surface, mfxBitstream *bs, mfxFrameSurface1 **reordered_surface, mfxEncodeInternalParams *pInternalParams) = 0; 89 virtual 90 mfxStatus EncodeFrame(mfxEncodeCtrl *ctrl, mfxEncodeInternalParams *pInternalParams, mfxFrameSurface1 *surface, mfxBitstream *bs) = 0; 91 virtual 92 mfxStatus CancelFrame(mfxEncodeCtrl *ctrl, mfxEncodeInternalParams *pInternalParams, mfxFrameSurface1 *surface, mfxBitstream *bs) = 0; 93 virtual 94 mfxTaskThreadingPolicy GetThreadingPolicy(void) = 0; 95 96 }; 97 class FramesSet 98 { 99 public: 100 mfxFrameSurface1 *m_pInputFrame; 101 mfxFrameSurface1 *m_pRefFrame[2]; 102 mfxFrameSurface1 *m_pRawFrame[2]; 103 mfxFrameSurface1 *m_pRecFrame; 104 mfxU32 m_nFrame; 105 mfxU32 m_nRefFrame[2]; 106 mfxI32 m_nLastRefBeforeIntra; 107 mfxI32 m_nLastRef; 108 public: 109 FramesSet(); 110 void Reset(); 111 mfxStatus ReleaseFrames(VideoCORE* pCore); 112 mfxStatus LockRefFrames(VideoCORE* pCore); LockFrames(VideoCORE * pCore)113 inline mfxStatus LockFrames(VideoCORE* pCore) 114 { 115 if (m_pInputFrame) 116 { 117 MFX_CHECK_STS (pCore->IncreaseReference(&m_pInputFrame->Data)); 118 } 119 if (m_pRecFrame) 120 { 121 MFX_CHECK_STS (pCore->IncreaseReference(&m_pRecFrame->Data)); 122 } 123 return LockRefFrames(pCore); 124 } 125 }; 126 mfxStatus CheckHwCaps( VideoCORE* core, 127 mfxVideoParam const * par, 128 mfxExtCodingOption const * ext = 0, 129 ENCODE_CAPS* pCaps = 0); 130 131 HW_MODE GetHwEncodeMode(ENCODE_CAPS &caps); 132 133 mfxStatus ApplyTargetUsage(mfxVideoParamEx_MPEG2* par); 134 135 mfxExtCodingOptionSPSPPS* GetExtCodingOptionsSPSPPS(mfxExtBuffer** ebuffers, 136 mfxU32 nbuffers); 137 mfxStatus CheckExtendedBuffers (mfxVideoParam* par); 138 139 mfxStatus UnlockFrames (MFXGOP* pGOP, MFXWaitingList* pWaitingList, VideoCORE* pcore); 140 141 mfxStatus FillMFXFrameParams(mfxFrameParamMPEG2* pFrameParams, 142 mfxU8 frameType, 143 mfxVideoParamEx_MPEG2 *pExParams, 144 mfxU16 surface_pict_struct, 145 bool bBackwOnly, 146 bool bFwdOnly); 147 148 149 class ControllerBase 150 { 151 private: 152 VideoCORE* m_pCore; 153 mfxU32 m_nEncodeCalls; 154 mfxU32 m_nFrameInGOP; 155 156 MFXGOP* m_pGOP; 157 MFXWaitingList* m_pWaitingList; 158 mfxI32 m_InputFrameOrder; 159 mfxI32 m_OutputFrameOrder; 160 mfxU64 m_BitstreamLen; 161 mfxVideoParamEx_MPEG2 m_VideoParamsEx; 162 163 InputSurfaces m_InputSurfaces; 164 165 mfxU16 m_InitWidth; 166 mfxU16 m_InitHeight; 167 bool m_bInitialized; 168 bool m_bAVBR_WA; 169 170 protected: is_initialized()171 inline bool is_initialized () 172 {return m_bInitialized;} 173 174 public: 175 176 ControllerBase(VideoCORE *core, bool bAVBR_WA = false); ~ControllerBase()177 ~ControllerBase() 178 { 179 Close(); 180 } 181 mfxStatus Close(void); 182 mfxStatus Reset(mfxVideoParam *par, bool bAllowRawFrames); 183 mfxStatus GetVideoParam(mfxVideoParam *par); 184 mfxStatus GetFrameParam(mfxFrameParam *par); 185 mfxStatus GetEncodeStat(mfxEncodeStat *stat); 186 mfxStatus EncodeFrameCheck(mfxEncodeCtrl *ctrl, 187 mfxFrameSurface1 *surface, 188 mfxBitstream *bs, 189 mfxFrameSurface1 **reordered_surface, 190 mfxEncodeInternalParams *pInternalParams); 191 192 static mfxStatus 193 Query(VideoCORE *core, mfxVideoParam *in, mfxVideoParam *out, bool bAVBR_WA = false); 194 static mfxStatus 195 QueryIOSurf (VideoCORE *core, mfxVideoParam *par, mfxFrameAllocRequest *request); 196 197 mfxStatus ReorderFrame(mfxEncodeInternalParams *pInInternalParams, mfxFrameSurface1 *in, 198 mfxEncodeInternalParams *pOutInternalParams, mfxFrameSurface1 **out); 199 200 mfxStatus CheckNextFrame(mfxEncodeInternalParams *pOutInternalParams, mfxFrameSurface1 **out); 201 202 mfxStatus CheckFrameType (mfxEncodeInternalParams *pInternalParams); 203 isHWInput()204 inline bool isHWInput () {return !m_InputSurfaces.isSysMemFrames();} isOpaq()205 inline bool isOpaq() { return m_InputSurfaces.isOpaq(); } 206 GetInputFrameType()207 inline mfxU16 GetInputFrameType() 208 { 209 return (mfxU16)( MFX_MEMTYPE_EXTERNAL_FRAME | 210 (m_InputSurfaces.isSysMemFrames() ? MFX_MEMTYPE_SYSTEM_MEMORY : MFX_MEMTYPE_DXVA2_DECODER_TARGET)| 211 MFX_MEMTYPE_FROM_ENCODE); 212 } 213 isRawFrames()214 inline bool isRawFrames() 215 {return m_VideoParamsEx.bRawFrames;} 216 getVideoParamsEx()217 inline mfxVideoParamEx_MPEG2* getVideoParamsEx() 218 {return &m_VideoParamsEx;} 219 GetFrameNumber()220 inline mfxI32 GetFrameNumber() 221 { return m_OutputFrameOrder; } 222 FinishFrame(mfxU32 frameSize)223 inline void FinishFrame(mfxU32 frameSize) 224 { 225 m_OutputFrameOrder ++; 226 m_BitstreamLen = m_BitstreamLen + frameSize; 227 } GetOutputFrameOrder()228 mfxI32 GetOutputFrameOrder () 229 { 230 return m_OutputFrameOrder; 231 } 232 SetAllocResponse(mfxFrameAllocResponse * pAR,bool bHW)233 inline void SetAllocResponse(mfxFrameAllocResponse* pAR, bool bHW) 234 { 235 if (bHW) 236 m_VideoParamsEx.pRecFramesResponse_hw = pAR; 237 else 238 m_VideoParamsEx.pRecFramesResponse_sw = pAR; 239 } 240 GetOriginalSurface(mfxFrameSurface1 * surface)241 mfxFrameSurface1 *GetOriginalSurface(mfxFrameSurface1 *surface) 242 { 243 return m_InputSurfaces.GetOriginalSurface(surface); 244 } 245 GetOpaqSurface(mfxFrameSurface1 * surface)246 mfxFrameSurface1 *GetOpaqSurface(mfxFrameSurface1 *surface) 247 { 248 return m_InputSurfaces.GetOpaqSurface(surface); 249 } 250 251 252 }; // class ControllerBase 253 254 255 class MPEG2BRC_HW 256 { 257 private: 258 UMC::VideoBrc* m_pBRC; 259 mfxU32 m_bConstantQuant; 260 mfxU32 m_MinFrameSizeBits[3]; 261 mfxU32 m_MinFieldSizeBits[3]; 262 VideoCORE* m_pCore; 263 mfxU32 m_FirstGopSize; 264 mfxU32 m_GopSize; 265 mfxU32 m_bufferSizeInKB; 266 mfxI32 m_InputBitsPerFrame; 267 bool m_bLimitedMode; 268 269 protected: 270 271 void QuantIntoScaleTypeAndCode (int32_t quant_value, int32_t &q_scale_type, int32_t &quantiser_scale_code); ScaleTypeAndCodeIntoQuant(int32_t q_scale_type,int32_t quantiser_scale_code)272 inline int32_t ScaleTypeAndCodeIntoQuant (int32_t q_scale_type, int32_t quantiser_scale_code) 273 { 274 static int32_t Val_QScale[2][32] = 275 { 276 /* linear q_scale */ 277 {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 278 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62}, 279 /* non-linear q_scale */ 280 {0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 281 24, 28, 32, 36, 40, 44, 48, 52, 56, 64, 72, 80, 88, 96,104,112}}; 282 283 return Val_QScale[q_scale_type][quantiser_scale_code]; 284 } 285 286 287 int32_t ChangeQuant(int32_t quant_value_old, int32_t quant_value_new); 288 289 public: MPEG2BRC_HW(VideoCORE * pCore)290 MPEG2BRC_HW(VideoCORE* pCore) 291 { 292 m_pCore = pCore; 293 m_pBRC = 0; 294 m_bConstantQuant = 0; 295 m_MinFrameSizeBits [0] = 0; 296 m_MinFrameSizeBits [1] = 0; 297 m_MinFrameSizeBits [2] = 0; 298 299 m_MinFieldSizeBits [0] = 0; 300 m_MinFieldSizeBits [1] = 0; 301 m_MinFieldSizeBits [2] = 0; 302 303 m_FirstGopSize = 0; 304 m_GopSize = 0; 305 m_bufferSizeInKB = 0; 306 m_InputBitsPerFrame = 0; 307 m_bLimitedMode = 0; 308 309 } ~MPEG2BRC_HW()310 ~MPEG2BRC_HW () 311 { 312 Close(); 313 } 314 mfxStatus Init(mfxVideoParam* par); 315 Reset(mfxVideoParam * par)316 inline mfxStatus Reset(mfxVideoParam* par) 317 { 318 return Init(par); 319 } 320 void Close (); 321 322 mfxStatus StartNewFrame(const mfxFrameParamMPEG2 *pFrameParams, mfxI32 recode); 323 mfxStatus SetQuantDCPredAndDelay(mfxFrameParamMPEG2 *pFrameParams, mfxU8 *pQuant); 324 325 mfxStatus UpdateBRC(const mfxFrameParamMPEG2 *pParams, mfxBitstream* pBitsream, mfxU32 bitsize, mfxU32 numEncodedFrame, bool bNotEnoughBuffer ,mfxI32 &recode); SetQuant(mfxU32 Quant,mfxU32 FrameType)326 inline void SetQuant(mfxU32 Quant, mfxU32 FrameType) 327 { 328 if (m_pBRC && m_bConstantQuant) 329 { 330 if (Quant > 0) 331 { 332 if (FrameType & MFX_FRAMETYPE_I) 333 m_pBRC->SetQP(Quant, UMC::I_PICTURE); 334 else if (FrameType & MFX_FRAMETYPE_P) 335 m_pBRC->SetQP(Quant, UMC::P_PICTURE); 336 else if (FrameType & MFX_FRAMETYPE_B) 337 m_pBRC->SetQP(Quant, UMC::B_PICTURE); 338 } 339 } 340 } 341 IsSkipped(mfxI32 & recode)342 inline bool IsSkipped (mfxI32 &recode) 343 { 344 if (m_bLimitedMode && recode == 0) 345 { 346 recode = UMC::BRC_EXT_FRAMESKIP; 347 return true; 348 } 349 else if (m_bLimitedMode) 350 { 351 return true; 352 } 353 return false; 354 } 355 private: 356 // Declare private copy constructor to avoid accidental assignment 357 // and klocwork complaining. 358 MPEG2BRC_HW(const MPEG2BRC_HW &); 359 MPEG2BRC_HW & operator = (const MPEG2BRC_HW &); 360 }; 361 362 enum TaskStatus 363 { 364 NOT_STARTED = 0, 365 INPUT_READY = 1, 366 ENC_STARTED = 2, 367 ENC_READY = 3, 368 }; 369 class FrameStore 370 { 371 private: 372 FrameStore(const FrameStore&); // non-copyable 373 void operator=(const FrameStore&); // non-copyable 374 375 mfxU16 m_InputType; 376 bool m_bHWFrames; 377 378 mfxFrameSurface1 *m_pRefFrame[2]; 379 mfxFrameSurface1 *m_pRawFrame[2]; 380 mfxU32 m_nRefFrame[2]; 381 382 mfxFrameSurface1 *m_pRefFramesStore; // reference frames 383 mfxFrameSurface1 *m_pInputFramesStore; // input frames in case of system memory 384 mfxU32 m_nRefFrames; 385 mfxU32 m_nInputFrames; 386 VideoCORE* m_pCore; 387 mfxFrameAllocRequest m_RefRequest; 388 mfxFrameAllocResponse m_RefResponse; 389 mfxFrameAllocRequest m_InputRequest; 390 mfxFrameAllocResponse m_InputResponse; 391 mfxU32 m_nFrame; 392 mfxI32 m_nLastRefBeforeIntra; 393 mfxI32 m_nLastRef; 394 bool m_bRawFrame; 395 396 protected: 397 mfxStatus ReleaseFrames(); 398 mfxStatus GetInternalRefFrame(mfxFrameSurface1** ppFrame); 399 mfxStatus GetInternalInputFrame(mfxFrameSurface1** ppFrame); 400 401 public: 402 FrameStore(VideoCORE * pCore)403 FrameStore(VideoCORE* pCore) 404 { 405 m_InputType = 0; 406 m_bHWFrames = false; 407 408 memset (m_pRefFrame,0,sizeof(mfxFrameSurface1*)*2); 409 memset (m_pRawFrame,0,sizeof(mfxFrameSurface1*)*2); 410 memset (m_nRefFrame,0,sizeof(mfxU32)*2); 411 412 m_pRefFramesStore = 0; 413 m_pInputFramesStore = 0; 414 m_nRefFrames = 0; 415 m_nInputFrames = 0; 416 417 m_nFrame = 0; 418 m_nRefFrame[0] = 0; 419 m_nRefFrame[1] = 0; 420 m_nLastRefBeforeIntra = -1; 421 m_nLastRef = -1; 422 423 memset(&m_RefRequest, 0, sizeof(mfxFrameAllocRequest)); 424 memset(&m_RefResponse, 0, sizeof(mfxFrameAllocResponse)); 425 memset(&m_InputRequest, 0, sizeof(mfxFrameAllocRequest)); 426 memset(&m_InputResponse, 0, sizeof(mfxFrameAllocResponse)); 427 428 m_bRawFrame = 0; 429 m_pCore = pCore; 430 } 431 ~FrameStore()432 ~FrameStore() 433 { 434 Close(); 435 } 436 437 inline mfxStatus Reset(bool bRawFrame, mfxU16 InputFrameType, bool bHWFrames, mfxU32 nTasks, mfxFrameInfo* pFrameInfo, bool bProtected = false) 438 { 439 return Init(bRawFrame, InputFrameType, bHWFrames, nTasks, pFrameInfo, bProtected); 440 } 441 442 mfxStatus Init(bool bRawFrame, mfxU16 InputFrameType, bool bHWFrames, mfxU32 mTasks, mfxFrameInfo* pFrameInfo, bool bProtected = false); 443 444 mfxStatus NextFrame(mfxFrameSurface1 *pInputFrame, mfxU32 nFrame, mfxU16 frameType, mfxU32 intFlags, FramesSet *pFrames); 445 446 mfxStatus Close(); 447 GetFrameAllocResponse()448 inline mfxFrameAllocResponse* GetFrameAllocResponse() 449 { 450 return &m_RefResponse; 451 } 452 }; 453 454 class EncodeFrameTask 455 { 456 public: 457 TaskStatus m_taskStatus; 458 mfxFrameParamMPEG2 m_FrameParams; 459 mfxBitstream* m_pBitstream; 460 FramesSet m_Frames; 461 VideoCORE* m_pCore; 462 mfxU32 m_nFrameOrder; 463 mfxEncodeInternalParams 464 m_sEncodeInternalParams; 465 mfxU32 m_FeedbackNumber; 466 mfxU32 m_BitstreamFrameNumber; 467 468 protected: 469 inline Reset()470 void Reset() 471 { 472 memset(&m_FrameParams,0,sizeof(mfxFrameParamMPEG2)); 473 memset(&m_sEncodeInternalParams, 0, sizeof(mfxEncodeInternalParams)); 474 m_pBitstream = 0; 475 m_pCore = 0; 476 m_nFrameOrder = 0; 477 m_taskStatus = NOT_STARTED; 478 m_Frames.Reset(); 479 m_FeedbackNumber = 0; 480 m_BitstreamFrameNumber = 0; 481 } 482 483 public: EncodeFrameTask()484 EncodeFrameTask() 485 { 486 Reset(); 487 } 488 inline Reset(VideoCORE * pCore)489 mfxStatus Reset(VideoCORE* pCore) 490 { 491 mfxStatus sts = MFX_ERR_NONE; 492 sts = m_Frames.ReleaseFrames(m_pCore); 493 Reset(); 494 m_pCore = pCore; 495 return sts; 496 } 497 inline Close()498 mfxStatus Close() 499 { 500 mfxStatus sts = MFX_ERR_NONE; 501 sts = m_Frames.ReleaseFrames(m_pCore); 502 Reset(); 503 return sts; 504 } 505 506 inline SetFrames(FramesSet * pFrames,mfxEncodeInternalParams * pEncodeInternalParams)507 void SetFrames(FramesSet *pFrames, 508 mfxEncodeInternalParams* pEncodeInternalParams) 509 { 510 m_Frames = *pFrames; 511 m_sEncodeInternalParams = *pEncodeInternalParams; 512 } 513 inline FillFrameParams(mfxU8 frameType,mfxVideoParamEx_MPEG2 * pExParams,mfxU16 surface_pict_struct,bool bBackwOnly,bool bFwdOnly,bool bAddSH,bool bAddEOS)514 mfxStatus FillFrameParams (mfxU8 frameType, mfxVideoParamEx_MPEG2 *pExParams, mfxU16 surface_pict_struct, bool bBackwOnly, bool bFwdOnly, bool bAddSH, bool bAddEOS) 515 { 516 mfxStatus sts = MFX_ERR_NONE; 517 sts = FillMFXFrameParams(&m_FrameParams, frameType, pExParams, surface_pict_struct, bBackwOnly, bFwdOnly); 518 MFX_CHECK_STS(sts); 519 m_FrameParams.TemporalReference = (mfxU16)(m_Frames.m_nFrame - m_Frames.m_nLastRefBeforeIntra - 1); 520 m_FrameParams.ExtraFlags = (mfxU16)(( bAddSH ? MFX_IFLAG_ADD_HEADER:0)| (bAddEOS ? MFX_IFLAG_ADD_EOS:0)); // those values are not declared 521 return sts; 522 } 523 }; 524 525 } 526 527 528 #endif // MFX_ENABLE_MPEG2_VIDEO_ENCODE 529 #endif 530