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