b46786b534b9e362aba48e4e01843c18686e6c08
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / sys / msdk / msdk.c
1 /* GStreamer Intel MSDK plugin
2  * Copyright (c) 2016, Oblong Industries, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  *    this list of conditions and the following disclaimer in the documentation
13  *    and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "msdk.h"
33 #include "gstmsdkvideomemory.h"
34 #include "gstmsdksystemmemory.h"
35
36 GST_DEBUG_CATEGORY_EXTERN (gst_msdk_debug);
37 #define GST_CAT_DEFAULT gst_msdk_debug
38
39 #define INVALID_INDEX         ((guint) -1)
40 #define GST_MSDK_ALIGNMENT_PADDING(num,padding) ((padding) - ((num) & ((padding) - 1)))
41
42 struct map
43 {
44   GstVideoFormat format;
45   mfxU16 mfx_chroma_format;
46   mfxU32 mfx_fourcc;
47 };
48
49 #define GST_VIDEO_INFO_TO_MFX_MAP(FORMAT, CHROMA, FOURCC) \
50     { GST_VIDEO_FORMAT_##FORMAT, MFX_CHROMAFORMAT_##CHROMA, MFX_FOURCC_##FOURCC }
51
52 static const struct map gst_msdk_video_format_to_mfx_map[] = {
53   GST_VIDEO_INFO_TO_MFX_MAP (NV12, YUV420, NV12),
54   GST_VIDEO_INFO_TO_MFX_MAP (YV12, YUV420, YV12),
55   GST_VIDEO_INFO_TO_MFX_MAP (I420, YUV420, YV12),
56   GST_VIDEO_INFO_TO_MFX_MAP (P010_10LE, YUV420, P010),
57   GST_VIDEO_INFO_TO_MFX_MAP (YUY2, YUV422, YUY2),
58   GST_VIDEO_INFO_TO_MFX_MAP (UYVY, YUV422, UYVY),
59   GST_VIDEO_INFO_TO_MFX_MAP (BGRA, YUV444, RGB4),
60   GST_VIDEO_INFO_TO_MFX_MAP (BGRx, YUV444, RGB4),
61 #if (MFX_VERSION >= 1028)
62   GST_VIDEO_INFO_TO_MFX_MAP (RGB16, YUV444, RGB565),
63 #endif
64   GST_VIDEO_INFO_TO_MFX_MAP (VUYA, YUV444, AYUV),
65   GST_VIDEO_INFO_TO_MFX_MAP (BGR10A2_LE, YUV444, A2RGB10),
66 #if (MFX_VERSION >= 1027)
67   GST_VIDEO_INFO_TO_MFX_MAP (Y210, YUV422, Y210),
68   GST_VIDEO_INFO_TO_MFX_MAP (Y410, YUV444, Y410),
69 #endif
70 #if (MFX_VERSION >= 1031)
71   /* P016 is used for semi-planar 12 bits format in MSDK */
72   GST_VIDEO_INFO_TO_MFX_MAP (P012_LE, YUV420, P016),
73   /* Y216 is used for 12bit 4:2:2 format in MSDK */
74   GST_VIDEO_INFO_TO_MFX_MAP (Y212_LE, YUV422, Y216),
75   /* Y416 is used for 12bit 4:4:4:4 format in MSDK */
76   GST_VIDEO_INFO_TO_MFX_MAP (Y412_LE, YUV444, Y416),
77 #endif
78 #if (MFX_VERSION >=2004)
79   GST_VIDEO_INFO_TO_MFX_MAP (RGBP, YUV444, RGBP),
80   GST_VIDEO_INFO_TO_MFX_MAP (BGRP, YUV444, BGRP),
81 #endif
82   {0, 0, 0}
83 };
84
85 const gchar *
86 msdk_status_to_string (mfxStatus status)
87 {
88   switch (status) {
89       /* no error */
90     case MFX_ERR_NONE:
91       return "no error";
92       /* reserved for unexpected errors */
93     case MFX_ERR_UNKNOWN:
94       return "unknown error";
95       /* error codes <0 */
96     case MFX_ERR_NULL_PTR:
97       return "null pointer";
98     case MFX_ERR_UNSUPPORTED:
99       return "undeveloped feature";
100     case MFX_ERR_MEMORY_ALLOC:
101       return "failed to allocate memory";
102     case MFX_ERR_NOT_ENOUGH_BUFFER:
103       return "insufficient buffer at input/output";
104     case MFX_ERR_INVALID_HANDLE:
105       return "invalid handle";
106     case MFX_ERR_LOCK_MEMORY:
107       return "failed to lock the memory block";
108     case MFX_ERR_NOT_INITIALIZED:
109       return "member function called before initialization";
110     case MFX_ERR_NOT_FOUND:
111       return "the specified object is not found";
112     case MFX_ERR_MORE_DATA:
113       return "expect more data at input";
114     case MFX_ERR_MORE_SURFACE:
115       return "expect more surface at output";
116     case MFX_ERR_ABORTED:
117       return "operation aborted";
118     case MFX_ERR_DEVICE_LOST:
119       return "lose the HW acceleration device";
120     case MFX_ERR_INCOMPATIBLE_VIDEO_PARAM:
121       return "incompatible video parameters";
122     case MFX_ERR_INVALID_VIDEO_PARAM:
123       return "invalid video parameters";
124     case MFX_ERR_UNDEFINED_BEHAVIOR:
125       return "undefined behavior";
126     case MFX_ERR_DEVICE_FAILED:
127       return "device operation failure";
128     case MFX_ERR_MORE_BITSTREAM:
129       return "expect more bitstream buffers at output";
130 #if (MFX_VERSION < 2000)
131     case MFX_ERR_INCOMPATIBLE_AUDIO_PARAM:
132       return "incompatible audio parameters";
133     case MFX_ERR_INVALID_AUDIO_PARAM:
134       return "invalid audio parameters";
135 #endif
136       /* warnings >0 */
137     case MFX_WRN_IN_EXECUTION:
138       return "the previous asynchronous operation is in execution";
139     case MFX_WRN_DEVICE_BUSY:
140       return "the HW acceleration device is busy";
141     case MFX_WRN_VIDEO_PARAM_CHANGED:
142       return "the video parameters are changed during decoding";
143     case MFX_WRN_PARTIAL_ACCELERATION:
144       return "SW is used";
145     case MFX_WRN_INCOMPATIBLE_VIDEO_PARAM:
146       return "incompatible video parameters";
147     case MFX_WRN_VALUE_NOT_CHANGED:
148       return "the value is saturated based on its valid range";
149     case MFX_WRN_OUT_OF_RANGE:
150       return "the value is out of valid range";
151     case MFX_WRN_FILTER_SKIPPED:
152       return "one of requested filters has been skipped";
153 #if (MFX_VERSION < 2000)
154     case MFX_WRN_INCOMPATIBLE_AUDIO_PARAM:
155       return "incompatible audio parameters";
156 #endif
157     default:
158       break;
159   }
160   return "undefined error";
161 }
162
163 mfxU16
164 msdk_get_platform_codename (mfxSession session)
165 {
166   mfxU16 codename = MFX_PLATFORM_UNKNOWN;
167
168 #if (MFX_VERSION >= 1019)
169   {
170     mfxStatus status;
171     mfxPlatform platform = { 0 };
172     status = MFXVideoCORE_QueryPlatform (session, &platform);
173     if (MFX_ERR_NONE == status)
174       codename = platform.CodeName;
175   }
176 #endif
177
178   return codename;
179 }
180
181 #if (MFX_VERSION >= 2000)
182
183 mfxStatus
184 msdk_init_msdk_session (mfxIMPL impl, mfxVersion * pver,
185     MsdkSession * msdk_session)
186 {
187   mfxStatus sts = MFX_ERR_NONE;
188   mfxLoader loader = NULL;
189   mfxSession session = NULL;
190   uint32_t impl_idx = 0;
191   mfxConfig cfg;
192   mfxVariant impl_value;
193
194   loader = msdk_session->loader;
195
196   if (!loader) {
197     loader = MFXLoad ();
198
199     GST_INFO ("Use the Intel oneVPL SDK to create MFX session");
200
201     if (!loader) {
202       GST_WARNING ("Failed to create a MFX loader");
203       return MFX_ERR_UNKNOWN;
204     }
205
206     /* Create configurations for implementation */
207     cfg = MFXCreateConfig (loader);
208
209     if (!cfg) {
210       GST_ERROR ("Failed to create a MFX configuration");
211       MFXUnload (loader);
212       return MFX_ERR_UNKNOWN;
213     }
214
215     impl_value.Type = MFX_VARIANT_TYPE_U32;
216     impl_value.Data.U32 =
217         (impl ==
218         MFX_IMPL_SOFTWARE) ? MFX_IMPL_TYPE_SOFTWARE : MFX_IMPL_TYPE_HARDWARE;
219     sts =
220         MFXSetConfigFilterProperty (cfg,
221         (const mfxU8 *) "mfxImplDescription.Impl", impl_value);
222
223     if (sts != MFX_ERR_NONE) {
224       GST_ERROR ("Failed to add an additional MFX configuration (%s)",
225           msdk_status_to_string (sts));
226       MFXUnload (loader);
227       return sts;
228     }
229
230     impl_value.Type = MFX_VARIANT_TYPE_U32;
231     impl_value.Data.U32 = pver->Version;
232     sts =
233         MFXSetConfigFilterProperty (cfg,
234         (const mfxU8 *) "mfxImplDescription.ApiVersion.Version", impl_value);
235
236     if (sts != MFX_ERR_NONE) {
237       GST_ERROR ("Failed to add an additional MFX configuration (%s)",
238           msdk_status_to_string (sts));
239       MFXUnload (loader);
240       return sts;
241     }
242   }
243
244   while (1) {
245     /* Enumerate all implementations */
246     mfxImplDescription *impl_desc;
247
248     sts = MFXEnumImplementations (loader, impl_idx,
249         MFX_IMPLCAPS_IMPLDESCSTRUCTURE, (mfxHDL *) & impl_desc);
250
251     /* Failed to find an available implementation */
252     if (sts == MFX_ERR_NOT_FOUND)
253       break;
254     else if (sts != MFX_ERR_NONE) {
255       impl_idx++;
256       continue;
257     }
258
259     sts = MFXCreateSession (loader, impl_idx, &session);
260     MFXDispReleaseImplDescription (loader, impl_desc);
261
262     if (sts == MFX_ERR_NONE)
263       break;
264
265     impl_idx++;
266   }
267
268   if (sts != MFX_ERR_NONE) {
269     GST_ERROR ("Failed to create a MFX session (%s)",
270         msdk_status_to_string (sts));
271
272     if (!msdk_session->loader)
273       MFXUnload (loader);
274
275     return sts;
276   }
277
278   msdk_session->session = session;
279   msdk_session->loader = loader;
280
281   return MFX_ERR_NONE;
282 }
283
284 #else
285
286 mfxStatus
287 msdk_init_msdk_session (mfxIMPL impl, mfxVersion * pver,
288     MsdkSession * msdk_session)
289 {
290   mfxStatus status;
291   mfxSession session = NULL;
292   mfxInitParam init_par = { impl, *pver };
293
294   GST_INFO ("Use the " MFX_API_SDK " to create MFX session");
295
296 #if (MFX_VERSION >= 1025)
297   init_par.GPUCopy = 1;
298 #endif
299
300   status = MFXInitEx (init_par, &session);
301
302   if (status != MFX_ERR_NONE) {
303     GST_WARNING ("Failed to initialize a MFX session (%s)",
304         msdk_status_to_string (status));
305     return status;
306   }
307
308   msdk_session->session = session;
309   msdk_session->loader = NULL;
310
311   return MFX_ERR_NONE;
312 }
313
314 void
315 MFXUnload (mfxLoader loader)
316 {
317   g_assert (loader == NULL);
318 }
319
320 #endif
321
322 void
323 msdk_close_mfx_session (mfxSession session)
324 {
325   mfxStatus status;
326
327   if (!session)
328     return;
329
330   status = MFXClose (session);
331   if (status != MFX_ERR_NONE)
332     GST_ERROR ("Close failed (%s)", msdk_status_to_string (status));
333 }
334
335 void
336 msdk_close_session (MsdkSession * msdk_session)
337 {
338   msdk_close_mfx_session (msdk_session->session);
339   MFXUnload (msdk_session->loader);
340 }
341
342 MsdkSession
343 msdk_open_session (mfxIMPL impl)
344 {
345   mfxSession session = NULL;
346   mfxVersion version = { {1, 1}
347   };
348   mfxIMPL implementation;
349   mfxStatus status;
350   MsdkSession msdk_session;
351
352   static const gchar *implementation_names[] = {
353     "AUTO", "SOFTWARE", "HARDWARE", "AUTO_ANY", "HARDWARE_ANY", "HARDWARE2",
354     "HARDWARE3", "HARDWARE4", "RUNTIME"
355   };
356
357   msdk_session.session = NULL;
358   msdk_session.loader = NULL;
359   status = msdk_init_msdk_session (impl, &version, &msdk_session);
360
361   if (status != MFX_ERR_NONE)
362     return msdk_session;
363   else
364     session = msdk_session.session;
365
366   status = MFXQueryIMPL (session, &implementation);
367   if (status != MFX_ERR_NONE) {
368     GST_ERROR ("Query implementation failed (%s)",
369         msdk_status_to_string (status));
370     goto failed;
371   }
372
373   status = MFXQueryVersion (session, &version);
374   if (status != MFX_ERR_NONE) {
375     GST_ERROR ("Query version failed (%s)", msdk_status_to_string (status));
376     goto failed;
377   }
378
379   GST_INFO ("MFX implementation: 0x%04x (%s)", implementation,
380       implementation_names[MFX_IMPL_BASETYPE (implementation)]);
381   GST_INFO ("MFX version: %d.%d", version.Major, version.Minor);
382
383   return msdk_session;
384
385 failed:
386   msdk_close_session (&msdk_session);
387   msdk_session.session = NULL;
388   msdk_session.loader = NULL;
389   return msdk_session;
390 }
391
392 gboolean
393 msdk_is_available (void)
394 {
395   /* Make sure we can create GstMsdkContext instance (the job type is not used actually) */
396   GstMsdkContext *msdk_context = gst_msdk_context_new (1, GST_MSDK_JOB_DECODER);
397
398   if (!msdk_context) {
399     return FALSE;
400   }
401
402   gst_object_unref (msdk_context);
403   return TRUE;
404 }
405
406 void
407 gst_msdk_set_video_alignment (GstVideoInfo * info, guint alloc_w, guint alloc_h,
408     GstVideoAlignment * alignment)
409 {
410   guint i, width, height;
411   guint stride_align = 127;     /* 128-byte alignment */
412
413   width = GST_VIDEO_INFO_WIDTH (info);
414   height = GST_VIDEO_INFO_HEIGHT (info);
415
416   g_assert (alloc_w == 0 || alloc_w >= width);
417   g_assert (alloc_h == 0 || alloc_h >= height);
418
419   if (alloc_w == 0)
420     alloc_w = width;
421
422   if (alloc_h == 0)
423     alloc_h = height;
424
425   /* PitchAlignment is set to 64 bytes in the media driver for the following formats */
426   if (GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_FORMAT_BGRA ||
427       GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_FORMAT_BGRx ||
428       GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_FORMAT_BGR10A2_LE ||
429       GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_FORMAT_RGB16)
430     stride_align = 63;          /* 64-byte alignment */
431
432   gst_video_alignment_reset (alignment);
433   for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++)
434     alignment->stride_align[i] = stride_align;
435
436   alignment->padding_right = GST_ROUND_UP_16 (alloc_w) - width;
437   alignment->padding_bottom = GST_ROUND_UP_32 (alloc_h) - height;
438 }
439
440 static const struct map *
441 _map_lookup_format (GstVideoFormat format)
442 {
443   const struct map *m = gst_msdk_video_format_to_mfx_map;
444
445   for (; m->format != 0; m++) {
446     if (m->format == format)
447       return m;
448   }
449   return NULL;
450 }
451
452 gint
453 gst_msdk_get_mfx_chroma_from_format (GstVideoFormat format)
454 {
455   const struct map *const m = _map_lookup_format (format);
456
457   return m ? m->mfx_chroma_format : -1;
458 }
459
460 gint
461 gst_msdk_get_mfx_fourcc_from_format (GstVideoFormat format)
462 {
463   const struct map *const m = _map_lookup_format (format);
464
465   return m ? m->mfx_fourcc : -1;
466 }
467
468 void
469 gst_msdk_set_mfx_frame_info_from_video_info (mfxFrameInfo * mfx_info,
470     GstVideoInfo * info)
471 {
472   g_return_if_fail (info && mfx_info);
473
474   /* Use the first component in info to calculate mfx width / height */
475   mfx_info->Width =
476       GST_ROUND_UP_16 (GST_VIDEO_INFO_COMP_STRIDE (info,
477           0) / GST_VIDEO_INFO_COMP_PSTRIDE (info, 0));
478
479   if (GST_VIDEO_INFO_N_PLANES (info) > 1)
480     mfx_info->Height =
481         GST_ROUND_UP_32 (GST_VIDEO_INFO_COMP_OFFSET (info,
482             1) / GST_VIDEO_INFO_COMP_STRIDE (info, 0));
483   else
484     mfx_info->Height =
485         GST_ROUND_UP_32 (GST_VIDEO_INFO_SIZE (info) /
486         GST_VIDEO_INFO_COMP_STRIDE (info, 0));
487
488   mfx_info->CropW = GST_VIDEO_INFO_WIDTH (info);
489   mfx_info->CropH = GST_VIDEO_INFO_HEIGHT (info);
490   mfx_info->FrameRateExtN = GST_VIDEO_INFO_FPS_N (info);
491   mfx_info->FrameRateExtD = GST_VIDEO_INFO_FPS_D (info);
492   mfx_info->AspectRatioW = GST_VIDEO_INFO_PAR_N (info);
493   mfx_info->AspectRatioH = GST_VIDEO_INFO_PAR_D (info);
494   mfx_info->PicStruct =
495       !GST_VIDEO_INFO_IS_INTERLACED (info) ? MFX_PICSTRUCT_PROGRESSIVE :
496       MFX_PICSTRUCT_UNKNOWN;
497   mfx_info->FourCC =
498       gst_msdk_get_mfx_fourcc_from_format (GST_VIDEO_INFO_FORMAT (info));
499   mfx_info->ChromaFormat =
500       gst_msdk_get_mfx_chroma_from_format (GST_VIDEO_INFO_FORMAT (info));
501
502   switch (mfx_info->FourCC) {
503     case MFX_FOURCC_P010:
504 #if (MFX_VERSION >= 1027)
505     case MFX_FOURCC_Y210:
506 #endif
507       mfx_info->BitDepthLuma = 10;
508       mfx_info->BitDepthChroma = 10;
509       mfx_info->Shift = 1;
510
511       break;
512
513 #if (MFX_VERSION >= 1027)
514     case MFX_FOURCC_Y410:
515       mfx_info->BitDepthLuma = 10;
516       mfx_info->BitDepthChroma = 10;
517       mfx_info->Shift = 0;
518
519       break;
520 #endif
521
522 #if (MFX_VERSION >= 1031)
523     case MFX_FOURCC_P016:
524     case MFX_FOURCC_Y216:
525     case MFX_FOURCC_Y416:
526       mfx_info->BitDepthLuma = 12;
527       mfx_info->BitDepthChroma = 12;
528       mfx_info->Shift = 1;
529
530       break;
531 #endif
532
533     default:
534       break;
535   }
536
537   return;
538 }
539
540 gboolean
541 gst_msdk_is_msdk_buffer (GstBuffer * buf)
542 {
543   GstAllocator *allocator;
544   GstMemory *mem = gst_buffer_peek_memory (buf, 0);
545
546   allocator = GST_MEMORY_CAST (mem)->allocator;
547
548   if (allocator && (GST_IS_MSDK_VIDEO_ALLOCATOR (allocator) ||
549           GST_IS_MSDK_SYSTEM_ALLOCATOR (allocator) ||
550           GST_IS_MSDK_DMABUF_ALLOCATOR (allocator)))
551     return TRUE;
552   else
553     return FALSE;
554 }
555
556 mfxFrameSurface1 *
557 gst_msdk_get_surface_from_buffer (GstBuffer * buf)
558 {
559   GstAllocator *allocator;
560   GstMemory *mem = gst_buffer_peek_memory (buf, 0);
561
562   allocator = GST_MEMORY_CAST (mem)->allocator;
563
564   if (GST_IS_MSDK_VIDEO_ALLOCATOR (allocator))
565     return GST_MSDK_VIDEO_MEMORY_CAST (mem)->surface;
566   else if (GST_IS_MSDK_SYSTEM_ALLOCATOR (allocator))
567     return GST_MSDK_SYSTEM_MEMORY_CAST (mem)->surface;
568   else if (GST_IS_MSDK_DMABUF_ALLOCATOR (allocator)) {
569     return gst_mini_object_get_qdata (GST_MINI_OBJECT (mem),
570         g_quark_from_static_string ("GstMsdkBufferSurface"));
571   }
572
573   return NULL;
574 }
575
576 GstVideoFormat
577 gst_msdk_get_video_format_from_mfx_fourcc (mfxU32 fourcc)
578 {
579   const struct map *m = gst_msdk_video_format_to_mfx_map;
580
581   for (; m->mfx_fourcc != 0; m++) {
582     if (m->mfx_fourcc == fourcc)
583       return m->format;
584   }
585
586   return GST_VIDEO_FORMAT_UNKNOWN;
587 }
588
589 void
590 gst_msdk_update_mfx_frame_info_from_mfx_video_param (mfxFrameInfo * mfx_info,
591     mfxVideoParam * param)
592 {
593   mfx_info->BitDepthLuma = param->mfx.FrameInfo.BitDepthLuma;
594   mfx_info->BitDepthChroma = param->mfx.FrameInfo.BitDepthChroma;
595   mfx_info->Shift = param->mfx.FrameInfo.Shift;
596 }
597
598 void
599 gst_msdk_get_mfx_video_orientation_from_video_direction (guint value,
600     guint * mfx_mirror, guint * mfx_rotation)
601 {
602   *mfx_mirror = MFX_MIRRORING_DISABLED;
603   *mfx_rotation = MFX_ANGLE_0;
604
605   switch (value) {
606     case GST_VIDEO_ORIENTATION_IDENTITY:
607       *mfx_mirror = MFX_MIRRORING_DISABLED;
608       *mfx_rotation = MFX_ANGLE_0;
609       break;
610     case GST_VIDEO_ORIENTATION_HORIZ:
611       *mfx_mirror = MFX_MIRRORING_HORIZONTAL;
612       *mfx_rotation = MFX_ANGLE_0;
613       break;
614     case GST_VIDEO_ORIENTATION_VERT:
615       *mfx_mirror = MFX_MIRRORING_VERTICAL;
616       *mfx_rotation = MFX_ANGLE_0;
617       break;
618     case GST_VIDEO_ORIENTATION_90R:
619       *mfx_mirror = MFX_MIRRORING_DISABLED;
620       *mfx_rotation = MFX_ANGLE_90;
621       break;
622     case GST_VIDEO_ORIENTATION_180:
623       *mfx_mirror = MFX_MIRRORING_DISABLED;
624       *mfx_rotation = MFX_ANGLE_180;
625       break;
626     case GST_VIDEO_ORIENTATION_90L:
627       *mfx_mirror = MFX_MIRRORING_DISABLED;
628       *mfx_rotation = MFX_ANGLE_270;
629       break;
630     case GST_VIDEO_ORIENTATION_UL_LR:
631       *mfx_mirror = MFX_MIRRORING_HORIZONTAL;
632       *mfx_rotation = MFX_ANGLE_90;
633       break;
634     case GST_VIDEO_ORIENTATION_UR_LL:
635       *mfx_mirror = MFX_MIRRORING_VERTICAL;
636       *mfx_rotation = MFX_ANGLE_90;
637       break;
638     default:
639       break;
640   }
641 }
642
643 gboolean
644 gst_msdk_load_plugin (mfxSession session, const mfxPluginUID * uid,
645     mfxU32 version, const gchar * plugin)
646 {
647 #if (MFX_VERSION < 2000)
648   mfxStatus status;
649
650   status = MFXVideoUSER_Load (session, uid, version);
651
652   if (status == MFX_ERR_UNDEFINED_BEHAVIOR) {
653     GST_WARNING ("Media SDK Plugin for %s has been loaded", plugin);
654   } else if (status < MFX_ERR_NONE) {
655     GST_ERROR ("Media SDK Plugin for %s load failed (%s)", plugin,
656         msdk_status_to_string (status));
657     return FALSE;
658   } else if (status > MFX_ERR_NONE) {
659     GST_WARNING ("Media SDK Plugin for %s load warning: %s", plugin,
660         msdk_status_to_string (status));
661   }
662 #endif
663
664   return TRUE;
665 }