1 // Copyright (c) 2017-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 #include "mfx_common.h" 22 23 #if defined (MFX_ENABLE_MPEG2_VIDEO_ENCODE) 24 25 #include "mfx_enc_common.h" 26 #include "mfx_mpeg2_encode_utils_hw.h" 27 #include "mfx_brc_common.h" 28 #include "mfx_mpeg2_enc_common.h" 29 #include "umc_mpeg2_brc.h" 30 #include "mfx_task.h" 31 #include "libmfx_core.h" 32 33 // temporary defines 34 #define CHECK_VERSION(ver) /*ver.Major==0;*/ 35 #define CHECK_CODEC_ID(id, myid) /*id==myid;*/ 36 37 #define RANGE_TO_F_CODE(range, fcode) { \ 38 int32_t fc = 1; \ 39 while((4<<fc) < range && fc <= 15) \ 40 fc++; \ 41 fcode = fc; \ 42 } 43 namespace MPEG2EncoderHW 44 { CheckHwCaps(VideoCORE * core,mfxVideoParam const * par,mfxExtCodingOption const * ext,ENCODE_CAPS * pCaps)45 mfxStatus CheckHwCaps(VideoCORE* core, mfxVideoParam const * par, mfxExtCodingOption const * ext, ENCODE_CAPS* pCaps) 46 { 47 ENCODE_CAPS hwCaps {}; 48 49 mfxU16 codecProfile = MFX_PROFILE_MPEG2_MAIN; 50 if (par->mfx.CodecProfile != MFX_PROFILE_UNKNOWN) 51 codecProfile = par->mfx.CodecProfile; 52 mfxStatus sts = MfxHwMpeg2Encode::QueryHwCaps(core, hwCaps, codecProfile); 53 MFX_CHECK_STS(sts); 54 55 if (par->mfx.FrameInfo.Width > hwCaps.MaxPicWidth || 56 par->mfx.FrameInfo.Height > hwCaps.MaxPicHeight) 57 return MFX_WRN_PARTIAL_ACCELERATION; 58 59 if (par->mfx.FrameInfo.PicStruct != MFX_PICSTRUCT_PROGRESSIVE) 60 { 61 if (ext == 0) 62 ext = GetExtCodingOptions(par->ExtParam, par->NumExtParam); 63 64 if (ext != 0 && ext->FramePicture == MFX_CODINGOPTION_OFF) 65 return MFX_WRN_PARTIAL_ACCELERATION; 66 } 67 if (!hwCaps.EncodeFunc && !hwCaps.EncFunc) 68 { 69 return MFX_WRN_PARTIAL_ACCELERATION; 70 } 71 if( pCaps ) 72 { 73 *pCaps = hwCaps; 74 } 75 76 return MFX_ERR_NONE; 77 } GetHwEncodeMode(ENCODE_CAPS & caps)78 HW_MODE GetHwEncodeMode(ENCODE_CAPS &caps) 79 { 80 if( caps.EncodeFunc ) 81 { 82 return FULL_ENCODE; 83 } 84 else if(caps.EncFunc) 85 { 86 return HYBRID_ENCODE; 87 } 88 else 89 { 90 return UNSUPPORTED; 91 } 92 } ApplyTargetUsage(mfxVideoParamEx_MPEG2 * par)93 mfxStatus ApplyTargetUsage (mfxVideoParamEx_MPEG2* par) 94 { 95 if (par->mfxVideoParams.mfx.CodecProfile == MFX_PROFILE_MPEG2_SIMPLE) 96 { 97 par->mfxVideoParams.mfx.GopRefDist = 1; 98 } 99 100 if (par->mfxVideoParams.mfx.GopRefDist == 0) 101 { 102 par->mfxVideoParams.mfx.GopRefDist = 3; 103 } 104 if (par->mfxVideoParams.mfx.GopPicSize == 0) 105 { 106 par->mfxVideoParams.mfx.GopPicSize = 24; 107 } 108 if (par->mfxVideoParams.mfx.GopRefDist > par->mfxVideoParams.mfx.GopPicSize) 109 { 110 par->mfxVideoParams.mfx.GopRefDist = par->mfxVideoParams.mfx.GopPicSize; 111 } 112 if (par->MVRangeP[0] == 0 || par->MVRangeP[1] == 0 ) 113 { 114 mfxU32 FrameW = par->mfxVideoParams.mfx.FrameInfo.Width; 115 116 par->MVRangeP[0] = FrameW < 200 ? 32 /*3*/ : FrameW < 500 ? 64 /*4*/ : FrameW < 1400 ? 128 /*5*/ : 256/*6*/; // 200, 500, 1400 are horizontal resolution 117 par->MVRangeP[1] = par->MVRangeP[0] > 128 /*5*/ ? 128 /*5*/ : par->MVRangeP[0]; 118 } 119 par->MVRangeB[0][0] = par->MVRangeP[0]; 120 par->MVRangeB[0][1] = par->MVRangeP[1]; 121 par->MVRangeB[1][0] = par->MVRangeP[0]; 122 par->MVRangeB[1][1] = par->MVRangeP[1]; 123 124 par->bAllowFieldPrediction = 1; 125 par->bAllowFieldDCT = 1; 126 127 return MFX_ERR_NONE; 128 } 129 GetExtCodingOptionsSPSPPS(mfxExtBuffer ** ebuffers,mfxU32 nbuffers)130 mfxExtCodingOptionSPSPPS* GetExtCodingOptionsSPSPPS(mfxExtBuffer** ebuffers, 131 mfxU32 nbuffers) 132 { 133 for(mfxU32 i=0; i<nbuffers; i++) 134 { 135 if((0 != (*ebuffers+i)) && ((*ebuffers+i)->BufferId == MFX_EXTBUFF_CODING_OPTION_SPSPPS)) 136 { 137 return (mfxExtCodingOptionSPSPPS*)(*ebuffers+i); 138 } 139 } 140 return 0; 141 } 142 CheckExtendedBuffers(mfxVideoParam * par)143 mfxStatus CheckExtendedBuffers (mfxVideoParam* par) 144 { 145 mfxU32 supported_buffers[] = { 146 MFX_EXTBUFF_CODING_OPTION 147 ,MFX_EXTBUFF_CODING_OPTION_SPSPPS 148 ,MFX_EXTBUFF_OPAQUE_SURFACE_ALLOCATION 149 ,MFX_EXTBUFF_VIDEO_SIGNAL_INFO 150 ,MFX_EXTBUFF_CODING_OPTION2 151 ,MFX_EXTBUFF_CODING_OPTION3 152 }; 153 mfxU32 num_supported = 0; 154 155 if (par->NumExtParam == 0 || par->ExtParam == 0) 156 { 157 return MFX_ERR_NONE; 158 } 159 for (mfxU32 n_buf=0; n_buf < sizeof(supported_buffers)/sizeof(mfxU32); n_buf++) 160 { 161 mfxU32 num = 0; 162 for (mfxU32 i=0; i < par->NumExtParam; i++) 163 { 164 if (par->ExtParam[i] == NULL) 165 { 166 return MFX_ERR_NULL_PTR; 167 } 168 if (par->ExtParam[i]->BufferId == supported_buffers[n_buf]) 169 { 170 num ++; 171 } 172 } 173 if (num > 1) 174 { 175 return MFX_ERR_UNDEFINED_BEHAVIOR; 176 } 177 num_supported += num; 178 179 } 180 return (num_supported == par->NumExtParam) ? MFX_ERR_NONE : MFX_ERR_UNSUPPORTED; 181 } 182 183 /*static mfxU16 GetBufferSizeInKB (mfxU16 TargetKbps, double frame_rate, bool bMin = false) 184 { 185 mfxU32 numFrames = (bMin)? 2:10; 186 if (TargetKbps==0 || frame_rate == 0.0) 187 { 188 return 0; 189 } 190 return (mfxU16)((numFrames*TargetKbps)/(frame_rate*8)); 191 } 192 static mfxU16 GetBitRate(mfxU16 w, mfxU16 h, double frame_rate, bool bIntraFrames ,bool bMin = false) 193 { 194 double coeff = 0; 195 if (bIntraFrames) 196 { 197 coeff = (bMin)? 30.0:15.0; 198 } 199 else 200 { 201 coeff = (bMin)? 250.0:25.0; 202 } 203 return (mfxU16)(frame_rate*(double)(w*h*3/2)*8.0/1000.0/coeff); 204 }*/ FillMFXFrameParams(mfxFrameParamMPEG2 * pFrameParams,mfxU8 frameType,mfxVideoParamEx_MPEG2 * pExParams,mfxU16 inputPictStruct,bool bBackwOnly,bool bFwdOnly)205 mfxStatus FillMFXFrameParams(mfxFrameParamMPEG2* pFrameParams, 206 mfxU8 frameType, 207 mfxVideoParamEx_MPEG2 *pExParams, 208 mfxU16 inputPictStruct, 209 bool bBackwOnly, 210 bool bFwdOnly) 211 { 212 mfxU16 seqPicStruct = pExParams->mfxVideoParams.mfx.FrameInfo.PicStruct & 0x0F; 213 bool bField = false; 214 215 pFrameParams->FrameType = frameType; 216 217 mfxU16 curPicStruct = 0; 218 switch (seqPicStruct) 219 { 220 case MFX_PICSTRUCT_PROGRESSIVE: 221 curPicStruct = mfxU16(MFX_PICSTRUCT_PROGRESSIVE | (inputPictStruct &0xF0)); break; 222 case MFX_PICSTRUCT_FIELD_TFF: 223 curPicStruct = mfxU16(MFX_PICSTRUCT_FIELD_TFF | (inputPictStruct & (~MFX_PICSTRUCT_FIELD_BFF) & 0x0F)); break; 224 case MFX_PICSTRUCT_FIELD_BFF: 225 curPicStruct = mfxU16(MFX_PICSTRUCT_FIELD_BFF | (inputPictStruct & (~MFX_PICSTRUCT_FIELD_TFF) & 0x0F)); break; 226 case MFX_PICSTRUCT_UNKNOWN: 227 default: 228 curPicStruct = mfxU16((inputPictStruct == MFX_PICSTRUCT_UNKNOWN) ? MFX_PICSTRUCT_PROGRESSIVE : inputPictStruct); break; 229 } 230 231 pFrameParams->CodecFlags = 0; 232 pFrameParams->BitStreamPCEelement = 0; 233 234 if(curPicStruct & MFX_PICSTRUCT_PROGRESSIVE) { 235 236 if (!(seqPicStruct & MFX_PICSTRUCT_PROGRESSIVE)) /*progressive frame in not progressive sequence*/ 237 { 238 pFrameParams->TopFieldFirst = (curPicStruct & MFX_PICSTRUCT_FIELD_BFF)? 0:1; 239 pFrameParams->RepeatFirstField = (curPicStruct & MFX_PICSTRUCT_FIELD_REPEATED)? 1:0; 240 } 241 else /*progressive frame in progressive sequence*/ 242 { 243 if (curPicStruct & MFX_PICSTRUCT_FRAME_DOUBLING) 244 { 245 pFrameParams->RepeatFirstField = 1; 246 } 247 else if (curPicStruct & MFX_PICSTRUCT_FRAME_TRIPLING) 248 { 249 pFrameParams->RepeatFirstField = 1; 250 pFrameParams->TopFieldFirst = 1; 251 } 252 } 253 pFrameParams->PicStructure = MFX_MPEG2_FRAME_PICTURE; 254 pFrameParams->ProgressiveFrame = 1; 255 pFrameParams->FrameMbsOnlyFlag = 1; 256 pFrameParams->FrameDCTprediction = 1; 257 } 258 else if(curPicStruct & MFX_PICSTRUCT_FIELD_TFF) 259 { 260 pFrameParams->TopFieldFirst = 1; 261 262 if (pExParams->bFieldCoding) 263 { 264 pFrameParams->PicStructure = MFX_MPEG2_TOP_FIELD; 265 pFrameParams->FieldPicFlag = 1; 266 bField = true; 267 } 268 else 269 { 270 pFrameParams->PicStructure = MFX_MPEG2_FRAME_PICTURE; 271 pFrameParams->InterlacedFrameFlag = 1; 272 pFrameParams->FrameDCTprediction = 0; 273 pFrameParams->FrameMbsOnlyFlag = 0; 274 } 275 } 276 else if(curPicStruct & MFX_PICSTRUCT_FIELD_BFF) 277 { 278 279 if (pExParams->bFieldCoding) 280 { 281 pFrameParams->PicStructure = MFX_MPEG2_BOTTOM_FIELD; 282 pFrameParams->BottomFieldFlag = 1; 283 pFrameParams->FieldPicFlag = 1; 284 bField = true; 285 } 286 else 287 { 288 pFrameParams->PicStructure = MFX_MPEG2_FRAME_PICTURE; 289 pFrameParams->InterlacedFrameFlag = 1; 290 pFrameParams->FrameDCTprediction = 0; 291 pFrameParams->FrameMbsOnlyFlag = 0; 292 293 } 294 } 295 else 296 { 297 pFrameParams->PicStructure = MFX_MPEG2_FRAME_PICTURE; 298 pFrameParams->TopFieldFirst = 1; 299 pFrameParams->ProgressiveFrame = 1; 300 pFrameParams->FrameMbsOnlyFlag = 1; 301 pFrameParams->FrameDCTprediction= 1; 302 } 303 304 pFrameParams->Chroma420type = 1; 305 pFrameParams->ChromaFormatIdc = MFX_CHROMAFORMAT_YUV420; 306 pFrameParams->FrameHinMbMinus1 = (pExParams->mfxVideoParams.mfx.FrameInfo.Height)>>4; 307 pFrameParams->FrameWinMbMinus1 = (pExParams->mfxVideoParams.mfx.FrameInfo.Width )>>4; 308 if (bField) 309 { 310 pFrameParams->FrameHinMbMinus1 = (pFrameParams->FrameHinMbMinus1>>1); 311 } 312 313 MFX_CHECK(pFrameParams->FrameHinMbMinus1>=1 &&pFrameParams->FrameWinMbMinus1>=1, MFX_ERR_UNSUPPORTED); 314 315 pFrameParams->NumMb = pFrameParams->FrameHinMbMinus1*pFrameParams->FrameWinMbMinus1; 316 pFrameParams->FrameHinMbMinus1 = pFrameParams->FrameHinMbMinus1 - 1; 317 pFrameParams->FrameWinMbMinus1 = pFrameParams->FrameWinMbMinus1 - 1; 318 pFrameParams->CloseEntryFlag = !!(pExParams->mfxVideoParams.mfx.GopOptFlag & MFX_GOP_CLOSED); 319 320 if (pFrameParams->FrameType & MFX_FRAMETYPE_I) 321 { 322 pFrameParams->RefPicFlag = 1; 323 pFrameParams->BackwardPredFlag = 0; 324 pFrameParams->IntraPicFlag = 1; 325 pFrameParams->ForwardPredFlag = 0; 326 pFrameParams->NumRefFrame = 0; 327 } 328 else if (pFrameParams->FrameType & MFX_FRAMETYPE_P) 329 { 330 pFrameParams->RefPicFlag = 1; 331 pFrameParams->BackwardPredFlag = 0; 332 pFrameParams->IntraPicFlag = 0; 333 pFrameParams->ForwardPredFlag = 1; 334 pFrameParams->NumRefFrame = 1; 335 } 336 else if (pFrameParams->FrameType & MFX_FRAMETYPE_B) 337 { 338 pFrameParams->RefPicFlag = 0; 339 pFrameParams->BackwardPredFlag = (bFwdOnly) ? 0 : 1; 340 pFrameParams->ForwardPredFlag = (bBackwOnly) ? 0 : 1; 341 pFrameParams->IntraPicFlag = 0; 342 pFrameParams->NumRefFrame = (bBackwOnly || bFwdOnly) ? 1 : 2; 343 } 344 else 345 { 346 return MFX_ERR_UNSUPPORTED; 347 } 348 pFrameParams->BSConcealmentNeed = 0; 349 pFrameParams->BSConcealmentMethod = 0; 350 pFrameParams->MvGridAndChroma = 0; 351 pFrameParams->BitStreamFcodes = 0; 352 pFrameParams->IntraDCprecision = 1; 353 354 if (pFrameParams->IntraPicFlag) 355 { 356 pFrameParams->BitStreamFcodes = 0xffff; 357 } 358 else if (pFrameParams->RefPicFlag) 359 { 360 pFrameParams->BitStreamFcodes = 0xff; 361 362 mfxU32 fcode=0; 363 RANGE_TO_F_CODE (((mfxI32)pExParams->MVRangeP[0]),fcode); 364 pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<12; 365 366 fcode=0; 367 RANGE_TO_F_CODE (((mfxI32)pExParams->MVRangeP[1]), fcode); 368 pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<8; 369 370 } 371 else 372 { 373 mfxU32 fcode=0; 374 RANGE_TO_F_CODE ((mfxI32)pExParams->MVRangeB[0][0],fcode); 375 pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<12; 376 377 fcode=0; 378 RANGE_TO_F_CODE ((mfxI32)pExParams->MVRangeB[0][1], fcode); 379 pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<8; 380 381 fcode=0; 382 RANGE_TO_F_CODE ((mfxI32)pExParams->MVRangeB[1][0],fcode); 383 pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<4; 384 385 fcode=0; 386 RANGE_TO_F_CODE ((mfxI32)pExParams->MVRangeB[1][1], fcode); 387 pFrameParams->BitStreamFcodes |= (fcode & 0x0f)<<0; 388 } 389 return MFX_ERR_NONE; 390 391 } AVBR_via_CBR(mfxVideoParam * par)392 bool AVBR_via_CBR (mfxVideoParam *par) 393 { 394 if (par->mfx.RateControlMethod != MFX_RATECONTROL_AVBR) 395 return false; 396 par->mfx.RateControlMethod = MFX_RATECONTROL_CBR; 397 par->mfx.MaxKbps = par->mfx.TargetKbps; 398 par->mfx.InitialDelayInKB = par->mfx.BufferSizeInKB = 0; 399 return true; 400 } 401 FramesSet()402 FramesSet::FramesSet() 403 { 404 Reset(); 405 } Reset()406 void FramesSet::Reset() 407 { 408 m_pInputFrame = 0; 409 m_pRefFrame[0] = m_pRefFrame[1] = 0; 410 m_pRawFrame[0] = m_pRawFrame[1] = 0; 411 m_pRecFrame = 0; 412 m_nFrame = 0; 413 m_nRefFrame[0] = m_nRefFrame[1] = 0; 414 m_nLastRefBeforeIntra = -1; 415 m_nLastRef = -1; 416 } ReleaseFrames(VideoCORE * pCore)417 mfxStatus FramesSet::ReleaseFrames(VideoCORE* pCore) 418 { 419 mfxStatus sts = MFX_ERR_NONE; 420 if (m_pInputFrame) 421 { 422 sts = pCore->DecreaseReference(&m_pInputFrame->Data); 423 MFX_CHECK_STS(sts); 424 m_pInputFrame = 0; 425 } 426 if (m_pRecFrame) 427 { 428 sts = pCore->DecreaseReference(&m_pRecFrame->Data); 429 MFX_CHECK_STS(sts); 430 m_pRecFrame = 0; 431 } 432 if (m_pRefFrame[0]) 433 { 434 sts = pCore->DecreaseReference(&m_pRefFrame[0]->Data); 435 MFX_CHECK_STS(sts); 436 m_pRefFrame[0] = 0; 437 } 438 if (m_pRefFrame[1]) 439 { 440 sts = pCore->DecreaseReference(&m_pRefFrame[1]->Data); 441 MFX_CHECK_STS(sts); 442 m_pRefFrame[1] = 0; 443 } 444 if (m_pRawFrame[0]) 445 { 446 sts = pCore->DecreaseReference(&m_pRawFrame[0]->Data); 447 MFX_CHECK_STS(sts); 448 m_pRawFrame[0] = 0; 449 } 450 if (m_pRawFrame[1]) 451 { 452 sts = pCore->DecreaseReference(&m_pRawFrame[1]->Data); 453 MFX_CHECK_STS(sts); 454 m_pRawFrame[1] = 0; 455 } 456 return sts; 457 } LockRefFrames(VideoCORE * pCore)458 mfxStatus FramesSet::LockRefFrames(VideoCORE* pCore) 459 { 460 mfxStatus sts = MFX_ERR_NONE; 461 462 if (m_pRefFrame[0]) 463 { 464 sts = pCore->IncreaseReference(&m_pRefFrame[0]->Data); 465 MFX_CHECK_STS(sts); 466 } 467 if (m_pRefFrame[1]) 468 { 469 sts = pCore->IncreaseReference(&m_pRefFrame[1]->Data); 470 MFX_CHECK_STS(sts); 471 } 472 if (m_pRawFrame[0]) 473 { 474 sts = pCore->IncreaseReference(&m_pRawFrame[0]->Data); 475 MFX_CHECK_STS(sts); 476 } 477 if (m_pRawFrame[1]) 478 { 479 sts = pCore->IncreaseReference(&m_pRawFrame[1]->Data); 480 MFX_CHECK_STS(sts); 481 } 482 return sts; 483 } 484 Query(VideoCORE * core,mfxVideoParam * in,mfxVideoParam * out,bool bAVBR_WA)485 mfxStatus ControllerBase::Query(VideoCORE * core, mfxVideoParam *in, mfxVideoParam *out, bool bAVBR_WA) 486 { 487 MFX_AUTO_LTRACE(MFX_TRACE_LEVEL_HOTSPOTS, "ControllerBase::Query"); 488 MFX_CHECK_NULL_PTR1(out); 489 if(in==0) 490 { 491 memset(&out->mfx, 0, sizeof(mfxInfoMFX)); 492 out->mfx.FrameInfo.FourCC = 1; 493 out->mfx.FrameInfo.Width = 1; 494 out->mfx.FrameInfo.Height = 1; 495 out->mfx.FrameInfo.CropX = 0; 496 out->mfx.FrameInfo.CropY = 0; 497 out->mfx.FrameInfo.CropW = 1; 498 out->mfx.FrameInfo.CropH = 1; 499 out->mfx.FrameInfo.ChromaFormat = 1; 500 out->mfx.FrameInfo.FrameRateExtN = 1; 501 out->mfx.FrameInfo.FrameRateExtD = 1; 502 out->mfx.FrameInfo.AspectRatioW = 1; 503 out->mfx.FrameInfo.AspectRatioH = 1; 504 out->mfx.FrameInfo.PicStruct = 1; 505 out->mfx.CodecProfile = 1; 506 out->mfx.CodecLevel = 1; 507 out->mfx.GopPicSize = 1; 508 out->mfx.GopRefDist = 1; 509 out->mfx.GopOptFlag = 1; 510 out->mfx.RateControlMethod = 1; // not sure, it is BRC 511 out->mfx.InitialDelayInKB = 1; // not sure, it is BRC 512 out->mfx.BufferSizeInKB = 1; // not sure, it is BRC 513 out->mfx.TargetKbps = 1; 514 out->mfx.MaxKbps = 1; // not sure, it is BRC 515 out->mfx.NumSlice = 1; 516 out->mfx.NumThread = 1; 517 out->mfx.TargetUsage = 1; 518 out->IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY; 519 out->AsyncDepth = 0; 520 out->Protected = 0; 521 522 MFX_CHECK_STS (CheckExtendedBuffers(out)); 523 mfxExtCodingOption* ext_out = GetExtCodingOptions(out->ExtParam,out->NumExtParam); 524 if (ext_out) 525 { 526 mfxU32 bufOffset = sizeof(mfxExtBuffer); 527 mfxU32 bufSize = sizeof(mfxExtCodingOption) - bufOffset; 528 529 memset ((mfxU8*)(ext_out) + bufOffset,0, bufSize); 530 531 ext_out->EndOfSequence = 1; 532 ext_out->FramePicture = 1; 533 } 534 mfxExtCodingOptionSPSPPS* pSPSPPS_out = GetExtCodingOptionsSPSPPS (out->ExtParam, out->NumExtParam); 535 if (pSPSPPS_out) 536 { 537 pSPSPPS_out->PPSBuffer = NULL; 538 pSPSPPS_out->PPSBufSize = 0; 539 pSPSPPS_out->SPSBuffer = NULL; 540 pSPSPPS_out->SPSBufSize = 0; 541 } 542 mfxExtVideoSignalInfo* pVideoSignal_out = GetExtVideoSignalInfo(out->ExtParam, out->NumExtParam); 543 if (pVideoSignal_out) 544 { 545 pVideoSignal_out->VideoFormat = 1; 546 pVideoSignal_out->ColourDescriptionPresent = 1; 547 pVideoSignal_out->ColourPrimaries = 1; 548 pVideoSignal_out->TransferCharacteristics = 1; 549 pVideoSignal_out->MatrixCoefficients = 1; 550 pVideoSignal_out->VideoFullRange = 0; 551 } 552 } 553 else 554 { 555 bool bUnsupported = false; 556 bool bWarning = false; 557 //bool bInvalid = false; 558 559 mfxExtCodingOptionSPSPPS* pSPSPPS_out = GetExtCodingOptionsSPSPPS (out->ExtParam, out->NumExtParam); 560 mfxExtCodingOptionSPSPPS* pSPSPPS_in = GetExtCodingOptionsSPSPPS (in->ExtParam, in->NumExtParam); 561 562 if (pSPSPPS_out && pSPSPPS_in) 563 { 564 if (pSPSPPS_in->SPSBuffer && pSPSPPS_out->SPSBuffer && pSPSPPS_out->SPSBufSize && pSPSPPS_in->SPSBufSize) 565 { 566 mfxU32 real_size = 0; 567 if (SHParametersEx::CheckSHParameters (pSPSPPS_in->SPSBuffer, pSPSPPS_in->SPSBufSize, real_size, out, 0)) 568 { 569 if (real_size <= pSPSPPS_out->SPSBufSize) 570 { 571 std::copy(pSPSPPS_in->SPSBuffer, pSPSPPS_in->SPSBuffer + real_size, pSPSPPS_out->SPSBuffer); 572 memset(pSPSPPS_out->SPSBuffer + real_size, 0, pSPSPPS_out->SPSBufSize - real_size); 573 } 574 else 575 { 576 memset(pSPSPPS_out->SPSBuffer, 0, pSPSPPS_out->SPSBufSize); 577 bUnsupported = true; 578 } 579 580 } 581 else 582 { 583 memset(pSPSPPS_out->SPSBuffer, 0, pSPSPPS_out->SPSBufSize); 584 bUnsupported = true; 585 } 586 } 587 else if (pSPSPPS_in->SPSBuffer || pSPSPPS_out->SPSBuffer || pSPSPPS_out->SPSBufSize || pSPSPPS_in->SPSBufSize) 588 { 589 bUnsupported = true; 590 } 591 } 592 else if (!(pSPSPPS_in == 0 && pSPSPPS_out ==0)) 593 { 594 bUnsupported = true; 595 } 596 597 out->mfx = in->mfx; 598 out->IOPattern = in->IOPattern; 599 out->Protected = in->Protected; 600 out->AsyncDepth = in->AsyncDepth; 601 602 mfxStatus stsCaps = CheckHwCaps(core, out); 603 604 MFX_CHECK_STS (CheckExtendedBuffers(in)); 605 MFX_CHECK_STS (CheckExtendedBuffers(out)); 606 607 if (out->Protected) 608 { 609 out->Protected = 0; 610 bUnsupported = true; 611 } 612 613 if (out->mfx.FrameInfo.FourCC != MFX_FOURCC_NV12 && out->mfx.FrameInfo.FourCC !=0) 614 { 615 out->mfx.FrameInfo.FourCC = 0; 616 bUnsupported = true; 617 } 618 619 mfxU16 ps = out->mfx.FrameInfo.PicStruct & (MFX_PICSTRUCT_PROGRESSIVE|MFX_PICSTRUCT_FIELD_TFF|MFX_PICSTRUCT_FIELD_BFF); 620 621 if (ps != MFX_PICSTRUCT_PROGRESSIVE && 622 ps != MFX_PICSTRUCT_FIELD_TFF && 623 ps != MFX_PICSTRUCT_FIELD_BFF && 624 ps != MFX_PICSTRUCT_UNKNOWN) 625 { 626 ps = MFX_PICSTRUCT_UNKNOWN; 627 bWarning = true; 628 } 629 if (out->mfx.FrameInfo.PicStruct != ps) 630 { 631 out->mfx.FrameInfo.PicStruct = ps; 632 bWarning = true; 633 } 634 635 mfxU16 t = (out->mfx.FrameInfo.PicStruct == MFX_PICSTRUCT_PROGRESSIVE) ? 0x0f:0x1f; 636 637 if ((out->mfx.FrameInfo.Width !=0 && out->mfx.FrameInfo.Height==0) || 638 (out->mfx.FrameInfo.Width ==0 && out->mfx.FrameInfo.Height!=0)) 639 { 640 out->mfx.FrameInfo.Width = 0; 641 out->mfx.FrameInfo.Height= 0; 642 bUnsupported = true; 643 } 644 if (out->mfx.FrameInfo.Width > 0x1fff ||(out->mfx.FrameInfo.Width & 0x0f)) 645 { 646 out->mfx.FrameInfo.Width = 0; 647 bUnsupported = true; 648 } 649 if (out->mfx.FrameInfo.Height > 0x1fff ||(out->mfx.FrameInfo.Height & t)) 650 { 651 out->mfx.FrameInfo.Height = 0; 652 bUnsupported = true; 653 } 654 655 if (out->mfx.FrameInfo.CropX != 0) 656 { 657 out->mfx.FrameInfo.CropX = 0; 658 bUnsupported = true; 659 } 660 if (out->mfx.FrameInfo.CropY != 0) 661 { 662 out->mfx.FrameInfo.CropY = 0; 663 bUnsupported = true; 664 } 665 666 /* 667 if (out->mfx.FrameInfo.CropW > out->mfx.FrameInfo.Width) 668 { 669 out->mfx.FrameInfo.CropW = 0; 670 bUnsupported = true; 671 } 672 if (out->mfx.FrameInfo.CropH > out->mfx.FrameInfo.Height) 673 { 674 out->mfx.FrameInfo.CropH = 0; 675 bUnsupported = true; 676 }*/ 677 678 switch(out->IOPattern) 679 { 680 case 0: 681 case MFX_IOPATTERN_IN_VIDEO_MEMORY: 682 case MFX_IOPATTERN_IN_SYSTEM_MEMORY: 683 case MFX_IOPATTERN_IN_OPAQUE_MEMORY: 684 break; 685 default: 686 bWarning = true; 687 if (out->IOPattern & MFX_IOPATTERN_IN_VIDEO_MEMORY) 688 out->IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY; 689 else if (in->IOPattern & MFX_IOPATTERN_IN_OPAQUE_MEMORY) 690 out->IOPattern = MFX_IOPATTERN_IN_OPAQUE_MEMORY; 691 else if (out->IOPattern & MFX_IOPATTERN_IN_SYSTEM_MEMORY) 692 out->IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY; 693 else 694 out->IOPattern = MFX_IOPATTERN_IN_VIDEO_MEMORY; 695 } 696 697 mfxExtCodingOption* ext_in = GetExtCodingOptions(in->ExtParam, in->NumExtParam); 698 mfxExtCodingOption* ext_out = GetExtCodingOptions(out->ExtParam,out->NumExtParam); 699 700 MFX_CHECK ((ext_in !=0 && ext_out != 0) || (ext_in == 0 && ext_out == 0), MFX_ERR_UNDEFINED_BEHAVIOR ); 701 702 if (ext_in && ext_out) 703 { 704 mfxExtCodingOption temp = {}; 705 706 mfxU32 bufOffset = sizeof(mfxExtBuffer); 707 mfxU32 bufSize = sizeof(mfxExtCodingOption) - bufOffset; 708 709 temp = *ext_in; 710 711 memset ((mfxU8*)(ext_out) + bufOffset,0, bufSize); 712 713 ext_out->EndOfSequence = temp.EndOfSequence; 714 ext_out->FramePicture = temp.FramePicture; 715 716 bWarning = bWarning || (memcmp((mfxU8*)(ext_out) + bufOffset,(mfxU8*)(&temp) + bufOffset, bufSize)!= 0); 717 bUnsupported = bUnsupported || (temp.FieldOutput == MFX_CODINGOPTION_ON); 718 } 719 720 mfxExtVideoSignalInfo* pVideoSignal_out = GetExtVideoSignalInfo(out->ExtParam, out->NumExtParam); 721 mfxExtVideoSignalInfo* pVideoSignal_in = GetExtVideoSignalInfo(in->ExtParam, in->NumExtParam); 722 723 MFX_CHECK ((pVideoSignal_in == 0) == (pVideoSignal_out == 0), MFX_ERR_UNDEFINED_BEHAVIOR ); 724 725 if (pVideoSignal_in && pVideoSignal_out) 726 { 727 *pVideoSignal_out = *pVideoSignal_in; 728 729 if (CheckExtVideoSignalInfo(pVideoSignal_out) == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) 730 { 731 bWarning = true; 732 } 733 } 734 735 if ((out->mfx.FrameInfo.Width!= 0 && out->mfx.FrameInfo.CropW > out->mfx.FrameInfo.Width) || 736 (out->mfx.FrameInfo.CropW == 0 && out->mfx.FrameInfo.CropH != 0)) 737 { 738 bWarning = true; 739 out->mfx.FrameInfo.CropW = out->mfx.FrameInfo.Width; 740 } 741 742 if ((out->mfx.FrameInfo.Height != 0 && out->mfx.FrameInfo.CropH > out->mfx.FrameInfo.Height)|| 743 (out->mfx.FrameInfo.CropW != 0 && out->mfx.FrameInfo.CropH == 0)) 744 { 745 bWarning = true; 746 out->mfx.FrameInfo.CropH = out->mfx.FrameInfo.Height; 747 } 748 749 if (out->mfx.FrameInfo.CropX || out->mfx.FrameInfo.CropY) 750 { 751 out->mfx.FrameInfo.CropX = 0; 752 out->mfx.FrameInfo.CropY = 0; 753 bWarning = true; 754 } 755 756 if (out->mfx.FrameInfo.FrameRateExtN !=0 && out->mfx.FrameInfo.FrameRateExtD != 0) 757 { 758 mfxStatus sts = CheckFrameRateMPEG2(out->mfx.FrameInfo.FrameRateExtD, out->mfx.FrameInfo.FrameRateExtN); 759 if (sts != MFX_ERR_NONE) 760 { 761 bWarning = true; 762 } 763 } 764 else 765 { 766 if (out->mfx.FrameInfo.FrameRateExtN !=0 || out->mfx.FrameInfo.FrameRateExtD != 0) 767 { 768 out->mfx.FrameInfo.FrameRateExtN = 0; 769 out->mfx.FrameInfo.FrameRateExtD = 0; 770 bUnsupported = true; 771 } 772 } 773 774 775 if ((out->mfx.TargetUsage < MFX_TARGETUSAGE_BEST_QUALITY || out->mfx.TargetUsage > MFX_TARGETUSAGE_BEST_SPEED)&& 776 out->mfx.TargetUsage !=0) 777 { 778 out->mfx.TargetUsage = MFX_TARGETUSAGE_UNKNOWN; 779 bWarning = true; 780 } 781 782 783 if (out->mfx.FrameInfo.ChromaFormat != 0 && 784 out->mfx.FrameInfo.ChromaFormat != MFX_CHROMAFORMAT_YUV420) 785 { 786 out->mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420; 787 bWarning = true; 788 } 789 790 mfxStatus sts = CheckAspectRatioMPEG2( 791 out->mfx.FrameInfo.AspectRatioW, 792 out->mfx.FrameInfo.AspectRatioH, 793 out->mfx.FrameInfo.Width, 794 out->mfx.FrameInfo.Height, 795 out->mfx.FrameInfo.CropW, 796 out->mfx.FrameInfo.CropH); 797 798 if (sts != MFX_ERR_NONE) 799 { 800 bWarning = true; 801 if (sts < MFX_ERR_NONE) 802 { 803 out->mfx.FrameInfo.AspectRatioW = 1; 804 out->mfx.FrameInfo.AspectRatioH = 1; 805 } 806 } 807 808 if (out->mfx.CodecProfile != MFX_PROFILE_MPEG2_SIMPLE && 809 out->mfx.CodecProfile != MFX_PROFILE_MPEG2_MAIN && 810 out->mfx.CodecProfile != MFX_PROFILE_MPEG2_HIGH && 811 out->mfx.CodecProfile != MFX_PROFILE_UNKNOWN) 812 { 813 out->mfx.CodecProfile = MFX_PROFILE_UNKNOWN; 814 bWarning = true; 815 } 816 if (out->mfx.CodecLevel != MFX_LEVEL_MPEG2_LOW && 817 out->mfx.CodecLevel != MFX_LEVEL_MPEG2_MAIN && 818 out->mfx.CodecLevel != MFX_LEVEL_MPEG2_HIGH1440 && 819 out->mfx.CodecLevel != MFX_LEVEL_MPEG2_HIGH && 820 out->mfx.CodecLevel != MFX_LEVEL_UNKNOWN) 821 { 822 out->mfx.CodecLevel = MFX_LEVEL_UNKNOWN; 823 bWarning = true; 824 } 825 if (CorrectProfileLevelMpeg2(out->mfx.CodecProfile, out->mfx.CodecLevel, 826 out->mfx.FrameInfo.Width, out->mfx.FrameInfo.Height, 827 CalculateUMCFramerate(out->mfx.FrameInfo.FrameRateExtN, out->mfx.FrameInfo.FrameRateExtD), 828 out->mfx.RateControlMethod == MFX_RATECONTROL_CQP ? 0 : (mfxU32)(out->mfx.TargetKbps * out->mfx.BRCParamMultiplier * BRC_BITS_IN_KBIT), 829 out->mfx.GopRefDist)) 830 { 831 bWarning = true; 832 } 833 834 if (bAVBR_WA) 835 { 836 bWarning = AVBR_via_CBR(out) ? true : bWarning; 837 } 838 839 840 // invalid modes 841 if (out->mfx.RateControlMethod == MFX_RATECONTROL_VCM || 842 out->mfx.RateControlMethod == MFX_RATECONTROL_ICQ || 843 out->mfx.RateControlMethod == MFX_RATECONTROL_QVBR || 844 out->mfx.RateControlMethod == MFX_RATECONTROL_LA || 845 out->mfx.RateControlMethod == MFX_RATECONTROL_LA_ICQ || 846 out->mfx.RateControlMethod == MFX_RATECONTROL_LA_EXT || 847 out->mfx.RateControlMethod == MFX_RATECONTROL_LA_HRD || 848 out->mfx.RateControlMethod == MFX_RATECONTROL_RESERVED1 || 849 out->mfx.RateControlMethod == MFX_RATECONTROL_RESERVED2 || 850 out->mfx.RateControlMethod == MFX_RATECONTROL_RESERVED3 || 851 out->mfx.RateControlMethod == MFX_RATECONTROL_RESERVED4) 852 { 853 out->mfx.RateControlMethod = 0; 854 bUnsupported = true; 855 } 856 857 // unknown mode - set to VBR with warning 858 if (out->mfx.RateControlMethod != MFX_RATECONTROL_CBR && 859 out->mfx.RateControlMethod != MFX_RATECONTROL_VBR && 860 out->mfx.RateControlMethod != MFX_RATECONTROL_AVBR && 861 out->mfx.RateControlMethod != MFX_RATECONTROL_CQP && 862 out->mfx.RateControlMethod != 0) 863 { 864 out->mfx.RateControlMethod = MFX_RATECONTROL_VBR; 865 bWarning = true; 866 } 867 868 mfxExtCodingOption2 * extOpt2 = (mfxExtCodingOption2 *)GetExtendedBuffer(out->ExtParam, out->NumExtParam, MFX_EXTBUFF_CODING_OPTION2); 869 if (extOpt2 && extOpt2->SkipFrame) 870 { 871 // TODO: check hwCaps 872 if (extOpt2->SkipFrame != MFX_SKIPFRAME_INSERT_DUMMY || out->mfx.RateControlMethod != MFX_RATECONTROL_CQP) 873 { 874 extOpt2->SkipFrame = 0; 875 bWarning = true; 876 } 877 } 878 879 mfxExtCodingOption3 * extOpt3 = (mfxExtCodingOption3 *)GetExtendedBuffer(out->ExtParam, out->NumExtParam, MFX_EXTBUFF_CODING_OPTION3); 880 if (extOpt3 && extOpt3->EnableMBQP == MFX_CODINGOPTION_ON) 881 { 882 if (out->mfx.RateControlMethod != MFX_RATECONTROL_CQP) 883 { 884 extOpt3->EnableMBQP = MFX_CODINGOPTION_OFF; 885 bWarning = true; 886 } 887 // MPEG2 MBQP currently only supported on Linux 888 if (core->GetVAType() != MFX_HW_VAAPI) 889 { 890 extOpt3->EnableMBQP = MFX_CODINGOPTION_OFF; 891 bUnsupported = true; 892 } 893 } 894 if (extOpt3 && extOpt3->EnableMBQP == MFX_CODINGOPTION_UNKNOWN) 895 { 896 extOpt3->EnableMBQP = MFX_CODINGOPTION_OFF; 897 } 898 899 if (extOpt3 && (extOpt3->WeightedPred != MFX_WEIGHTED_PRED_UNKNOWN || extOpt3->WeightedBiPred != MFX_WEIGHTED_PRED_UNKNOWN)) 900 { 901 extOpt3->WeightedPred = 0; 902 bUnsupported = true; 903 } 904 905 if (extOpt3 && (extOpt3->FadeDetection == MFX_CODINGOPTION_ON)) 906 { 907 extOpt3->FadeDetection = 0; 908 bUnsupported = true; 909 } 910 911 mfxU16 gof = out->mfx.GopOptFlag & (MFX_GOP_CLOSED | MFX_GOP_STRICT); 912 if (out->mfx.GopOptFlag != gof) 913 { 914 out->mfx.GopOptFlag = gof; 915 bWarning = true; 916 } 917 918 if (extOpt3 && extOpt3->BRCPanicMode == MFX_CODINGOPTION_OFF) 919 { 920 // MPEG2 BRC panic mode disabling currently only supported on Linux 921 if ((core->GetVAType() != MFX_HW_VAAPI) 922 || (out->mfx.RateControlMethod != MFX_RATECONTROL_CBR 923 && out->mfx.RateControlMethod != MFX_RATECONTROL_VBR 924 && out->mfx.RateControlMethod != MFX_RATECONTROL_AVBR)) 925 { 926 extOpt3->BRCPanicMode = MFX_CODINGOPTION_UNKNOWN; 927 bUnsupported = true; 928 } 929 } 930 931 MFX_CHECK_STS(stsCaps); 932 933 if (bUnsupported) 934 { 935 return MFX_ERR_UNSUPPORTED; 936 } 937 /* Unreachable code is commented out 938 if(bInvalid) 939 return MFX_ERR_INVALID_VIDEO_PARAM;*/ 940 if (bWarning) 941 { 942 return MFX_WRN_INCOMPATIBLE_VIDEO_PARAM; 943 } 944 945 } 946 return MFX_ERR_NONE; 947 } 948 QueryIOSurf(VideoCORE * core,mfxVideoParam * par,mfxFrameAllocRequest * request)949 mfxStatus ControllerBase::QueryIOSurf(VideoCORE * core, mfxVideoParam *par, mfxFrameAllocRequest *request) 950 { 951 MFX_AUTO_LTRACE(MFX_TRACE_LEVEL_HOTSPOTS, "ControllerBase::QueryIOSurf"); 952 mfxVideoParamEx_MPEG2 videoParamEx = {}; 953 954 MFX_CHECK_NULL_PTR1(par); 955 MFX_CHECK_NULL_PTR1(request); 956 CHECK_VERSION(par->Version); 957 CHECK_CODEC_ID(par->mfx.CodecId, MFX_CODEC_MPEG2); 958 MFX_CHECK (CheckExtendedBuffers(par) == MFX_ERR_NONE, MFX_ERR_INVALID_VIDEO_PARAM); 959 960 mfxStatus sts = core->IsGuidSupported(DXVA2_Intel_Encode_MPEG2, par, true); 961 MFX_CHECK_STS(sts); 962 963 mfxExtCodingOption* ext = GetExtCodingOptions(par->ExtParam, par->NumExtParam); 964 mfxExtCodingOptionSPSPPS* pSPSPPS = GetExtCodingOptionsSPSPPS (par->ExtParam, par->NumExtParam); 965 966 mfxVideoParam parFromSpsPps = {}; 967 968 mfxExtCodingOption extFromSpsPps = {}; 969 970 if (pSPSPPS) 971 { 972 parFromSpsPps = *par; 973 if (ext) 974 extFromSpsPps = *ext; 975 976 //mfxStatus sts = MFX_ERR_NONE; 977 mfxU32 real_len = 0; 978 MFX_CHECK(pSPSPPS->PPSBufSize == 0, MFX_ERR_INVALID_VIDEO_PARAM); 979 MFX_CHECK(!pSPSPPS->PPSBuffer, MFX_ERR_INVALID_VIDEO_PARAM); 980 981 if (!SHParametersEx::CheckSHParameters(pSPSPPS->SPSBuffer, pSPSPPS->SPSBufSize, real_len, &parFromSpsPps, &extFromSpsPps)) 982 return MFX_ERR_INVALID_VIDEO_PARAM; 983 984 par = &parFromSpsPps; 985 ext = &extFromSpsPps; 986 } 987 988 ENCODE_CAPS EncCaps = {}; 989 990 sts = CheckHwCaps(core, par, ext, &EncCaps); 991 MFX_CHECK_STS(sts); 992 993 mfxU32 mask = (par->mfx.FrameInfo.PicStruct & MFX_PICSTRUCT_PROGRESSIVE)? 0x0f:0x1f; 994 if ((par->mfx.FrameInfo.Width & 0x0f) != 0 || (par->mfx.FrameInfo.Height & mask) != 0 ) 995 { 996 return MFX_ERR_INVALID_VIDEO_PARAM; 997 } 998 videoParamEx.mfxVideoParams = *par; 999 ApplyTargetUsage (&videoParamEx); 1000 1001 if ((par->IOPattern & (MFX_IOPATTERN_IN_VIDEO_MEMORY|MFX_IOPATTERN_IN_SYSTEM_MEMORY)) == MFX_IOPATTERN_IN_VIDEO_MEMORY || 1002 ((par->IOPattern & (MFX_IOPATTERN_IN_VIDEO_MEMORY|MFX_IOPATTERN_IN_SYSTEM_MEMORY|MFX_IOPATTERN_IN_OPAQUE_MEMORY))== MFX_IOPATTERN_IN_OPAQUE_MEMORY)) 1003 { 1004 request->Info = videoParamEx.mfxVideoParams.mfx.FrameInfo ; 1005 request->NumFrameMin = videoParamEx.mfxVideoParams.mfx.GopRefDist + 3; 1006 request->NumFrameSuggested = request->NumFrameMin; 1007 request->Type = (par->IOPattern & MFX_IOPATTERN_IN_OPAQUE_MEMORY) 1008 ? MFX_MEMTYPE_FROM_ENCODE|MFX_MEMTYPE_OPAQUE_FRAME |MFX_MEMTYPE_DXVA2_DECODER_TARGET 1009 : MFX_MEMTYPE_FROM_ENCODE|MFX_MEMTYPE_EXTERNAL_FRAME|MFX_MEMTYPE_DXVA2_DECODER_TARGET; 1010 } 1011 else if ((par->IOPattern & (MFX_IOPATTERN_IN_VIDEO_MEMORY|MFX_IOPATTERN_IN_SYSTEM_MEMORY))==MFX_IOPATTERN_IN_SYSTEM_MEMORY) 1012 { 1013 request->Info = videoParamEx.mfxVideoParams.mfx.FrameInfo; 1014 request->NumFrameMin = videoParamEx.mfxVideoParams.mfx.GopRefDist + 3; 1015 request->NumFrameSuggested = request->NumFrameMin; 1016 request->Type = MFX_MEMTYPE_FROM_ENCODE|MFX_MEMTYPE_EXTERNAL_FRAME|MFX_MEMTYPE_SYSTEM_MEMORY; 1017 } 1018 else 1019 { 1020 return MFX_ERR_INVALID_VIDEO_PARAM; 1021 } 1022 if (ext && (ext->EndOfSequence==MFX_CODINGOPTION_ON)) 1023 { 1024 request->NumFrameMin = request->NumFrameMin*2+1; 1025 request->NumFrameSuggested = request->NumFrameSuggested*2+1; 1026 } 1027 if (EncCaps.EncodeFunc) 1028 { 1029 request->NumFrameMin = request->NumFrameMin + videoParamEx.mfxVideoParams.AsyncDepth; 1030 request->NumFrameSuggested = request->NumFrameSuggested + videoParamEx.mfxVideoParams.AsyncDepth; 1031 } 1032 1033 return MFX_ERR_NONE; 1034 } 1035 UnlockFrames(MFXGOP * pGOP,MFXWaitingList * pWaitingList,VideoCORE * pcore)1036 mfxStatus UnlockFrames (MFXGOP* pGOP, MFXWaitingList* pWaitingList, VideoCORE* pcore) 1037 { 1038 mfxStatus sts = MFX_ERR_NONE; 1039 if (pGOP !=0) 1040 { 1041 pGOP->CloseGop(false); 1042 for (;;) 1043 { 1044 sFrameEx fr = {}; 1045 if (!pGOP->GetFrameExForDecoding(&fr,0,0,0)) 1046 { 1047 break; 1048 } 1049 sts = pcore->DecreaseReference(&fr.m_pFrame->Data); 1050 MFX_CHECK_STS(sts); 1051 pGOP->ReleaseCurrentFrame(); 1052 } 1053 } 1054 if (pWaitingList) 1055 { 1056 for (;;) 1057 { 1058 sFrameEx fr = {}; 1059 if (!pWaitingList->GetFrameEx(&fr)) 1060 { 1061 break; 1062 } 1063 sts = pcore->DecreaseReference(&fr.m_pFrame->Data); 1064 MFX_CHECK_STS(sts); 1065 pWaitingList->MoveOnNextFrame(); 1066 } 1067 } 1068 return sts; 1069 } ControllerBase(VideoCORE * core,bool bAVBR_WA)1070 ControllerBase::ControllerBase(VideoCORE *core, bool bAVBR_WA ) 1071 : m_pCore (core) 1072 , m_nEncodeCalls(0) 1073 , m_nFrameInGOP(0) 1074 , m_pGOP(0) 1075 , m_pWaitingList(0) 1076 , m_InputFrameOrder(-1) 1077 , m_OutputFrameOrder(-1) 1078 , m_BitstreamLen (0) 1079 , m_InputSurfaces(core) 1080 , m_InitWidth(0) 1081 , m_InitHeight(0) 1082 , m_bInitialized (false) 1083 , m_bAVBR_WA (bAVBR_WA) 1084 { 1085 memset (&m_VideoParamsEx, 0, sizeof(m_VideoParamsEx)); 1086 } Reset(mfxVideoParam * par,bool bAllowRawFrames)1087 mfxStatus ControllerBase::Reset(mfxVideoParam *par, bool bAllowRawFrames) 1088 { 1089 mfxStatus sts = MFX_ERR_NONE; 1090 1091 bool bProgressiveSequence = false; 1092 mfxFrameInfo *pFrameInfo = 0; 1093 bool bCorrected = false; 1094 bool bUnsupported = false; 1095 bool bInvalid = false; 1096 eMFXHWType type = m_pCore->GetHWType(); 1097 1098 1099 MFX_CHECK_NULL_PTR1(par); 1100 CHECK_VERSION(par->Version); 1101 CHECK_CODEC_ID(par->mfx.CodecId, MFX_CODEC_MPEG2); 1102 MFX_CHECK(CheckExtendedBuffers(par) == MFX_ERR_NONE, MFX_ERR_INVALID_VIDEO_PARAM); 1103 1104 memset(&m_VideoParamsEx,0,sizeof(mfxVideoParamEx_MPEG2)); 1105 m_VideoParamsEx.mfxVideoParams.mfx = par->mfx; 1106 m_VideoParamsEx.mfxVideoParams.IOPattern = par->IOPattern; 1107 m_VideoParamsEx.mfxVideoParams.Protected = par->Protected; 1108 m_VideoParamsEx.mfxVideoParams.AsyncDepth = par->AsyncDepth == 0 ? 2: par->AsyncDepth; 1109 1110 1111 if (m_VideoParamsEx.mfxVideoParams.mfx.BRCParamMultiplier == 0) 1112 m_VideoParamsEx.mfxVideoParams.mfx.BRCParamMultiplier = 1; 1113 1114 /*-------------------Check and correct parameters:---------------------*/ 1115 sts = CheckVideoParamEncoders(par, m_pCore->IsExternalFrameAllocator(), type); 1116 MFX_CHECK_STS(sts); 1117 1118 MFX_CHECK(par->Protected == 0,MFX_ERR_INVALID_VIDEO_PARAM); 1119 1120 mfxExtCodingOption extFromSpsPps = {}; 1121 mfxExtCodingOption* ext = GetExtCodingOptions(par->ExtParam, par->NumExtParam); 1122 1123 1124 if (mfxExtCodingOptionSPSPPS* pSPSPPS = GetExtCodingOptionsSPSPPS (par->ExtParam, par->NumExtParam)) 1125 { 1126 MFX_CHECK(pSPSPPS->PPSBufSize == 0, MFX_ERR_INVALID_VIDEO_PARAM); 1127 MFX_CHECK(!pSPSPPS->PPSBuffer, MFX_ERR_INVALID_VIDEO_PARAM); 1128 1129 mfxU32 real_len = 0; 1130 if (ext != 0) 1131 { 1132 extFromSpsPps = *ext; 1133 } 1134 if (!SHParametersEx::CheckSHParameters(pSPSPPS->SPSBuffer, pSPSPPS->SPSBufSize, real_len, &m_VideoParamsEx.mfxVideoParams, &extFromSpsPps)) 1135 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM; 1136 1137 ext = &extFromSpsPps; 1138 } 1139 1140 if (mfxExtVideoSignalInfo* pVideoSignalInfo = GetExtVideoSignalInfo(par->ExtParam, par->NumExtParam)) 1141 { 1142 m_VideoParamsEx.videoSignalInfo = *pVideoSignalInfo; 1143 m_VideoParamsEx.bAddDisplayExt = true; 1144 } 1145 else 1146 { 1147 m_VideoParamsEx.bAddDisplayExt = false; 1148 } 1149 1150 1151 sts = CheckHwCaps(m_pCore, &m_VideoParamsEx.mfxVideoParams, ext); 1152 if (sts != MFX_ERR_NONE) 1153 { 1154 return is_initialized() 1155 ? MFX_ERR_INVALID_VIDEO_PARAM // reset can't return partial acceleration 1156 : MFX_WRN_PARTIAL_ACCELERATION; 1157 } 1158 m_nEncodeCalls = 0; 1159 m_nFrameInGOP = 0; 1160 1161 pFrameInfo = &m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo; 1162 1163 switch (pFrameInfo->PicStruct) 1164 { 1165 case MFX_PICSTRUCT_PROGRESSIVE: 1166 bProgressiveSequence = true; 1167 break; 1168 case MFX_PICSTRUCT_FIELD_TFF: 1169 case MFX_PICSTRUCT_UNKNOWN: 1170 case MFX_PICSTRUCT_FIELD_BFF: 1171 break; 1172 default: 1173 return MFX_ERR_INVALID_VIDEO_PARAM; 1174 } 1175 if (pFrameInfo->CropX!=0 || pFrameInfo->CropY!=0 || 1176 pFrameInfo->Width > 0x1fff || pFrameInfo->Height > 0x1fff || 1177 pFrameInfo->CropW > pFrameInfo->Width || 1178 pFrameInfo->CropH > pFrameInfo->Height) 1179 return MFX_ERR_INVALID_VIDEO_PARAM; 1180 1181 sts = CheckFrameRateMPEG2(pFrameInfo->FrameRateExtD,pFrameInfo->FrameRateExtN); 1182 if (sts == MFX_WRN_INCOMPATIBLE_VIDEO_PARAM) 1183 { 1184 bCorrected = true; 1185 } 1186 else if (sts == MFX_ERR_INVALID_VIDEO_PARAM) 1187 { 1188 bInvalid = true; 1189 } 1190 if ((pFrameInfo->Width & 15) != 0) 1191 return MFX_ERR_INVALID_VIDEO_PARAM; 1192 1193 if (pFrameInfo->CropW) 1194 pFrameInfo->Width = mfx::align2_value(pFrameInfo->CropW, 16); 1195 1196 mfxU32 heightAlignment = bProgressiveSequence ? 16 : 32; 1197 1198 if ((pFrameInfo->Height & (heightAlignment - 1)) != 0) 1199 return MFX_ERR_INVALID_VIDEO_PARAM; 1200 1201 if (pFrameInfo->CropH) 1202 pFrameInfo->Height = mfx::align2_value(pFrameInfo->CropH, heightAlignment); 1203 1204 if (m_bInitialized == false) 1205 { 1206 m_InitWidth = pFrameInfo->Width; 1207 m_InitHeight = pFrameInfo->Height; 1208 } 1209 else if (m_InitWidth < pFrameInfo->Width || m_InitHeight < pFrameInfo->Height) 1210 { 1211 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM; 1212 } 1213 1214 if (ext) 1215 { 1216 mfxExtCodingOption temp = {}; 1217 1218 mfxU32 bufOffset = sizeof(mfxExtBuffer); 1219 mfxU32 bufSize = sizeof(mfxExtCodingOption) - bufOffset; 1220 temp.EndOfSequence = ext->EndOfSequence; 1221 temp.FramePicture = ext->FramePicture; 1222 1223 bCorrected = bCorrected || (memcmp((mfxU8*)(ext) + bufOffset,(mfxU8*)(&temp) + bufOffset, bufSize)!= 0); 1224 bUnsupported = bUnsupported || (ext->FieldOutput == MFX_CODINGOPTION_ON); 1225 1226 } 1227 m_VideoParamsEx.bFieldCoding = false; 1228 if (!bProgressiveSequence) 1229 { 1230 m_VideoParamsEx.bFieldCoding = (ext && ext->FramePicture == MFX_CODINGOPTION_OFF)? true:false; 1231 } 1232 1233 sts = CheckAspectRatioMPEG2( 1234 pFrameInfo->AspectRatioW, 1235 pFrameInfo->AspectRatioH, 1236 pFrameInfo->Width, 1237 pFrameInfo->Height, 1238 pFrameInfo->CropW, 1239 pFrameInfo->CropH); 1240 1241 if (sts < 0) 1242 { 1243 if (!m_bInitialized) 1244 { 1245 pFrameInfo->AspectRatioW = 0; 1246 pFrameInfo->AspectRatioH = 0; 1247 bInvalid = true; 1248 } 1249 else 1250 { 1251 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM; 1252 } 1253 } 1254 if (m_bAVBR_WA) 1255 { 1256 bCorrected = AVBR_via_CBR(&m_VideoParamsEx.mfxVideoParams) ? true : bCorrected; 1257 } 1258 1259 mfxU16& RateControl = m_VideoParamsEx.mfxVideoParams.mfx.RateControlMethod; 1260 1261 // invalid modes 1262 if (RateControl == MFX_RATECONTROL_VCM || 1263 RateControl == MFX_RATECONTROL_ICQ || 1264 RateControl == MFX_RATECONTROL_QVBR || 1265 RateControl == MFX_RATECONTROL_LA || 1266 RateControl == MFX_RATECONTROL_LA_ICQ || 1267 RateControl == MFX_RATECONTROL_LA_EXT || 1268 RateControl == MFX_RATECONTROL_LA_HRD || 1269 RateControl == MFX_RATECONTROL_RESERVED1 || 1270 RateControl == MFX_RATECONTROL_RESERVED2 || 1271 RateControl == MFX_RATECONTROL_RESERVED3 || 1272 RateControl == MFX_RATECONTROL_RESERVED4) 1273 { 1274 return MFX_ERR_INVALID_VIDEO_PARAM; 1275 } 1276 1277 // unknown mode - set to VBR with warning 1278 if (RateControl != MFX_RATECONTROL_CBR && 1279 RateControl != MFX_RATECONTROL_VBR && 1280 RateControl != MFX_RATECONTROL_AVBR && 1281 RateControl != MFX_RATECONTROL_CQP) 1282 { 1283 /*if RateControlMethod was undefined MSDK have to use default one */ 1284 RateControl = MFX_RATECONTROL_VBR; 1285 bCorrected = true; 1286 } 1287 1288 mfxExtCodingOption2 * extOpt2 = (mfxExtCodingOption2 *)GetExtendedBuffer(par->ExtParam, par->NumExtParam, MFX_EXTBUFF_CODING_OPTION2); 1289 if (extOpt2 && extOpt2->SkipFrame) 1290 { 1291 1292 } 1293 1294 mfxExtCodingOption3 * extOpt3 = (mfxExtCodingOption3 *)GetExtendedBuffer(par->ExtParam, par->NumExtParam, MFX_EXTBUFF_CODING_OPTION3); 1295 if (extOpt3 && extOpt3->EnableMBQP == MFX_CODINGOPTION_ON) 1296 { 1297 // MPEG2 MBQP currently only supported on Linux and only valid for CQP mode 1298 if (m_pCore->GetVAType() != MFX_HW_VAAPI) 1299 { 1300 extOpt3->EnableMBQP = MFX_CODINGOPTION_OFF; 1301 return MFX_ERR_UNSUPPORTED; 1302 } 1303 if (m_VideoParamsEx.mfxVideoParams.mfx.RateControlMethod != MFX_RATECONTROL_CQP) 1304 { 1305 extOpt3->EnableMBQP = MFX_CODINGOPTION_OFF; 1306 bCorrected = true; // return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM; 1307 } 1308 else 1309 { 1310 m_VideoParamsEx.bMbqpMode = true; 1311 } 1312 } 1313 1314 if (extOpt3 && extOpt3->BRCPanicMode == MFX_CODINGOPTION_OFF) 1315 { 1316 // MPEG2 BRC panic mode disabling currently only supported on Linux and only valid for non-CQP modes 1317 const mfxU16 selectedRateControl = m_VideoParamsEx.mfxVideoParams.mfx.RateControlMethod; 1318 if (selectedRateControl != MFX_RATECONTROL_CBR 1319 && selectedRateControl != MFX_RATECONTROL_VBR 1320 && selectedRateControl != MFX_RATECONTROL_AVBR) 1321 { 1322 extOpt3->BRCPanicMode = MFX_CODINGOPTION_UNKNOWN; 1323 bCorrected = true; 1324 } 1325 if (m_pCore->GetVAType() != MFX_HW_VAAPI) 1326 { 1327 extOpt3->BRCPanicMode = MFX_CODINGOPTION_UNKNOWN; 1328 return MFX_ERR_UNSUPPORTED; 1329 } 1330 1331 m_VideoParamsEx.bDisablePanicMode = true; 1332 } 1333 1334 if (extOpt3 && (extOpt3->WeightedPred != MFX_WEIGHTED_PRED_UNKNOWN || extOpt3->WeightedBiPred != MFX_WEIGHTED_PRED_UNKNOWN || extOpt3->FadeDetection == MFX_CODINGOPTION_ON)) 1335 { 1336 return MFX_ERR_INVALID_VIDEO_PARAM; 1337 } 1338 1339 double fr = CalculateUMCFramerate(m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.FrameRateExtN, 1340 m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.FrameRateExtD); 1341 1342 if (CorrectProfileLevelMpeg2(m_VideoParamsEx.mfxVideoParams.mfx.CodecProfile, 1343 m_VideoParamsEx.mfxVideoParams.mfx.CodecLevel, 1344 m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.Width, 1345 m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.Height, 1346 fr, 1347 m_VideoParamsEx.mfxVideoParams.mfx.RateControlMethod == MFX_RATECONTROL_CQP 1348 ? 0 1349 : (mfxU32)(m_VideoParamsEx.mfxVideoParams.mfx.TargetKbps * m_VideoParamsEx.mfxVideoParams.mfx.BRCParamMultiplier * BRC_BITS_IN_KBIT), 1350 m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist)) 1351 bCorrected = true;; 1352 1353 ApplyTargetUsage(&m_VideoParamsEx); 1354 1355 m_InputFrameOrder = -1; 1356 m_OutputFrameOrder= -1; 1357 m_BitstreamLen = 0; 1358 1359 m_VideoParamsEx.bAddEOS = (ext && (ext->EndOfSequence == MFX_CODINGOPTION_ON)); 1360 1361 sts = UnlockFrames (m_pGOP, m_pWaitingList,m_pCore); 1362 MFX_CHECK_STS(sts); 1363 1364 mfxU16 GopRefDist = m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist; 1365 1366 mfxI32 maxFramesInWaitingList = 0; 1367 mfxI32 minFramesInWaitingList = 0; 1368 mfxI32 delayInWaitingList = 0; 1369 1370 1371 if (par->mfx.EncodedOrder) 1372 { 1373 maxFramesInWaitingList = m_VideoParamsEx.mfxVideoParams.AsyncDepth + ((m_VideoParamsEx.bAddEOS)? 1 : 0); 1374 minFramesInWaitingList = (m_VideoParamsEx.bAddEOS)? 1 : 0; 1375 delayInWaitingList = minFramesInWaitingList + m_VideoParamsEx.mfxVideoParams.AsyncDepth - 1; 1376 } 1377 else 1378 { 1379 maxFramesInWaitingList = (GopRefDist + 1)*3; 1380 minFramesInWaitingList = ((m_VideoParamsEx.bAddEOS)? 1 : 0); 1381 delayInWaitingList = GopRefDist + minFramesInWaitingList; 1382 } 1383 1384 if (m_pGOP) 1385 { 1386 if (m_pGOP->GetMaxBFrames() < GopRefDist - 1) 1387 { 1388 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM; 1389 } 1390 m_pGOP->Reset(m_VideoParamsEx.mfxVideoParams.mfx.GopOptFlag&MFX_GOP_CLOSED, m_VideoParamsEx.mfxVideoParams.mfx.IdrInterval,ext && ext->EndOfSequence !=0,m_VideoParamsEx.mfxVideoParams.mfx.EncodedOrder!=0); 1391 } 1392 else 1393 { 1394 m_pGOP = new MFXGOP; 1395 if (!m_pGOP) 1396 { 1397 return MFX_ERR_NULL_PTR; 1398 } 1399 sts = m_pGOP->Init(GopRefDist - 1, m_VideoParamsEx.mfxVideoParams.mfx.GopOptFlag&MFX_GOP_CLOSED, m_VideoParamsEx.mfxVideoParams.mfx.IdrInterval,ext && ext->EndOfSequence==MFX_CODINGOPTION_ON,m_VideoParamsEx.mfxVideoParams.mfx.EncodedOrder!=0); 1400 MFX_CHECK_STS(sts); 1401 } 1402 1403 if (m_pWaitingList) 1404 { 1405 if (m_pWaitingList->GetMaxFrames() < maxFramesInWaitingList) 1406 { 1407 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM; 1408 } 1409 m_pWaitingList->Reset(minFramesInWaitingList, delayInWaitingList); 1410 } 1411 else 1412 { 1413 m_pWaitingList = new MFXWaitingList; 1414 if (!m_pWaitingList) 1415 { 1416 return MFX_ERR_NULL_PTR; 1417 } 1418 sts = m_pWaitingList->Init(maxFramesInWaitingList, minFramesInWaitingList,delayInWaitingList); 1419 MFX_CHECK_STS(sts); 1420 } 1421 1422 m_VideoParamsEx.bRawFrames = bAllowRawFrames 1423 && (m_pCore->GetHWType() <= MFX_HW_IVB) 1424 && (m_VideoParamsEx.mfxVideoParams.mfx.TargetUsage > 5); 1425 1426 m_VideoParamsEx.mfxVideoParams.mfx.NumSlice = (mfxU16)((m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.Height)>>4); 1427 1428 { 1429 mfxFrameAllocRequest request = {}; 1430 sts = QueryIOSurf(m_pCore, par, &request); 1431 MFX_CHECK(sts>=0,sts); 1432 sts = m_InputSurfaces.Reset (par, request.NumFrameMin); 1433 MFX_CHECK(sts != MFX_ERR_INVALID_VIDEO_PARAM, m_bInitialized ? MFX_ERR_INCOMPATIBLE_VIDEO_PARAM: sts); 1434 MFX_CHECK_STS(sts); 1435 } 1436 1437 if (bUnsupported) 1438 return MFX_ERR_UNSUPPORTED; 1439 if(bInvalid) 1440 return MFX_ERR_INVALID_VIDEO_PARAM; 1441 m_bInitialized = true; 1442 1443 return bCorrected ? MFX_WRN_INCOMPATIBLE_VIDEO_PARAM : MFX_ERR_NONE; 1444 } 1445 1446 //virtual mfxStatus Close(void); // same name Close(void)1447 mfxStatus ControllerBase::Close(void) 1448 { 1449 mfxStatus sts = MFX_ERR_NONE; 1450 1451 sts = UnlockFrames (m_pGOP, m_pWaitingList,m_pCore); 1452 MFX_CHECK_STS(sts); 1453 1454 if (m_pGOP) 1455 { 1456 m_pGOP->Close(); 1457 delete m_pGOP; 1458 m_pGOP = 0; 1459 } 1460 if (m_pWaitingList) 1461 { 1462 m_pWaitingList->Close(); 1463 delete m_pWaitingList; 1464 m_pWaitingList = 0; 1465 } 1466 m_InputSurfaces.Close(); 1467 1468 m_bInitialized = false; 1469 1470 1471 return MFX_ERR_NONE; 1472 } 1473 GetVideoParam(mfxVideoParam * par)1474 mfxStatus ControllerBase::GetVideoParam(mfxVideoParam *par) 1475 { 1476 MFX_CHECK_NULL_PTR1(par); 1477 CHECK_VERSION(par->Version); 1478 1479 par->mfx = m_VideoParamsEx.mfxVideoParams.mfx; 1480 par->IOPattern = m_VideoParamsEx.mfxVideoParams.IOPattern; 1481 par->mfx.CodecId = MFX_CODEC_MPEG2; 1482 mfxExtCodingOption* ext = GetExtCodingOptions(par->ExtParam, par->NumExtParam); 1483 if (ext) 1484 ext->FramePicture= (mfxU16)((m_VideoParamsEx.bFieldCoding) ? MFX_CODINGOPTION_OFF : MFX_CODINGOPTION_ON); 1485 1486 return MFX_ERR_NONE; 1487 } GetEncodeStat(mfxEncodeStat * stat)1488 mfxStatus ControllerBase::GetEncodeStat(mfxEncodeStat *stat) 1489 { 1490 MFX_CHECK_NULL_PTR1(stat) 1491 if(!is_initialized()) 1492 return MFX_ERR_NOT_INITIALIZED; 1493 1494 stat->NumBit = (mfxU64)(m_BitstreamLen*8); 1495 stat->NumFrame = m_OutputFrameOrder + 1; 1496 1497 stat->NumCachedFrame = m_InputFrameOrder - m_OutputFrameOrder; 1498 return MFX_ERR_NONE; 1499 } ReorderFrame(mfxEncodeInternalParams * pInInternalParams,mfxFrameSurface1 * in,mfxEncodeInternalParams * pOutInternalParams,mfxFrameSurface1 ** out)1500 mfxStatus ControllerBase::ReorderFrame(mfxEncodeInternalParams *pInInternalParams, mfxFrameSurface1 *in, 1501 mfxEncodeInternalParams *pOutInternalParams, mfxFrameSurface1 **out) 1502 { 1503 if (in) 1504 { 1505 if (!m_pWaitingList->AddFrame( in, pInInternalParams)) 1506 { 1507 return MFX_ERR_NOT_ENOUGH_BUFFER; 1508 } 1509 } 1510 // Fill GOP structure using waiting list 1511 for(;;) 1512 { 1513 sFrameEx CurFrame = {}; 1514 1515 if (!m_pWaitingList->GetFrameEx(&CurFrame, in == NULL)) 1516 { 1517 break; 1518 } 1519 if (!m_pGOP->AddFrame(&CurFrame)) 1520 { 1521 break; 1522 } 1523 m_pWaitingList->MoveOnNextFrame(); 1524 } 1525 1526 if (!in) 1527 { 1528 bool strictGop = 0 != (m_VideoParamsEx.mfxVideoParams.mfx.GopOptFlag & MFX_GOP_STRICT); 1529 m_pGOP->CloseGop(strictGop); 1530 } 1531 1532 sFrameEx CurFrame = {}; 1533 1534 // Extract next frame from GOP structure 1535 if (!m_pGOP->GetFrameExForDecoding(&CurFrame,m_pWaitingList->isNextReferenceIntra(), m_pWaitingList->isNextBFrame(),m_pWaitingList->isLastFrame())) 1536 { 1537 return MFX_ERR_MORE_DATA; 1538 } 1539 mfxU16 frameType = CurFrame.m_sEncodeInternalParams.FrameType; 1540 1541 //Correct InternalFlags 1542 CurFrame.m_sEncodeInternalParams.InternalFlags = (CurFrame.m_bAddHeader)? MFX_IFLAG_ADD_HEADER:0; 1543 if (CurFrame.m_bAddEOS) 1544 { 1545 CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_ADD_EOS; 1546 } 1547 if (CurFrame.m_bOnlyBwdPrediction && isBPredictedFrame(frameType)) 1548 { 1549 CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_BWD_ONLY; 1550 } 1551 if (CurFrame.m_bOnlyFwdPrediction && isBPredictedFrame(frameType)) 1552 { 1553 CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_FWD_ONLY; 1554 } 1555 // Check frame order parameters 1556 if (isPredictedFrame(frameType)) 1557 { 1558 sFrameEx refFrame = {}; 1559 if (m_pGOP->GetFrameExReference(&refFrame)) 1560 { 1561 1562 MFX_CHECK((CurFrame.m_FrameOrder > refFrame.m_FrameOrder) && ((int32_t)CurFrame.m_FrameOrder - (int32_t)refFrame.m_FrameOrder <= m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist) ,MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 1563 } 1564 } 1565 else if (isBPredictedFrame(frameType)) 1566 { 1567 if (CurFrame.m_bOnlyBwdPrediction) 1568 { 1569 sFrameEx refFrame = {}; 1570 if (m_pGOP->GetFrameExReference(&refFrame,true)) 1571 { 1572 MFX_CHECK((CurFrame.m_FrameOrder < refFrame.m_FrameOrder) && ((int32_t)refFrame.m_FrameOrder - (int32_t)CurFrame.m_FrameOrder < m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist) ,MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 1573 } 1574 } 1575 else if (CurFrame.m_bOnlyFwdPrediction) 1576 { 1577 sFrameEx refFrame = {}; 1578 if (m_pGOP->GetFrameExReference(&refFrame,false)) 1579 { 1580 MFX_CHECK((CurFrame.m_FrameOrder > refFrame.m_FrameOrder) && ((int32_t)CurFrame.m_FrameOrder - (int32_t)refFrame.m_FrameOrder < m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist) ,MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 1581 } 1582 } 1583 else 1584 { 1585 sFrameEx refFrameF = {}; 1586 sFrameEx refFrameB = {}; 1587 if (m_pGOP->GetFrameExReference(&refFrameF,false) && m_pGOP->GetFrameExReference(&refFrameB,true)) 1588 { 1589 MFX_CHECK((CurFrame.m_FrameOrder < refFrameB.m_FrameOrder) && (CurFrame.m_FrameOrder > refFrameF.m_FrameOrder) ,MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 1590 } 1591 } 1592 } 1593 *out = CurFrame.m_pFrame; 1594 *pOutInternalParams = CurFrame.m_sEncodeInternalParams; 1595 1596 m_pGOP->ReleaseCurrentFrame(); 1597 1598 return MFX_ERR_NONE; 1599 } CheckNextFrame(mfxEncodeInternalParams * pOutInternalParams,mfxFrameSurface1 ** out)1600 mfxStatus ControllerBase::CheckNextFrame(mfxEncodeInternalParams *pOutInternalParams, mfxFrameSurface1 **out) 1601 { 1602 1603 // Fill GOP structure using waiting list 1604 for(;;) 1605 { 1606 sFrameEx CurFrame = {}; 1607 1608 if (!m_pWaitingList->GetFrameEx(&CurFrame, false)) 1609 { 1610 break; 1611 } 1612 if (!m_pGOP->AddFrame(&CurFrame)) 1613 { 1614 break; 1615 } 1616 m_pWaitingList->MoveOnNextFrame(); 1617 } 1618 1619 sFrameEx CurFrame = {}; 1620 1621 // Extract next frame from GOP structure 1622 if (!m_pGOP->GetFrameExForDecoding(&CurFrame,m_pWaitingList->isNextReferenceIntra(), m_pWaitingList->isNextBFrame(),m_pWaitingList->isLastFrame())) 1623 { 1624 return MFX_ERR_MORE_DATA; 1625 } 1626 mfxU16 frameType = CurFrame.m_sEncodeInternalParams.FrameType; 1627 1628 //Correct InternalFlags 1629 CurFrame.m_sEncodeInternalParams.InternalFlags = (CurFrame.m_bAddHeader)? MFX_IFLAG_ADD_HEADER:0; 1630 if (CurFrame.m_bAddEOS) 1631 { 1632 CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_ADD_EOS; 1633 } 1634 if (CurFrame.m_bOnlyBwdPrediction && isBPredictedFrame(frameType)) 1635 { 1636 CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_BWD_ONLY; 1637 } 1638 if (CurFrame.m_bOnlyFwdPrediction && isBPredictedFrame(frameType)) 1639 { 1640 CurFrame.m_sEncodeInternalParams.InternalFlags |= MFX_IFLAG_FWD_ONLY; 1641 } 1642 1643 *out = CurFrame.m_pFrame; 1644 *pOutInternalParams = CurFrame.m_sEncodeInternalParams; 1645 1646 m_pGOP->ReleaseCurrentFrame(); 1647 1648 return MFX_ERR_NONE; 1649 } 1650 EncodeFrameCheck(mfxEncodeCtrl * ctrl,mfxFrameSurface1 * surface,mfxBitstream * bs,mfxFrameSurface1 ** reordered_surface,mfxEncodeInternalParams * pInternalParams)1651 mfxStatus ControllerBase::EncodeFrameCheck( 1652 mfxEncodeCtrl *ctrl, 1653 mfxFrameSurface1 *surface, 1654 mfxBitstream *bs, 1655 mfxFrameSurface1 **reordered_surface, 1656 mfxEncodeInternalParams *pInternalParams) 1657 { 1658 mfxStatus sts = MFX_ERR_NONE; 1659 bool bWarning = false; 1660 1661 MFX_CHECK(is_initialized(),MFX_ERR_NOT_INITIALIZED); 1662 CHECK_VERSION(bs->Version); 1663 MFX_CHECK_NULL_PTR2(bs, pInternalParams); 1664 MFX_CHECK(bs->DataOffset <= 32 , MFX_ERR_UNDEFINED_BEHAVIOR); 1665 1666 mfxU32 startbspos = bs->DataOffset + bs->DataLength; 1667 mfxU32 output_buffer_size = bs->MaxLength > startbspos ? (bs->MaxLength - startbspos) : 0; 1668 1669 MFX_CHECK(output_buffer_size >= mfxU32(m_VideoParamsEx.mfxVideoParams.mfx.BufferSizeInKB * m_VideoParamsEx.mfxVideoParams.mfx.BRCParamMultiplier * 1000), MFX_ERR_NOT_ENOUGH_BUFFER); 1670 MFX_CHECK_NULL_PTR1(bs->Data); 1671 1672 if (surface) 1673 { 1674 if ((m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.PicStruct&0x0f) != MFX_PICSTRUCT_UNKNOWN) 1675 { 1676 if ((surface->Info.PicStruct&0x0f) != (m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.PicStruct&0x0f) && 1677 (surface->Info.PicStruct&0x0f) != MFX_PICSTRUCT_UNKNOWN && 1678 (surface->Info.PicStruct&0x0f) != MFX_PICSTRUCT_PROGRESSIVE) 1679 { 1680 bWarning=true; 1681 } 1682 } 1683 else if ((surface->Info.PicStruct&0x0f) == MFX_PICSTRUCT_UNKNOWN) 1684 { 1685 return MFX_ERR_UNDEFINED_BEHAVIOR; 1686 } 1687 1688 MFX_CHECK(surface->Info.Width >= m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.Width, MFX_ERR_INVALID_VIDEO_PARAM); 1689 MFX_CHECK(surface->Info.Height >= m_VideoParamsEx.mfxVideoParams.mfx.FrameInfo.Height, MFX_ERR_INVALID_VIDEO_PARAM); 1690 MFX_CHECK(surface->Info.FourCC == MFX_FOURCC_NV12, MFX_ERR_UNDEFINED_BEHAVIOR); 1691 1692 if (surface->Data.Y) 1693 { 1694 MFX_CHECK(surface->Data.Pitch < 0x8000, MFX_ERR_UNDEFINED_BEHAVIOR); 1695 CHECK_VERSION(surface->Version); 1696 } 1697 sts = m_pCore->IncreaseReference(&surface->Data); 1698 MFX_CHECK_STS(sts); 1699 m_InputFrameOrder++; 1700 1701 mfxU16 frameType = (ctrl)? ctrl->FrameType : 0; 1702 if (m_VideoParamsEx.mfxVideoParams.mfx.EncodedOrder) 1703 { 1704 mfxU16 type = frameType & (MFX_FRAMETYPE_I|MFX_FRAMETYPE_P|MFX_FRAMETYPE_B); 1705 MFX_CHECK ((type == MFX_FRAMETYPE_I || type == MFX_FRAMETYPE_P || type == MFX_FRAMETYPE_B), MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 1706 } 1707 1708 pInternalParams->FrameType = frameType; 1709 pInternalParams->FrameOrder = (!m_VideoParamsEx.mfxVideoParams.mfx.EncodedOrder)? m_InputFrameOrder:surface->Data.FrameOrder; 1710 if (ctrl) 1711 { 1712 pInternalParams->ExtParam = ctrl->ExtParam; 1713 pInternalParams->NumExtParam = ctrl->NumExtParam; 1714 pInternalParams->NumPayload = ctrl->NumPayload; 1715 pInternalParams->Payload = ctrl->Payload; 1716 pInternalParams->QP = ctrl->QP; 1717 pInternalParams->SkipFrame = ctrl->SkipFrame; 1718 } 1719 else 1720 { 1721 pInternalParams->ExtParam = 0; 1722 pInternalParams->NumExtParam = 0; 1723 pInternalParams->NumPayload = 0; 1724 pInternalParams->Payload = 0; 1725 pInternalParams->QP = 0; 1726 pInternalParams->SkipFrame = 0; 1727 } 1728 1729 *reordered_surface = GetOpaqSurface(surface); 1730 1731 if (m_InputFrameOrder < m_pWaitingList->GetDelay()) 1732 { 1733 return (mfxStatus)MFX_ERR_MORE_DATA_SUBMIT_TASK; 1734 } 1735 else 1736 { 1737 m_nEncodeCalls ++; 1738 return bWarning? MFX_WRN_INCOMPATIBLE_VIDEO_PARAM: MFX_ERR_NONE; 1739 } 1740 } 1741 else 1742 { 1743 m_nEncodeCalls ++; 1744 *reordered_surface = 0; 1745 return (m_nEncodeCalls <= (mfxU32)m_InputFrameOrder+1)? MFX_ERR_NONE : MFX_ERR_MORE_DATA; 1746 } 1747 } 1748 CheckFrameType(mfxEncodeInternalParams * pInternalParams)1749 mfxStatus ControllerBase::CheckFrameType(mfxEncodeInternalParams *pInternalParams) 1750 { 1751 mfxU16 type = pInternalParams->FrameType & (MFX_FRAMETYPE_I|MFX_FRAMETYPE_P|MFX_FRAMETYPE_B); 1752 if (!m_VideoParamsEx.mfxVideoParams.mfx.EncodedOrder) 1753 { 1754 if (type != MFX_FRAMETYPE_I) 1755 { 1756 GetFrameTypeMpeg2 (m_nFrameInGOP, 1757 m_VideoParamsEx.mfxVideoParams.mfx.GopPicSize, 1758 m_VideoParamsEx.mfxVideoParams.mfx.GopRefDist, 1759 m_VideoParamsEx.mfxVideoParams.mfx.GopOptFlag&MFX_GOP_CLOSED, 1760 &pInternalParams->FrameType); 1761 } 1762 m_nFrameInGOP = (pInternalParams->FrameType & MFX_FRAMETYPE_I) ? 1 : m_nFrameInGOP + 1; 1763 } 1764 else 1765 { 1766 MFX_CHECK((type == MFX_FRAMETYPE_I || type == MFX_FRAMETYPE_P || type == MFX_FRAMETYPE_B), MFX_ERR_UNDEFINED_BEHAVIOR); 1767 } 1768 return MFX_ERR_NONE; 1769 } 1770 1771 #define RET_UMC_TO_MFX(umc_ret) ConvertStatusUmc2Mfx(umc_ret) ConvertFrameParamsToUMC(const mfxFrameParamMPEG2 * pFrameParams,UMC::FrameType & frType,uint32_t & picture_structure,uint32_t & repeat_first_field,uint32_t & top_field_first,uint32_t & second_field)1772 static void ConvertFrameParamsToUMC(const mfxFrameParamMPEG2* pFrameParams, UMC::FrameType &frType, 1773 uint32_t &picture_structure, 1774 uint32_t &repeat_first_field, 1775 uint32_t &top_field_first, 1776 uint32_t &second_field) 1777 { 1778 frType = ((pFrameParams->FrameType & MFX_FRAMETYPE_I) ? UMC::I_PICTURE : (pFrameParams->FrameType & MFX_FRAMETYPE_P ? UMC::P_PICTURE : UMC::B_PICTURE)); 1779 picture_structure = pFrameParams->PicStructure; 1780 repeat_first_field = (pFrameParams->RepeatFirstField) ? 1:0; 1781 top_field_first = (pFrameParams->TopFieldFirst) ? 1:0; 1782 second_field = (pFrameParams->SecondFieldFlag) ? 1:0; 1783 } 1784 QuantIntoScaleTypeAndCode(int32_t quant_value,int32_t & q_scale_type,int32_t & quantiser_scale_code)1785 void MPEG2BRC_HW::QuantIntoScaleTypeAndCode (int32_t quant_value, int32_t &q_scale_type, int32_t &quantiser_scale_code) 1786 { 1787 if(quant_value > 7 && quant_value <= 62) 1788 { 1789 q_scale_type = 0; 1790 quantiser_scale_code = (quant_value + 1) >> 1; 1791 } 1792 else 1793 { // non-linear quantizer 1794 q_scale_type = 1; 1795 if(quant_value <= 8) 1796 { 1797 quantiser_scale_code = quant_value; 1798 } 1799 else if (quant_value > 62) 1800 { 1801 quantiser_scale_code = 25+((quant_value-64+4)>>3); 1802 } 1803 } 1804 if(quantiser_scale_code < 1) 1805 { 1806 quantiser_scale_code = 1; 1807 } 1808 if(quantiser_scale_code > 31) 1809 { 1810 quantiser_scale_code = 31; 1811 } 1812 } ChangeQuant(int32_t quant_value_old,int32_t quant_value_new)1813 int32_t MPEG2BRC_HW::ChangeQuant(int32_t quant_value_old, int32_t quant_value_new) 1814 { 1815 int32_t q_scale_type = 0; 1816 int32_t quantiser_scale_code = 0; 1817 int32_t quant_value = quant_value_new; 1818 1819 1820 if(quant_value_old == quant_value) 1821 { 1822 return quant_value; 1823 } 1824 QuantIntoScaleTypeAndCode (quant_value_new, q_scale_type, quantiser_scale_code); 1825 quant_value = ScaleTypeAndCodeIntoQuant (q_scale_type, quantiser_scale_code); 1826 1827 if (quant_value == quant_value_old) 1828 { 1829 if (quant_value_new > quant_value_old) 1830 { 1831 if (quantiser_scale_code == 31) 1832 { 1833 return quant_value; 1834 } 1835 else 1836 { 1837 quantiser_scale_code ++; 1838 } 1839 } 1840 else 1841 { 1842 if (quantiser_scale_code == 1) 1843 { 1844 return quant_value; 1845 } 1846 else 1847 { 1848 quantiser_scale_code --; 1849 } 1850 } 1851 quant_value = ScaleTypeAndCodeIntoQuant (q_scale_type, quantiser_scale_code); 1852 } 1853 1854 return quant_value; 1855 } Init(mfxVideoParam * par)1856 mfxStatus MPEG2BRC_HW::Init(mfxVideoParam* par) 1857 { 1858 MFX_AUTO_LTRACE(MFX_TRACE_LEVEL_HOTSPOTS, "MPEG2BRC_HW::Init"); 1859 mfxStatus sts = MFX_ERR_NONE; 1860 1861 m_bConstantQuant = (par->mfx.RateControlMethod == MFX_RATECONTROL_CQP)? 1:0; 1862 m_bLimitedMode = 0; 1863 1864 if (m_bConstantQuant) 1865 { 1866 UMC::Mpeg2_BrcParams brcParams; 1867 UMC::Status ret = UMC::UMC_OK; 1868 brcParams.frameWidth = par->mfx.FrameInfo.Width; 1869 brcParams.frameHeight = par->mfx.FrameInfo.Height; 1870 brcParams.quant[0] = par->mfx.QPI; 1871 brcParams.quant[1] = par->mfx.QPP; 1872 brcParams.quant[2] = par->mfx.QPB; 1873 1874 1875 if (m_pBRC == NULL) 1876 { 1877 m_pBRC = new UMC::MPEG2BRC_CONST_QUNT; 1878 } 1879 ret = m_pBRC->Init(&brcParams); 1880 MFX_CHECK_UMC_STS (ret); 1881 1882 ret = m_pBRC->GetParams(&brcParams); 1883 MFX_CHECK_UMC_STS (ret); 1884 1885 mfxU32 bufferSizeInKB = ((brcParams.maxFrameSize + 999)/1000); 1886 par->mfx.BRCParamMultiplier = (mfxU16)((bufferSizeInKB + 0x10000) / 0x10000); 1887 par->mfx.BufferSizeInKB = (mfxU16)(bufferSizeInKB / par->mfx.BRCParamMultiplier); 1888 } 1889 else 1890 { 1891 UMC::VideoBrcParams brcParams; 1892 UMC::Status ret = UMC::UMC_OK; 1893 1894 sts = ConvertVideoParam_Brc(par, &brcParams); 1895 MFX_CHECK_STS(sts); 1896 if (brcParams.HRDBufferSizeBytes == 0) 1897 brcParams.HRDBufferSizeBytes = std::min(65535000, brcParams.targetBitrate / 4); // limit buffer size with 2 seconds 1898 if (brcParams.maxBitrate == 0) 1899 brcParams.maxBitrate = brcParams.targetBitrate; 1900 1901 switch (par->mfx.FrameInfo.PicStruct) 1902 { 1903 case MFX_PICSTRUCT_PROGRESSIVE: 1904 brcParams.info.interlace_type = UMC::PROGRESSIVE; 1905 break; 1906 case MFX_PICSTRUCT_FIELD_TFF: 1907 case MFX_PICSTRUCT_UNKNOWN: 1908 brcParams.info.interlace_type = UMC::INTERLEAVED_TOP_FIELD_FIRST; 1909 break; 1910 case MFX_PICSTRUCT_FIELD_BFF: 1911 brcParams.info.interlace_type = UMC::INTERLEAVED_BOTTOM_FIELD_FIRST; 1912 break; 1913 default: 1914 return MFX_ERR_INVALID_VIDEO_PARAM; 1915 } 1916 1917 if (m_pBRC == NULL) 1918 { 1919 m_pBRC = new UMC::MPEG2BRC; 1920 ret = m_pBRC->Init(&brcParams,m_pCore->GetHWType() < MFX_HW_HSW || m_pCore->GetHWType()==MFX_HW_VLV); 1921 MFX_CHECK_UMC_STS (ret); 1922 } 1923 else 1924 { 1925 m_pBRC->Close(); 1926 ret = m_pBRC->Init(&brcParams, m_pCore->GetHWType() < MFX_HW_HSW || m_pCore->GetHWType()==MFX_HW_VLV); 1927 MFX_CHECK_UMC_STS (ret); 1928 } 1929 1930 ret = m_pBRC->GetParams(&brcParams); 1931 MFX_CHECK_UMC_STS (ret); 1932 1933 m_bufferSizeInKB = (mfxU32)(brcParams.HRDBufferSizeBytes / 1000); 1934 m_InputBitsPerFrame = (mfxI32)(brcParams.targetBitrate / brcParams.info.framerate); 1935 1936 mfxU32 maxVal32 = std::max<mfxU32>({ 1937 mfxU32(brcParams.HRDInitialDelayBytes / 1000), 1938 mfxU32(brcParams.HRDBufferSizeBytes / 1000), 1939 mfxU32(brcParams.targetBitrate / 1000), 1940 mfxU32(brcParams.maxBitrate / 1000)}); 1941 1942 par->mfx.BRCParamMultiplier = (mfxU16)((maxVal32 + 0x10000) / 0x10000); 1943 par->mfx.BufferSizeInKB = (mfxU16)(m_bufferSizeInKB / par->mfx.BRCParamMultiplier); 1944 par->mfx.InitialDelayInKB = (mfxU16)(brcParams.HRDInitialDelayBytes / 1000 / par->mfx.BRCParamMultiplier); 1945 par->mfx.TargetKbps = (mfxU16)(brcParams.targetBitrate / 1000 / par->mfx.BRCParamMultiplier); 1946 par->mfx.MaxKbps = (mfxU16)(brcParams.maxBitrate / 1000 / par->mfx.BRCParamMultiplier); 1947 1948 1949 mfxU32 MBcount = (par->mfx.FrameInfo.Width/16)*(par->mfx.FrameInfo.Height/16); 1950 1951 m_MinFrameSizeBits[0] = 16 * 6 * MBcount + 140 + (par->mfx.FrameInfo.Width/16)*32; 1952 m_MinFrameSizeBits[1] = 1*MBcount + 140 + (par->mfx.FrameInfo.Width/16)*32; 1953 m_MinFrameSizeBits[2] = 1*MBcount + 140 + (par->mfx.FrameInfo.Width/16)*32; 1954 1955 m_MinFieldSizeBits[0] = 12 * 6 * (MBcount/2) + 140 + (par->mfx.FrameInfo.Width/16)*32; 1956 m_MinFieldSizeBits[1] = 1*MBcount/2 + 140 + (par->mfx.FrameInfo.Width/16)*32; 1957 m_MinFieldSizeBits[2] = 1*MBcount/2 + 140 + (par->mfx.FrameInfo.Width/16)*32; 1958 1959 1960 mfxU32 GOPLengthBits = ((mfxU32)(brcParams.maxBitrate/brcParams.info.framerate))*brcParams.GOPPicSize; 1961 mfxI32 numPFrames = (brcParams.GOPPicSize/brcParams.GOPRefDist > 1) ? brcParams.GOPPicSize/brcParams.GOPRefDist - 1:0; 1962 mfxI32 numBFrames = (brcParams.GOPPicSize > numPFrames + 1) ? brcParams.GOPPicSize - numPFrames - 1:0; 1963 1964 mfxU32 minGOPLengthBits = m_MinFrameSizeBits[0] + numPFrames * m_MinFrameSizeBits[1] + numBFrames *m_MinFrameSizeBits[2]; 1965 1966 m_GopSize = par->mfx.GopPicSize; 1967 m_FirstGopSize = (m_GopSize - 1)/par->mfx.GopRefDist * par->mfx.GopRefDist + 1; 1968 1969 1970 if (GOPLengthBits < minGOPLengthBits) 1971 { 1972 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM; 1973 } 1974 1975 } 1976 return sts; 1977 } Close()1978 void MPEG2BRC_HW::Close () 1979 { 1980 delete m_pBRC; 1981 m_pBRC = 0; 1982 1983 m_bConstantQuant = 0; 1984 m_MinFrameSizeBits [0] = 0; 1985 m_MinFrameSizeBits [1] = 0; 1986 m_MinFrameSizeBits [2] = 0; 1987 1988 m_MinFieldSizeBits [0] = 0; 1989 m_MinFieldSizeBits [1] = 0; 1990 m_MinFieldSizeBits [2] = 0; 1991 1992 m_FirstGopSize = 0; 1993 m_GopSize = 0; 1994 m_bufferSizeInKB = 0; 1995 m_InputBitsPerFrame = 0; 1996 m_bLimitedMode = 0; 1997 } StartNewFrame(const mfxFrameParamMPEG2 * pFrameParams,mfxI32 recode)1998 mfxStatus MPEG2BRC_HW::StartNewFrame(const mfxFrameParamMPEG2 *pFrameParams, mfxI32 recode) 1999 { 2000 UMC::Status ret = UMC::UMC_OK; 2001 uint32_t picture_structure = 0; 2002 uint32_t repeat_first_field = 0; 2003 uint32_t top_field_first = 0; 2004 uint32_t second_field = 0; 2005 UMC::FrameType frType = ((pFrameParams->FrameType & MFX_FRAMETYPE_I) ? 2006 UMC::I_PICTURE : (pFrameParams->FrameType & MFX_FRAMETYPE_P ? UMC::P_PICTURE : UMC::B_PICTURE)); 2007 2008 if (UMC::BRC_RECODE_NONE == recode ) 2009 { 2010 if (pFrameParams->FrameType & (MFX_FRAMETYPE_P|MFX_FRAMETYPE_I)) 2011 { 2012 m_bLimitedMode = 0; 2013 } 2014 } 2015 if (UMC::BRC_RECODE_NONE == recode && m_bLimitedMode) 2016 { 2017 recode = UMC::BRC_EXT_FRAMESKIP; 2018 } 2019 2020 ConvertFrameParamsToUMC(pFrameParams, frType,picture_structure,repeat_first_field, top_field_first,second_field); 2021 ret = m_pBRC->SetPictureFlags(frType, picture_structure, repeat_first_field, top_field_first, second_field); 2022 MFX_CHECK_UMC_STS (ret); 2023 ret = m_pBRC->PreEncFrame(frType,recode); 2024 MFX_CHECK_UMC_STS (ret); 2025 2026 return MFX_ERR_NONE; 2027 } 2028 2029 SetQuantDCPredAndDelay(mfxFrameParamMPEG2 * pFrameParams,mfxU8 * pQuant)2030 mfxStatus MPEG2BRC_HW::SetQuantDCPredAndDelay(mfxFrameParamMPEG2 *pFrameParams, mfxU8 *pQuant) 2031 { 2032 UMC::FrameType frType = ((pFrameParams->FrameType & MFX_FRAMETYPE_I) ? 2033 UMC::I_PICTURE : (pFrameParams->FrameType & MFX_FRAMETYPE_P ? UMC::P_PICTURE : UMC::B_PICTURE)); 2034 2035 int32_t quant_value = m_pBRC->GetQP(frType); 2036 int32_t q_scale_type = 0; 2037 int32_t quantiser_scale_code = 0; 2038 UMC::Status ret = UMC::UMC_OK; 2039 double hrdBufFullness = 0; 2040 UMC::VideoBrcParams brcParams; 2041 2042 QuantIntoScaleTypeAndCode (quant_value, q_scale_type, quantiser_scale_code); 2043 2044 if (pFrameParams->FrameType & MFX_FRAMETYPE_I) 2045 { 2046 if(quant_value < 15) 2047 pFrameParams->IntraVLCformat = 1; 2048 else 2049 pFrameParams->IntraVLCformat = 0; 2050 } 2051 2052 pFrameParams->QuantScaleType = q_scale_type; 2053 2054 ret = m_pBRC->GetHRDBufferFullness(&hrdBufFullness, 0); 2055 MFX_CHECK_UMC_STS (ret); 2056 ret = m_pBRC->GetParams(&brcParams); 2057 MFX_CHECK_UMC_STS (ret); 2058 2059 pFrameParams->VBVDelay = 0xffff; 2060 2061 if(quant_value >= 8) 2062 { 2063 pFrameParams->IntraDCprecision = 0; 2064 } 2065 else if(quant_value >= 4) 2066 { 2067 pFrameParams->IntraDCprecision = 1; 2068 } 2069 else 2070 { 2071 pFrameParams->IntraDCprecision = 2; 2072 } 2073 *pQuant = (mfxU8)quantiser_scale_code; 2074 2075 return MFX_ERR_NONE; 2076 } UpdateBRC(const mfxFrameParamMPEG2 * pParams,mfxBitstream * pBitsream,mfxU32 bitsize,mfxU32 numEncodedFrame,bool bNotEnoughBuffer,mfxI32 & recode)2077 mfxStatus MPEG2BRC_HW::UpdateBRC(const mfxFrameParamMPEG2 *pParams, mfxBitstream* pBitsream, mfxU32 bitsize, mfxU32 numEncodedFrame, bool bNotEnoughBuffer ,mfxI32 &recode) 2078 { 2079 if (m_bConstantQuant) 2080 { 2081 return bNotEnoughBuffer ? MFX_ERR_NOT_ENOUGH_BUFFER: MFX_ERR_NONE; 2082 } 2083 2084 UMC::BRCStatus hrdSts = UMC::BRC_OK; 2085 mfxStatus sts = MFX_ERR_NONE; 2086 int32_t framestoI = 0; 2087 int32_t gopSize = 0; 2088 int32_t maxSize = 0, minSize = 0; 2089 double buffullness = 0; 2090 int32_t buffullnessbyI = 0; 2091 2092 UMC::VideoBrcParams brcParams; 2093 UMC::FrameType frType = ((pParams->FrameType & MFX_FRAMETYPE_I) ? 2094 UMC::I_PICTURE : (pParams->FrameType & MFX_FRAMETYPE_P ? UMC::P_PICTURE : UMC::B_PICTURE)); 2095 2096 2097 if (numEncodedFrame >= m_FirstGopSize) 2098 { 2099 gopSize = m_GopSize; 2100 framestoI = gopSize - ((numEncodedFrame - m_FirstGopSize) % gopSize) - 1; 2101 } 2102 else 2103 { 2104 gopSize = m_FirstGopSize; 2105 framestoI = gopSize - numEncodedFrame - 1; 2106 } 2107 if (bNotEnoughBuffer) 2108 { 2109 bitsize = (m_bufferSizeInKB+1)*1000*8; 2110 } 2111 2112 hrdSts = m_pBRC->PostPackFrame(frType, bitsize, 0, recode); 2113 2114 m_pBRC->GetHRDBufferFullness(&buffullness, 0); 2115 m_pBRC->GetMinMaxFrameSize(&minSize, &maxSize); 2116 m_pBRC->GetParams(&brcParams); 2117 2118 if (hrdSts == UMC::BRC_OK) 2119 { 2120 int32_t inputbitsPerPic = m_InputBitsPerFrame; 2121 int32_t minbitsPerPredPic = 0, minbitsPerIPic = 0; 2122 recode = 0; 2123 2124 if (pParams->FieldPicFlag) 2125 { 2126 minbitsPerPredPic = m_MinFieldSizeBits[1]; 2127 minbitsPerIPic = m_MinFieldSizeBits[0]; 2128 inputbitsPerPic >>= 1; 2129 framestoI *= 2; 2130 if (!pParams->SecondFieldFlag) 2131 { 2132 framestoI--; 2133 } 2134 } 2135 else 2136 { 2137 minbitsPerPredPic = m_MinFrameSizeBits[1]; 2138 minbitsPerIPic = m_MinFrameSizeBits[0]; 2139 } 2140 buffullnessbyI = (int32_t)buffullness + framestoI * (inputbitsPerPic - minbitsPerPredPic); 2141 2142 if (buffullnessbyI < minbitsPerIPic || 2143 (pParams->FieldPicFlag && !pParams->SecondFieldFlag && 2144 bitsize*2 > (mfxU32)(inputbitsPerPic + maxSize) )) 2145 { 2146 if (!m_bLimitedMode) 2147 { 2148 int32_t quant = m_pBRC->GetQP(frType); 2149 int32_t new_quant = ChangeQuant(quant, quant+2); 2150 2151 recode = UMC::BRC_RECODE_EXT_QP; 2152 2153 if (new_quant == quant ) 2154 { 2155 m_bLimitedMode = true; 2156 recode = UMC::BRC_RECODE_EXT_PANIC; 2157 } 2158 m_pBRC->SetQP(new_quant, frType); 2159 } 2160 else 2161 { 2162 if (!bNotEnoughBuffer) 2163 { 2164 sts = MFX_ERR_NONE; 2165 } 2166 else 2167 { 2168 sts = MFX_ERR_NOT_ENOUGH_BUFFER; 2169 } 2170 } 2171 } 2172 } 2173 else 2174 { 2175 if (!(hrdSts & UMC::BRC_NOT_ENOUGH_BUFFER)) 2176 { 2177 recode = UMC::BRC_RECODE_QP; 2178 } 2179 else 2180 { 2181 if (hrdSts & UMC::BRC_ERR_SMALL_FRAME) 2182 { 2183 maxSize = 0, minSize = 0; 2184 uint8_t *p = pBitsream->Data + pBitsream->DataOffset + pBitsream->DataLength; 2185 m_pBRC->GetMinMaxFrameSize(&minSize, &maxSize); 2186 if (bitsize < (mfxU32)minSize && pBitsream->DataOffset + 1 + pBitsream->DataLength < pBitsream->MaxLength) 2187 { 2188 mfxU32 nBytes = ((mfxU32)minSize - bitsize + 7)/8; 2189 nBytes = (pBitsream->DataOffset + pBitsream->DataLength + nBytes < pBitsream->MaxLength) ? nBytes : pBitsream->MaxLength - (pBitsream->DataOffset + pBitsream->DataLength); 2190 memset (p,0,nBytes); 2191 pBitsream->DataLength += nBytes; 2192 bitsize += (nBytes*8); 2193 // p += nBytes; 2194 } 2195 m_pBRC->PostPackFrame(frType, bitsize, 0, recode); 2196 recode = UMC::BRC_RECODE_NONE; 2197 2198 } 2199 else 2200 { 2201 if (!m_bLimitedMode) 2202 { 2203 m_bLimitedMode = true; 2204 recode = UMC::BRC_RECODE_EXT_PANIC; 2205 } 2206 else 2207 { 2208 sts = MFX_ERR_NOT_ENOUGH_BUFFER; 2209 } 2210 } 2211 } 2212 } 2213 return sts; 2214 2215 } 2216 2217 #define isNONLocked(pSurface) (pSurface->Data.Y == 0) 2218 GetInternalRefFrame(mfxFrameSurface1 ** ppFrame)2219 mfxStatus FrameStore::GetInternalRefFrame(mfxFrameSurface1** ppFrame) 2220 { 2221 mfxFrameSurface1* pFrames = m_pRefFramesStore; 2222 mfxU32 numFrames = m_nRefFrames; 2223 2224 for (mfxU32 i = 0; i < numFrames; i++) 2225 { 2226 if (!pFrames[i].Data.Locked) 2227 { 2228 *ppFrame = &pFrames[i]; 2229 return MFX_ERR_NONE; 2230 } 2231 } 2232 return MFX_ERR_NOT_FOUND; 2233 } 2234 GetInternalInputFrame(mfxFrameSurface1 ** ppFrame)2235 mfxStatus FrameStore::GetInternalInputFrame(mfxFrameSurface1** ppFrame) 2236 { 2237 mfxFrameSurface1* pFrames = m_pInputFramesStore; 2238 mfxU32 numFrames = m_nInputFrames; 2239 2240 for (mfxU32 i = 0; i < numFrames; i++) 2241 { 2242 if (!pFrames[i].Data.Locked) 2243 { 2244 *ppFrame = &pFrames[i]; 2245 return MFX_ERR_NONE; 2246 } 2247 } 2248 return MFX_ERR_NOT_FOUND; 2249 } 2250 ReleaseFrames()2251 mfxStatus FrameStore::ReleaseFrames () 2252 { 2253 mfxStatus sts = MFX_ERR_NONE; 2254 if (m_pRefFrame[0]) 2255 { 2256 sts = m_pCore->DecreaseReference(&m_pRefFrame[0]->Data); 2257 MFX_CHECK_STS (sts); 2258 } 2259 if (m_pRefFrame[1]) 2260 { 2261 sts = m_pCore->DecreaseReference(&m_pRefFrame[1]->Data); 2262 MFX_CHECK_STS (sts); 2263 } 2264 if (m_pRawFrame[0]) 2265 { 2266 sts = m_pCore->DecreaseReference(&m_pRawFrame[0]->Data); 2267 MFX_CHECK_STS (sts); 2268 } 2269 if (m_pRawFrame[1]) 2270 { 2271 sts = m_pCore->DecreaseReference(&m_pRawFrame[1]->Data); 2272 MFX_CHECK_STS (sts); 2273 } 2274 2275 m_pRefFrame[0] = 0; 2276 m_pRefFrame[1] = 0; 2277 2278 m_pRawFrame[0] = 0; 2279 m_pRawFrame[1] = 0; 2280 2281 m_nFrame = 0; 2282 m_nRefFrame[0] = 0; 2283 m_nRefFrame[1] = 0; 2284 2285 m_nLastRefBeforeIntra = -1; 2286 m_nLastRef = -1; 2287 2288 return sts; 2289 2290 } Init(bool bRawFrame,mfxU16 InputFrameType,bool bHW,mfxU32 mTasks,mfxFrameInfo * pFrameInfo,bool bProtected)2291 mfxStatus FrameStore::Init(bool bRawFrame, mfxU16 InputFrameType, bool bHW, mfxU32 mTasks, mfxFrameInfo* pFrameInfo, bool bProtected) 2292 { 2293 MFX_AUTO_LTRACE(MFX_TRACE_LEVEL_HOTSPOTS, "FrameStore::Init"); 2294 mfxStatus sts = MFX_ERR_NONE; 2295 mfxU32 numref = 0; 2296 mfxU32 numinput = 0; 2297 mfxU16 type=0; 2298 bool bHWInput = ((InputFrameType & MFX_MEMTYPE_DXVA2_DECODER_TARGET) != 0); 2299 2300 m_InputType = InputFrameType; 2301 m_bHWFrames = bHW; 2302 m_bRawFrame = bRawFrame; 2303 2304 ReleaseFrames(); 2305 2306 if (bHWInput != bHW) 2307 { 2308 numinput += mTasks; 2309 if (m_bRawFrame) 2310 { 2311 numinput += mTasks*2; 2312 } 2313 } 2314 numref += mTasks*3; // reconstructed frames 2315 2316 m_RefRequest.NumFrameSuggested = m_RefRequest.NumFrameMin = (mfxU16)numref; 2317 2318 m_InputRequest.NumFrameSuggested = m_InputRequest.NumFrameMin = (mfxU16)numinput; 2319 2320 type = bHW ? 2321 (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME |MFX_MEMTYPE_DXVA2_DECODER_TARGET|MFX_MEMTYPE_FROM_ENCODE | MFX_MEMTYPE_VIDEO_MEMORY_ENCODER_TARGET): 2322 (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME |MFX_MEMTYPE_SYSTEM_MEMORY|MFX_MEMTYPE_FROM_ENCODE); 2323 2324 MFX_CHECK(!bProtected,MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 2325 2326 2327 if (m_RefResponse.NumFrameActual>0) 2328 { 2329 MFX_CHECK(m_RefRequest.Type == type, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 2330 MFX_CHECK(m_RefRequest.Info.Width >= pFrameInfo->Width && m_RefRequest.Info.Height >= pFrameInfo->Height, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 2331 MFX_CHECK(m_RefResponse.NumFrameActual >= m_RefRequest.NumFrameMin, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 2332 2333 m_nRefFrames = m_RefResponse.NumFrameActual; 2334 for (mfxU32 i = 0; i < m_nRefFrames; i++) 2335 { 2336 m_pRefFramesStore[i].Data.Locked = 0; 2337 } 2338 } 2339 else if (m_RefRequest.NumFrameSuggested) 2340 { 2341 m_RefRequest.Type = type; 2342 m_RefRequest.Info = *pFrameInfo; 2343 2344 sts = m_pCore->AllocFrames(&m_RefRequest, &m_RefResponse); 2345 MFX_CHECK_STS(sts); 2346 2347 if (m_RefResponse.NumFrameActual < m_RefRequest.NumFrameMin) 2348 return MFX_ERR_MEMORY_ALLOC; 2349 2350 m_nRefFrames = m_RefResponse.NumFrameActual; 2351 2352 if (m_pRefFramesStore) 2353 return MFX_ERR_MEMORY_ALLOC; 2354 2355 m_pRefFramesStore = new mfxFrameSurface1 [m_nRefFrames]; 2356 MFX_CHECK_NULL_PTR1(m_pRefFramesStore); 2357 2358 memset (m_pRefFramesStore, 0, sizeof(mfxFrameSurface1)*m_nRefFrames); 2359 2360 for (mfxU32 i=0; i < m_nRefFrames; i++) 2361 { 2362 m_pRefFramesStore[i].Data.MemId = m_RefResponse.mids[i]; 2363 m_pRefFramesStore[i].Info = m_RefRequest.Info; 2364 m_pRefFramesStore[i].Data.reserved[0] = 0x01; 2365 } 2366 } 2367 2368 type = bHW ? 2369 (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME |MFX_MEMTYPE_DXVA2_DECODER_TARGET|MFX_MEMTYPE_FROM_ENCODE): 2370 (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME |MFX_MEMTYPE_SYSTEM_MEMORY|MFX_MEMTYPE_FROM_ENCODE); 2371 2372 if (m_InputResponse.NumFrameActual>0) 2373 { 2374 MFX_CHECK(m_InputRequest.Type == type, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 2375 MFX_CHECK(m_InputRequest.Info.Width >= pFrameInfo->Width && m_InputRequest.Info.Height >= pFrameInfo->Height, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 2376 MFX_CHECK(m_InputResponse.NumFrameActual >= m_InputRequest.NumFrameMin, MFX_ERR_INCOMPATIBLE_VIDEO_PARAM); 2377 2378 m_nInputFrames = m_InputResponse.NumFrameActual; 2379 for (mfxU32 i = 0; i < m_nInputFrames; i++) 2380 { 2381 m_pInputFramesStore[i].Data.Locked = 0; 2382 } 2383 } 2384 else if (m_InputRequest.NumFrameSuggested) 2385 { 2386 m_InputRequest.Type = type; 2387 m_InputRequest.Info = *pFrameInfo; 2388 2389 sts = m_pCore->AllocFrames(&m_InputRequest, &m_InputResponse); 2390 MFX_CHECK_STS(sts); 2391 2392 if (m_InputResponse.NumFrameActual < m_InputRequest.NumFrameMin) 2393 return MFX_ERR_MEMORY_ALLOC; 2394 2395 m_nInputFrames = m_InputResponse.NumFrameActual; 2396 2397 if (m_pInputFramesStore) 2398 return MFX_ERR_MEMORY_ALLOC; 2399 2400 m_pInputFramesStore = new mfxFrameSurface1 [m_nInputFrames]; 2401 MFX_CHECK_NULL_PTR1(m_pInputFramesStore); 2402 2403 memset (m_pInputFramesStore, 0, sizeof(mfxFrameSurface1)*m_nInputFrames); 2404 2405 for (mfxU32 i=0; i < m_nInputFrames; i++) 2406 { 2407 m_pInputFramesStore[i].Data.MemId = m_InputResponse.mids[i]; 2408 m_pInputFramesStore[i].Info = m_InputRequest.Info; 2409 m_pInputFramesStore[i].Data.reserved[0] = 0x01; 2410 } 2411 } 2412 2413 return MFX_ERR_NONE; 2414 } NextFrame(mfxFrameSurface1 * pInputFrame,mfxU32 nFrame,mfxU16 frameType,mfxU32 intFlags,FramesSet * pFrames)2415 mfxStatus FrameStore::NextFrame(mfxFrameSurface1 *pInputFrame, mfxU32 nFrame, mfxU16 frameType, mfxU32 intFlags, FramesSet *pFrames) 2416 { 2417 mfxStatus sts = MFX_ERR_NONE; 2418 bool bHWInput = (m_InputType & MFX_MEMTYPE_DXVA2_DECODER_TARGET)? true: false ; 2419 mfxU16 localFrameType = m_bHWFrames 2420 ? (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME|MFX_MEMTYPE_DXVA2_DECODER_TARGET|MFX_MEMTYPE_FROM_ENCODE) 2421 : (mfxU16)(MFX_MEMTYPE_INTERNAL_FRAME|MFX_MEMTYPE_SYSTEM_MEMORY|MFX_MEMTYPE_FROM_ENCODE); 2422 bool bReference = !!(frameType & (MFX_FRAMETYPE_I|MFX_FRAMETYPE_P)); 2423 bool bIntra = !!(frameType & MFX_FRAMETYPE_I); 2424 2425 m_nFrame = nFrame; 2426 2427 if (bIntra) 2428 { 2429 m_nLastRefBeforeIntra = m_nLastRef; 2430 } 2431 if (bReference) 2432 { 2433 m_nLastRef = nFrame; 2434 } 2435 if (bHWInput == m_bHWFrames) 2436 { 2437 pFrames->m_pInputFrame = pInputFrame; 2438 } 2439 else 2440 { 2441 mfxFrameSurface1* pTmpFrame = 0; 2442 sts = GetInternalInputFrame(&pTmpFrame); 2443 MFX_CHECK_STS(sts); 2444 sts = m_pCore->DoFastCopyWrapper(pTmpFrame, localFrameType, pInputFrame, m_InputType); 2445 MFX_CHECK_STS(sts); 2446 pTmpFrame->Data.TimeStamp = pInputFrame->Data.TimeStamp; 2447 pFrames->m_pInputFrame = pTmpFrame; 2448 } 2449 sts = m_pCore->IncreaseReference(&pFrames->m_pInputFrame->Data); 2450 MFX_CHECK_STS(sts); 2451 2452 // prepare reconstructed 2453 { 2454 mfxFrameSurface1* pTmpFrame = 0; 2455 sts = GetInternalRefFrame(&pTmpFrame); 2456 MFX_CHECK_STS(sts); 2457 pFrames->m_pRecFrame = pTmpFrame; 2458 sts = m_pCore->IncreaseReference(&pFrames->m_pRecFrame->Data); 2459 MFX_CHECK_STS(sts); 2460 } 2461 2462 if (bReference) 2463 { 2464 m_nRefFrame[0] = m_nRefFrame[1]; 2465 m_nRefFrame[1] = nFrame; 2466 2467 // prepare reference 2468 if (m_pRefFrame[0]) 2469 { 2470 sts = m_pCore->DecreaseReference(&m_pRefFrame[0]->Data); 2471 MFX_CHECK_STS(sts); 2472 } 2473 m_pRefFrame[0] = m_pRefFrame[1]; 2474 m_pRefFrame[1] = pFrames->m_pRecFrame; 2475 sts = m_pCore->IncreaseReference(&m_pRefFrame[1]->Data); 2476 MFX_CHECK_STS(sts); 2477 2478 if (m_bRawFrame) 2479 { 2480 if (m_pRawFrame[0]) 2481 { 2482 sts = m_pCore->DecreaseReference(&m_pRawFrame[0]->Data); 2483 MFX_CHECK_STS(sts); 2484 } 2485 m_pRawFrame[0] = m_pRawFrame[1]; 2486 m_pRawFrame[1] = pFrames->m_pInputFrame; 2487 sts = m_pCore->IncreaseReference(&m_pRawFrame[1]->Data); 2488 MFX_CHECK_STS(sts); 2489 } 2490 } 2491 // Set Reference frames 2492 2493 pFrames->m_pRefFrame[0] = m_pRefFrame[0]; 2494 pFrames->m_pRefFrame[1] = m_pRefFrame[1]; 2495 2496 pFrames->m_pRawFrame[0] = m_pRawFrame[0]; 2497 pFrames->m_pRawFrame[1] = m_pRawFrame[1]; 2498 2499 pFrames->m_nFrame = m_nFrame; 2500 pFrames->m_nLastRefBeforeIntra = m_nLastRefBeforeIntra; 2501 pFrames->m_nLastRef = m_nLastRef; 2502 pFrames->m_nRefFrame[0] = m_nRefFrame [0]; 2503 pFrames->m_nRefFrame[1] = m_nRefFrame [1]; 2504 2505 if ((0 != (frameType & MFX_FRAMETYPE_B)) && (0 != (intFlags & MFX_IFLAG_BWD_ONLY))) 2506 { 2507 pFrames->m_pRefFrame[0] = 0; 2508 pFrames->m_nRefFrame[0] = 0; 2509 } 2510 if ((0 != (frameType & MFX_FRAMETYPE_B)) && (0 != (intFlags & MFX_IFLAG_FWD_ONLY))) 2511 { 2512 pFrames->m_pRefFrame[1] = 0; 2513 pFrames->m_nRefFrame[1] = 0; 2514 } 2515 2516 sts = pFrames->LockRefFrames(m_pCore); 2517 MFX_CHECK_STS(sts); 2518 2519 return sts; 2520 } Close()2521 mfxStatus FrameStore::Close() 2522 { 2523 mfxStatus sts = MFX_ERR_NONE; 2524 2525 sts = ReleaseFrames(); 2526 MFX_CHECK_STS(sts); 2527 2528 if (m_RefResponse.NumFrameActual) 2529 { 2530 sts = m_pCore->FreeFrames(&m_RefResponse); 2531 m_RefResponse.NumFrameActual = 0; 2532 } 2533 2534 if (m_nRefFrames) 2535 { 2536 delete [] m_pRefFramesStore; 2537 m_nRefFrames = 0; 2538 m_pRefFramesStore = 0; 2539 } 2540 2541 if (m_InputResponse.NumFrameActual) 2542 { 2543 sts = m_pCore->FreeFrames(&m_InputResponse); 2544 m_InputResponse.NumFrameActual = 0; 2545 } 2546 2547 if (m_nInputFrames) 2548 { 2549 delete [] m_pInputFramesStore; 2550 m_nInputFrames = 0; 2551 m_pInputFramesStore = 0; 2552 } 2553 2554 m_InputType = 0; 2555 2556 memset(&m_RefRequest, 0, sizeof(mfxFrameAllocRequest)); 2557 memset(&m_RefResponse, 0, sizeof(mfxFrameAllocResponse)); 2558 memset(&m_InputRequest, 0, sizeof(mfxFrameAllocRequest)); 2559 memset(&m_InputResponse, 0, sizeof(mfxFrameAllocResponse)); 2560 2561 return sts; 2562 } 2563 2564 2565 } 2566 2567 2568 2569 2570 2571 #endif // MFX_ENABLE_MPEG2_VIDEO_ENCODE 2572