1 // Copyright (c) 2019-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 <cmath>
22 #include "common_utils.h"
23 #include <algorithm>
24
25 #if defined(_WIN32) || defined(_WIN64)
26 #include <intrin.h>
27 #include <array>
28 #include <vector>
29 #endif
30
31 // =================================================================
32 // Utility functions, not directly tied to Intel Media SDK functionality
33 //
34
PrintErrString(int err,const char * filestr,int line)35 void PrintErrString(int err,const char* filestr,int line)
36 {
37 switch (err) {
38 case 0:
39 printf("\n No error.\n");
40 break;
41 case -1:
42 printf("\n Unknown error: %s %d\n",filestr,line);
43 break;
44 case -2:
45 printf("\n Null pointer. Check filename/path + permissions? %s %d\n",filestr,line);
46 break;
47 case -3:
48 printf("\n Unsupported feature/library load error. %s %d\n",filestr,line);
49 break;
50 case -4:
51 printf("\n Could not allocate memory. %s %d\n",filestr,line);
52 break;
53 case -5:
54 printf("\n Insufficient IO buffers. %s %d\n",filestr,line);
55 break;
56 case -6:
57 printf("\n Invalid handle. %s %d\n",filestr,line);
58 break;
59 case -7:
60 printf("\n Memory lock failure. %s %d\n",filestr,line);
61 break;
62 case -8:
63 printf("\n Function called before initialization. %s %d\n",filestr,line);
64 break;
65 case -9:
66 printf("\n Specified object not found. %s %d\n",filestr,line);
67 break;
68 case -10:
69 printf("\n More input data expected. %s %d\n",filestr,line);
70 break;
71 case -11:
72 printf("\n More output surfaces expected. %s %d\n",filestr,line);
73 break;
74 case -12:
75 printf("\n Operation aborted. %s %d\n",filestr,line);
76 break;
77 case -13:
78 printf("\n HW device lost. %s %d\n",filestr,line);
79 break;
80 case -14:
81 printf("\n Incompatible video parameters. %s %d\n",filestr,line);
82 break;
83 case -15:
84 printf("\n Invalid video parameters. %s %d\n",filestr,line);
85 break;
86 case -16:
87 printf("\n Undefined behavior. %s %d\n",filestr,line);
88 break;
89 case -17:
90 printf("\n Device operation failure. %s %d\n",filestr,line);
91 break;
92 case -18:
93 printf("\n More bitstream data expected. %s %d\n",filestr,line);
94 break;
95 case -19:
96 printf("\n Incompatible audio parameters. %s %d\n",filestr,line);
97 break;
98 case -20:
99 printf("\n Invalid audio parameters. %s %d\n",filestr,line);
100 break;
101 default:
102 printf("\nError code %d,\t%s\t%d\n\n", err, filestr, line);
103 }
104 }
105
OpenFile(const char * fileName,const char * mode)106 FILE* OpenFile(const char* fileName, const char* mode)
107 {
108 FILE* openFile = nullptr;
109 MSDK_FOPEN(openFile, fileName, mode);
110 return openFile;
111 }
112
CloseFile(FILE * fHdl)113 void CloseFile(FILE* fHdl)
114 {
115 if(fHdl)
116 fclose(fHdl);
117 }
118
ReadPlaneData(mfxU16 w,mfxU16 h,mfxU8 * buf,mfxU8 * ptr,mfxU16 pitch,mfxU16 offset,FILE * fSource)119 mfxStatus ReadPlaneData(mfxU16 w, mfxU16 h, mfxU8* buf, mfxU8* ptr,
120 mfxU16 pitch, mfxU16 offset, FILE* fSource)
121 {
122 mfxU32 nBytesRead;
123 for (mfxU16 i = 0; i < h; i++) {
124 nBytesRead = (mfxU32) fread(buf, 1, w, fSource);
125 if (w != nBytesRead)
126 return MFX_ERR_MORE_DATA;
127 for (mfxU16 j = 0; j < w; j++)
128 ptr[i * pitch + j * 2 + offset] = buf[j];
129 }
130 return MFX_ERR_NONE;
131 }
132
LoadRawFrame(mfxFrameSurface1 * pSurface,FILE * fSource)133 mfxStatus LoadRawFrame(mfxFrameSurface1* pSurface, FILE* fSource)
134 {
135 if (!fSource) {
136 // Simulate instantaneous access to 1000 "empty" frames.
137 static int frameCount = 0;
138 if (1000 == frameCount++)
139 return MFX_ERR_MORE_DATA;
140 else
141 return MFX_ERR_NONE;
142 }
143
144 mfxStatus sts = MFX_ERR_NONE;
145 mfxU32 nBytesRead;
146 mfxU16 w, h, i, pitch;
147 mfxU8* ptr;
148 mfxFrameInfo* pInfo = &pSurface->Info;
149 mfxFrameData* pData = &pSurface->Data;
150
151 if (pInfo->CropH > 0 && pInfo->CropW > 0) {
152 w = pInfo->CropW;
153 h = pInfo->CropH;
154 } else {
155 w = pInfo->Width;
156 h = pInfo->Height;
157 }
158
159 pitch = pData->Pitch;
160 ptr = pData->Y + pInfo->CropX + pInfo->CropY * pData->Pitch;
161
162 // read luminance plane
163 for (i = 0; i < h; i++) {
164 nBytesRead = (mfxU32) fread(ptr + i * pitch, 1, w, fSource);
165 if (w != nBytesRead)
166 return MFX_ERR_MORE_DATA;
167 }
168
169 mfxU8 buf[2048]; // maximum supported chroma width for nv12
170 w /= 2;
171 h /= 2;
172 ptr = pData->UV + pInfo->CropX + (pInfo->CropY / 2) * pitch;
173 if (w > 2048)
174 return MFX_ERR_UNSUPPORTED;
175
176 // load V
177 sts = ReadPlaneData(w, h, buf, ptr, pitch, 1, fSource);
178 if (MFX_ERR_NONE != sts)
179 return sts;
180 // load U
181 ReadPlaneData(w, h, buf, ptr, pitch, 0, fSource);
182 if (MFX_ERR_NONE != sts)
183 return sts;
184
185 return MFX_ERR_NONE;
186 }
187
ReadPlaneData10Bit(mfxU16 w,mfxU16 h,mfxU16 * buf,mfxU8 * ptr,mfxU16 pitch,mfxU16 shift,FILE * fSource)188 mfxStatus ReadPlaneData10Bit(mfxU16 w, mfxU16 h, mfxU16* buf, mfxU8* ptr,
189 mfxU16 pitch, mfxU16 shift, FILE* fSource)
190 {
191 mfxU32 nBytesRead;
192 mfxU16* shortPtr;
193
194 for (mfxU16 i = 0; i < h; i++) {
195 nBytesRead = (mfxU32)fread(buf, 2, w, fSource); //Reading in 16bits per pixel.
196 if (w != nBytesRead)
197 return MFX_ERR_MORE_DATA;
198 // Read data with P010 and convert it to MS-P010
199 //Shifting left the data in a 16bits boundary
200 //Because each 10bit pixel channel takes 2 bytes with the LSB on the right side of the 16bits
201 //See this web page for the description of MS-P010 format
202 //https://msdn.microsoft.com/en-us/library/windows/desktop/bb970578(v=vs.85).aspx#overview
203 if (shift > 0) {
204 shortPtr = (mfxU16 *)(ptr + i * pitch);
205 for (mfxU16 j = 0; j < w; j++)
206 shortPtr[j] = buf[j] << 6;
207 }
208 }
209 return MFX_ERR_NONE;
210 }
211
LoadRaw10BitFrame(mfxFrameSurface1 * pSurface,FILE * fSource)212 mfxStatus LoadRaw10BitFrame(mfxFrameSurface1* pSurface, FILE* fSource)
213 {
214 if (!fSource) {
215 // Simulate instantaneous access to 1000 "empty" frames.
216 static int frameCount = 0;
217 if (1000 == frameCount++)
218 return MFX_ERR_MORE_DATA;
219 else
220 return MFX_ERR_NONE;
221 }
222
223 mfxStatus sts = MFX_ERR_NONE;
224 mfxU16 w, h,pitch;
225 mfxU8* ptr;
226 mfxFrameInfo* pInfo = &pSurface->Info;
227 mfxFrameData* pData = &pSurface->Data;
228
229 if (pInfo->CropH > 0 && pInfo->CropW > 0) {
230 w = pInfo->CropW;
231 h = pInfo->CropH;
232 }
233 else {
234 w = pInfo->Width;
235 h = pInfo->Height;
236 }
237
238 pitch = pData->Pitch;
239 mfxU16 buf[4096]; // maximum supported chroma width for nv12
240
241 // read luminance plane
242 ptr = pData->Y + pInfo->CropX + pInfo->CropY * pData->Pitch;
243 sts = ReadPlaneData10Bit(w, h, buf, ptr, pitch, pInfo->Shift, fSource);
244 if (MFX_ERR_NONE != sts)
245 return sts;
246
247 // Load UV plan
248 h /= 2;
249 ptr = pData->UV + pInfo->CropX + (pInfo->CropY / 2) * pitch;
250
251 // load U
252 sts = ReadPlaneData10Bit(w, h, buf, ptr, pitch, pInfo->Shift, fSource);
253 if (MFX_ERR_NONE != sts)
254 return sts;
255
256 return MFX_ERR_NONE;
257 }
258
LoadRawRGBFrame(mfxFrameSurface1 * pSurface,FILE * fSource)259 mfxStatus LoadRawRGBFrame(mfxFrameSurface1* pSurface, FILE* fSource)
260 {
261 if (!fSource) {
262 // Simulate instantaneous access to 1000 "empty" frames.
263 static int frameCount = 0;
264 if (1000 == frameCount++)
265 return MFX_ERR_MORE_DATA;
266 else
267 return MFX_ERR_NONE;
268 }
269
270 mfxU32 nBytesRead;
271 mfxU16 w, h;
272 mfxFrameInfo* pInfo = &pSurface->Info;
273
274 if (pInfo->CropH > 0 && pInfo->CropW > 0) {
275 w = pInfo->CropW;
276 h = pInfo->CropH;
277 } else {
278 w = pInfo->Width;
279 h = pInfo->Height;
280 }
281
282 for (mfxU16 i = 0; i < h; i++) {
283 nBytesRead = (mfxU32)fread(pSurface->Data.B + i * pSurface->Data.Pitch,
284 1, w * 4, fSource);
285 if ((mfxU32)(w * 4) != nBytesRead)
286 return MFX_ERR_MORE_DATA;
287 }
288
289 return MFX_ERR_NONE;
290 }
291
WriteBitStreamFrame(mfxBitstream * pMfxBitstream,FILE * fSink)292 mfxStatus WriteBitStreamFrame(mfxBitstream* pMfxBitstream, FILE* fSink)
293 {
294 if (!pMfxBitstream)
295 return MFX_ERR_NULL_PTR;
296
297 if (fSink) {
298 mfxU32 nBytesWritten =
299 (mfxU32) fwrite(pMfxBitstream->Data + pMfxBitstream->DataOffset, 1,
300 pMfxBitstream->DataLength, fSink);
301
302 if (nBytesWritten != pMfxBitstream->DataLength)
303 return MFX_ERR_UNDEFINED_BEHAVIOR;
304 }
305
306 pMfxBitstream->DataLength = 0;
307
308 return MFX_ERR_NONE;
309 }
310
ReadBitStreamData(mfxBitstream * pBS,FILE * fSource)311 mfxStatus ReadBitStreamData(mfxBitstream* pBS, FILE* fSource)
312 {
313 memmove(pBS->Data, pBS->Data + pBS->DataOffset, pBS->DataLength);
314 pBS->DataOffset = 0;
315
316 mfxU32 nBytesRead = (mfxU32) fread(pBS->Data + pBS->DataLength, 1,
317 pBS->MaxLength - pBS->DataLength,
318 fSource);
319
320 if (0 == nBytesRead)
321 return MFX_ERR_MORE_DATA;
322
323 pBS->DataLength += nBytesRead;
324
325 return MFX_ERR_NONE;
326 }
327
WriteSection(mfxU8 * plane,mfxU16 factor,mfxU16 chunksize,mfxFrameInfo * pInfo,mfxFrameData * pData,mfxU32 i,mfxU32 j,FILE * fSink)328 mfxStatus WriteSection(mfxU8* plane, mfxU16 factor, mfxU16 chunksize,
329 mfxFrameInfo* pInfo, mfxFrameData* pData, mfxU32 i,
330 mfxU32 j, FILE* fSink)
331 {
332 if (chunksize !=
333 fwrite(plane +
334 (pInfo->CropY * pData->Pitch / factor + pInfo->CropX) +
335 i * pData->Pitch + j, 1, chunksize, fSink))
336 return MFX_ERR_UNDEFINED_BEHAVIOR;
337 return MFX_ERR_NONE;
338 }
339
WriteRawFrame(mfxFrameSurface1 * pSurface,FILE * fSink)340 mfxStatus WriteRawFrame(mfxFrameSurface1* pSurface, FILE* fSink)
341 {
342 mfxFrameInfo* pInfo = &pSurface->Info;
343 mfxFrameData* pData = &pSurface->Data;
344 mfxU32 nByteWrite;
345 mfxU16 i, j, h, w, pitch;
346 mfxU8* ptr;
347 mfxStatus sts = MFX_ERR_NONE;
348
349 if (pInfo->CropH > 0 && pInfo->CropW > 0)
350 {
351 w = pInfo->CropW;
352 h = pInfo->CropH;
353 }
354 else
355 {
356 w = pInfo->Width;
357 h = pInfo->Height;
358 }
359
360 if (pInfo->FourCC == MFX_FOURCC_RGB4 || pInfo->FourCC == MFX_FOURCC_A2RGB10)
361 {
362 pitch = pData->Pitch;
363 ptr = std::min(std::min(pData->R, pData->G), pData->B);
364
365 for (i = 0; i < h; i++)
366 {
367 nByteWrite = (mfxU32)fwrite(ptr + i * pitch, 1, w * 4, fSink);
368 if ((mfxU32)(w * 4) != nByteWrite)
369 {
370 return MFX_ERR_MORE_DATA;
371 }
372 }
373 }
374 else
375 {
376 for (i = 0; i < pInfo->CropH; i++)
377 sts = WriteSection(pData->Y, 1, pInfo->CropW, pInfo, pData, i, 0, fSink);
378
379 h = pInfo->CropH / 2;
380 w = pInfo->CropW;
381 for (i = 0; i < h; i++)
382 for (j = 0; j < w; j += 2)
383 sts = WriteSection(pData->UV, 2, 1, pInfo, pData, i, j, fSink);
384 for (i = 0; i < h; i++)
385 for (j = 1; j < w; j += 2)
386 sts = WriteSection(pData->UV, 2, 1, pInfo, pData, i, j, fSink);
387 }
388
389 return sts;
390 }
391
WriteSection10Bit(mfxU8 * plane,mfxU16 factor,mfxU16 chunksize,mfxFrameInfo * pInfo,mfxFrameData * pData,mfxU32 i,FILE * fSink)392 mfxStatus WriteSection10Bit(mfxU8* plane, mfxU16 factor, mfxU16 chunksize,
393 mfxFrameInfo* pInfo, mfxFrameData* pData, mfxU32 i,
394 /*mfxU32 j,*/ FILE* fSink)
395 {
396 // Temporary buffer to convert MS-P010 to P010
397 std::vector<mfxU16> tmp;
398 mfxU16* shortPtr;
399
400 shortPtr = (mfxU16*)(plane + (pInfo->CropY * pData->Pitch / factor + pInfo->CropX) + i * pData->Pitch);
401 if (pInfo->Shift)
402 {
403 // Convert MS-P010 to P010 and write
404 tmp.resize(pData->Pitch);
405
406 //Shifting right the data in a 16bits boundary
407 //Because each 10bit pixel channel takes 2 bytes with the LSB on the right side of the 16bits
408 //See this web page for the description of 10bit YUV format
409 //https://msdn.microsoft.com/en-us/library/windows/desktop/bb970578(v=vs.85).aspx#overview
410 for (int idx = 0; idx < pInfo->CropW; idx++)
411 {
412 tmp[idx] = shortPtr[idx] >> 6;
413 }
414 if (chunksize != fwrite(&tmp[0], 1, chunksize, fSink))
415 return MFX_ERR_UNDEFINED_BEHAVIOR;
416 }
417 else {
418 if (chunksize != fwrite(shortPtr, 1, chunksize, fSink))
419 return MFX_ERR_UNDEFINED_BEHAVIOR;
420 }
421
422 return MFX_ERR_NONE;
423 }
424
WriteRaw10BitFrame(mfxFrameSurface1 * pSurface,FILE * fSink)425 mfxStatus WriteRaw10BitFrame(mfxFrameSurface1* pSurface, FILE* fSink)
426 {
427 mfxFrameInfo* pInfo = &pSurface->Info;
428 mfxFrameData* pData = &pSurface->Data;
429 mfxStatus sts = MFX_ERR_NONE;
430
431
432 for (mfxU16 i = 0; i < pInfo->CropH; i++) {
433 sts = WriteSection10Bit(pData->Y, 1, pInfo->CropW * 2, pInfo, pData, i, fSink);
434 }
435
436 for (mfxU16 i = 0; i < pInfo->CropH / 2; i++) {
437 sts = WriteSection10Bit(pData->UV, 2, pInfo->CropW * 2, pInfo, pData, i, fSink);
438 }
439
440 return sts;
441 }
442
GetFreeTaskIndex(Task * pTaskPool,mfxU16 nPoolSize)443 int GetFreeTaskIndex(Task* pTaskPool, mfxU16 nPoolSize)
444 {
445 if (pTaskPool)
446 for (int i = 0; i < nPoolSize; i++)
447 if (!pTaskPool[i].syncp)
448 return i;
449 return MFX_ERR_NOT_FOUND;
450 }
451
ClearYUVSurfaceSysMem(mfxFrameSurface1 * pSfc,mfxU16 width,mfxU16 height)452 void ClearYUVSurfaceSysMem(mfxFrameSurface1* pSfc, mfxU16 width, mfxU16 height)
453 {
454 // In case simulating direct access to frames we initialize the allocated surfaces with default pattern
455 memset(pSfc->Data.Y, 100, width * height); // Y plane
456 memset(pSfc->Data.U, 50, (width * height)/2); // UV plane
457 }
458
459
460 // Get free raw frame surface
GetFreeSurfaceIndex(mfxFrameSurface1 ** pSurfacesPool,mfxU16 nPoolSize)461 int GetFreeSurfaceIndex(mfxFrameSurface1** pSurfacesPool, mfxU16 nPoolSize)
462 {
463 if (pSurfacesPool)
464 for (mfxU16 i = 0; i < nPoolSize; i++)
465 if (0 == pSurfacesPool[i]->Data.Locked)
466 return i;
467 return MFX_ERR_NOT_FOUND;
468 }
469
GetFreeSurfaceIndex(const std::vector<mfxFrameSurface1> & pSurfacesPool)470 int GetFreeSurfaceIndex(const std::vector<mfxFrameSurface1>& pSurfacesPool)
471 {
472 auto it = std::find_if(pSurfacesPool.begin(), pSurfacesPool.end(), [](const mfxFrameSurface1& surface) {
473 return 0 == surface.Data.Locked;
474 });
475
476 if(it == pSurfacesPool.end())
477 return MFX_ERR_NOT_FOUND;
478 else return it - pSurfacesPool.begin();
479 }
480
mfxFrameTypeString(mfxU16 FrameType)481 char mfxFrameTypeString(mfxU16 FrameType)
482 {
483 mfxU8 FrameTmp = FrameType & 0xF;
484 char FrameTypeOut;
485 switch (FrameTmp) {
486 case MFX_FRAMETYPE_I:
487 FrameTypeOut = 'I';
488 break;
489 case MFX_FRAMETYPE_P:
490 FrameTypeOut = 'P';
491 break;
492 case MFX_FRAMETYPE_B:
493 FrameTypeOut = 'B';
494 break;
495 default:
496 FrameTypeOut = '*';
497 }
498 return FrameTypeOut;
499 }
500
501 #if defined(_WIN32) || defined(_WIN64)
502 //This function is modified according to the MSDN example at
503 // https://msdn.microsoft.com/en-us/library/hskdteyh(v=vs.140).aspx#Example
showCPUInfo()504 void showCPUInfo() {
505 int nIds;
506 int nExIds;
507 std::vector<std::array<int, 4>> vendorData;
508 std::vector<std::array<int, 4>> procData;
509 std::array<int, 4> cpui;
510
511 // Calling __cpuid with 0x0 as the function_id argument
512 // gets the number of the highest valid function ID.
513 __cpuid(cpui.data(), 0);
514 nIds = cpui[0];
515
516 for (int i = 0; i <= nIds; ++i)
517 {
518 __cpuidex(cpui.data(), i, 0);
519 vendorData.push_back(cpui);
520 }
521
522 // Capture vendor string
523 char vendor[0x20];
524 memset(vendor, 0, sizeof(vendor));
525 *reinterpret_cast<int*>(vendor) = vendorData[0][1];
526 *reinterpret_cast<int*>(vendor + 4) = vendorData[0][3];
527 *reinterpret_cast<int*>(vendor + 8) = vendorData[0][2];
528
529 // Calling __cpuid with 0x80000000 as the function_id argument
530 // gets the number of the highest valid extended ID.
531 __cpuid(cpui.data(), 0x80000000);
532 nExIds = cpui[0];
533
534 char processor[0x40];
535 memset(processor, 0, sizeof(processor));
536
537 for (int i = 0x80000000; i <= nExIds; ++i)
538 {
539 __cpuidex(cpui.data(), i, 0);
540 procData.push_back(cpui);
541 }
542
543 // Interpret CPU brand string if reported
544 if (nExIds >= 0x80000004)
545 {
546 memcpy(processor, procData[2].data(), sizeof(cpui));
547 memcpy(processor + 16, procData[3].data(), sizeof(cpui));
548 memcpy(processor + 32, procData[4].data(), sizeof(cpui));
549 }
550
551 printf("Vendor: %s\n", vendor);
552 printf("Processor: %s\n", processor);
553 printf("Please check http://ark.intel.com/ for the GPU info\n");
554 }
555 #endif
556
msdkGetPluginUID(mfxIMPL impl,msdkComponentType type,mfxU32 uCodecid)557 const mfxPluginUID & msdkGetPluginUID(mfxIMPL impl, msdkComponentType type, mfxU32 uCodecid)
558 {
559 if (impl == MFX_IMPL_SOFTWARE)
560 {
561 switch (type)
562 {
563 case MSDK_VDECODE:
564 switch (uCodecid)
565 {
566 case MFX_CODEC_HEVC:
567 return MFX_PLUGINID_HEVCD_SW;
568 }
569 break;
570 case MSDK_VENCODE:
571 switch (uCodecid)
572 {
573 case MFX_CODEC_HEVC:
574 return MFX_PLUGINID_HEVCE_SW;
575 }
576 break;
577 }
578 }
579 else if ((impl |= MFX_IMPL_HARDWARE))
580 {
581 switch (type)
582 {
583 case MSDK_VDECODE:
584 switch (uCodecid)
585 {
586 case MFX_CODEC_HEVC:
587 return MFX_PLUGINID_HEVCD_HW; // MFX_PLUGINID_HEVCD_SW for now
588 case MFX_CODEC_VP8:
589 return MFX_PLUGINID_VP8D_HW;
590 }
591 break;
592 case MSDK_VENCODE:
593 switch (uCodecid)
594 {
595 case MFX_CODEC_HEVC:
596 return MFX_PLUGINID_HEVCE_HW;
597 }
598 break;
599 case MSDK_VENC:
600 switch (uCodecid)
601 {
602 case MFX_CODEC_HEVC:
603 return MFX_PLUGINID_HEVCE_FEI_HW; // HEVC FEI uses ENC interface
604 }
605 break;
606 }
607 }
608
609 return MSDK_PLUGINGUID_NULL;
610 }
611
AreGuidsEqual(const mfxPluginUID & guid1,const mfxPluginUID & guid2)612 bool AreGuidsEqual(const mfxPluginUID& guid1, const mfxPluginUID& guid2)
613 {
614 for (size_t i = 0; i != sizeof(mfxPluginUID); i++)
615 {
616 if (guid1.Data[i] != guid2.Data[i])
617 return false;
618 }
619 return true;
620 }
621
ConvertGuidToString(const mfxPluginUID & guid)622 char* ConvertGuidToString(const mfxPluginUID& guid)
623 {
624 static char szGuid[256] = { 0 };
625
626 for (size_t i = 0; i != sizeof(mfxPluginUID); i++)
627 {
628 sprintf(&szGuid[2 * i], "%02x", guid.Data[i]);
629 }
630
631 return szGuid;
632 }
633
ConvertFrameRate(mfxF64 dFrameRate,mfxU32 * pnFrameRateExtN,mfxU32 * pnFrameRateExtD)634 mfxStatus ConvertFrameRate(mfxF64 dFrameRate, mfxU32* pnFrameRateExtN, mfxU32* pnFrameRateExtD)
635 {
636 MSDK_CHECK_POINTER(pnFrameRateExtN, MFX_ERR_NULL_PTR);
637 MSDK_CHECK_POINTER(pnFrameRateExtD, MFX_ERR_NULL_PTR);
638
639 mfxU32 fr;
640
641 fr = (mfxU32)(dFrameRate + .5);
642
643 if (fabs(fr - dFrameRate) < 0.0001)
644 {
645 *pnFrameRateExtN = fr;
646 *pnFrameRateExtD = 1;
647 return MFX_ERR_NONE;
648 }
649
650 fr = (mfxU32)(dFrameRate * 1.001 + .5);
651
652 if (fabs(fr * 1000 - dFrameRate * 1001) < 10)
653 {
654 *pnFrameRateExtN = fr * 1000;
655 *pnFrameRateExtD = 1001;
656 return MFX_ERR_NONE;
657 }
658
659 *pnFrameRateExtN = (mfxU32)(dFrameRate * 10000 + .5);
660 *pnFrameRateExtD = 10000;
661
662 return MFX_ERR_NONE;
663 }
664