1 // Copyright (c) 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 "mctf_common.h"
22 #include "asc.h"
23 #include "asc_defs.h"
24
25 #include "genx_me_gen8_isa.h"
26 #include "genx_mc_gen8_isa.h"
27 #include "genx_sd_gen8_isa.h"
28
29 #include "genx_me_gen9_isa.h"
30 #include "genx_mc_gen9_isa.h"
31 #include "genx_sd_gen9_isa.h"
32
33 #include "genx_me_gen11_isa.h"
34 #include "genx_mc_gen11_isa.h"
35 #include "genx_sd_gen11_isa.h"
36
37 #include "genx_me_gen11lp_isa.h"
38 #include "genx_mc_gen11lp_isa.h"
39 #include "genx_sd_gen11lp_isa.h"
40 #include "genx_me_gen12lp_isa.h"
41 #include "genx_mc_gen12lp_isa.h"
42 #include "genx_sd_gen12lp_isa.h"
43
44 #include <algorithm>
45 #include <climits>
46 #include <cmath>
47 #include <limits>
48 #include "cmrt_cross_platform.h"
49
50 using std::min;
51 using std::max;
52 using namespace ns_asc;
53
54 const mfxU16 CMC::AUTO_FILTER_STRENGTH = 0;
55 const mfxU16 CMC::DEFAULT_FILTER_STRENGTH = 8;
56 const mfxU16 CMC::INPIPE_FILTER_STRENGTH = 5;
57 const mfxU32 CMC::DEFAULT_BPP = 0; //Automode
58 const mfxU16 CMC::DEFAULT_DEBLOCKING = MFX_CODINGOPTION_OFF;
59 const mfxU16 CMC::DEFAULT_OVERLAP = MFX_CODINGOPTION_OFF;
60 const mfxU16 CMC::DEFAULT_ME = MFX_MVPRECISION_INTEGER >> 1;
61 const mfxU16 CMC::DEFAULT_REFS = MCTF_TEMPORAL_MODE_2REF;
62
QueryDefaultParams(IntMctfParams * pBuffer)63 void CMC::QueryDefaultParams(
64 IntMctfParams * pBuffer
65 )
66 {
67 if (!pBuffer) return;
68 pBuffer->Deblocking = DEFAULT_DEBLOCKING;
69 pBuffer->Overlap = DEFAULT_OVERLAP;
70 pBuffer->subPelPrecision = DEFAULT_ME;
71 pBuffer->TemporalMode = DEFAULT_REFS;
72 pBuffer->FilterStrength = DEFAULT_FILTER_STRENGTH; // [0...20]
73 pBuffer->BitsPerPixelx100k = DEFAULT_BPP;
74 };
75
QueryDefaultParams(mfxExtVppMctf * pBuffer)76 void CMC::QueryDefaultParams(
77 mfxExtVppMctf * pBuffer
78 )
79 {
80 if (!pBuffer) return;
81 IntMctfParams
82 Mctfparam;
83 QueryDefaultParams(&Mctfparam);
84 pBuffer->FilterStrength = Mctfparam.FilterStrength;
85 #ifdef MFX_ENABLE_MCTF_EXT
86 pBuffer->BitsPerPixelx100k = Mctfparam.BitsPerPixelx100k;
87 pBuffer->Overlap = Mctfparam.Overlap;
88 pBuffer->Deblocking = Mctfparam.Deblocking;
89 pBuffer->TemporalMode = Mctfparam.TemporalMode;
90 pBuffer->MVPrecision = Mctfparam.subPelPrecision;
91 #endif
92 };
93
CheckAndFixParams(mfxExtVppMctf * pBuffer)94 mfxStatus CMC::CheckAndFixParams(
95 mfxExtVppMctf * pBuffer
96 )
97 {
98 mfxStatus
99 sts = MFX_ERR_NONE;
100 if (!pBuffer) return MFX_ERR_NULL_PTR;
101 if (pBuffer->FilterStrength > 20)
102 {
103 pBuffer->FilterStrength = AUTO_FILTER_STRENGTH;
104 sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
105 }
106 #ifdef MFX_ENABLE_MCTF_EXT
107 if (MFX_CODINGOPTION_OFF != pBuffer->Deblocking &&
108 MFX_CODINGOPTION_ON != pBuffer->Deblocking &&
109 MFX_CODINGOPTION_UNKNOWN != pBuffer->Deblocking) {
110 pBuffer->Deblocking = DEFAULT_DEBLOCKING;
111 sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
112 }else
113 if (MFX_CODINGOPTION_UNKNOWN == pBuffer->Deblocking){
114 pBuffer->Deblocking = DEFAULT_DEBLOCKING;
115 // keep previous status to not override possibe WRN
116 }
117 if (MFX_CODINGOPTION_OFF != pBuffer->Overlap &&
118 MFX_CODINGOPTION_ON != pBuffer->Overlap &&
119 MFX_CODINGOPTION_UNKNOWN != pBuffer->Overlap) {
120 pBuffer->Overlap = DEFAULT_OVERLAP;
121 sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
122 }else
123 if (MFX_CODINGOPTION_UNKNOWN == pBuffer->Overlap) {
124 pBuffer->Overlap = DEFAULT_OVERLAP;
125 // keep previous status to not override possibe WRN
126 }
127
128 if (MCTF_TEMPORAL_MODE_SPATIAL != pBuffer->TemporalMode &&
129 MCTF_TEMPORAL_MODE_1REF != pBuffer->TemporalMode &&
130 MCTF_TEMPORAL_MODE_2REF != pBuffer->TemporalMode &&
131 MCTF_TEMPORAL_MODE_4REF != pBuffer->TemporalMode &&
132 MCTF_TEMPORAL_MODE_UNKNOWN != pBuffer->TemporalMode) {
133 pBuffer->TemporalMode = DEFAULT_REFS;
134 sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
135 }else
136 if (MCTF_TEMPORAL_MODE_UNKNOWN == pBuffer->TemporalMode) {
137 pBuffer->TemporalMode = DEFAULT_REFS;
138 // keep previous status to not override possibe WRN
139 }
140
141
142 if (MFX_MVPRECISION_INTEGER != pBuffer->MVPrecision &&
143 MFX_MVPRECISION_QUARTERPEL != pBuffer->MVPrecision &&
144 MFX_MVPRECISION_UNKNOWN != pBuffer->MVPrecision) {
145 pBuffer->MVPrecision = DEFAULT_ME;
146 sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
147 }else
148 if (MFX_MVPRECISION_UNKNOWN == pBuffer->MVPrecision)
149 {
150 pBuffer->MVPrecision = DEFAULT_ME;
151 // keep previous status to not override possibe WRN
152 }
153
154 if (pBuffer->BitsPerPixelx100k > DEFAULT_BPP) {
155 pBuffer->BitsPerPixelx100k = DEFAULT_BPP;
156 sts = MFX_WRN_INCOMPATIBLE_VIDEO_PARAM;
157 }
158 #endif
159 return sts;
160 }
161
162 // this function fills MCTF params based on extended buffer
FillParamControl(IntMctfParams * pBuffer,const mfxExtVppMctf * pSrc)163 void CMC::FillParamControl(
164 IntMctfParams * pBuffer,
165 const mfxExtVppMctf * pSrc
166 )
167 {
168 pBuffer->FilterStrength = pSrc->FilterStrength;
169 #ifdef MFX_ENABLE_MCTF_EXT
170 pBuffer->Deblocking = pSrc->Deblocking;
171 pBuffer->Overlap = pSrc->Overlap;
172 pBuffer->subPelPrecision = pSrc->MVPrecision;
173 pBuffer->TemporalMode = pSrc->TemporalMode;
174 pBuffer->BitsPerPixelx100k = pSrc->BitsPerPixelx100k;
175 #endif
176 }
177
SetFilterStrenght(unsigned short tFs,unsigned short sFs)178 mfxStatus CMC::SetFilterStrenght(
179 unsigned short tFs,//Temporal filter strength
180 unsigned short sFs //Spatial filter strength
181 )
182 {
183 if (tFs > 21 || sFs > 21)
184 return MFX_ERR_INVALID_VIDEO_PARAM;
185
186 p_ctrl->th = tFs * 50;
187 if (sFs)
188 p_ctrl->sTh = (mfxU16)min(sFs + CHROMABASE, MAXCHROMA);
189 else
190 p_ctrl->sTh = MCTFNOFILTER;
191 res = ctrlBuf->WriteSurface((const uint8_t *)p_ctrl.get(), NULL, sizeof(MeControlSmall));
192 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
193 return MFX_ERR_NONE;
194 }
195
SetFilterStrenght(unsigned short fs)196 inline mfxStatus CMC::SetFilterStrenght(
197 unsigned short fs
198 )
199 {
200 MCTF_CHECK_CM_ERR(SetFilterStrenght(fs, fs), MFX_ERR_DEVICE_FAILED);
201 return MFX_ERR_NONE;
202 }
203
SetupMeControl(const mfxFrameInfo & FrameInfo,mfxU16 th,mfxU16 subPelPre)204 inline mfxStatus CMC::SetupMeControl(
205 const mfxFrameInfo & FrameInfo,
206 mfxU16 th,
207 mfxU16 subPelPre
208 )
209 {
210 p_ctrl.reset(new MeControlSmall);
211 const mfxU8 Diamond[MCTFSEARCHPATHSIZE] = {
212 0x0F,0xF1,0x0F,0x12,//5
213 0x0D,0xE2,0x22,0x1E,//9
214 0x10,0xFF,0xE2,0x20,//13
215 0xFC,0x06,0xDD,//16
216 0x2E,0xF1,0x3F,0xD3,0x11,0x3D,0xF3,0x1F,//24
217 0xEB,0xF1,0xF1,0xF1,//28
218 0x4E,0x11,0x12,0xF2,0xF1,//33
219 0xE0,0xFF,0xFF,0x0D,0x1F,0x1F,//39
220 0x20,0x11,0xCF,0xF1,0x05,0x11,//45
221 0x00,0x00,0x00,0x00,0x00,0x00,//51
222 };
223 std::copy(std::begin(Diamond), std::end(Diamond), std::begin(p_ctrl->searchPath.sp));
224
225 p_ctrl->searchPath.lenSp = 16;
226 p_ctrl->searchPath.maxNumSu = 57;
227
228 p_ctrl->width = FrameInfo.Width;
229 p_ctrl->height = FrameInfo.Height;
230
231 mfxU16 CropX(FrameInfo.CropX), CropY(FrameInfo.CropY), CropW(FrameInfo.CropW), CropH(FrameInfo.CropH);
232
233 // this code align crop regin to CROP_BLOCK_ALIGNMENT boundary;
234 // doing this, it follows the principle that initial crop-region
235 // to be included in the crop-region after alignment;
236
237 mfxU16 CropRBX = CropX + CropW - 1;
238 mfxU16 CropRBY = CropY + CropH - 1;
239 CropX = (CropX / CROP_BLOCK_ALIGNMENT) * CROP_BLOCK_ALIGNMENT;
240 CropY = (CropY / CROP_BLOCK_ALIGNMENT) * CROP_BLOCK_ALIGNMENT;
241 CropW = CropRBX - CropX + 1;
242 CropH = CropRBY - CropY + 1;
243
244 CropW = (DIVUP(CropW, CROP_BLOCK_ALIGNMENT)) * CROP_BLOCK_ALIGNMENT;
245 CropH = (DIVUP(CropH, CROP_BLOCK_ALIGNMENT)) * CROP_BLOCK_ALIGNMENT;
246
247 if ((CropX + CropW > FrameInfo.Width) || (CropY + CropH > FrameInfo.Height))
248 return MFX_ERR_INCOMPATIBLE_VIDEO_PARAM;
249
250 p_ctrl->CropX = CropX;
251 p_ctrl->CropY = CropY;
252 p_ctrl->CropW = CropW;
253 p_ctrl->CropH = CropH;
254
255 if (th > 20)
256 return MFX_ERR_INVALID_VIDEO_PARAM;
257 p_ctrl->th = th * 50;
258 p_ctrl->sTh = (mfxU16)min(th + CHROMABASE, MAXCHROMA);
259 p_ctrl->mre_width = 0;
260 p_ctrl->mre_height = 0;
261 if (MFX_MVPRECISION_INTEGER >> 1 == subPelPre)
262 p_ctrl->subPrecision = 0;
263 else
264 if (MFX_MVPRECISION_QUARTERPEL >> 1 == subPelPre)
265 p_ctrl->subPrecision = 1;
266 else
267 return MFX_ERR_INVALID_VIDEO_PARAM;
268 return MFX_ERR_NONE;
269 }
270
MCTF_GET_FRAME(CmSurface2D * outFrame)271 mfxStatus CMC::MCTF_GET_FRAME(
272 CmSurface2D * outFrame
273 )
274 {
275 mfxStatus sts = MFX_ERR_NONE;
276 if (!outFrame)
277 return MFX_ERR_UNDEFINED_BEHAVIOR;
278 if (!mco)
279 {
280 // we are in the end of a stream, and it must be the configuration with
281 // > 1 reference as there is no reason to get another surface out of MCTF
282 // if no delay was assumed.
283 if (NO_REFERENCES == number_of_References || ONE_REFERENCE == number_of_References)
284 {
285 //this is undefined behavior
286 return MFX_ERR_UNDEFINED_BEHAVIOR;
287 }
288 else
289 {
290 // let map outframe to mco
291 mco = outFrame;
292 INT cmSts = mco->GetIndex(idxMco);
293 MFX_CHECK((CM_SUCCESS == cmSts), MFX_ERR_DEVICE_FAILED);
294 }
295 }
296
297 if (QfIn.size() == 5)
298 {
299 if (lastFrame == 1)
300 {
301 res = MCTF_RUN_MCTF_DEN(true);
302 lastFrame++;
303 }
304 else if (lastFrame == 2)
305 MCTF_RUN_AMCTF(lastFrame);
306 }
307 else if (QfIn.size() == 3)
308 {
309 if (lastFrame == 1)
310 //res = MCTF_RUN_AMCTF(lastFrame);
311 res = MCTF_RUN_MCTF_DEN(true);
312 }
313
314 MFX_CHECK(mco, MFX_ERR_UNDEFINED_BEHAVIOR);
315 mco = nullptr;
316 if (!lastFrame)
317 lastFrame = 1;
318 return sts;
319 }
320
MCTF_GET_FRAME(mfxU8 * outFrame)321 mfxStatus CMC::MCTF_GET_FRAME(
322 mfxU8 * outFrame
323 )
324 {
325 mfxStatus sts = MFX_ERR_NONE;
326 if (!outFrame)
327 return MFX_ERR_UNDEFINED_BEHAVIOR;
328 if (!mco)
329 {
330 if (NO_REFERENCES == number_of_References || ONE_REFERENCE == number_of_References)
331 {
332 //this is undefined behavior
333 return MFX_ERR_UNDEFINED_BEHAVIOR;
334 }
335 else
336 return MFX_ERR_DEVICE_FAILED;
337 }
338
339 if (lastFrame == 1)
340 res = MCTF_RUN_MCTF_DEN(true);
341
342 MFX_CHECK(mco, MFX_ERR_UNDEFINED_BEHAVIOR);
343
344 if (QfIn[0].filterStrength > 0)
345 {
346 res = queue->EnqueueCopyGPUToCPU(mco, outFrame, copyEv);
347 MFX_CHECK((CM_SUCCESS == res), MFX_ERR_DEVICE_FAILED);
348
349 CM_STATUS
350 status = CM_STATUS_FLUSHED;
351
352 copyEv->GetStatus(status);
353 while (status != CM_STATUS_FINISHED)
354 copyEv->GetStatus(status);
355
356 MctfState = AMCTF_NOT_READY;
357 }
358
359 return sts;
360 }
361
MCTF_CHECK_FILTER_USE()362 bool CMC::MCTF_CHECK_FILTER_USE()
363 {
364 if (QfIn.front().filterStrength == 0)
365 return false;
366 return true;
367 }
368
MCTF_RELEASE_FRAME(bool isCmUsed)369 mfxStatus CMC::MCTF_RELEASE_FRAME(
370 bool isCmUsed
371 )
372 {
373 if (MCTF_ReadyToOutput())
374 {
375 MctfState = AMCTF_NOT_READY;
376 if (mco2)
377 {
378 mco = mco2;
379 idxMco = idxMco2;
380 mco2 = nullptr;
381 idxMco2 = nullptr;
382 }
383 }
384 //Buffer has rotated enough at this point that last position is old and needs to eb recycled.
385 if (isCmUsed)
386 {
387 if (QfIn.back().frameData)
388 {
389 device->DestroySurface(QfIn.back().frameData);//This Surface is created by MCTF and needs to be destroyed after denoised frame has been used.
390 QfIn.back().frameData = nullptr;
391 QfIn.back().fIdx = nullptr;
392 QfIn.back().mfxFrame = nullptr;
393 }
394 }
395 return MFX_ERR_NONE;
396 }
397
MCTF_TrackTimeStamp(mfxFrameSurface1 * outFrame)398 mfxStatus CMC::MCTF_TrackTimeStamp(
399 mfxFrameSurface1 * outFrame
400 )
401 {
402 outFrame->Data.FrameOrder = QfIn[CurrentIdx2Out].mfxFrame->Data.FrameOrder;
403 outFrame->Data.TimeStamp = QfIn[CurrentIdx2Out].mfxFrame->Data.TimeStamp;
404 return MFX_ERR_NONE;
405 }
406
MCTF_InitQueue(mfxU16 refNum)407 mfxStatus CMC::MCTF_InitQueue(
408 mfxU16 refNum
409 )
410 {
411 mfxU32 buffer_size(0);
412 switch (refNum)
413 {
414 case MCTF_TEMPORAL_MODE_4REF:
415 {
416 number_of_References = FOUR_REFERENCES;
417 DefaultIdx2Out = 1;
418 CurrentIdx2Out = 0;
419 MctfState = AMCTF_NOT_READY;
420 buffer_size = FOUR_REFERENCES + 1;
421 };
422 break;
423 case MCTF_TEMPORAL_MODE_2REF:
424 {
425 number_of_References = TWO_REFERENCES;
426 DefaultIdx2Out = 0;
427 CurrentIdx2Out = 0;
428 MctfState = AMCTF_NOT_READY;
429 buffer_size = TWO_REFERENCES + 1;
430 };
431 break;
432 case MCTF_TEMPORAL_MODE_1REF:
433 {
434 number_of_References = ONE_REFERENCE;
435 DefaultIdx2Out = 0;
436 CurrentIdx2Out = 0;
437 MctfState = AMCTF_READY;
438 buffer_size = ONE_REFERENCE + 1;
439 };
440 break;
441 case MCTF_TEMPORAL_MODE_SPATIAL:
442 { //refNum == 0
443 number_of_References = NO_REFERENCES;
444 DefaultIdx2Out = 0;
445 CurrentIdx2Out = 0;
446 MctfState = AMCTF_READY;
447 buffer_size = ONE_REFERENCE ;
448 };
449 break;
450 default:
451 return MFX_ERR_INVALID_VIDEO_PARAM;
452 };
453
454 for (mfxU8 i = 0; i < buffer_size; i++)
455 {
456 scene_numbers[i] = 0;
457 QfIn.push_back(gpuFrameData());
458 }
459
460 return MFX_ERR_NONE;
461 }
462
DIM_SET(mfxU16 overlap)463 mfxStatus CMC::DIM_SET(
464 mfxU16 overlap
465 )
466 {
467 // if (p_ctrl->height <= MINHEIGHT)
468 if (p_ctrl->CropH <= MINHEIGHT)
469 blsize = 8;
470 if (MFX_CODINGOPTION_OFF != overlap &&
471 MFX_CODINGOPTION_ON != overlap &&
472 MFX_CODINGOPTION_UNKNOWN != overlap)
473 return MFX_ERR_INVALID_VIDEO_PARAM;
474 overlap_Motion = overlap;
475 switch (overlap_Motion)
476 {
477 case MFX_CODINGOPTION_ON:
478 {
479 ov_width_bl = (DIVUP(p_ctrl->CropW, blsize) * 2) - 1;
480 ov_height_bl = (DIVUP(p_ctrl->CropH, blsize) * 2) - 1;
481 }
482 break;
483 case MFX_CODINGOPTION_UNKNOWN:
484 case MFX_CODINGOPTION_OFF:
485 {
486 ov_width_bl = DIVUP(p_ctrl->CropW, blsize) * 2;
487 ov_height_bl = DIVUP(p_ctrl->CropH, blsize) * 2;
488 }
489 break;
490 default:
491 return MFX_ERR_INVALID_VIDEO_PARAM;
492 }
493 int var_sc_area = DIVUP(p_ctrl->CropW, 16) * DIVUP(p_ctrl->CropH, 16);
494 distRef.resize(ov_width_bl * ov_height_bl, 0);
495 var_sc.resize(var_sc_area);
496
497 return MFX_ERR_NONE;
498 }
499
500
IM_SURF_SET(CmSurface2D ** p_surface,SurfaceIndex ** p_idxSurf)501 mfxStatus CMC::IM_SURF_SET(
502 CmSurface2D ** p_surface,
503 SurfaceIndex ** p_idxSurf
504 )
505 {
506 res = device->CreateSurface2D(p_ctrl->width, p_ctrl->height, CM_SURFACE_FORMAT_NV12, *p_surface);
507 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
508 res = (*p_surface)->GetIndex(*p_idxSurf);
509 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
510 return MFX_ERR_NONE;
511 }
512
IM_SURF_SET(AbstractSurfaceHandle pD3DSurf,CmSurface2D ** p_surface,SurfaceIndex ** p_idxSurf)513 mfxStatus CMC::IM_SURF_SET(
514 AbstractSurfaceHandle pD3DSurf,
515 CmSurface2D ** p_surface,
516 SurfaceIndex ** p_idxSurf
517 )
518 {
519 res = device->CreateSurface2D(pD3DSurf, *p_surface);
520 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
521 res = (*p_surface)->GetIndex(*p_idxSurf);
522 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
523 return MFX_ERR_NONE;
524 }
525
IM_MRE_SURF_SET(CmSurface2D ** p_Surface,SurfaceIndex ** p_idxSurf)526 mfxStatus CMC::IM_MRE_SURF_SET(
527 CmSurface2D ** p_Surface,
528 SurfaceIndex ** p_idxSurf
529 )
530 {
531 mfxU32
532 width = SUBMREDIM, height = SUBMREDIM;
533 res = device->CreateSurface2D(width * sizeof(mfxI16Pair), height, CM_SURFACE_FORMAT_A8, *p_Surface);
534 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
535 res = (*p_Surface)->GetIndex(*p_idxSurf);
536 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
537 return MFX_ERR_NONE;
538 }
539
IM_SURF_SET_Int()540 mfxStatus CMC::IM_SURF_SET_Int() {
541 for (mfxU32 i = 0; i < QfIn.size(); i++) {
542 res += IM_SURF_SET(&QfIn[i].frameData, &QfIn[i].fIdx);
543 QfIn[i].scene_idx = 0;
544 }
545 return MFX_ERR_NONE;
546 }
547
IM_SURF_SET()548 mfxStatus CMC::IM_SURF_SET()
549 {
550 for (mfxU32 i = 0; i < QfIn.size(); i++)
551 {
552 MFX_SAFE_CALL(IM_MRE_SURF_SET(&QfIn[i].magData, &QfIn[i].idxMag));
553 mfxHDLPair
554 handle;
555 // if a surface is opaque, need to extract normal surface
556 mfxFrameSurface1
557 * pSurf = m_pCore->GetNativeSurface(QfIn[i].mfxFrame);
558 QfIn[i].mfxFrame = pSurf ? pSurf : QfIn[i].mfxFrame;
559 // GetFrameHDL is used as QfIn[].mfxFrme is allocated via call to Core Alloc function
560 MFX_SAFE_CALL(m_pCore->GetFrameHDL(QfIn[i].mfxFrame->Data.MemId, reinterpret_cast<mfxHDL*>(&handle)));
561 MFX_SAFE_CALL(IM_SURF_SET(reinterpret_cast<AbstractSurfaceHandle>(handle.first), &QfIn[i].frameData, &QfIn[i].fIdx));
562 QfIn[i].scene_idx = 0;
563 }
564 return MFX_ERR_NONE;
565 }
566
MCTF_QUERY_NUMBER_OF_REFERENCES()567 mfxU16 CMC::MCTF_QUERY_NUMBER_OF_REFERENCES()
568 {
569 return number_of_References;
570 }
571
MCTF_GetQueueDepth()572 mfxU32 CMC::MCTF_GetQueueDepth()
573 {
574 return (mfxU32)QfIn.size();
575 }
576
MCTF_SetMemory(const std::vector<mfxFrameSurface1 * > & mfxSurfPool)577 mfxStatus CMC::MCTF_SetMemory(
578 const std::vector<mfxFrameSurface1*> & mfxSurfPool
579 )
580 {
581 if (mfxSurfPool.size() != QfIn.size())
582 return MFX_ERR_UNDEFINED_BEHAVIOR;
583 else
584 {
585 auto inp_iter = mfxSurfPool.begin();
586 for (auto it = QfIn.begin(); it != QfIn.end() && inp_iter != mfxSurfPool.end(); ++it, ++inp_iter)
587 it->mfxFrame = *inp_iter;
588 res = IM_SURF_SET();
589 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
590 // mco & idxmco will be extracted from an output surface
591 mco = nullptr;
592 res = IM_SURF_SET(&mco2, &idxMco2);
593 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
594
595 //Setup for 2 references
596 res = GEN_SURF_SET(&mv_1, &mvSys1, &idxMv_1);
597 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
598 res = GEN_SURF_SET(&mv_2, &mvSys2, &idxMv_2);
599 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
600 if (number_of_References > 2)
601 {
602 //Setup for 4 references
603 res = GEN_SURF_SET(&mv_3, &mvSys3, &idxMv_3);
604 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
605 res = GEN_SURF_SET(&mv_4, &mvSys4, &idxMv_4);
606 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
607 }
608
609 res = GEN_SURF_SET(&distSurf, &distSys, &idxDist);
610 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
611 res = GEN_NoiseSURF_SET(&noiseAnalysisSurf, &noiseAnalysisSys, &idxNoiseAnalysis);
612 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
613 return MFX_ERR_NONE;
614 }
615 }
616
MCTF_SetMemory(bool isCmUsed)617 mfxStatus CMC::MCTF_SetMemory(
618 bool isCmUsed
619 )
620 {
621 // mco & idxmco will be extracted from input/output surface
622 if (!isCmUsed)
623 {
624 res = IM_SURF_SET_Int();
625 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
626 }
627 mco = nullptr;
628 idxMco = nullptr;
629 mco2 = nullptr;
630 idxMco2 = nullptr;
631
632 //Setup for 2 references
633 res = GEN_SURF_SET(&mv_1, &mvSys1, &idxMv_1);
634 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
635 res = GEN_SURF_SET(&mv_2, &mvSys2, &idxMv_2);
636 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
637 if (number_of_References > 2)
638 {
639 //Setup for 4 references
640 res = GEN_SURF_SET(&mv_3, &mvSys3, &idxMv_3);
641 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
642 res = GEN_SURF_SET(&mv_4, &mvSys4, &idxMv_4);
643 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
644 }
645
646 res = GEN_SURF_SET(&distSurf, &distSys, &idxDist);
647 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
648 res = GEN_NoiseSURF_SET(&noiseAnalysisSurf, &noiseAnalysisSys, &idxNoiseAnalysis);
649 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
650 return MFX_ERR_NONE;
651 }
652
MCTF_INIT(VideoCORE * core,CmDevice * pCmDevice,const mfxFrameInfo & FrameInfo,const IntMctfParams * pMctfParam,bool isCmUsed,const bool externalSCD,const bool useFilterAdaptControl,const bool isNCActive)653 mfxStatus CMC::MCTF_INIT(
654 VideoCORE * core,
655 CmDevice * pCmDevice,
656 const mfxFrameInfo & FrameInfo,
657 const IntMctfParams * pMctfParam,
658 bool isCmUsed,
659 const bool externalSCD,
660 const bool useFilterAdaptControl,
661 const bool isNCActive
662 )
663 {
664 version = 400;
665 argIdx = 0;
666 tsWidthFull = 0;
667 tsWidth = 0;
668 tsHeight = 0;
669 bth = 500;
670 blsize = 16;
671 device = NULL;
672 sceneNum = 0;
673 countFrames = 0;
674 firstFrame = 1;
675 lastFrame = 0;
676 exeTime = 0;
677 exeTimeT = 0;
678 m_externalSCD = externalSCD;
679 m_adaptControl = useFilterAdaptControl;
680 m_doFilterFrame = false;
681
682 //--filter configuration parameters
683 m_AutoMode = MCTF_MODE::MCTF_NOT_INITIALIZED_MODE;
684 ConfigMode = MCTF_CONFIGURATION::MCTF_NOT_CONFIGURED;
685 number_of_References = MCTF_TEMPORAL_MODE_2REF;
686 bitrate_Adaptation = false;
687 deblocking_Control = MFX_CODINGOPTION_OFF;
688 bpp = 0.0;
689 m_FrameRateExtD = 1;
690 m_FrameRateExtN = 0;
691
692 ctrlBuf = 0;
693 idxCtrl = 0;
694 distSys = 0;
695 time = 0;
696
697 qpel1 = 0;
698 qpel2 = 0;
699 idxMv_1 = 0;
700
701 bufferCount = 0;
702 //ME elements
703 genxRefs1 = 0;
704 genxRefs2 = 0;
705 genxRefs3 = 0;
706 genxRefs4 = 0;
707 idxMv_1 = NULL;
708 idxMv_2 = NULL;
709 idxMv_3 = NULL;
710 idxMv_4 = NULL;
711
712 //Motion Estimation
713 programMe = 0;
714 kernelMe = 0;
715
716 //MC elements
717 mco = 0;
718 idxMco = 0;
719 mco2 = 0;
720 idxMco2 = 0;
721
722 //Motion Compensation
723 programMc = 0;
724 kernelMcDen = 0;
725 kernelMc1r = 0;
726 kernelMc2r = 0;
727 kernelMc4r = 0;
728 //Common elements
729 queue = NULL;
730 //copyQ = NULL;
731 copyEv = NULL;
732
733 // m_IOPattern = io_pattern;
734 // m_ioMode = io_mode;
735
736 if (core)
737 m_pCore = core;
738 else
739 return MFX_ERR_NOT_INITIALIZED;
740
741 if (pCmDevice)
742 device = pCmDevice;
743 else
744 return MFX_ERR_NOT_INITIALIZED;
745
746 mfxStatus sts = MFX_ERR_NONE;
747 if(!m_externalSCD)
748 pSCD.reset(new(ASC));
749
750 IntMctfParams MctfParam{};
751 QueryDefaultParams(&MctfParam);
752
753 // if no MctfParams are passed, to use default
754 if (!pMctfParam)
755 pMctfParam = &MctfParam;
756 sts = MCTF_SET_ENV(core, FrameInfo, pMctfParam, isCmUsed, isNCActive);
757
758 MFX_CHECK_STS(sts);
759 return sts;
760 }
761
MCTF_INIT(VideoCORE * core,CmDevice * pCmDevice,const mfxFrameInfo & FrameInfo,const IntMctfParams * pMctfParam)762 mfxStatus CMC::MCTF_INIT(
763 VideoCORE * core,
764 CmDevice * pCmDevice,
765 const mfxFrameInfo & FrameInfo,
766 const IntMctfParams * pMctfParam
767 )
768 {
769 return (MCTF_INIT(core, pCmDevice, FrameInfo, pMctfParam, false, false));
770 }
771
MCTF_INIT(VideoCORE * core,CmDevice * pCmDevice,const mfxFrameInfo & FrameInfo,const IntMctfParams * pMctfParam,const bool externalSCD,const bool isNCActive)772 mfxStatus CMC::MCTF_INIT(
773 VideoCORE * core,
774 CmDevice * pCmDevice,
775 const mfxFrameInfo & FrameInfo,
776 const IntMctfParams * pMctfParam,
777 const bool externalSCD,
778 const bool isNCActive
779 )
780 {
781 return (MCTF_INIT(core, pCmDevice, FrameInfo, pMctfParam, false, externalSCD, false, isNCActive));
782 }
783
MCTF_SET_ENV(VideoCORE * core,const mfxFrameInfo & FrameInfo,const IntMctfParams * pMctfParam,bool isCmUsed,bool isNCActive)784 mfxStatus CMC::MCTF_SET_ENV(
785 VideoCORE * core,
786 const mfxFrameInfo & FrameInfo,
787 const IntMctfParams * pMctfParam,
788 bool isCmUsed,
789 bool isNCActive
790 )
791 {
792 IntMctfParams localMctfParam = *pMctfParam;
793 mfxStatus sts = MFX_ERR_NONE;
794 if (!device)
795 return MFX_ERR_NOT_INITIALIZED;
796
797 hwSize = 4;
798 res = device->GetCaps(CAP_GPU_PLATFORM, hwSize, &hwType);
799 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
800
801 if (core->GetHWType() >= MFX_HW_ICL)
802 res = device->CreateQueueEx(queue, CM_VME_QUEUE_CREATE_OPTION);
803 else
804 res = device->CreateQueue(queue);
805 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
806
807 task = 0;
808 // --- bitrate
809 if (localMctfParam.BitsPerPixelx100k) //todo: to do correctcompare with 0.0
810 bitrate_Adaptation = true;
811 else
812 bitrate_Adaptation = false;
813
814 // ---- BitsPerPixel
815 MCTF_UpdateBitrateInfo(localMctfParam.BitsPerPixelx100k);
816
817 // --- deblock
818 if (MFX_CODINGOPTION_ON != localMctfParam.Deblocking &&
819 MFX_CODINGOPTION_OFF != localMctfParam.Deblocking &&
820 MFX_CODINGOPTION_UNKNOWN != localMctfParam.Deblocking)
821 return MFX_ERR_INVALID_VIDEO_PARAM;
822
823 //Dimensions, control and io
824 if (MCTF_TEMPORAL_MODE_SPATIAL == localMctfParam.TemporalMode)
825 {
826 localMctfParam.Overlap = MFX_CODINGOPTION_OFF;
827 localMctfParam.Deblocking = MFX_CODINGOPTION_OFF;
828 localMctfParam.subPelPrecision = MFX_MVPRECISION_INTEGER;
829 }
830 deblocking_Control = localMctfParam.Deblocking;
831
832 // MRE is initialized inside
833 sts = SetupMeControl(FrameInfo, localMctfParam.FilterStrength, localMctfParam.subPelPrecision);
834 MFX_CHECK_STS(sts);
835
836 sts = MCTF_InitQueue(localMctfParam.TemporalMode);
837 MFX_CHECK_STS(sts);
838
839 sts = DIM_SET(localMctfParam.Overlap);
840 MFX_CHECK_STS(sts);
841
842 if (bitrate_Adaptation || !localMctfParam.FilterStrength)
843 m_AutoMode = MCTF_MODE::MCTF_AUTO_MODE;
844 else
845 m_AutoMode = MCTF_MODE::MCTF_MANUAL_MODE;
846
847 if (bitrate_Adaptation)
848 ConfigMode = MCTF_CONFIGURATION::MCTF_AUT_CA_BA;
849 else
850 {
851 ConfigMode = MCTF_MODE::MCTF_AUTO_MODE == m_AutoMode ? MCTF_CONFIGURATION::MCTF_AUT_CA_NBA : MCTF_CONFIGURATION::MCTF_MAN_NCA_NBA;
852 }
853
854 pMCTF_SpDen_func = nullptr;
855 pMCTF_NOA_func = nullptr;
856 pMCTF_LOAD_func = nullptr;
857 pMCTF_ME_func = nullptr;
858 pMCTF_MERGE_func = nullptr;
859 pMCTF_func = nullptr;
860
861 pMCTF_func = &CMC::MCTF_RUN_MCTF_DEN;
862 if (m_AutoMode == MCTF_MODE::MCTF_AUTO_MODE || isNCActive)
863 pMCTF_NOA_func = &CMC::noise_estimator;
864
865 if (number_of_References == FOUR_REFERENCES)
866 {
867 pMCTF_LOAD_func = &CMC::MCTF_LOAD_4REF;
868 pMCTF_ME_func = &CMC::MCTF_RUN_ME_4REF;
869 pMCTF_MERGE_func = &CMC::MCTF_RUN_MERGE;
870 }
871 else if (number_of_References == TWO_REFERENCES)
872 {
873 pMCTF_LOAD_func = &CMC::MCTF_LOAD_2REF;
874 if (isNCActive)
875 pMCTF_ME_func = &CMC::MCTF_RUN_ME_2REF_HE;
876 else
877 pMCTF_ME_func = &CMC::MCTF_RUN_ME_2REF;
878 pMCTF_MERGE_func = NULL;
879 }
880 else if (number_of_References == ONE_REFERENCE)
881 {
882 pMCTF_func = &CMC::MCTF_RUN_MCTF_DEN_1REF;
883 pMCTF_LOAD_func = &CMC::MCTF_LOAD_1REF;
884 pMCTF_ME_func = &CMC::MCTF_RUN_ME_1REF;
885 pMCTF_MERGE_func = &CMC::MCTF_RUN_BLEND;
886 }
887 else if (number_of_References == NO_REFERENCES)
888 {
889 pMCTF_func = &CMC::MCTF_RUN_MCTF_DEN_1REF;
890 pMCTF_LOAD_func = &CMC::MCTF_LOAD_1REF;
891 pMCTF_ME_func = NULL;
892 pMCTF_MERGE_func = &CMC::MCTF_RUN_AMCTF;
893 }
894 else
895 return MFX_ERR_UNDEFINED_BEHAVIOR;
896
897 //deblocking only if ME is used
898 if (MFX_CODINGOPTION_ON == deblocking_Control &&
899 (ONE_REFERENCE == number_of_References ||
900 TWO_REFERENCES == number_of_References ||
901 FOUR_REFERENCES == number_of_References)
902 )
903 pMCTF_SpDen_func = &CMC::MCTF_RUN_Denoise;
904
905 if (blsize < VMEBLSIZE)
906 p_ctrl->th = p_ctrl->th / 4;
907 res = device->CreateBuffer(sizeof(MeControlSmall), ctrlBuf);
908 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
909 res = ctrlBuf->WriteSurface((const uint8_t *)p_ctrl.get(), NULL, sizeof(MeControlSmall));
910 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
911 res = ctrlBuf->GetIndex(idxCtrl);
912 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
913
914 //Init internal buffer which is not shared
915 if (isNCActive)
916 {
917 res = MCTF_SetMemory(isCmUsed);
918 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
919 }
920
921 //Motion Estimation
922 switch (hwType)
923 {
924 #ifdef MFX_ENABLE_KERNELS
925 case PLATFORM_INTEL_BDW:
926 res = device->LoadProgram((void *)genx_me_gen8, sizeof(genx_me_gen8), programMe, "nojitter");
927 break;
928 case PLATFORM_INTEL_ICL:
929 res = device->LoadProgram((void *)genx_me_gen11, sizeof(genx_me_gen11), programMe, "nojitter");
930 break;
931 case PLATFORM_INTEL_ICLLP:
932 res = device->LoadProgram((void *)genx_me_gen11lp, sizeof(genx_me_gen11lp), programMe, "nojitter");
933 break;
934 case PLATFORM_INTEL_TGLLP:
935 case PLATFORM_INTEL_RKL:
936 case PLATFORM_INTEL_DG1:
937 res = device->LoadProgram((void *)genx_me_gen12lp, sizeof(genx_me_gen12lp), programMe, "nojitter");
938 break;
939 case PLATFORM_INTEL_SKL:
940 case PLATFORM_INTEL_BXT:
941 case PLATFORM_INTEL_CNL:
942 case PLATFORM_INTEL_KBL:
943 case PLATFORM_INTEL_CFL:
944 case PLATFORM_INTEL_GLK:
945 res = device->LoadProgram((void *)genx_me_gen9, sizeof(genx_me_gen9), programMe, "nojitter");
946 break;
947 #endif
948 default:
949 return MFX_ERR_UNSUPPORTED;
950 }
951 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
952
953 //ME Kernel
954 if (MFX_CODINGOPTION_ON == overlap_Motion)
955 {
956 res = device->CreateKernel(programMe, CM_KERNEL_FUNCTION(MeP16_1MV_MRE), kernelMe);
957 res = device->CreateKernel(programMe, CM_KERNEL_FUNCTION(MeP16bi_1MV2_MRE), kernelMeB);
958 res = device->CreateKernel(programMe, CM_KERNEL_FUNCTION(MeP16bi_1MV2_MRE), kernelMeB2);
959
960 }
961 else
962 if (MFX_CODINGOPTION_OFF == overlap_Motion || MFX_CODINGOPTION_UNKNOWN == overlap_Motion)
963 {
964 res = device->CreateKernel(programMe, CM_KERNEL_FUNCTION(MeP16_1MV_MRE_8x8), kernelMe);
965 if (isNCActive)
966 {
967 res = device->CreateKernel(programMe, CM_KERNEL_FUNCTION(MeP16_1ME_2BiRef_MRE_8x8), kernelMeB);
968 res = device->CreateKernel(programMe, CM_KERNEL_FUNCTION(MeP16_1ME_2BiRef_MRE_8x8), kernelMeB2);
969 }
970 else
971 {
972 res = device->CreateKernel(programMe, CM_KERNEL_FUNCTION(MeP16bi_1MV2_MRE_8x8), kernelMeB);
973 res = device->CreateKernel(programMe, CM_KERNEL_FUNCTION(MeP16bi_1MV2_MRE_8x8), kernelMeB2);
974 }
975
976 }
977 else
978 return MFX_ERR_INVALID_VIDEO_PARAM;
979 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
980
981 //Motion Compensation
982 switch (hwType)
983 {
984 #ifdef MFX_ENABLE_KERNELS
985 case PLATFORM_INTEL_BDW:
986 res = device->LoadProgram((void *)genx_mc_gen8, sizeof(genx_mc_gen8), programMc, "nojitter");
987 break;
988 case PLATFORM_INTEL_ICL:
989 res = device->LoadProgram((void *)genx_mc_gen11, sizeof(genx_mc_gen11), programMc, "nojitter");
990 break;
991 case PLATFORM_INTEL_ICLLP:
992 res = device->LoadProgram((void *)genx_mc_gen11lp, sizeof(genx_mc_gen11lp), programMc, "nojitter");
993 break;
994 case PLATFORM_INTEL_TGLLP:
995 case PLATFORM_INTEL_RKL:
996 case PLATFORM_INTEL_DG1:
997 res = device->LoadProgram((void *)genx_mc_gen12lp, sizeof(genx_mc_gen12lp), programMc, "nojitter");
998 break;
999 case PLATFORM_INTEL_SKL:
1000 case PLATFORM_INTEL_BXT:
1001 case PLATFORM_INTEL_CNL:
1002 case PLATFORM_INTEL_KBL:
1003 case PLATFORM_INTEL_CFL:
1004 case PLATFORM_INTEL_GLK:
1005 res = device->LoadProgram((void *)genx_mc_gen9, sizeof(genx_mc_gen9), programMc, "nojitter");
1006 break;
1007 #endif
1008 default:
1009 return MFX_ERR_UNSUPPORTED;
1010 }
1011 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1012
1013 switch (hwType)
1014 {
1015 #ifdef MFX_ENABLE_KERNELS
1016 case PLATFORM_INTEL_BDW:
1017 res = device->LoadProgram((void *)genx_sd_gen8, sizeof(genx_sd_gen8), programDe, "nojitter");
1018 break;
1019 case PLATFORM_INTEL_ICL:
1020 res = device->LoadProgram((void *)genx_sd_gen11, sizeof(genx_sd_gen11), programDe, "nojitter");
1021 break;
1022 case PLATFORM_INTEL_ICLLP:
1023 res = device->LoadProgram((void *)genx_sd_gen11lp, sizeof(genx_sd_gen11lp), programDe, "nojitter");
1024 break;
1025 case PLATFORM_INTEL_TGLLP:
1026 case PLATFORM_INTEL_RKL:
1027 case PLATFORM_INTEL_DG1:
1028 res = device->LoadProgram((void *)genx_sd_gen12lp, sizeof(genx_sd_gen12lp), programDe, "nojitter");
1029 break;
1030 case PLATFORM_INTEL_SKL:
1031 case PLATFORM_INTEL_BXT:
1032 case PLATFORM_INTEL_CNL:
1033 case PLATFORM_INTEL_KBL:
1034 case PLATFORM_INTEL_CFL:
1035 case PLATFORM_INTEL_GLK:
1036 res = device->LoadProgram((void *)genx_sd_gen9, sizeof(genx_sd_gen9), programDe, "nojitter");
1037 break;
1038 #endif
1039 default:
1040 return MFX_ERR_UNSUPPORTED;
1041 }
1042 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1043
1044 //Denoising No reference Kernel
1045 res = device->CreateKernel(programDe, CM_KERNEL_FUNCTION(SpatialDenoiser_8x8_NV12), kernelMcDen);
1046 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1047 //Motion Compensation 1 Ref Kernel
1048 res = device->CreateKernel(programMc, CM_KERNEL_FUNCTION(McP16_4MV_1SURF_WITH_CHR), kernelMc1r);
1049 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1050 //Motion Compensation 2 Ref Kernel
1051 res = device->CreateKernel(programMc, CM_KERNEL_FUNCTION(McP16_4MV_2SURF_WITH_CHR), kernelMc2r);
1052 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1053 //Motion Compensation 4 Ref Kernel
1054 if (number_of_References == FOUR_REFERENCES) {
1055 res = device->CreateKernel(programMc, CM_KERNEL_FUNCTION(MC_MERGE4), kernelMc4r);
1056 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1057 }
1058
1059 res = device->CreateKernel(programMc, CM_KERNEL_FUNCTION(MC_VAR_SC_CALC), kernelNoise);
1060 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1061 if (!m_externalSCD)
1062 {
1063 sts = pSCD->Init(p_ctrl->CropW, p_ctrl->CropH, p_ctrl->width, MFX_PICSTRUCT_PROGRESSIVE, device);
1064 MFX_CHECK_STS(sts);
1065 sts = pSCD->SetGoPSize(Immediate_GoP);
1066 MFX_CHECK_STS(sts);
1067 pSCD->SetControlLevel(0);
1068 }
1069 if (m_AutoMode == MCTF_MODE::MCTF_AUTO_MODE)
1070 {
1071 sts = SetFilterStrenght(DEFAULT_FILTER_STRENGTH);
1072 m_RTParams.FilterStrength = DEFAULT_FILTER_STRENGTH;
1073 }
1074 else
1075 {
1076 if (isNCActive)
1077 {
1078 sts = SetFilterStrenght(INPIPE_FILTER_STRENGTH);
1079 m_RTParams.FilterStrength = INPIPE_FILTER_STRENGTH;
1080 }
1081 else
1082 {
1083 sts = SetFilterStrenght(localMctfParam.FilterStrength);
1084 m_RTParams.FilterStrength = localMctfParam.FilterStrength;
1085 }
1086 }
1087 // now initialize run-time parameters
1088 m_RTParams = localMctfParam;
1089 m_InitRTParams = m_RTParams;
1090
1091 return sts;
1092 }
MCTF_CheckRTParams(const IntMctfParams * pMctfControl)1093 mfxStatus CMC::MCTF_CheckRTParams(
1094 const IntMctfParams * pMctfControl
1095 )
1096 {
1097 mfxStatus sts = MFX_ERR_NONE;
1098 if (pMctfControl)
1099 {
1100 #ifdef MFX_ENABLE_MCTF_EXT
1101 // check BPP for max value. the threshold must be adjusted for higher bit-depths
1102 if (pMctfControl->BitsPerPixelx100k > (DEFAULT_BPP))
1103 sts = MFX_ERR_INVALID_VIDEO_PARAM;
1104 #endif
1105 if (pMctfControl->FilterStrength > 21)
1106 sts = MFX_ERR_INVALID_VIDEO_PARAM;
1107 }
1108 return sts;
1109 }
MCTF_UpdateRTParams(IntMctfParams * pMctfControl)1110 mfxStatus CMC::MCTF_UpdateRTParams(
1111 IntMctfParams * pMctfControl
1112 )
1113 {
1114 mfxStatus sts = MCTF_CheckRTParams(pMctfControl);
1115
1116 if (pMctfControl && MFX_ERR_NONE == sts)
1117 m_RTParams = *pMctfControl;
1118 else
1119 m_RTParams = m_InitRTParams;
1120 return MFX_ERR_NONE;
1121 }
MCTF_UpdateANDApplyRTParams(mfxU8 srcNum)1122 mfxStatus CMC::MCTF_UpdateANDApplyRTParams(
1123 mfxU8 srcNum
1124 )
1125 {
1126 // deblock can be controled for every mode
1127 if (MCTF_CONFIGURATION::MCTF_MAN_NCA_NBA == ConfigMode ||
1128 MCTF_CONFIGURATION::MCTF_AUT_CA_BA == ConfigMode ||
1129 MCTF_CONFIGURATION::MCTF_AUT_CA_NBA == ConfigMode)
1130 {
1131
1132 #ifdef MCTF_UPDATE_RT_FRAME_ORDER_BASED
1133 m_RTParams = QfIn[srcNum].mfxMctfControl;
1134 #else
1135 (void)srcNum;
1136 #endif
1137 if (MCTF_CONFIGURATION::MCTF_MAN_NCA_NBA == ConfigMode)
1138 {
1139 SetFilterStrenght(m_RTParams.FilterStrength);
1140 }
1141 #ifdef MFX_ENABLE_MCTF_EXT
1142 deblocking_Control = m_RTParams.Deblocking;
1143 //deblocking only if ME is used
1144 if (MFX_CODINGOPTION_ON == deblocking_Control &&
1145 (ONE_REFERENCE == number_of_References ||
1146 TWO_REFERENCES == number_of_References ||
1147 FOUR_REFERENCES == number_of_References)
1148 )
1149 pMCTF_SpDen_func = &CMC::MCTF_RUN_Denoise;
1150 else
1151 pMCTF_SpDen_func = NULL;
1152
1153 if (MCTF_CONFIGURATION::MCTF_AUT_CA_BA == ConfigMode)
1154 MFX_SAFE_CALL (MCTF_UpdateBitrateInfo(m_RTParams.BitsPerPixelx100k));
1155 #endif
1156 }
1157 return MFX_ERR_NONE;
1158 }
1159
1160 // todo: what if bitrate is close to 0?
MCTF_UpdateBitrateInfo(mfxU32 BitsPerPexelx100k)1161 mfxStatus CMC::MCTF_UpdateBitrateInfo(
1162 mfxU32 BitsPerPexelx100k
1163 )
1164 {
1165 if (MCTF_CONFIGURATION::MCTF_NOT_CONFIGURED == ConfigMode ||
1166 MCTF_CONFIGURATION::MCTF_AUT_CA_BA == ConfigMode )
1167 {
1168 // todo: intially here was a code that uses 12bpp in case
1169 // of no bitrate or FPS numerator are passed;
1170 // what should be now?
1171 bpp = BitsPerPexelx100k * 1.0 / MCTF_BITRATE_MULTIPLIER;
1172 return MFX_ERR_NONE;
1173 }
1174 else
1175 {
1176 // if any other mode, update the bitrate does not have any effect;
1177 // let notify a caller about this;
1178 // however, its not critical as MCTF can operate further
1179 return MFX_WRN_VALUE_NOT_CHANGED;
1180 }
1181 }
1182
GEN_NoiseSURF_SET(CmSurface2DUP ** p_Surface,void ** p_Sys,SurfaceIndex ** p_idxSurf)1183 mfxStatus CMC::GEN_NoiseSURF_SET(
1184 CmSurface2DUP ** p_Surface,
1185 void ** p_Sys,
1186 SurfaceIndex ** p_idxSurf
1187 )
1188 {
1189 surfNoisePitch = 0;
1190 surfNoiseSize = 0;
1191 res = device->GetSurface2DInfo(DIVUP(p_ctrl->CropW, 16) * sizeof(spatialNoiseAnalysis), DIVUP(p_ctrl->CropH, 16), CM_SURFACE_FORMAT_A8, surfNoisePitch, surfNoiseSize);
1192 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1193
1194 *p_Sys = CM_ALIGNED_MALLOC(surfNoiseSize, 0x1000);
1195 MFX_CHECK(*p_Sys, MFX_ERR_NULL_PTR);
1196 memset(*p_Sys, 0, surfNoiseSize);
1197 res = device->CreateSurface2DUP(DIVUP(p_ctrl->CropW, 16) * sizeof(spatialNoiseAnalysis), DIVUP(p_ctrl->CropH, 16), CM_SURFACE_FORMAT_A8, *p_Sys, *p_Surface);
1198 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1199 res = (*p_Surface)->GetIndex(*p_idxSurf);
1200 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1201 return MFX_ERR_NONE;
1202 }
GEN_SURF_SET(CmSurface2DUP ** p_Surface,void ** p_Sys,SurfaceIndex ** p_idxSurf)1203 mfxStatus CMC::GEN_SURF_SET(
1204 CmSurface2DUP ** p_Surface,
1205 void ** p_Sys,
1206 SurfaceIndex **p_idxSurf
1207 )
1208 {
1209 surfPitch = 0;
1210 surfSize = 0;
1211 res = device->GetSurface2DInfo(ov_width_bl * sizeof(mfxI16Pair), ov_height_bl, CM_SURFACE_FORMAT_A8, surfPitch, surfSize);
1212 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1213 *p_Sys = CM_ALIGNED_MALLOC(surfSize, 0x1000);
1214 MFX_CHECK(*p_Sys, MFX_ERR_NULL_PTR);
1215 memset(*p_Sys, 0, surfSize);
1216 res = device->CreateSurface2DUP(ov_width_bl * sizeof(mfxI16Pair), ov_height_bl, CM_SURFACE_FORMAT_A8, *p_Sys, *p_Surface);
1217 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1218 res = (*p_Surface)->GetIndex(*p_idxSurf);
1219 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
1220 return MFX_ERR_NONE;
1221 }
1222
MCTF_GetEmptySurface(mfxFrameSurface1 ** ppSurface)1223 mfxStatus CMC::MCTF_GetEmptySurface(
1224 mfxFrameSurface1 ** ppSurface
1225 )
1226 {
1227 size_t buffer_size = QfIn.size() - 1;
1228 if (bufferCount > buffer_size)
1229 return MFX_ERR_UNDEFINED_BEHAVIOR;
1230 if (QfIn[bufferCount].mfxFrame->Data.Locked)
1231 {
1232 *ppSurface = nullptr;
1233 return MFX_ERR_NONE;
1234 }
1235 else
1236 {
1237 m_pCore->IncreaseReference(&(QfIn[bufferCount].mfxFrame->Data));
1238 *ppSurface = QfIn[bufferCount].mfxFrame;
1239 return MFX_ERR_NONE;
1240 }
1241 }
1242
MCTF_PUT_FRAME(mfxU32 sceneNumber,CmSurface2D * OutSurf)1243 mfxStatus CMC::MCTF_PUT_FRAME(
1244 mfxU32 sceneNumber,
1245 CmSurface2D* OutSurf
1246 )
1247 {
1248 size_t buffer_size = QfIn.size() - 1;
1249 if (bufferCount > buffer_size)
1250 {
1251 #ifdef MFX_MCTF_DEBUG_PRINT
1252 ASC_PRINTF("Error: Invalid frame buffer position\n");
1253 #endif
1254 return MFX_ERR_UNDEFINED_BEHAVIOR;
1255 }
1256
1257 #ifdef MCTF_UPDATE_RT_FRAME_ORDER_BASED
1258 QfIn[bufferCount].mfxMctfControl = m_RTParams;
1259 #endif
1260 QfIn[bufferCount].scene_idx = sceneNumber;
1261 QfIn[bufferCount].frame_number = countFrames;
1262
1263 // if outFrame is nullptr, it means we cannot output result;
1264 if (OutSurf)
1265 {
1266 mco = OutSurf;
1267 INT cmSts = OutSurf->GetIndex(idxMco);
1268 MFX_CHECK((CM_SUCCESS == cmSts), MFX_ERR_DEVICE_FAILED);
1269 }
1270 return MFX_ERR_NONE;
1271 }
1272
MCTF_UpdateBufferCount()1273 mfxStatus CMC::MCTF_UpdateBufferCount()
1274 {
1275 size_t buffer_size = QfIn.size() - 1;
1276 if (bufferCount > buffer_size)
1277 return MFX_ERR_UNDEFINED_BEHAVIOR;
1278 bufferCount = (bufferCount < buffer_size) ? bufferCount + 1 : buffer_size;
1279 return MFX_ERR_NONE;
1280 }
1281
MCTF_LOAD_1REF()1282 mfxI32 CMC::MCTF_LOAD_1REF()
1283 {
1284 res = device->CreateVmeSurfaceG7_5(QfIn[1].frameData, &QfIn[0].frameData, NULL, 1, 0, genxRefs1);
1285 MCTF_CHECK_CM_ERR(res, res);
1286 return res;
1287 }
1288
MCTF_LOAD_2REF()1289 mfxI32 CMC::MCTF_LOAD_2REF()
1290 {
1291 res = device->CreateVmeSurfaceG7_5(QfIn[1].frameData, &QfIn[0].frameData, &QfIn[2].frameData, 1, 1, genxRefs1);
1292 MCTF_CHECK_CM_ERR(res, res);
1293 res = device->CreateVmeSurfaceG7_5(QfIn[1].frameData, &QfIn[2].frameData, NULL, 1, 0, genxRefs2);
1294 MCTF_CHECK_CM_ERR(res, res);
1295 return res;
1296 }
1297
MCTF_LOAD_4REF()1298 mfxI32 CMC::MCTF_LOAD_4REF()
1299 {
1300 res = device->CreateVmeSurfaceG7_5(QfIn[2].frameData, &QfIn[1].frameData, &QfIn[3].frameData, 1, 1, genxRefs1);
1301 MCTF_CHECK_CM_ERR(res, res);
1302 res = device->CreateVmeSurfaceG7_5(QfIn[2].frameData, &QfIn[3].frameData, NULL, 1, 0, genxRefs2);
1303 MCTF_CHECK_CM_ERR(res, res);
1304 res = device->CreateVmeSurfaceG7_5(QfIn[2].frameData, &QfIn[0].frameData, &QfIn[4].frameData, 1, 1, genxRefs3);
1305 MCTF_CHECK_CM_ERR(res, res);
1306 res = device->CreateVmeSurfaceG7_5(QfIn[2].frameData, &QfIn[4].frameData, NULL, 1, 0, genxRefs4);
1307 MCTF_CHECK_CM_ERR(res, res);
1308 return res;
1309 }
1310
MCTF_SET_KERNELMe(SurfaceIndex * GenxRefs,SurfaceIndex * idxMV,mfxU16 start_x,mfxU16 start_y,mfxU8 blSize)1311 mfxI32 CMC::MCTF_SET_KERNELMe(
1312 SurfaceIndex * GenxRefs,
1313 SurfaceIndex * idxMV,
1314 mfxU16 start_x,
1315 mfxU16 start_y,
1316 mfxU8 blSize)
1317 {
1318 argIdx = 0;
1319 res = kernelMe->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1320 MCTF_CHECK_CM_ERR(res, res);
1321 res = kernelMe->SetKernelArg(argIdx++, sizeof(*GenxRefs), GenxRefs);
1322 MCTF_CHECK_CM_ERR(res, res);
1323 res = kernelMe->SetKernelArg(argIdx++, sizeof(*idxDist), idxDist);
1324 MCTF_CHECK_CM_ERR(res, res);
1325 res = kernelMe->SetKernelArg(argIdx++, sizeof(*idxMV), idxMV);
1326 MCTF_CHECK_CM_ERR(res, res);
1327 // set start mb
1328 mfxU16Pair start_xy = { start_x, start_y };
1329 res = kernelMe->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1330 MCTF_CHECK_CM_ERR(res, res);
1331 res = kernelMe->SetKernelArg(argIdx++, sizeof(blSize), &blSize);
1332 MCTF_CHECK_CM_ERR(res, res);
1333 return res;
1334 }
1335
MCTF_SET_KERNELMeBi(SurfaceIndex * GenxRefs,SurfaceIndex * GenxRefs2,SurfaceIndex * idxMV,SurfaceIndex * idxMV2,mfxU16 start_x,mfxU16 start_y,mfxU8 blSize,mfxI8 forwardRefDist,mfxI8 backwardRefDist)1336 mfxI32 CMC::MCTF_SET_KERNELMeBi(
1337 SurfaceIndex * GenxRefs,
1338 SurfaceIndex * GenxRefs2,
1339 SurfaceIndex * idxMV,
1340 SurfaceIndex * idxMV2,
1341 mfxU16 start_x,
1342 mfxU16 start_y,
1343 mfxU8 blSize,
1344 mfxI8 forwardRefDist,
1345 mfxI8 backwardRefDist
1346 )
1347 {
1348 argIdx = 0;
1349 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1350 MCTF_CHECK_CM_ERR(res, res);
1351 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*GenxRefs), GenxRefs);
1352 MCTF_CHECK_CM_ERR(res, res);
1353 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*GenxRefs2), GenxRefs2);
1354 MCTF_CHECK_CM_ERR(res, res);
1355 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*idxDist), idxDist);
1356 MCTF_CHECK_CM_ERR(res, res);
1357 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*idxMV), idxMV);
1358 MCTF_CHECK_CM_ERR(res, res);
1359 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*idxMV2), idxMV2);
1360 MCTF_CHECK_CM_ERR(res, res);
1361 // set start mb
1362 mfxU16Pair start_xy = { start_x, start_y };
1363 res = kernelMeB->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1364 MCTF_CHECK_CM_ERR(res, res);
1365 res = kernelMeB->SetKernelArg(argIdx++, sizeof(blSize), &blSize);
1366 MCTF_CHECK_CM_ERR(res, res);
1367 res = kernelMeB->SetKernelArg(argIdx++, sizeof(forwardRefDist), &forwardRefDist);
1368 MCTF_CHECK_CM_ERR(res, res);
1369 res = kernelMeB->SetKernelArg(argIdx++, sizeof(backwardRefDist), &backwardRefDist);
1370 MCTF_CHECK_CM_ERR(res, res);
1371 return res;
1372 }
1373
MCTF_SET_KERNELMeBiMRE(SurfaceIndex * GenxRefs,SurfaceIndex * GenxRefs2,SurfaceIndex * idxMV,SurfaceIndex * idxMV2,mfxU16 start_x,mfxU16 start_y,mfxU8 blSize,mfxI8 forwardRefDist,mfxI8 backwardRefDist)1374 mfxU32 CMC::MCTF_SET_KERNELMeBiMRE(
1375 SurfaceIndex* GenxRefs, SurfaceIndex* GenxRefs2,
1376 SurfaceIndex* idxMV, SurfaceIndex* idxMV2,
1377 mfxU16 start_x, mfxU16 start_y, mfxU8 blSize,
1378 mfxI8 forwardRefDist, mfxI8 backwardRefDist) {
1379 argIdx = 0;
1380 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1381 MCTF_CHECK_CM_ERR(res, res);
1382 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*GenxRefs), GenxRefs);
1383 MCTF_CHECK_CM_ERR(res, res);
1384 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*GenxRefs2), GenxRefs2);
1385 MCTF_CHECK_CM_ERR(res, res);
1386 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*idxDist), idxDist);
1387 MCTF_CHECK_CM_ERR(res, res);
1388 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*idxMV), idxMV);
1389 MCTF_CHECK_CM_ERR(res, res);
1390 res = kernelMeB->SetKernelArg(argIdx++, sizeof(*idxMV2), idxMV2);
1391 MCTF_CHECK_CM_ERR(res, res);
1392 // set start mb
1393 mfxU16Pair start_xy = { start_x, start_y };
1394 res = kernelMeB->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1395 MCTF_CHECK_CM_ERR(res, res);
1396 res = kernelMeB->SetKernelArg(argIdx++, sizeof(blSize), &blSize);
1397 MCTF_CHECK_CM_ERR(res, res);
1398 res = kernelMeB->SetKernelArg(argIdx++, sizeof(forwardRefDist), &forwardRefDist);
1399 MCTF_CHECK_CM_ERR(res, res);
1400 res = kernelMeB->SetKernelArg(argIdx++, sizeof(backwardRefDist), &backwardRefDist);
1401 MCTF_CHECK_CM_ERR(res, res);
1402 return res;
1403 }
1404
MCTF_SET_KERNELMeBiMRE2(SurfaceIndex * GenxRefs,SurfaceIndex * GenxRefs2,SurfaceIndex * idxMV,SurfaceIndex * idxMV2,mfxU16 start_x,mfxU16 start_y,mfxU8 blSize,mfxI8 forwardRefDist,mfxI8 backwardRefDist)1405 mfxU32 CMC::MCTF_SET_KERNELMeBiMRE2(
1406 SurfaceIndex* GenxRefs, SurfaceIndex* GenxRefs2,
1407 SurfaceIndex* idxMV, SurfaceIndex* idxMV2,
1408 mfxU16 start_x, mfxU16 start_y, mfxU8 blSize,
1409 mfxI8 forwardRefDist, mfxI8 backwardRefDist) {
1410 argIdx = 0;
1411 res = kernelMeB2->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1412 MCTF_CHECK_CM_ERR(res, res);
1413 res = kernelMeB2->SetKernelArg(argIdx++, sizeof(*GenxRefs), GenxRefs);
1414 MCTF_CHECK_CM_ERR(res, res);
1415 res = kernelMeB2->SetKernelArg(argIdx++, sizeof(*GenxRefs2), GenxRefs2);
1416 MCTF_CHECK_CM_ERR(res, res);
1417 res = kernelMeB2->SetKernelArg(argIdx++, sizeof(*idxDist), idxDist);
1418 MCTF_CHECK_CM_ERR(res, res);
1419 res = kernelMeB2->SetKernelArg(argIdx++, sizeof(*idxMV), idxMV);
1420 MCTF_CHECK_CM_ERR(res, res);
1421 res = kernelMeB2->SetKernelArg(argIdx++, sizeof(*idxMV2), idxMV2);
1422 MCTF_CHECK_CM_ERR(res, res);
1423 // set start mb
1424 mfxU16Pair start_xy = { start_x, start_y };
1425 res = kernelMeB2->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1426 MCTF_CHECK_CM_ERR(res, res);
1427 res = kernelMeB2->SetKernelArg(argIdx++, sizeof(blSize), &blSize);
1428 MCTF_CHECK_CM_ERR(res, res);
1429 res = kernelMeB2->SetKernelArg(argIdx++, sizeof(forwardRefDist), &forwardRefDist);
1430 MCTF_CHECK_CM_ERR(res, res);
1431 res = kernelMeB2->SetKernelArg(argIdx++, sizeof(backwardRefDist), &backwardRefDist);
1432 MCTF_CHECK_CM_ERR(res, res);
1433 return res;
1434 }
1435
MCTF_SET_KERNELMc(mfxU16 start_x,mfxU16 start_y,mfxU8 srcNum,mfxU8 refNum)1436 mfxI32 CMC::MCTF_SET_KERNELMc(
1437 mfxU16 start_x,
1438 mfxU16 start_y,
1439 mfxU8 srcNum,
1440 mfxU8 refNum
1441 )
1442 {
1443 argIdx = 0;
1444 res = kernelMc1r->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1445 MCTF_CHECK_CM_ERR(res, res);
1446 res = kernelMc1r->SetKernelArg(argIdx++, sizeof(*QfIn[refNum].fIdx), QfIn[refNum].fIdx);
1447 MCTF_CHECK_CM_ERR(res, res);
1448 res = kernelMc1r->SetKernelArg(argIdx++, sizeof(*idxMv_1), idxMv_1);
1449 MCTF_CHECK_CM_ERR(res, res);
1450 res = kernelMc1r->SetKernelArg(argIdx++, sizeof(*QfIn[srcNum].fIdx), QfIn[srcNum].fIdx);
1451 MCTF_CHECK_CM_ERR(res, res);
1452 res = kernelMc1r->SetKernelArg(argIdx++, sizeof(*idxMco), idxMco);
1453 MCTF_CHECK_CM_ERR(res, res);
1454 // set start mb
1455 mfxU16Pair start_xy = { start_x, start_y };
1456 res = kernelMc1r->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1457 MCTF_CHECK_CM_ERR(res, res);
1458 //scene numbers
1459 mfxU8quad scene_num_gpu = { (mfxU8)scene_numbers[0], (mfxU8)scene_numbers[1], (mfxU8)scene_numbers[2], 2 };
1460 res = kernelMc1r->SetKernelArg(argIdx++, sizeof(scene_num_gpu), &scene_num_gpu);
1461 MCTF_CHECK_CM_ERR(res, res);
1462 return res;
1463
1464 }
1465
MCTF_SET_KERNELMc2r(mfxU16 start_x,mfxU16 start_y)1466 mfxI32 CMC::MCTF_SET_KERNELMc2r(
1467 mfxU16 start_x,
1468 mfxU16 start_y
1469 )
1470 {
1471 argIdx = 0;
1472 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1473 MCTF_CHECK_CM_ERR(res, res);
1474 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*QfIn[0].fIdx), QfIn[0].fIdx);
1475 MCTF_CHECK_CM_ERR(res, res);
1476 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*idxMv_1), idxMv_1);
1477 MCTF_CHECK_CM_ERR(res, res);
1478 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*QfIn[2].fIdx), QfIn[2].fIdx);
1479 MCTF_CHECK_CM_ERR(res, res);
1480 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*idxMv_2), idxMv_2);
1481 MCTF_CHECK_CM_ERR(res, res);
1482 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*QfIn[1].fIdx), QfIn[1].fIdx);
1483 MCTF_CHECK_CM_ERR(res, res);
1484 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*idxMco), idxMco);
1485 MCTF_CHECK_CM_ERR(res, res);
1486 // set start mb
1487 mfxU16Pair start_xy = { start_x, start_y };
1488 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1489 MCTF_CHECK_CM_ERR(res, res);
1490 //scene numbers
1491 mfxU8quad scene_num_gpu = { (mfxU8)scene_numbers[0], (mfxU8)scene_numbers[1], (mfxU8)scene_numbers[2], 2 };
1492 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(scene_num_gpu), &scene_num_gpu);
1493 MCTF_CHECK_CM_ERR(res, res);
1494 return res;
1495 }
1496
MCTF_SET_KERNELMc2rDen(mfxU16 start_x,mfxU16 start_y)1497 mfxI32 CMC::MCTF_SET_KERNELMc2rDen(
1498 mfxU16 start_x,
1499 mfxU16 start_y
1500 )
1501 {
1502 argIdx = 0;
1503 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1504 MCTF_CHECK_CM_ERR(res, res);
1505 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*QfIn[0].fIdx), QfIn[0].fIdx);
1506 MCTF_CHECK_CM_ERR(res, res);
1507 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*idxMv_1), idxMv_1);
1508 MCTF_CHECK_CM_ERR(res, res);
1509 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*QfIn[2].fIdx), QfIn[2].fIdx);
1510 MCTF_CHECK_CM_ERR(res, res);
1511 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*idxMv_2), idxMv_2);
1512 MCTF_CHECK_CM_ERR(res, res);
1513 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*QfIn[1].fIdx), QfIn[1].fIdx);
1514 MCTF_CHECK_CM_ERR(res, res);
1515 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*idxMco2), idxMco2);
1516 MCTF_CHECK_CM_ERR(res, res);
1517 // set start mb
1518 mfxU16Pair start_xy = { start_x, start_y };
1519 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1520 MCTF_CHECK_CM_ERR(res, res);
1521 //scene numbers
1522 mfxU8quad scene_num_gpu = { (mfxU8)scene_numbers[0], (mfxU8)scene_numbers[1], (mfxU8)scene_numbers[2], 2 };
1523 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(scene_num_gpu), &scene_num_gpu);
1524 MCTF_CHECK_CM_ERR(res, res);
1525 return res;
1526 }
1527
MCTF_SET_KERNELMc4r(mfxU16 start_x,mfxU16 start_y)1528 mfxI32 CMC::MCTF_SET_KERNELMc4r(
1529 mfxU16 start_x,
1530 mfxU16 start_y
1531 )
1532 {
1533 argIdx = 0;
1534 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1535 MCTF_CHECK_CM_ERR(res, res);
1536 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxRef1), idxRef1);
1537 MCTF_CHECK_CM_ERR(res, res);
1538 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxMv_1), idxMv_1);
1539 MCTF_CHECK_CM_ERR(res, res);
1540 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxRef2), idxRef2);
1541 MCTF_CHECK_CM_ERR(res, res);
1542 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxMv_2), idxMv_2);
1543 MCTF_CHECK_CM_ERR(res, res);
1544 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxRef3), idxRef3);
1545 MCTF_CHECK_CM_ERR(res, res);
1546 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxMv_3), idxMv_3);
1547 MCTF_CHECK_CM_ERR(res, res);
1548 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxRef4), idxRef4);
1549 MCTF_CHECK_CM_ERR(res, res);
1550 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxMv_4), idxMv_4);
1551 MCTF_CHECK_CM_ERR(res, res);
1552 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxSrc), idxSrc);
1553 MCTF_CHECK_CM_ERR(res, res);
1554 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxMco), idxMco);
1555 MCTF_CHECK_CM_ERR(res, res);
1556 // set start mb
1557 mfxU16Pair start_xy = { start_x, start_y };
1558 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1559 MCTF_CHECK_CM_ERR(res, res);
1560 return res;
1561 }
1562
MCTF_SET_KERNELMc4r(mfxU16 start_x,mfxU16 start_y,SurfaceIndex * multiIndex)1563 mfxI32 CMC::MCTF_SET_KERNELMc4r(
1564 mfxU16 start_x,
1565 mfxU16 start_y,
1566 SurfaceIndex * multiIndex
1567 )
1568 {
1569 argIdx = 0;
1570 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1571 MCTF_CHECK_CM_ERR(res, res);
1572 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*multiIndex), multiIndex);
1573 MCTF_CHECK_CM_ERR(res, res);
1574 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxSrc), idxSrc);
1575 MCTF_CHECK_CM_ERR(res, res);
1576 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxMco), idxMco);
1577 MCTF_CHECK_CM_ERR(res, res);
1578 // set start mb
1579 mfxU16Pair start_xy = { start_x, start_y };
1580 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1581 MCTF_CHECK_CM_ERR(res, res);
1582 return res;
1583 }
1584
MCTF_SET_KERNELMcMerge(mfxU16 start_x,mfxU16 start_y)1585 mfxI32 CMC::MCTF_SET_KERNELMcMerge(
1586 mfxU16 start_x,
1587 mfxU16 start_y
1588 )
1589 {
1590 argIdx = 0;
1591 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxMco), idxMco);
1592 MCTF_CHECK_CM_ERR(res, res);
1593 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(*idxMco2), idxMco2);
1594 MCTF_CHECK_CM_ERR(res, res);
1595 // set start mb
1596 mfxU16Pair start_xy = { start_x, start_y };
1597 res = kernelMc4r->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1598 MCTF_CHECK_CM_ERR(res, res);
1599 return res;
1600 }
1601
MCTF_SET_KERNELMc4r(mfxU16 start_x,mfxU16 start_y,mfxU8 runType)1602 mfxI32 CMC::MCTF_SET_KERNELMc4r(
1603 mfxU16 start_x,
1604 mfxU16 start_y,
1605 mfxU8 runType
1606 )
1607 {
1608 argIdx = 0;
1609 mfxU8
1610 currentFrame = 2,
1611 pastRef = 1,
1612 futureRef = 3;
1613 SurfaceIndex
1614 **mcOut = &idxMco,
1615 **pastMv = &idxMv_1,
1616 **futureMv = &idxMv_2;
1617
1618 if (runType == DEN_FAR_RUN)
1619 {
1620 pastRef = 0;
1621 futureRef = 4;
1622 mcOut = &idxMco2;
1623 pastMv = &idxMv_3;
1624 futureMv = &idxMv_4;
1625 }
1626
1627 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1628 MCTF_CHECK_CM_ERR(res, res);
1629 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*QfIn[pastRef].fIdx), QfIn[pastRef].fIdx);
1630 MCTF_CHECK_CM_ERR(res, res);
1631 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(**pastMv), *pastMv);
1632 MCTF_CHECK_CM_ERR(res, res);
1633 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*QfIn[futureRef].fIdx), QfIn[futureRef].fIdx);
1634 MCTF_CHECK_CM_ERR(res, res);
1635 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(**futureMv), *futureMv);
1636 MCTF_CHECK_CM_ERR(res, res);
1637 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(*QfIn[currentFrame].fIdx), QfIn[currentFrame].fIdx);
1638 MCTF_CHECK_CM_ERR(res, res);
1639 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(**mcOut), *mcOut);
1640 MCTF_CHECK_CM_ERR(res, res);
1641 // set start mb
1642 mfxU16Pair start_xy = { start_x, start_y };
1643 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1644 MCTF_CHECK_CM_ERR(res, res);
1645 //scene numbers
1646 mfxU8quad scene_num_gpu = { (mfxU8)scene_numbers[pastRef], (mfxU8)scene_numbers[currentFrame], (mfxU8)scene_numbers[futureRef], 2 };
1647 res = kernelMc2r->SetKernelArg(argIdx++, sizeof(scene_num_gpu), &scene_num_gpu);
1648 MCTF_CHECK_CM_ERR(res, res);
1649 return res;
1650 }
1651
MCTF_SET_KERNEL_Noise(mfxU16 srcNum,mfxU16 start_x,mfxU16 start_y)1652 mfxI32 CMC::MCTF_SET_KERNEL_Noise(
1653 mfxU16 srcNum,
1654 mfxU16 start_x,
1655 mfxU16 start_y
1656 )
1657 {
1658 argIdx = 0;
1659 res = kernelNoise->SetKernelArg(argIdx++, sizeof(*QfIn[srcNum].fIdx), QfIn[srcNum].fIdx);
1660 MCTF_CHECK_CM_ERR(res, res);
1661 res = kernelNoise->SetKernelArg(argIdx++, sizeof(*idxNoiseAnalysis), idxNoiseAnalysis);
1662 MCTF_CHECK_CM_ERR(res, res);
1663 // set start mb
1664 mfxU16Pair start_xy = { start_x, start_y };
1665 res = kernelNoise->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1666 MCTF_CHECK_CM_ERR(res, res);
1667 return res;
1668 }
1669
MCTF_SET_KERNELDe(mfxU16 srcNum,mfxU16 start_x,mfxU16 start_y)1670 mfxI32 CMC::MCTF_SET_KERNELDe(
1671 mfxU16 srcNum,
1672 mfxU16 start_x,
1673 mfxU16 start_y
1674 )
1675 {
1676 argIdx = 0;
1677 res = kernelMcDen->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1678 MCTF_CHECK_CM_ERR(res, res);
1679 res = kernelMcDen->SetKernelArg(argIdx++, sizeof(*QfIn[srcNum].fIdx), QfIn[srcNum].fIdx);
1680 MCTF_CHECK_CM_ERR(res, res);
1681 res = kernelMcDen->SetKernelArg(argIdx++, sizeof(*idxMco), idxMco);
1682 MCTF_CHECK_CM_ERR(res, res);
1683 // set start mb
1684 mfxU16Pair start_xy = { start_x, start_y };
1685 res = kernelMcDen->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1686 MCTF_CHECK_CM_ERR(res, res);
1687 return res;
1688 }
1689
MCTF_SET_KERNELDe(mfxU16 start_x,mfxU16 start_y)1690 mfxI32 CMC::MCTF_SET_KERNELDe(
1691 mfxU16 start_x,
1692 mfxU16 start_y
1693 )
1694 {
1695 argIdx = 0;
1696 res = kernelMcDen->SetKernelArg(argIdx++, sizeof(*idxCtrl), idxCtrl);
1697 MCTF_CHECK_CM_ERR(res, res);
1698 res = kernelMcDen->SetKernelArg(argIdx++, sizeof(*idxMco), idxMco);
1699 MCTF_CHECK_CM_ERR(res, res);
1700 res = kernelMcDen->SetKernelArg(argIdx++, sizeof(*idxMco), idxMco);
1701 MCTF_CHECK_CM_ERR(res, res);
1702 // set start mb
1703 mfxU16Pair start_xy = { start_x, start_y };
1704 res = kernelMcDen->SetKernelArg(argIdx++, sizeof(start_xy), &start_xy);
1705 MCTF_CHECK_CM_ERR(res, res);
1706 return res;
1707 }
1708
MCTF_Enqueue(CmTask * taskInt,CmEvent * & eInt,const CmThreadSpace * tSInt)1709 mfxI32 CMC::MCTF_Enqueue(
1710 CmTask* taskInt,
1711 CmEvent* & eInt,
1712 const CmThreadSpace* tSInt
1713 )
1714 {
1715 mfxI32
1716 ret = CM_FAILURE;
1717 switch (mctf_HWType){
1718 case MFX_HW_ICL:
1719 ret = queue->EnqueueFast(taskInt, eInt, tSInt);
1720 break;
1721 default:
1722 ret = queue->Enqueue(taskInt, eInt, tSInt);
1723 }
1724 return ret;
1725 }
1726
MCTF_RUN_TASK_NA(CmKernel * kernel,bool reset,mfxU16 widthTs,mfxU16 heightTs)1727 mfxI32 CMC::MCTF_RUN_TASK_NA(
1728 CmKernel * kernel,
1729 bool reset,
1730 mfxU16 widthTs,
1731 mfxU16 heightTs
1732 )
1733 {
1734 res = kernel->SetThreadCount(widthTs * heightTs);
1735 MCTF_CHECK_CM_ERR(res, res);
1736 res = device->CreateThreadSpace(widthTs, heightTs, threadSpace);
1737 MCTF_CHECK_CM_ERR(res, res);
1738 res = kernel->AssociateThreadSpace(threadSpace);
1739 MCTF_CHECK_CM_ERR(res, res);
1740
1741 if (reset)
1742 {
1743 res = task->Reset();
1744 MCTF_CHECK_CM_ERR(res, res);
1745 }
1746 else
1747 {
1748 res = device->CreateTask(task);
1749 MCTF_CHECK_CM_ERR(res, res);
1750 }
1751 res = task->AddKernel(kernel);
1752 MCTF_CHECK_CM_ERR(res, res);
1753 res = MCTF_Enqueue(task, e);
1754 MCTF_CHECK_CM_ERR(res, res);
1755 return res;
1756 }
1757
MCTF_RUN_TASK(CmKernel * kernel,bool reset)1758 mfxI32 CMC::MCTF_RUN_TASK(
1759 CmKernel * kernel,
1760 bool reset
1761 )
1762 {
1763 res = kernel->SetThreadCount(tsWidth * tsHeight);
1764 MCTF_CHECK_CM_ERR(res, res);
1765 res = device->CreateThreadSpace(tsWidth, tsHeight, threadSpace);
1766 MCTF_CHECK_CM_ERR(res, res);
1767 res = kernel->AssociateThreadSpace(threadSpace);
1768 MCTF_CHECK_CM_ERR(res, res);
1769
1770 if (reset)
1771 {
1772 res = task->Reset();
1773 MCTF_CHECK_CM_ERR(res, res);
1774 }
1775 else
1776 {
1777 res = device->CreateTask(task);
1778 MCTF_CHECK_CM_ERR(res, res);
1779 }
1780 res = task->AddKernel(kernel);
1781 MCTF_CHECK_CM_ERR(res, res);
1782 res = MCTF_Enqueue(task, e);
1783 MCTF_CHECK_CM_ERR(res, res);
1784 return res;
1785 }
1786
MCTF_RUN_DOUBLE_TASK(CmKernel * meKernel,CmKernel * mcKernel,bool reset)1787 mfxI32 CMC::MCTF_RUN_DOUBLE_TASK(
1788 CmKernel * meKernel,
1789 CmKernel * mcKernel,
1790 bool reset
1791 )
1792 {
1793 res = meKernel->SetThreadCount(tsWidth * tsHeight);
1794 MCTF_CHECK_CM_ERR(res, res);
1795 res = device->CreateThreadSpace(tsWidth, tsHeight, threadSpace2);
1796 MCTF_CHECK_CM_ERR(res, res);
1797 res = meKernel->AssociateThreadSpace(threadSpace2);
1798 MCTF_CHECK_CM_ERR(res, res);
1799
1800 res = mcKernel->SetThreadCount(tsWidthMC * tsHeightMC);
1801 MCTF_CHECK_CM_ERR(res, res);
1802 res = device->CreateThreadSpace(tsWidthMC, tsHeightMC, threadSpaceMC);
1803 MCTF_CHECK_CM_ERR(res, res);
1804 res = mcKernel->AssociateThreadSpace(threadSpaceMC);
1805 MCTF_CHECK_CM_ERR(res, res);
1806
1807 if (reset)
1808 {
1809 res = task->Reset();
1810 MCTF_CHECK_CM_ERR(res, res);
1811 }
1812 else
1813 {
1814 res = device->CreateTask(task);
1815 MCTF_CHECK_CM_ERR(res, res);
1816 }
1817 res = task->AddKernel(meKernel);
1818 MCTF_CHECK_CM_ERR(res, res);
1819 res = task->AddSync();
1820 MCTF_CHECK_CM_ERR(res, res);
1821 res = task->AddKernel(mcKernel);
1822 MCTF_CHECK_CM_ERR(res, res);
1823 res = MCTF_Enqueue(task, e);
1824 MCTF_CHECK_CM_ERR(res, res);
1825 return res;
1826 }
1827
MCTF_RUN_MCTASK(CmKernel * kernel,bool reset)1828 mfxI32 CMC::MCTF_RUN_MCTASK(
1829 CmKernel * kernel,
1830 bool reset
1831 )
1832 {
1833 res = kernel->SetThreadCount(tsWidthMC * tsHeightMC);
1834 MCTF_CHECK_CM_ERR(res, res);
1835 res = device->CreateThreadSpace(tsWidthMC, tsHeightMC, threadSpaceMC2);
1836 MCTF_CHECK_CM_ERR(res, res);
1837
1838 if (reset)
1839 {
1840 res = task->Reset();
1841 MCTF_CHECK_CM_ERR(res, res);
1842 }
1843 else
1844 {
1845 res = device->CreateTask(task);
1846 MCTF_CHECK_CM_ERR(res, res);
1847 }
1848 res = task->AddKernel(kernel);
1849 MCTF_CHECK_CM_ERR(res, res);
1850 res = MCTF_Enqueue(task, e, threadSpaceMC2);
1851 MCTF_CHECK_CM_ERR(res, res);
1852 return res;
1853 }
1854
MCTF_RUN_TASK(CmKernel * kernel,bool reset,CmThreadSpace * tS)1855 mfxI32 CMC::MCTF_RUN_TASK(
1856 CmKernel * kernel,
1857 bool reset,
1858 CmThreadSpace * tS
1859 )
1860 {
1861 res = kernel->SetThreadCount(tsWidth * tsHeight);
1862 MCTF_CHECK_CM_ERR(res, res);
1863 res = device->CreateThreadSpace(tsWidth, tsHeight, tS);
1864 MCTF_CHECK_CM_ERR(res, res);
1865 if (reset)
1866 {
1867 res = task->Reset();
1868 MCTF_CHECK_CM_ERR(res, res);
1869 }
1870 else
1871 {
1872 res = device->CreateTask(task);
1873 MCTF_CHECK_CM_ERR(res, res);
1874 }
1875 res = task->AddKernel(kernel);
1876 MCTF_CHECK_CM_ERR(res, res);
1877 res = MCTF_Enqueue(task, e, tS);
1878 MCTF_CHECK_CM_ERR(res, res);
1879 res = device->DestroyThreadSpace(tS);
1880 return res;
1881 }
1882
SetOverlapOp()1883 mfxU8 CMC::SetOverlapOp()
1884 {
1885 mfxU8 blSize = 0;
1886 switch (overlap_Motion)
1887 {
1888 case MFX_CODINGOPTION_ON:
1889 {
1890 blSize = VMEBLSIZE / 2;
1891 tsHeight = (DIVUP(p_ctrl->CropH, VMEBLSIZE) * 2) - 1;//Motion Estimation of any block size is performed in 16x16 units
1892 tsWidthFull = (DIVUP(p_ctrl->CropW, VMEBLSIZE) * 2) - 1;
1893 }
1894 break;
1895 case MFX_CODINGOPTION_UNKNOWN:
1896 case MFX_CODINGOPTION_OFF:
1897 {
1898 blSize = VMEBLSIZE;
1899 tsHeight = DIVUP(p_ctrl->CropH, VMEBLSIZE);//Motion Estimation of any block size is performed in 16x16 units
1900 tsWidthFull = DIVUP(p_ctrl->CropW, VMEBLSIZE);
1901 }
1902 break;
1903 default:
1904 throw CMCRuntimeError();
1905 }
1906 tsWidth = tsWidthFull;
1907 return blSize;
1908 }
1909
SetOverlapOp_half()1910 mfxU8 CMC::SetOverlapOp_half()
1911 {
1912 mfxU8 blSize = 0;
1913 switch (overlap_Motion)
1914 {
1915 case MFX_CODINGOPTION_ON:
1916 {
1917 blSize = VMEBLSIZE / 2;
1918 tsHeight = DIVUP(p_ctrl->CropH, VMEBLSIZE) - 1;//Motion Estimation of any block size is performed in 16x16 units
1919 tsWidthFull = (DIVUP(p_ctrl->CropW, VMEBLSIZE) * 2) - 1;
1920 }
1921 break;
1922
1923 case MFX_CODINGOPTION_OFF:
1924 case MFX_CODINGOPTION_UNKNOWN:
1925 {
1926 blSize = VMEBLSIZE;
1927 tsHeight = DIVUP(p_ctrl->CropH, VMEBLSIZE) / 2;//Motion Estimation of any block size is performed in 16x16 units
1928 tsWidthFull = DIVUP(p_ctrl->CropW, VMEBLSIZE);
1929 }
1930 break;
1931 default:
1932 throw CMCRuntimeError();
1933 }
1934 tsWidth = tsWidthFull;
1935 return blSize;
1936 }
1937
MCTF_RUN_ME(SurfaceIndex * GenxRefs,SurfaceIndex * idxMV)1938 mfxI32 CMC::MCTF_RUN_ME(
1939 SurfaceIndex * GenxRefs,
1940 SurfaceIndex * idxMV
1941 )
1942 {
1943 time = 0;
1944
1945 mfxU8
1946 blSize = SetOverlapOp();
1947 res = MCTF_SET_KERNELMe(GenxRefs, idxMV, DIVUP(p_ctrl->CropX, blSize) , DIVUP(p_ctrl->CropY, blSize), blSize);
1948 MCTF_CHECK_CM_ERR(res, res);
1949 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
1950 tsWidth = (tsWidthFull >> 1) & ~1; // must be even for 32x32 blocks
1951
1952 threadSpace = 0;
1953 res = MCTF_RUN_TASK(kernelMe, task != 0);
1954 MCTF_CHECK_CM_ERR(res, res);
1955
1956 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
1957 {
1958 mfxU16 start_mbX = tsWidth;
1959 tsWidth = tsWidthFull - tsWidth;
1960 res = MCTF_SET_KERNELMe(GenxRefs, idxMV, start_mbX, DIVUP(p_ctrl->CropY, blSize), blSize);
1961 MCTF_CHECK_CM_ERR(res, res);
1962 // the rest of frame TS
1963 res = MCTF_RUN_TASK(kernelMe, task != 0);
1964 MCTF_CHECK_CM_ERR(res, res);
1965 }
1966 return res;
1967 }
1968
MCTF_RUN_ME(SurfaceIndex * GenxRefs,SurfaceIndex * GenxRefs2,SurfaceIndex * idxMV,SurfaceIndex * idxMV2,char forwardRefDist,char backwardRefDist)1969 mfxI32 CMC::MCTF_RUN_ME(
1970 SurfaceIndex * GenxRefs,
1971 SurfaceIndex * GenxRefs2,
1972 SurfaceIndex * idxMV,
1973 SurfaceIndex * idxMV2,
1974 char forwardRefDist,
1975 char backwardRefDist
1976 )
1977 {
1978 mfxU8
1979 blSize = SetOverlapOp();
1980 res = MCTF_SET_KERNELMeBi(GenxRefs, GenxRefs2, idxMV, idxMV2, 0, 0, blSize, forwardRefDist, backwardRefDist);
1981 MCTF_CHECK_CM_ERR(res, res);
1982 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
1983 tsWidth = (tsWidthFull >> 1) & ~1; // must be even for 32x32 blocks
1984
1985 threadSpace = 0;
1986 res = MCTF_RUN_TASK(kernelMeB, task != 0);
1987 MCTF_CHECK_CM_ERR(res, res);
1988
1989 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
1990 {
1991 mfxU16
1992 start_mbX = tsWidth;
1993 tsWidth = tsWidthFull - tsWidth;
1994 res = MCTF_SET_KERNELMeBi(GenxRefs, GenxRefs2, idxMV, idxMV2, start_mbX, 0, blSize, forwardRefDist, backwardRefDist);
1995
1996 MCTF_CHECK_CM_ERR(res, res);
1997 // the rest of frame TS
1998 res = MCTF_RUN_TASK(kernelMeB, task != 0);
1999 MCTF_CHECK_CM_ERR(res, res);
2000 }
2001 return res;
2002 }
2003
MCTF_RUN_ME_MC_HE(SurfaceIndex * GenxRefs,SurfaceIndex * GenxRefs2,SurfaceIndex * idxMV,SurfaceIndex * idxMV2,mfxI8 forwardRefDist,mfxI8 backwardRefDist,mfxU8 mcSufIndex)2004 mfxI32 CMC::MCTF_RUN_ME_MC_HE(
2005 SurfaceIndex* GenxRefs,
2006 SurfaceIndex* GenxRefs2,
2007 SurfaceIndex* idxMV,
2008 SurfaceIndex* idxMV2,
2009 mfxI8 forwardRefDist,
2010 mfxI8 backwardRefDist,
2011 mfxU8 mcSufIndex
2012 )
2013 {
2014 p_ctrl->sTh = MCTF_CHROMAOFF;
2015 p_ctrl->th = QfIn[1].filterStrength * 50;
2016 res = ctrlBuf->WriteSurface((const mfxU8 *)p_ctrl.get(), NULL, sizeof(MeControlSmall));
2017 MCTF_CHECK_CM_ERR(res, res);
2018 time = 0;
2019
2020 mfxU8
2021 blSize = SetOverlapOp_half();
2022 mfxU16
2023 multiplier = 2;
2024 UINT64
2025 executionTime = 0;
2026 tsHeightMC = (DIVUP(p_ctrl->height, blsize) * multiplier);
2027 tsWidthFullMC = (DIVUP(p_ctrl->width, blsize) * multiplier);
2028 tsWidthMC = tsWidthFullMC;
2029
2030 res = MCTF_SET_KERNELMeBiMRE(GenxRefs, GenxRefs2, idxMV, idxMV2, 0, 0, blSize, forwardRefDist, backwardRefDist);
2031 MCTF_CHECK_CM_ERR(res, res);
2032 res = MCTF_SET_KERNELMeBiMRE2(GenxRefs, GenxRefs2, idxMV, idxMV2, 0, tsHeight, blSize, forwardRefDist, backwardRefDist);
2033 MCTF_CHECK_CM_ERR(res, res);
2034
2035 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MO)
2036 {
2037 tsWidth = (tsWidthFull >> 1) & ~1; // must be even for 32x32 blocks
2038 }
2039
2040 if (tsWidthFullMC > CM_MAX_THREADSPACE_WIDTH_FOR_MO)
2041 {
2042 tsWidthMC = (tsWidthFullMC >> 1) & ~1; // must be even for 32x32 blocks
2043 }
2044
2045 threadSpace = 0;
2046 threadSpace2 = 0;
2047 threadSpaceMC = 0;
2048
2049 res = kernelMeB->SetThreadCount(tsWidth * tsHeight);
2050 MCTF_CHECK_CM_ERR(res, res);
2051 res = device->CreateThreadSpace(tsWidth, tsHeight, threadSpace);
2052 MCTF_CHECK_CM_ERR(res, res);
2053 res = kernelMeB->AssociateThreadSpace(threadSpace);
2054 MCTF_CHECK_CM_ERR(res, res);
2055
2056 res = kernelMeB2->SetThreadCount(tsWidth * tsHeight);
2057 MCTF_CHECK_CM_ERR(res, res);
2058 res = device->CreateThreadSpace(tsWidth, tsHeight, threadSpace2);
2059 MCTF_CHECK_CM_ERR(res, res);
2060 res = kernelMeB2->AssociateThreadSpace(threadSpace2);
2061 MCTF_CHECK_CM_ERR(res, res);
2062
2063 res = kernelMc2r->SetThreadCount(tsWidthMC * tsHeightMC);
2064 MCTF_CHECK_CM_ERR(res, res);
2065 res = device->CreateThreadSpace(tsWidthMC, tsHeightMC, threadSpaceMC);
2066 MCTF_CHECK_CM_ERR(res, res);
2067 res = kernelMc2r->AssociateThreadSpace(threadSpaceMC);
2068 MCTF_CHECK_CM_ERR(res, res);
2069
2070 if (task)
2071 res = task->Reset();
2072 else
2073 res = device->CreateTask(task);
2074 MCTF_CHECK_CM_ERR(res, res);
2075
2076 res = task->AddKernel(kernelMeB);
2077 MCTF_CHECK_CM_ERR(res, res);
2078 if (pMCTF_NOA_func && p_ctrl->th == MCTFADAPTIVEVAL)
2079 {
2080 res = MCTF_Enqueue(task, e);
2081 MCTF_CHECK_CM_ERR(res, res);
2082 res = e->WaitForTaskFinished();
2083 MCTF_CHECK_CM_ERR(res, res);
2084
2085 res = device->DestroyThreadSpace(threadSpace);
2086 MCTF_CHECK_CM_ERR(res, res);
2087
2088 e->GetExecutionTime(executionTime);
2089 exeTime += executionTime / 1000;
2090 exeTimeT += executionTime / 1000;
2091
2092 (this->*(pMCTF_NOA_func))(m_adaptControl);
2093 if (QfIn[1].filterStrength == 0)
2094 {
2095 MctfState = AMCTF_READY;
2096 return CM_SUCCESS;
2097 }
2098
2099 if (mcSufIndex == 0)
2100 res = MCTF_SET_KERNELMc2r(0, 0);
2101 else if (mcSufIndex == 1)
2102 res = MCTF_SET_KERNELMc4r(0, 0, DEN_CLOSE_RUN);
2103 else
2104 res = MCTF_SET_KERNELMc4r(0, 0, DEN_FAR_RUN);
2105 MCTF_CHECK_CM_ERR(res, res);
2106
2107 res = task->Reset();
2108 MCTF_CHECK_CM_ERR(res, res);
2109
2110 }
2111 else {
2112 res = task->AddSync();
2113 if (mcSufIndex == 0)
2114 res = MCTF_SET_KERNELMc2r(0, 0);
2115 else if (mcSufIndex == 1)
2116 res = MCTF_SET_KERNELMc4r(0, 0, DEN_CLOSE_RUN);
2117 else
2118 res = MCTF_SET_KERNELMc4r(0, 0, DEN_FAR_RUN);
2119 MCTF_CHECK_CM_ERR(res, res);
2120 }
2121
2122 res = task->AddKernel(kernelMeB2);
2123 MCTF_CHECK_CM_ERR(res, res);
2124 res = task->AddSync();
2125 MCTF_CHECK_CM_ERR(res, res);
2126 res = task->AddKernel(kernelMc2r);
2127 MCTF_CHECK_CM_ERR(res, res);
2128
2129 res = MCTF_Enqueue(task, e);
2130 MCTF_CHECK_CM_ERR(res, res);
2131 MctfState = AMCTF_READY;
2132 res = e->WaitForTaskFinished();
2133 MCTF_CHECK_CM_ERR(res, res);
2134 e->GetExecutionTime(executionTime);
2135 exeTime += executionTime / 1000;
2136
2137 if (!pMCTF_NOA_func) {
2138 res = device->DestroyThreadSpace(threadSpace);
2139 MCTF_CHECK_CM_ERR(res, res);
2140 }
2141
2142 res = device->DestroyThreadSpace(threadSpace2);
2143 MCTF_CHECK_CM_ERR(res, res);
2144 res = device->DestroyThreadSpace(threadSpaceMC);
2145 MCTF_CHECK_CM_ERR(res, res);
2146
2147
2148 res = device->DestroyVmeSurfaceG7_5(GenxRefs);
2149 MCTF_CHECK_CM_ERR(res, res);
2150 res = device->DestroyVmeSurfaceG7_5(GenxRefs2);
2151 MCTF_CHECK_CM_ERR(res, res);
2152 res = device->DestroyTask(task);
2153 MCTF_CHECK_CM_ERR(res, res);
2154 MctfState = AMCTF_READY;
2155 task = 0;
2156 return res;
2157 }
2158
MCTF_RUN_ME_MC_H(SurfaceIndex * GenxRefs,SurfaceIndex * GenxRefs2,SurfaceIndex * idxMV,SurfaceIndex * idxMV2,mfxI8 forwardRefDist,mfxI8 backwardRefDist,mfxU8 mcSufIndex)2159 mfxI32 CMC::MCTF_RUN_ME_MC_H(
2160 SurfaceIndex * GenxRefs,
2161 SurfaceIndex * GenxRefs2,
2162 SurfaceIndex * idxMV,
2163 SurfaceIndex * idxMV2,
2164 mfxI8 forwardRefDist,
2165 mfxI8 backwardRefDist,
2166 mfxU8 mcSufIndex
2167 )
2168 {
2169 UINT64 executionTime;
2170 mfxU8
2171 blSize = SetOverlapOp_half();
2172 res = MCTF_SET_KERNELMeBi(GenxRefs, GenxRefs2, idxMV, idxMV2, DIVUP(p_ctrl->CropX, blSize), DIVUP(p_ctrl->CropY, blSize), blSize, forwardRefDist, backwardRefDist);
2173
2174 MCTF_CHECK_CM_ERR(res, res);
2175
2176 threadSpace = 0;
2177
2178 res = MCTF_RUN_TASK(kernelMeB, task != 0);
2179 res = e->WaitForTaskFinished();
2180 MCTF_CHECK_CM_ERR(res, res);
2181 e->GetExecutionTime(executionTime);
2182 exeTime += executionTime / 1000;
2183
2184 mfxU16 multiplier = 2;
2185 tsHeightMC = (DIVUP(p_ctrl->CropH, blsize) * multiplier);
2186 tsWidthFullMC = (DIVUP(p_ctrl->CropW, blsize) * multiplier);
2187 tsWidthMC = tsWidthFullMC;
2188
2189 if (pMCTF_NOA_func)
2190 {
2191 res = MCTF_Enqueue(task, e);
2192 MCTF_CHECK_CM_ERR(res, res);
2193 res = e->WaitForTaskFinished();
2194 MCTF_CHECK_CM_ERR(res, res);
2195 res = device->DestroyThreadSpace(threadSpace);
2196 MCTF_CHECK_CM_ERR(res, res);
2197
2198 res = device->DestroyTask(task);
2199 MCTF_CHECK_CM_ERR(res, res);
2200 e->GetExecutionTime(executionTime);
2201 exeTime += executionTime / 1000;
2202 res = queue->DestroyEvent(e);
2203 MCTF_CHECK_CM_ERR(res, res);
2204 task = 0;
2205 e = 0;
2206 (this->*(pMCTF_NOA_func))(m_adaptControl);
2207 }
2208 else
2209 res = task->AddSync();
2210 res = MCTF_SET_KERNELMeBi(GenxRefs, GenxRefs2, idxMV, idxMV2, DIVUP(p_ctrl->CropX, blsize), tsHeight, blSize, forwardRefDist, backwardRefDist);
2211
2212 MCTF_CHECK_CM_ERR(res, res);
2213 if (mcSufIndex == 0)
2214 res = MCTF_SET_KERNELMc2r(DIVUP(p_ctrl->CropX, blSize) * 2, DIVUP(p_ctrl->CropY, blSize) * 2);
2215 else if (mcSufIndex == 1)
2216 res = MCTF_SET_KERNELMc4r(DIVUP(p_ctrl->CropX, blSize) * 2, DIVUP(p_ctrl->CropY, blSize) * 2, DEN_CLOSE_RUN);
2217 else
2218 res = MCTF_SET_KERNELMc4r(DIVUP(p_ctrl->CropX, blSize) * 2, DIVUP(p_ctrl->CropY, blSize) * 2, DEN_FAR_RUN);
2219 MCTF_CHECK_CM_ERR(res, res);
2220
2221 threadSpace2 = 0;
2222 threadSpaceMC = 0;
2223
2224 MCTF_RUN_DOUBLE_TASK(kernelMeB, kernelMc2r, task != 0);
2225 MCTF_CHECK_CM_ERR(res, res);
2226 res = e->WaitForTaskFinished();
2227 MCTF_CHECK_CM_ERR(res, res);
2228 e->GetExecutionTime(executionTime);
2229 exeTime += executionTime / 1000;
2230 res = device->DestroyThreadSpace(threadSpace2);
2231 MCTF_CHECK_CM_ERR(res, res);
2232 res = device->DestroyThreadSpace(threadSpaceMC);
2233 MCTF_CHECK_CM_ERR(res, res);
2234 if (threadSpace)
2235 {
2236 res = device->DestroyThreadSpace(threadSpace);
2237 MCTF_CHECK_CM_ERR(res, res);
2238 }
2239
2240 res = device->DestroyVmeSurfaceG7_5(GenxRefs);
2241 MCTF_CHECK_CM_ERR(res, res);
2242 res = device->DestroyVmeSurfaceG7_5(GenxRefs2);
2243 MCTF_CHECK_CM_ERR(res, res);
2244 res = device->DestroyTask(task);
2245 MCTF_CHECK_CM_ERR(res, res);
2246 res = queue->DestroyEvent(e);
2247 task = 0;
2248 e = 0;
2249 return res;
2250 }
2251
GET_DISTDATA()2252 void CMC::GET_DISTDATA()
2253 {
2254 for (int y = 0; y < ov_height_bl; y++)
2255 {
2256 mfxU32 * src = reinterpret_cast<mfxU32*>(reinterpret_cast<mfxU8*>(distSys) + y * surfPitch);
2257 std::copy(src, src + ov_width_bl, &distRef[y * ov_width_bl]);
2258 }
2259 }
2260
GET_DISTDATA_H()2261 void CMC::GET_DISTDATA_H()
2262 {
2263 for (int y = 0; y < ov_height_bl / 2; y++)
2264 {
2265 mfxU32 * src = reinterpret_cast<mfxU32*>(reinterpret_cast<mfxU8*>(distSys) + y * surfPitch);
2266 std::copy(src, src + ov_width_bl, &distRef[y * ov_width_bl]);
2267 }
2268 }
2269
GET_NOISEDATA()2270 void CMC::GET_NOISEDATA()
2271 {
2272 for (int y = 0; y < DIVUP(p_ctrl->CropH, 16); y++)
2273 {
2274 spatialNoiseAnalysis * src = reinterpret_cast<spatialNoiseAnalysis*>(reinterpret_cast<mfxU8*>(noiseAnalysisSys) + y * surfNoisePitch);
2275 std::copy(src, src + DIVUP(p_ctrl->CropW, 16), &var_sc[y * DIVUP(p_ctrl->CropW, 16)]);
2276 }
2277 }
2278
GET_TOTAL_SAD()2279 mfxF64 CMC::GET_TOTAL_SAD()
2280 {
2281 mfxF64 total_sad = 0.0;
2282 // to not lose due-to normalization of floats
2283 mfxU64 uTotalSad = 0;
2284 switch (overlap_Motion)
2285 {
2286 case MFX_CODINGOPTION_ON:
2287 {//overlapped modes, need to remove extra SAD blocks and lines
2288 mfxI32
2289 pos_offset = 0;
2290 for (mfxI32 i = 0; i < ov_height_bl; i += OVERLAP_OFFSET)
2291 {
2292 pos_offset = i * ov_width_bl;
2293 for (mfxI32 j = 0; j < ov_width_bl; j += OVERLAP_OFFSET)
2294 uTotalSad += distRef[pos_offset + j];
2295 }
2296 }
2297 break;
2298 case MFX_CODINGOPTION_UNKNOWN:
2299 case MFX_CODINGOPTION_OFF:
2300 {// Non overlapped, all blocks are needed for frame SAD calculation
2301 for (mfxU32 i = 0; i < distRef.size(); i++)
2302 uTotalSad += distRef[i];
2303 }
2304 break;
2305 default:
2306 throw CMCRuntimeError();
2307 }
2308 total_sad = mfxF64(uTotalSad);
2309 return total_sad / (p_ctrl->CropW * p_ctrl->CropH);
2310 }
2311
CalcNoiseStrength(double NSC,double NSAD)2312 mfxU16 CalcNoiseStrength(
2313 double NSC,
2314 double NSAD
2315 )
2316 {
2317 // 10 epsilons
2318 if (std::fabs(NSC) <= 10 * std::numeric_limits<double>::epsilon()) return 0;
2319 mfxF64
2320 s,
2321 s2,
2322
2323 c3 = -907.05,
2324 c2 = 752.69,
2325 c1 = -175.7,
2326 c0 = 14.6,
2327 d3 = -0.0000004,
2328 d2 = 0.0002,
2329 d1 = -0.0245,
2330 d0 = 4.1647,
2331
2332 ISTC = NSAD * NSC,
2333 STC = NSAD / sqrt(NSC);
2334
2335 s = c3 * pow(STC, 3.0) + c2 * pow(STC, 2.0) + c1 * STC + c0;
2336 s2 = d3 * pow(ISTC, 3.0) + d2 * pow(ISTC, 2.0) + d1 * ISTC + d0;
2337 s = NMIN(s, s2) + 5;
2338 s = NMAX(0.0, NMIN(20.0, s));
2339 return (mfxU16)(s + 0.5);
2340 }
2341
2342
CalcSTC(mfxF64 SCpp2,mfxF64 sadpp)2343 mfxU8 CalcSTC(mfxF64 SCpp2, mfxF64 sadpp)
2344 {
2345 mfxU8
2346 stcVal = 0;
2347 sadpp *= sadpp;
2348 // Ref was Recon (quantization err in ref biases sad)
2349 if (sadpp < 0.03*SCpp2) stcVal = 0; // Very-Low
2350 else if (sadpp < 0.09*SCpp2) stcVal = 1; // Low
2351 else if (sadpp < 0.20*SCpp2) stcVal = 2; // Low-Medium
2352 else if (sadpp < 0.36*SCpp2) stcVal = 3; // Medium
2353 else if (sadpp < 1.44*SCpp2) stcVal = 4; // Medium-High
2354 else if (sadpp < 3.24*SCpp2) stcVal = 5; // High
2355 else stcVal = 6; // VeryHigh
2356 return stcVal;
2357 }
2358
2359
GetSpatioTemporalComplexityFrame(mfxU8 currentFrame)2360 void CMC::GetSpatioTemporalComplexityFrame(mfxU8 currentFrame)
2361 {
2362 mfxU8
2363 i;
2364 mfxF64
2365 SCpp2 = QfIn[currentFrame].frame_sc;
2366 static mfxF32
2367 lmt_sc2[10] = { 16.0, 81.0, 225.0, 529.0, 1024.0, 1764.0, 2809.0, 4225.0, 6084.0, (mfxF32)INT_MAX }; // lower limit of SFM(Rs,Cs) range for spatial classification
2368
2369 for (i = 0; i < 10; i++)
2370 {
2371 if (SCpp2 < lmt_sc2[i])
2372 {
2373 QfIn[currentFrame].sc = i;
2374 break;
2375 }
2376 }
2377 QfIn[currentFrame].tc = 0;
2378 QfIn[currentFrame].stc = 0;
2379 mfxF64
2380 sadpp = QfIn[currentFrame].frame_sad;
2381 static mfxF64
2382 lmt_tc[10] = { 0.75, 1.5, 2.25, 3.00, 4.00, 5.00, 6.00, 7.50, 9.25, mfxF64(INT_MAX) }; // lower limit of AFD
2383 for (i = 0; i < 10; i++)
2384 {
2385 if (sadpp < lmt_tc[i])
2386 {
2387 QfIn[currentFrame].tc = i;
2388 break;
2389 }
2390 }
2391 QfIn[currentFrame].stc = CalcSTC(SCpp2, sadpp);
2392 }
2393
computeQpClassFromBitRate(mfxU8 currentFrame)2394 mfxU32 CMC::computeQpClassFromBitRate(
2395 mfxU8 currentFrame
2396 )
2397 {
2398 mfxF64
2399 scL = log10(QfIn[currentFrame].sc),
2400 sadL = log10(QfIn[currentFrame].frame_sad);
2401 mfxF64
2402 d0 = sadL * scL,
2403 A, B = -0.75;
2404 d0 = pow(d0, 2.03);
2405 // 0.567701x + 1.092071
2406 A = 0.567701 * d0 + 1.092071;
2407
2408 mfxU32 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
2409 QP_CLASS[54] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
2410 mfxF64
2411 y, qs;
2412 y = A * pow(bpp, B);
2413 qs = 1.0 + log(y) / log(2.0);
2414
2415 mfxU32
2416 QP = (mfxU32)(6.0 * qs) + 4;
2417 mfxU32
2418 QCL = (QP > 53) ? 3 : QP_CLASS[QP];
2419 return QCL;
2420 }
2421
FilterEnable(gpuFrameData frame)2422 bool CMC::FilterEnable(
2423 gpuFrameData frame)
2424 {
2425 mfxF64
2426 noise_sad = frame.noise_sad;
2427 mfxU32
2428 noise_count = frame.noise_count;
2429 bool
2430 enableFilter = false;
2431 //Enabling/Disabling filter model coeficcients
2432 mfxF64
2433 s,
2434 #if defined(MFX_ENABLE_SOFT_CURVE)
2435 c2 = 165.51,
2436 c1 = -1614.4,
2437 c0 = 4085.7;
2438 s = c2 * pow(noise_sad, 2) + c1 * noise_sad + c0;
2439 #else
2440 c1 = 574.5,
2441 c0 = 2409.925;
2442 s = c1 * noise_sad + c0;
2443 #endif
2444
2445
2446 enableFilter = (mfxF64)noise_count > s;
2447 return enableFilter;
2448 }
2449
noise_estimator(bool adaptControl)2450 mfxI32 CMC::noise_estimator(
2451 bool adaptControl
2452 )
2453 {
2454 mfxU8
2455 currentFrame = (number_of_References <= 2) ? 1 : 2,
2456 previousFrame = currentFrame - 1;
2457 mfxU32
2458 width = DIVUP(p_ctrl->CropW, 16),
2459 height = DIVUP(p_ctrl->CropH, 16),
2460 count = 0,
2461 row, col;
2462 mfxI16
2463 fsModVal = 0;
2464 mfxF32
2465 tvar = 281,
2466 var, SCpp, SADpp;
2467
2468 QfIn[currentFrame].noise_var = 0.0,
2469 QfIn[currentFrame].noise_sad = 0.0,
2470 QfIn[currentFrame].noise_sc = 0.0;
2471 QfIn[currentFrame].noise_count = 1;
2472
2473 QfIn[currentFrame].frame_sc = 0.0;
2474 QfIn[currentFrame].frame_sad = 0.0;
2475 QfIn[currentFrame].frame_Cs = 0.0;
2476 QfIn[currentFrame].frame_Rs = 0.0;
2477
2478 GET_DISTDATA_H();
2479 res = MCTF_RUN_Noise_Analysis(currentFrame);
2480 MCTF_CHECK_CM_ERR(res, res);
2481
2482 GET_NOISEDATA();
2483 mfxU32 distRefStride = 2 * width;
2484 switch (overlap_Motion)
2485 {
2486 case MFX_CODINGOPTION_ON:
2487 {
2488 for (row = 1; row < height / 2 - 1; row++)
2489 {
2490 for (col = 1; col < width - 1; col++)
2491 {
2492 var = var_sc[row * width + col].var;
2493 SCpp = var_sc[row * width + col].SCpp;
2494 QfIn[currentFrame].frame_sc += SCpp;
2495 SADpp = (mfxF32)(distRef[row * 2 * width * 2 + col * 2] / 256);
2496 QfIn[currentFrame].frame_sad += SADpp;
2497 if (var < tvar && SCpp <tvar && SCpp>1.0 && (SADpp*SADpp) <= SCpp)
2498 {
2499 count++;
2500 QfIn[currentFrame].noise_var += var;
2501 QfIn[currentFrame].noise_sc += SCpp;
2502 QfIn[currentFrame].noise_sad += SADpp;
2503 }
2504 }
2505 }
2506 }
2507 break;
2508 case MFX_CODINGOPTION_UNKNOWN:
2509 case MFX_CODINGOPTION_OFF:
2510 {
2511 for (row = 1; row < height / 2 - 1; row++)
2512 {
2513 for (col = 1; col < width - 1; col++)
2514 {
2515 var = var_sc[row * width + col].var;
2516 SCpp = var_sc[row * width + col].SCpp;
2517 QfIn[currentFrame].frame_sc += SCpp;
2518 // NB: division by 256 is done in integers;
2519 // thus, for each calculation, 8 LSB are truncated
2520 // works good; but additional efforts can be taken,
2521 // to consider higher precision (thru calculations in integers)
2522 // followed by wise truncating.
2523 SADpp = (mfxF32)((distRef[row * 2 * distRefStride + col * 2] +
2524 distRef[row * 2 * distRefStride + col * 2 + 1] +
2525 distRef[(row * 2 + 1) * distRefStride + col * 2] +
2526 distRef[(row * 2 + 1) * distRefStride + col * 2 + 1]) / 256);
2527 QfIn[currentFrame].frame_sad += SADpp;
2528 if (var < tvar && SCpp <tvar && SCpp>1.0 && (SADpp*SADpp) <= SCpp)
2529 {
2530 ++count;
2531 QfIn[currentFrame].noise_var += var;
2532 QfIn[currentFrame].noise_sc += SCpp;
2533 QfIn[currentFrame].noise_sad += SADpp;
2534
2535 }
2536 }
2537 }
2538 }
2539 break;
2540 default:
2541 throw CMCRuntimeError();
2542 }
2543 QfIn[currentFrame].frame_sc /= ((height / 2 - 2) * (width - 2));
2544 QfIn[currentFrame].frame_sad /= ((height / 2 - 2) * (width - 2));
2545 if (count)
2546 {
2547 // noise_count is reserved for future use.
2548 QfIn[currentFrame].noise_count = count;
2549 QfIn[currentFrame].noise_var /= count;
2550 QfIn[currentFrame].noise_sc /= count;
2551 QfIn[currentFrame].noise_sad /= count;
2552 }
2553 mfxU16
2554 filterstrength = MCTFSTRENGTH;
2555 if (QfIn[currentFrame].scene_idx != QfIn[previousFrame].scene_idx)
2556 {
2557 filterstrength = QfIn[previousFrame].filterStrength;
2558 }
2559 else
2560 {
2561 filterstrength = CalcNoiseStrength(QfIn[currentFrame].noise_sc, QfIn[currentFrame].noise_sad);
2562 if (bitrate_Adaptation)
2563 {
2564 GetSpatioTemporalComplexityFrame(currentFrame);
2565 mfxU32
2566 QLC = computeQpClassFromBitRate(currentFrame);
2567 if (QLC == 0)
2568 fsModVal = QfIn[currentFrame].stc > 0.35 ? -2 : -1;
2569 else if (QLC == 1)
2570 fsModVal = 0;
2571 else if (QLC == 2)
2572 fsModVal = 1;
2573 else
2574 fsModVal = 2;
2575
2576 mfxI32 limit = filterstrength > 14 ? 13 : 20;
2577 filterstrength = mfxU16(max(0, min(limit, (mfxI16)filterstrength + fsModVal)));
2578 }
2579 }
2580 if (adaptControl)
2581 {
2582 filterstrength = FilterEnable(QfIn[currentFrame]) ? filterstrength : MCTFNOFILTER;
2583 m_doFilterFrame = !!filterstrength;
2584 }
2585 QfIn[currentFrame].filterStrength = filterstrength;
2586 gopBasedFilterStrength = filterstrength;
2587 if (adaptControl)
2588 res = SetFilterStrenght(filterstrength, MCTFNOFILTER);
2589 else
2590 res = SetFilterStrenght(filterstrength);
2591 MCTF_CHECK_CM_ERR(res, res);
2592 return res;
2593 }
2594
MCTF_RUN_Noise_Analysis(mfxU8 srcNum)2595 mfxI32 CMC::MCTF_RUN_Noise_Analysis(mfxU8 srcNum)
2596 {
2597 res = MCTF_SET_KERNEL_Noise(srcNum, DIVUP(p_ctrl->CropX, 16), DIVUP(p_ctrl->CropY, 16));
2598 MCTF_CHECK_CM_ERR(res, res);
2599 mfxU16
2600 tsHeightNA = DIVUP(p_ctrl->CropH, 16),
2601 tsWidthFullNA = DIVUP(p_ctrl->CropW, 16),
2602 tsWidthNA = tsWidthFullNA;
2603
2604 if (tsWidthFullNA > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2605 tsWidthNA = (tsWidthFullNA >> 1) & ~1; // must be even for 32x32 blocks
2606
2607 threadSpace = 0;
2608 res = MCTF_RUN_TASK_NA(kernelNoise, task != 0, tsWidthNA, tsHeightNA);
2609 MCTF_CHECK_CM_ERR(res, res);
2610
2611 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2612 {
2613 mfxU16
2614 start_mbX = tsWidth;
2615 tsWidth = tsWidthFull - tsWidth;
2616 res = MCTF_SET_KERNEL_Noise(srcNum, start_mbX, DIVUP(p_ctrl->CropY, 16));
2617 MCTF_CHECK_CM_ERR(res, res);
2618 if (threadSpace != NULL)
2619 {
2620 res = device->DestroyThreadSpace(threadSpace);
2621 MCTF_CHECK_CM_ERR(res, res);
2622 }
2623 // the rest of frame TS
2624 res = MCTF_RUN_TASK_NA(kernelNoise, task != 0, tsWidthNA, tsHeightNA);
2625 MCTF_CHECK_CM_ERR(res, res);
2626 }
2627 res = e->WaitForTaskFinished();
2628 MCTF_CHECK_CM_ERR(res, res);
2629 device->DestroyThreadSpace(threadSpace);
2630 queue->DestroyEvent(e);
2631 e = 0;
2632 return res;
2633 }
2634
MCTF_RUN_BLEND()2635 mfxI32 CMC::MCTF_RUN_BLEND()
2636 {
2637 mfxU16 multiplier = 2;
2638 res = MCTF_SET_KERNELMc(DIVUP(p_ctrl->CropX, blsize) * multiplier, DIVUP(p_ctrl->CropY, blsize) * multiplier, 1, 0);
2639 MCTF_CHECK_CM_ERR(res, res);
2640 tsHeight = (DIVUP(p_ctrl->CropH, blsize) * multiplier);
2641 tsWidthFull = (DIVUP(p_ctrl->CropW, blsize) * multiplier);
2642 tsWidth = tsWidthFull;
2643
2644 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2645 tsWidth = (tsWidthFull >> 1) & ~1; // must be even for 32x32 blocks
2646
2647 threadSpace = 0;
2648 res = MCTF_RUN_TASK(kernelMc1r, task != 0);
2649 MCTF_CHECK_CM_ERR(res, res);
2650
2651 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2652 {
2653 mfxU16
2654 start_mbX = tsWidth;
2655 tsWidth = tsWidthFull - tsWidth;
2656 res = MCTF_SET_KERNELMc(start_mbX, DIVUP(p_ctrl->CropY, blsize) * multiplier, 1, 0);
2657 MCTF_CHECK_CM_ERR(res, res);
2658 // the rest of frame TS
2659 res = MCTF_RUN_TASK(kernelMc1r, task != 0);
2660 MCTF_CHECK_CM_ERR(res, res);
2661 }
2662 res = e->WaitForTaskFinished();
2663 MCTF_CHECK_CM_ERR(res, res);
2664 UINT64 executionTime;
2665 e->GetExecutionTime(executionTime);
2666 exeTime += executionTime / 1000;
2667 device->DestroyThreadSpace(threadSpace);
2668 queue->DestroyEvent(e);
2669 e = 0;
2670 return res;
2671 }
2672
MCTF_RUN_BLEND(mfxU8 srcNum,mfxU8 refNum)2673 mfxI32 CMC::MCTF_RUN_BLEND(
2674 mfxU8 srcNum,
2675 mfxU8 refNum
2676 )
2677 {
2678 mfxU16 multiplier = 2;
2679 res = MCTF_SET_KERNELMc(DIVUP(p_ctrl->CropX, blsize) * multiplier , DIVUP(p_ctrl->CropY, blsize) * multiplier, srcNum, refNum);
2680 MCTF_CHECK_CM_ERR(res, res);
2681 tsHeight = (DIVUP(p_ctrl->CropH, blsize) * multiplier);
2682 tsWidthFull = (DIVUP(p_ctrl->CropW, blsize) * multiplier);
2683 tsWidth = tsWidthFull;
2684
2685 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2686 tsWidth = (tsWidthFull >> 1) & ~1; // must be even for 32x32 blocks
2687
2688 threadSpace = 0;
2689 res = MCTF_RUN_TASK(kernelMc1r, task != 0);
2690 MCTF_CHECK_CM_ERR(res, res);
2691
2692 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2693 {
2694 mfxU16
2695 start_mbX = tsWidth;
2696 tsWidth = tsWidthFull - tsWidth;
2697 res = MCTF_SET_KERNELMc(start_mbX, DIVUP(p_ctrl->CropY, blsize) * multiplier, srcNum, refNum);
2698 MCTF_CHECK_CM_ERR(res, res);
2699 // the rest of frame TS
2700 res = MCTF_RUN_TASK(kernelMc1r, task != 0);
2701 MCTF_CHECK_CM_ERR(res, res);
2702 }
2703 res = e->WaitForTaskFinished();
2704 MCTF_CHECK_CM_ERR(res, res);
2705 device->DestroyThreadSpace(threadSpace);
2706 queue->DestroyEvent(e);
2707 e = 0;
2708 return res;
2709 }
2710
MCTF_RUN_BLEND2R()2711 mfxI32 CMC::MCTF_RUN_BLEND2R()
2712 {
2713 mfxU16 multiplier = 2;
2714 res = MCTF_SET_KERNELMc2r(DIVUP(p_ctrl->CropX, blsize) * multiplier, DIVUP(p_ctrl->CropY, blsize) * multiplier);
2715 MCTF_CHECK_CM_ERR(res, res);
2716
2717 tsHeightMC = (DIVUP(p_ctrl->CropH, blsize) * multiplier);
2718 tsWidthFullMC = (DIVUP(p_ctrl->CropW, blsize) * multiplier);
2719 tsWidthMC = tsWidthFullMC;
2720
2721 if (tsWidthFullMC > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2722 tsWidthMC = (tsWidthFullMC >> 1) & ~1; // must be even for 32x32 blocks
2723
2724 threadSpaceMC = 0;
2725 res = MCTF_RUN_MCTASK(kernelMc2r, task != 0);
2726 MCTF_CHECK_CM_ERR(res, res);
2727
2728 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2729 {
2730 mfxU16 start_mbX = tsWidthMC;
2731 tsWidthMC = tsWidthFullMC - tsWidthMC;
2732 res = MCTF_SET_KERNELMc2r(start_mbX, DIVUP(p_ctrl->CropY, blsize) * multiplier);
2733 MCTF_CHECK_CM_ERR(res, res);
2734 // the rest of frame TS
2735 res = MCTF_RUN_MCTASK(kernelMc2r, task != 0);
2736 MCTF_CHECK_CM_ERR(res, res);
2737 }
2738 res = e->WaitForTaskFinished();
2739 MCTF_CHECK_CM_ERR(res, res);
2740 UINT64 executionTime;
2741 e->GetExecutionTime(executionTime);
2742 exeTime += executionTime / 1000;
2743 device->DestroyThreadSpace(threadSpaceMC);
2744 queue->DestroyEvent(e);
2745 e = 0;
2746 return res;
2747 }
2748
MCTF_RUN_BLEND2R_DEN()2749 mfxI32 CMC::MCTF_RUN_BLEND2R_DEN()
2750 {
2751 mfxU16 multiplier = 2;
2752 res = MCTF_SET_KERNELMc2rDen(DIVUP(p_ctrl->CropX, blsize) * multiplier, DIVUP(p_ctrl->CropY, blsize) * multiplier);
2753 MCTF_CHECK_CM_ERR(res, res);
2754 tsHeight = (DIVUP(p_ctrl->CropH, blsize) * multiplier);
2755 tsWidthFull = (DIVUP(p_ctrl->CropW, blsize) * multiplier);
2756 tsWidth = tsWidthFull;
2757
2758 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2759 tsWidth = (tsWidthFull >> 1) & ~1; // must be even for 32x32 blocks
2760
2761 threadSpace = 0;
2762 res = MCTF_RUN_TASK(kernelMc2r, task != 0);
2763 MCTF_CHECK_CM_ERR(res, res);
2764
2765 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2766 {
2767 mfxU16
2768 start_mbX = tsWidth;
2769 tsWidth = tsWidthFull - tsWidth;
2770
2771 res = MCTF_SET_KERNELMc2rDen(start_mbX, DIVUP(p_ctrl->CropY, blsize) * multiplier);
2772 MCTF_CHECK_CM_ERR(res, res);
2773 // the rest of frame TS
2774 res = MCTF_RUN_TASK(kernelMc2r, task != 0);
2775 MCTF_CHECK_CM_ERR(res, res);
2776 }
2777 res = e->WaitForTaskFinished();
2778 MCTF_CHECK_CM_ERR(res, res);
2779 device->DestroyThreadSpace(threadSpace);
2780 queue->DestroyEvent(e);
2781 e = 0;
2782 return res;
2783 }
2784
MCTF_RUN_BLEND4R(DRT typeRun)2785 mfxI32 CMC::MCTF_RUN_BLEND4R(
2786 DRT typeRun
2787 )
2788 {
2789 if (typeRun > 1)
2790 return MFX_ERR_INVALID_VIDEO_PARAM;
2791 mfxU16 multiplier = 2;
2792 res = MCTF_SET_KERNELMc4r(DIVUP(p_ctrl->CropX, blsize) * multiplier, DIVUP(p_ctrl->CropY, blsize) * multiplier, (mfxU8)typeRun);
2793 MCTF_CHECK_CM_ERR(res, res);
2794 tsHeight = (DIVUP(p_ctrl->CropH, blsize) * multiplier);
2795 tsWidthFull = (DIVUP(p_ctrl->CropW, blsize) * multiplier);
2796 tsWidth = tsWidthFull;
2797
2798 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2799 tsWidth = (tsWidthFull >> 1) & ~1; // must be even for 32x32 blocks
2800
2801 threadSpace = 0;
2802 res = MCTF_RUN_TASK(kernelMc2r, task != 0);
2803 MCTF_CHECK_CM_ERR(res, res);
2804
2805 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2806 {
2807 mfxU16
2808 start_mbX = tsWidth;
2809 tsWidth = tsWidthFull - tsWidth;
2810 res = MCTF_SET_KERNELMc4r(start_mbX, DIVUP(p_ctrl->CropY, blsize) * multiplier, (mfxU8)typeRun);
2811 MCTF_CHECK_CM_ERR(res, res);
2812 // the rest of frame TS
2813 res = MCTF_RUN_TASK(kernelMc2r, task != 0);
2814 MCTF_CHECK_CM_ERR(res, res);
2815 }
2816 res = e->WaitForTaskFinished();
2817 MCTF_CHECK_CM_ERR(res, res);
2818 device->DestroyThreadSpace(threadSpace);
2819 queue->DestroyEvent(e);
2820 e = 0;
2821 return res;
2822 }
2823
MCTF_RUN_MERGE()2824 mfxI32 CMC::MCTF_RUN_MERGE()
2825 {
2826 res = MCTF_SET_KERNELMcMerge(DIVUP(p_ctrl->CropX, 16), DIVUP(p_ctrl->CropY, 16));
2827 MCTF_CHECK_CM_ERR(res, res);
2828 tsHeight = DIVUP(p_ctrl->CropH, 16);
2829 tsWidthFull = DIVUP(p_ctrl->CropW, 16);
2830 tsWidth = tsWidthFull;
2831
2832 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2833 tsWidth = (tsWidthFull >> 1) & ~1; // must be even for 32x32 blocks
2834
2835 threadSpace = 0;
2836 res = MCTF_RUN_TASK(kernelMc4r, task != 0);
2837 MCTF_CHECK_CM_ERR(res, res);
2838
2839 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2840 {
2841 mfxU16
2842 start_mbX = tsWidth;
2843 tsWidth = tsWidthFull - tsWidth;
2844 res = MCTF_SET_KERNELMc4r(start_mbX, DIVUP(p_ctrl->CropY, 16));
2845 MCTF_CHECK_CM_ERR(res, res);
2846 // the rest of frame TS
2847 res = MCTF_RUN_TASK(kernelMc4r, task != 0);
2848 MCTF_CHECK_CM_ERR(res, res);
2849 }
2850 res = e->WaitForTaskFinished();
2851 MCTF_CHECK_CM_ERR(res, res);
2852 device->DestroyThreadSpace(threadSpace);
2853 queue->DestroyEvent(e);
2854 e = 0;
2855 return res;
2856 }
2857
MCTF_RUN_BLEND4R(SurfaceIndex * multiIndex)2858 mfxI32 CMC::MCTF_RUN_BLEND4R(
2859 SurfaceIndex * multiIndex
2860 )
2861 {
2862 mfxU16 multiplier = 2;
2863 res = MCTF_SET_KERNELMc4r(DIVUP(p_ctrl->CropX, blsize) * multiplier, DIVUP(p_ctrl->CropY, blsize) * multiplier, multiIndex);
2864 MCTF_CHECK_CM_ERR(res, res);
2865 tsHeight = (DIVUP(p_ctrl->CropH, blsize) * multiplier);
2866 tsWidthFull = (DIVUP(p_ctrl->CropW, blsize) * multiplier);
2867 tsWidth = tsWidthFull;
2868
2869 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2870 tsWidth = (tsWidthFull >> 1) & ~1; // must be even for 32x32 blocks
2871
2872 threadSpace = 0;
2873 res = MCTF_RUN_TASK(kernelMc2r, task != 0);
2874 MCTF_CHECK_CM_ERR(res, res);
2875
2876 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
2877 {
2878 mfxU16
2879 start_mbX = tsWidth;
2880 tsWidth = tsWidthFull - tsWidth;
2881 res = MCTF_SET_KERNELMc4r(start_mbX, DIVUP(p_ctrl->CropY, blsize) * multiplier, multiIndex);
2882 MCTF_CHECK_CM_ERR(res, res);
2883 res = MCTF_RUN_TASK(kernelMc2r, task != 0);
2884 MCTF_CHECK_CM_ERR(res, res);
2885 }
2886 res = e->WaitForTaskFinished();
2887 MCTF_CHECK_CM_ERR(res, res);
2888 device->DestroyThreadSpace(threadSpace);
2889 queue->DestroyEvent(e);
2890 e = 0;
2891 return res;
2892 }
2893
RotateBufferA()2894 void CMC::RotateBufferA()
2895 {
2896 std::swap(QfIn[0], QfIn[1]);
2897 std::swap(QfIn[0], QfIn[2]);
2898 }
2899
RotateBufferB()2900 void CMC::RotateBufferB()
2901 {
2902 std::swap(QfIn[0], QfIn[1]);
2903 std::swap(QfIn[1], QfIn[2]);
2904 std::swap(QfIn[2], QfIn[3]);
2905 }
2906
RotateBuffer()2907 void CMC::RotateBuffer()
2908 {
2909 mfxU8 correction = ((QfIn.size() > 3) && (firstFrame < 3)) << 1;
2910 for (mfxU8 i = 0; i < QfIn.size() - 1 - correction; i++)
2911 std::swap(QfIn[i], QfIn[i + 1]);
2912 }
2913
AssignSceneNumber()2914 void CMC::AssignSceneNumber()
2915 {
2916 for (mfxU8 i = 0; i < QfIn.size(); i++)
2917 scene_numbers[i] = QfIn[i].scene_idx;
2918 }
2919
MCTF_RUN_ME_1REF()2920 mfxI32 CMC::MCTF_RUN_ME_1REF()
2921 {
2922 res = MCTF_RUN_ME(genxRefs1, idxMv_1);
2923 MCTF_CHECK_CM_ERR(res, res);
2924
2925 res = e->WaitForTaskFinished();
2926 MCTF_CHECK_CM_ERR(res, res);
2927 UINT64 executionTime;
2928 e->GetExecutionTime(executionTime);
2929 exeTime += executionTime / 1000;
2930 device->DestroyThreadSpace(threadSpace);
2931 queue->DestroyEvent(e);
2932 device->DestroyVmeSurfaceG7_5(genxRefs1);
2933 e = 0;
2934
2935 if (pMCTF_NOA_func)
2936 (this->*(pMCTF_NOA_func))(m_adaptControl);
2937
2938 return res;
2939 }
2940
MCTF_RUN_ME_2REF_HE()2941 mfxI32 CMC::MCTF_RUN_ME_2REF_HE()
2942 {
2943 res = MCTF_RUN_ME_MC_HE(genxRefs1, genxRefs2, idxMv_1, idxMv_2, forward_distance, backward_distance, 0);
2944 MCTF_CHECK_CM_ERR(res, res);
2945 return res;
2946 }
2947
MCTF_RUN_ME_2REF()2948 mfxI32 CMC::MCTF_RUN_ME_2REF()
2949 {
2950 res = MCTF_RUN_ME_MC_H(genxRefs1, genxRefs2, idxMv_1, idxMv_2, forward_distance, backward_distance, 0);
2951 MCTF_CHECK_CM_ERR(res, res);
2952 return res;
2953 }
2954
MCTF_RUN_ME_4REF()2955 mfxI32 CMC::MCTF_RUN_ME_4REF()
2956 {
2957 res = MCTF_RUN_ME_MC_H(genxRefs1, genxRefs2, idxMv_1, idxMv_2, forward_distance, backward_distance, 1);
2958 MCTF_CHECK_CM_ERR(res, res);
2959 res = MCTF_RUN_ME_MC_H(genxRefs3, genxRefs4, idxMv_3, idxMv_4, forward_distance, backward_distance, 2);
2960 return res;
2961 }
2962
2963
MCTF_BLEND4R()2964 mfxI32 CMC::MCTF_BLEND4R()
2965 {
2966 res = MCTF_RUN_BLEND4R(DEN_CLOSE_RUN);
2967 MCTF_CHECK_CM_ERR(res, res);
2968 res = MCTF_RUN_BLEND4R(DEN_FAR_RUN);
2969 MCTF_CHECK_CM_ERR(res, res);
2970 res = MCTF_RUN_MERGE();
2971 MCTF_CHECK_CM_ERR(res, res);
2972 return res;
2973 }
2974
MCTF_RUN_MCTF_DEN_1REF(bool)2975 mfxI32 CMC::MCTF_RUN_MCTF_DEN_1REF(
2976 bool
2977 )
2978 {
2979 if (pMCTF_LOAD_func)
2980 {
2981 res = (this->*(pMCTF_LOAD_func))();
2982 MCTF_CHECK_CM_ERR(res, res);
2983 }
2984 AssignSceneNumber();
2985 if (pMCTF_ME_func)
2986 {
2987 res = (this->*(pMCTF_ME_func))();
2988 MCTF_CHECK_CM_ERR(res, res);
2989 }
2990 if (pMCTF_MERGE_func)
2991 {
2992 res = (this->*(pMCTF_MERGE_func))();
2993 MCTF_CHECK_CM_ERR(res, res);
2994 }
2995 if (pMCTF_SpDen_func)
2996 res = (this->*(pMCTF_SpDen_func))();
2997 RotateBuffer();
2998 return res;
2999 }
3000
MCTF_RUN_MCTF_DEN(bool notInPipeline)3001 mfxI32 CMC::MCTF_RUN_MCTF_DEN(
3002 bool notInPipeline
3003 )
3004 {
3005 if ((QfIn[1].filterStrength > 0) || notInPipeline)
3006 {
3007 if (pMCTF_LOAD_func)
3008 {
3009 res = (this->*(pMCTF_LOAD_func))();
3010 MCTF_CHECK_CM_ERR(res, res);
3011 }
3012 AssignSceneNumber();
3013 if (pMCTF_ME_func)
3014 {
3015 res = (this->*(pMCTF_ME_func))();
3016 MCTF_CHECK_CM_ERR(res, res);
3017 }
3018 if (pMCTF_MERGE_func)
3019 {
3020 res = (this->*(pMCTF_MERGE_func))();
3021 MCTF_CHECK_CM_ERR(res, res);
3022 }
3023 if (pMCTF_SpDen_func)
3024 res = (this->*(pMCTF_SpDen_func))();
3025 }
3026 RotateBuffer();
3027 return res;
3028 }
3029
MCTF_RUN_MCTF_DEN_4REF(bool)3030 mfxI32 CMC::MCTF_RUN_MCTF_DEN_4REF(
3031 bool
3032 )
3033 {
3034 res = (this->*(pMCTF_LOAD_func))();
3035 MCTF_CHECK_CM_ERR(res, res);
3036 AssignSceneNumber();
3037 res = (this->*(pMCTF_ME_func))();
3038 MCTF_CHECK_CM_ERR(res, res);
3039 res = (this->*(pMCTF_MERGE_func))();
3040 MCTF_CHECK_CM_ERR(res, res);
3041 if (pMCTF_SpDen_func)
3042 res = (this->*(pMCTF_SpDen_func))();
3043 RotateBuffer();
3044 return res;
3045 }
3046
MCTF_RUN_AMCTF_DEN()3047 mfxI32 CMC::MCTF_RUN_AMCTF_DEN()
3048 {
3049 res = (this->*(pMCTF_LOAD_func))();
3050 MCTF_CHECK_CM_ERR(res, res);
3051 AssignSceneNumber();
3052 res = MCTF_RUN_ME(genxRefs1, genxRefs2, idxMv_1, idxMv_2, forward_distance, backward_distance);
3053 MCTF_CHECK_CM_ERR(res, res);
3054 res = MCTF_RUN_BLEND2R();
3055 MCTF_CHECK_CM_ERR(res, res);
3056 res = MCTF_RUN_Denoise();
3057 MCTF_CHECK_CM_ERR(res, res);
3058 RotateBuffer();
3059 return res;
3060 }
3061
MCTF_RUN_AMCTF()3062 mfxI32 CMC::MCTF_RUN_AMCTF()
3063 {
3064 res = MCTF_RUN_Denoise(1);
3065 MCTF_CHECK_CM_ERR(res, res);
3066 return res;
3067 }
3068
MCTF_RUN_AMCTF(mfxU16 srcNum)3069 mfxI32 CMC::MCTF_RUN_AMCTF(mfxU16 srcNum)
3070 {
3071 res = MCTF_RUN_Denoise(srcNum);
3072 MCTF_CHECK_CM_ERR(res, res);
3073 MctfState = AMCTF_READY;
3074 return res;
3075 }
3076
MCTF_RUN_Denoise(mfxU16 srcNum)3077 mfxI32 CMC::MCTF_RUN_Denoise(mfxU16 srcNum)
3078 {
3079 if (QfIn[srcNum].filterStrength == 21)
3080 p_ctrl->sTh = MCTFSTRENGTH * 50 / 25;
3081 else
3082 p_ctrl->sTh = QfIn[srcNum].filterStrength * 50 / 25;
3083 res = ctrlBuf->WriteSurface((const mfxU8 *)p_ctrl.get(), NULL, sizeof(MeControlSmall));
3084 MCTF_CHECK_CM_ERR(res, res);
3085 res = MCTF_SET_KERNELDe(srcNum, 0, 0);
3086 MCTF_CHECK_CM_ERR(res, res);
3087 p_ctrl->sTh = 0;
3088 tsHeight = DIVUP(p_ctrl->height, 8);
3089 tsWidthFull = DIVUP(p_ctrl->width, 8);
3090 tsWidth = tsWidthFull;
3091
3092 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW) {
3093 tsWidth = (tsWidthFull >> 1) & ~1; // must be even for 32x32 blocks
3094 }
3095
3096 threadSpace = 0;
3097 res = MCTF_RUN_TASK(kernelMcDen, task != 0);
3098 MCTF_CHECK_CM_ERR(res, res);
3099
3100 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
3101 {
3102 mfxU16
3103 start_mbX = tsWidth;
3104 tsWidth = tsWidthFull - tsWidth;
3105 res = MCTF_SET_KERNELDe(srcNum, start_mbX, 0);
3106 MCTF_CHECK_CM_ERR(res, res);
3107 if (threadSpace != NULL) {
3108 res = device->DestroyThreadSpace(threadSpace);
3109 MCTF_CHECK_CM_ERR(res, res);
3110 }
3111 // the rest of frame TS
3112 res = MCTF_RUN_TASK(kernelMcDen, task != 0);
3113 MCTF_CHECK_CM_ERR(res, res);
3114 }
3115 res = e->WaitForTaskFinished();
3116 MCTF_CHECK_CM_ERR(res, res);
3117
3118 UINT64 executionTime;
3119 e->GetExecutionTime(executionTime);
3120 exeTime += executionTime / 1000;
3121 return res;
3122 }
3123
MCTF_RUN_Denoise()3124 mfxI32 CMC::MCTF_RUN_Denoise()
3125 {
3126 res = MCTF_SET_KERNELDe(DIVUP(p_ctrl->CropX, 8), DIVUP(p_ctrl->CropY, 8));
3127 MCTF_CHECK_CM_ERR(res, res);
3128 tsHeight = DIVUP(p_ctrl->CropH, 8);
3129 tsWidthFull = DIVUP(p_ctrl->CropW, 8);
3130 tsWidth = tsWidthFull;
3131
3132 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
3133 tsWidth = (tsWidthFull >> 1) & ~1; // must be even for 32x32 blocks
3134
3135 threadSpace = 0;
3136 res = MCTF_RUN_TASK(kernelMcDen, task != 0);
3137 MCTF_CHECK_CM_ERR(res, res);
3138
3139 if (tsWidthFull > CM_MAX_THREADSPACE_WIDTH_FOR_MW)
3140 {
3141 mfxU16
3142 start_mbX = tsWidth;
3143 tsWidth = tsWidthFull - tsWidth;
3144 res = MCTF_SET_KERNELDe(start_mbX, DIVUP(p_ctrl->CropY, 8));
3145 MCTF_CHECK_CM_ERR(res, res);
3146 res = MCTF_RUN_TASK(kernelMcDen, task != 0);
3147 MCTF_CHECK_CM_ERR(res, res);
3148 }
3149 res = e->WaitForTaskFinished();
3150 MCTF_CHECK_CM_ERR(res, res);
3151 UINT64 executionTime;
3152 e->GetExecutionTime(executionTime);
3153 exeTime += executionTime / 1000;
3154 return res;
3155 }
3156
IM_SURF_PUT(CmSurface2D * p_surface,mfxU8 * p_data)3157 mfxU32 CMC::IM_SURF_PUT(
3158 CmSurface2D *p_surface,
3159 mfxU8 *p_data)
3160 {
3161 CM_STATUS
3162 status = CM_STATUS_FLUSHED;
3163 res = queue->EnqueueCopyCPUToGPU(p_surface, p_data, copyEv);
3164 MCTF_CHECK_CM_ERR(res, res);
3165 copyEv->GetStatus(status);
3166 while (status != CM_STATUS_FINISHED)
3167 copyEv->GetStatus(status);
3168 return res;
3169 }
3170
IntBufferUpdate(bool isSceneChange,bool isIntraFrame,bool doIntraFiltering)3171 void CMC::IntBufferUpdate(
3172 bool isSceneChange,
3173 bool isIntraFrame,
3174 bool doIntraFiltering)
3175 {
3176 size_t
3177 buffer_size = QfIn.size() - 1;
3178 if (bufferCount > buffer_size) {
3179 printf("Error: Invalid frame buffer position\n");
3180 exit(-1);
3181 }
3182 if (bufferCount == 0)
3183 QfIn.back().frame_number = 0;
3184 else
3185 QfIn.back().frame_number = (QfIn.end() - 2)->frame_number + 1;
3186
3187 if (!firstFrame)
3188 sceneNum += isSceneChange;
3189
3190 QfIn.back().isSceneChange = (firstFrame || isSceneChange);
3191 QfIn.back().isIntra = isIntraFrame;
3192
3193 if (isSceneChange || isIntraFrame || bufferCount == 0)
3194 countFrames = 0;
3195 else
3196 countFrames++;
3197 QfIn.back().frame_relative_position = countFrames;
3198 QfIn.back().frame_added = false;
3199 QfIn.back().scene_idx = sceneNum;
3200 if((QfIn.back().isSceneChange || QfIn.back().isIntra) && doIntraFiltering)
3201 m_doFilterFrame = true;
3202 }
3203
BufferFilterAssignment(mfxU16 * filterStrength,bool doIntraFiltering,bool isAnchorFrame,bool isSceneChange)3204 void CMC::BufferFilterAssignment(
3205 mfxU16 * filterStrength,
3206 bool doIntraFiltering,
3207 bool isAnchorFrame,
3208 bool isSceneChange)
3209 {
3210 if (!filterStrength)
3211 {
3212 if (isAnchorFrame && isSceneChange)
3213 {
3214 QfIn.back().filterStrength = doIntraFiltering ? MCTFSTRENGTH : MCTFNOFILTER;
3215 #ifdef MFX_MCTF_DEBUG_PRINT
3216 ASC_PRINTF("\nI frame denoising is: %i, strength set at: %i\n", doIntraFiltering, QfIn[bufferCount].filterStrength));
3217 #endif
3218 gopBasedFilterStrength = MCTFADAPTIVE;
3219 }
3220 else if (isAnchorFrame)
3221 QfIn.back().filterStrength = gopBasedFilterStrength;
3222 else
3223 QfIn.back().filterStrength = MCTFNOFILTER;
3224 }
3225 else
3226 QfIn.back().filterStrength = *filterStrength;
3227 }
3228
MCTF_PUT_FRAME(void * frameInData,mfxHDLPair frameOutHandle,CmSurface2D ** frameOutData,bool isCmSurface,mfxU16 * filterStrength,bool needsOutput,bool doIntraFiltering)3229 mfxStatus CMC::MCTF_PUT_FRAME(
3230 void * frameInData,
3231 mfxHDLPair frameOutHandle,
3232 CmSurface2D ** frameOutData,
3233 bool isCmSurface,
3234 mfxU16 * filterStrength,
3235 bool needsOutput,
3236 bool doIntraFiltering
3237 )
3238 {
3239 if (!frameInData)
3240 return MFX_ERR_UNDEFINED_BEHAVIOR;
3241 if (isCmSurface)
3242 {
3243 mfxFrameSurface1 *
3244 mfxFrame = (mfxFrameSurface1 *)frameInData;
3245 mfxHDLPair
3246 handle;
3247 // if a surface is opaque, need to extract normal surface
3248 mfxFrameSurface1
3249 * pSurf = m_pCore->GetNativeSurface(mfxFrame);
3250 QfIn.back().mfxFrame = pSurf ? pSurf : mfxFrame;
3251 if (pSurf)
3252 {
3253 MFX_SAFE_CALL(m_pCore->GetFrameHDL(QfIn.back().mfxFrame->Data.MemId, reinterpret_cast<mfxHDL*>(&handle)));
3254 }
3255 else
3256 {
3257 MFX_SAFE_CALL(m_pCore->GetExternalFrameHDL(QfIn.back().mfxFrame->Data.MemId, reinterpret_cast<mfxHDL*>(&handle)));
3258 }
3259 MFX_SAFE_CALL(IM_SURF_SET(reinterpret_cast<AbstractSurfaceHandle>(handle.first), &QfIn.back().frameData, &QfIn.back().fIdx));
3260 }
3261 else
3262 {
3263 res = IM_SURF_PUT(QfIn.back().frameData, (mfxU8*)frameInData);
3264 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
3265 }
3266 QfIn.back().frame_added = true;
3267 if (needsOutput)
3268 {
3269 SurfaceIndex
3270 *fIdx = nullptr;
3271 MFX_SAFE_CALL(IM_SURF_SET(reinterpret_cast<AbstractSurfaceHandle>(frameOutHandle.first), frameOutData, &fIdx));
3272 QfIn.back().fOut = *frameOutData;
3273 QfIn.back().fIdxOut = fIdx;
3274 }
3275
3276 if (m_doFilterFrame)
3277 BufferFilterAssignment(filterStrength, doIntraFiltering, needsOutput, QfIn.back().isSceneChange);
3278 else
3279 QfIn.back().filterStrength = MCTFNOFILTER;
3280 return MFX_ERR_NONE;
3281 }
3282
MCTF_PUT_FRAME(IntMctfParams * pMctfControl,CmSurface2D * InSurf,CmSurface2D * OutSurf)3283 mfxStatus CMC::MCTF_PUT_FRAME(
3284 IntMctfParams * pMctfControl,
3285 CmSurface2D * InSurf,
3286 CmSurface2D * OutSurf
3287 )
3288 {
3289 lastFrame = 0;
3290 if (!InSurf)
3291 return MFX_ERR_UNDEFINED_BEHAVIOR;
3292 INT cmSts = 0;
3293
3294 SurfaceIndex* idxFrom;
3295 cmSts = InSurf->GetIndex(idxFrom);
3296 MFX_CHECK((CM_SUCCESS == cmSts), MFX_ERR_DEVICE_FAILED);
3297
3298 MFX_SAFE_CALL(pSCD->PutFrameProgressive(idxFrom));
3299
3300 MCTF_PUT_FRAME(
3301 pMctfControl,
3302 OutSurf,
3303 pSCD->Get_frame_shot_Decision()
3304 );
3305 return MFX_ERR_NONE;
3306 }
3307
MCTF_PUT_FRAME(IntMctfParams * pMctfControl,CmSurface2D * OutSurf,mfxU32 schgDesicion)3308 mfxStatus CMC::MCTF_PUT_FRAME(
3309 IntMctfParams * pMctfControl,
3310 CmSurface2D * OutSurf,
3311 mfxU32 schgDesicion
3312 )
3313 {
3314 lastFrame = 0;
3315 sceneNum += schgDesicion;
3316 MFX_SAFE_CALL(MCTF_UpdateRTParams(pMctfControl));
3317 MFX_SAFE_CALL(MCTF_PUT_FRAME(sceneNum, OutSurf));
3318 forward_distance = -1;
3319 backward_distance = 1;
3320 countFrames++;
3321 return MFX_ERR_NONE;
3322 }
3323
MCTF_DO_FILTERING_IN_AVC()3324 mfxStatus CMC::MCTF_DO_FILTERING_IN_AVC()
3325 {
3326 // do filtering based on temporal mode & how many frames are
3327 // already in the queue:
3328 res = MFX_ERR_NONE;
3329 switch (number_of_References)
3330 {
3331 case 2://else if (number_of_References == 2)
3332 {
3333 if (bufferCount < 2) /*One frame delay*/
3334 {
3335 firstFrame = 0;
3336 RotateBuffer();
3337 MctfState = AMCTF_NOT_READY;
3338 return MFX_ERR_NONE;
3339 }
3340
3341 MCTF_UpdateANDApplyRTParams(1);
3342 if (QfIn[1].fOut)
3343 {
3344 mco = QfIn[1].fOut;
3345 idxMco = QfIn[1].fIdxOut;
3346 if (QfIn[1].isSceneChange)
3347 {
3348 if(QfIn[1].filterStrength)
3349 res = MCTF_RUN_AMCTF(1);
3350 RotateBuffer();
3351 }
3352 else
3353 res = (this->*(pMCTF_func))(false);
3354 CurrentIdx2Out = DefaultIdx2Out;
3355 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
3356 QfIn.front().fOut = mco = nullptr;
3357 QfIn.front().fIdxOut = idxMco = nullptr;
3358 }
3359 else
3360 RotateBuffer();
3361 break;
3362 };
3363 break;
3364 default:// else
3365 return MFX_ERR_UNDEFINED_BEHAVIOR;
3366 }
3367 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
3368 return MFX_ERR_NONE;
3369 }
3370
MCTF_QUERY_FILTER_STRENGTH()3371 mfxU16 CMC::MCTF_QUERY_FILTER_STRENGTH()
3372 {
3373 return QfIn[1].filterStrength;
3374 }
3375
MCTF_DO_FILTERING()3376 mfxStatus CMC::MCTF_DO_FILTERING()
3377 {
3378 // do filtering based on temporal mode & how many frames are
3379 // already in the queue:
3380 switch (number_of_References)
3381 {
3382 case 4://if (number_of_References == 4)
3383 {
3384 if (bufferCount < 3)
3385 {
3386 MctfState = AMCTF_NOT_READY;
3387 mco = nullptr;
3388 return MFX_ERR_NONE;
3389 }
3390
3391 switch (firstFrame)
3392 {
3393 case 1:
3394 {
3395 pMCTF_MERGE_func = NULL;
3396 //todo: check is it correct that the current frame is 0?
3397 MCTF_UpdateANDApplyRTParams(0);
3398 pMCTF_ME_func = &CMC::MCTF_RUN_ME_2REF;
3399 pMCTF_LOAD_func = &CMC::MCTF_LOAD_2REF;
3400 RotateBufferA();
3401 res = MCTF_RUN_MCTF_DEN(true);
3402 CurrentIdx2Out = 0;
3403 MctfState = AMCTF_READY;
3404 firstFrame = 2;
3405 break;
3406 }
3407 case 2:
3408 {
3409 //todo: check is it correct that the current frame is 1?
3410 MCTF_UpdateANDApplyRTParams(1);
3411 res = MCTF_RUN_MCTF_DEN(true);
3412 RotateBufferA();
3413 CurrentIdx2Out = 1;
3414 MctfState = AMCTF_READY;
3415 firstFrame = 3;
3416
3417 pMCTF_MERGE_func = &CMC::MCTF_RUN_MERGE;
3418 pMCTF_ME_func = &CMC::MCTF_RUN_ME_4REF;
3419 pMCTF_LOAD_func = &CMC::MCTF_LOAD_4REF;
3420 break;
3421 }
3422
3423 default:
3424 {
3425 MCTF_UpdateANDApplyRTParams(2);
3426 res = (this->*(pMCTF_func))(true);
3427 CurrentIdx2Out = DefaultIdx2Out;
3428 MctfState = AMCTF_READY;
3429 break;
3430 }
3431 }
3432 };
3433 break;
3434 case 2://else if (number_of_References == 2)
3435 {
3436 if (bufferCount < 2) /*One frame delay*/
3437 {
3438 MctfState = AMCTF_NOT_READY;
3439 mco = nullptr;
3440 return MFX_ERR_NONE;
3441 }
3442
3443 switch (firstFrame)
3444 {
3445 case 0:
3446 {
3447 MCTF_UpdateANDApplyRTParams(1);
3448 res = (this->*(pMCTF_func))(true);
3449 CurrentIdx2Out = DefaultIdx2Out;
3450 MctfState = AMCTF_READY;
3451 break;
3452 }
3453 default:
3454 {
3455 MCTF_UpdateANDApplyRTParams(0);
3456 res = MCTF_RUN_AMCTF(0);
3457 firstFrame = 0;
3458 CurrentIdx2Out = 0;
3459 MctfState = AMCTF_READY;
3460 break;
3461 }
3462 }
3463 };
3464 break;
3465 case 1: //else if (number_of_References == 1)
3466 {
3467 if (firstFrame)
3468 {
3469 MCTF_UpdateANDApplyRTParams(0);
3470 res = MCTF_RUN_AMCTF(0);
3471 firstFrame = 0;
3472 MctfState = AMCTF_READY;
3473 }
3474 else
3475 {
3476 MCTF_UpdateANDApplyRTParams(1);
3477 if (QfIn[0].scene_idx != QfIn[1].scene_idx)
3478 {
3479 res = MCTF_RUN_AMCTF();
3480 RotateBuffer();
3481 }
3482 else
3483 res = (this->*(pMCTF_func))(true);
3484 MctfState = AMCTF_READY;
3485 }
3486 CurrentIdx2Out = DefaultIdx2Out;
3487 };
3488 break;
3489 case 0://else if (number_of_References == 0)
3490 {
3491 MCTF_UpdateANDApplyRTParams(0);
3492 res = MCTF_RUN_AMCTF(0);
3493 firstFrame = 0;
3494 MctfState = AMCTF_READY;
3495 CurrentIdx2Out = DefaultIdx2Out;
3496 };
3497 break;
3498 default:// else
3499 return MFX_ERR_UNDEFINED_BEHAVIOR;
3500 }
3501 MCTF_CHECK_CM_ERR(res, MFX_ERR_DEVICE_FAILED);
3502 return MFX_ERR_NONE;
3503 }
3504
MCTF_CLOSE()3505 void CMC::MCTF_CLOSE()
3506 {
3507 if (kernelMe)
3508 device->DestroyKernel(kernelMe);
3509 if (kernelMeB)
3510 device->DestroyKernel(kernelMeB);
3511 if (kernelMeB2)
3512 device->DestroyKernel(kernelMeB2);
3513 if (kernelMcDen)
3514 device->DestroyKernel(kernelMcDen);
3515 if (kernelMc1r)
3516 device->DestroyKernel(kernelMc1r);
3517 if (kernelMc2r)
3518 device->DestroyKernel(kernelMc2r);
3519 if (kernelMc4r)
3520 device->DestroyKernel(kernelMc4r);
3521 if (programMe)
3522 device->DestroyProgram(programMe);
3523 if (programMc)
3524 device->DestroyProgram(programMc);
3525 if (programDe)
3526 device->DestroyProgram(programDe);
3527 if (ctrlBuf)
3528 device->DestroySurface(ctrlBuf);
3529
3530
3531 if (task)
3532 device->DestroyTask(task);
3533 if (e)
3534 queue->DestroyEvent(e);
3535 if (copyEv)
3536 queue->DestroyEvent(copyEv);
3537
3538 if (mco2)
3539 device->DestroySurface(mco2);
3540 if (idxMv_1)
3541 {
3542 device->DestroySurface2DUP(mv_1);
3543 CM_ALIGNED_FREE(mvSys1);
3544 }
3545 if (idxMv_2)
3546 {
3547 device->DestroySurface2DUP(mv_2);
3548 CM_ALIGNED_FREE(mvSys2);
3549 }
3550 if (idxMv_3)
3551 {
3552 device->DestroySurface2DUP(mv_3);
3553 CM_ALIGNED_FREE(mvSys3);
3554 }
3555 if (idxMv_4)
3556 {
3557 device->DestroySurface2DUP(mv_4);
3558 CM_ALIGNED_FREE(mvSys4);
3559 }
3560 if (distSurf)
3561 {
3562 device->DestroySurface2DUP(distSurf);
3563 CM_ALIGNED_FREE(distSys);
3564 }
3565 if (noiseAnalysisSurf)
3566 {
3567 device->DestroySurface2DUP(noiseAnalysisSurf);
3568 CM_ALIGNED_FREE(noiseAnalysisSys);
3569 }
3570
3571 if (pSCD)
3572 {
3573 pSCD->Close();
3574 pSCD = nullptr;
3575 }
3576 }
3577