mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
msdk: Initial windows build support
https://bugzilla.gnome.org/show_bug.cgi?id=770990
This commit is contained in:
parent
8949c12aaf
commit
71df82db63
7 changed files with 357 additions and 232 deletions
|
@ -33,6 +33,7 @@ libgstmsdk_la_LIBADD = \
|
|||
|
||||
if USE_MSDK_LIBVA
|
||||
libgstmsdk_la_SOURCES += \
|
||||
msdk.c \
|
||||
msdk_libva.c
|
||||
libgstmsdk_la_CFLAGS += \
|
||||
$(LIBVA_DRM_CFLAGS)
|
||||
|
|
|
@ -38,11 +38,31 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gstmsdkenc.h"
|
||||
|
||||
static inline void *
|
||||
_aligned_alloc (size_t alignment, size_t size)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return _aligned_malloc (size, alignment);
|
||||
#else
|
||||
void *out;
|
||||
if (posix_memalign (&out, alignment, size) != 0)
|
||||
out = NULL;
|
||||
return out;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#define _aligned_free free
|
||||
#endif
|
||||
|
||||
static void gst_msdkenc_close_encoder (GstMsdkEnc * thiz);
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (gst_msdkenc_debug);
|
||||
|
@ -231,8 +251,8 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
|||
gsize size = Y_size + (Y_size >> 1);
|
||||
for (i = 0; i < thiz->num_surfaces; i++) {
|
||||
mfxFrameSurface1 *surface = &thiz->surfaces[i];
|
||||
mfxU8 *data;
|
||||
if (posix_memalign ((void **) &data, 32, size) != 0) {
|
||||
mfxU8 *data = _aligned_alloc (32, size);
|
||||
if (!data) {
|
||||
GST_ERROR_OBJECT (thiz, "Memory allocation failed");
|
||||
goto failed;
|
||||
}
|
||||
|
@ -272,8 +292,9 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
|||
thiz->num_tasks = thiz->param.AsyncDepth;
|
||||
thiz->tasks = g_new0 (MsdkEncTask, thiz->num_tasks);
|
||||
for (i = 0; i < thiz->num_tasks; i++) {
|
||||
if (posix_memalign ((void **) &thiz->tasks[i].output_bitstream.Data, 32,
|
||||
thiz->param.mfx.BufferSizeInKB * 1024) != 0) {
|
||||
thiz->tasks[i].output_bitstream.Data = _aligned_alloc (32,
|
||||
thiz->param.mfx.BufferSizeInKB * 1024);
|
||||
if (!thiz->tasks[i].output_bitstream.Data) {
|
||||
GST_ERROR_OBJECT (thiz, "Memory allocation failed");
|
||||
goto failed;
|
||||
}
|
||||
|
@ -316,7 +337,7 @@ gst_msdkenc_close_encoder (GstMsdkEnc * thiz)
|
|||
for (i = 0; i < thiz->num_tasks; i++) {
|
||||
MsdkEncTask *task = &thiz->tasks[i];
|
||||
if (task->output_bitstream.Data) {
|
||||
free (task->output_bitstream.Data);
|
||||
_aligned_free (task->output_bitstream.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -326,7 +347,7 @@ gst_msdkenc_close_encoder (GstMsdkEnc * thiz)
|
|||
for (i = 0; i < thiz->num_surfaces; i++) {
|
||||
mfxFrameSurface1 *surface = &thiz->surfaces[i];
|
||||
if (surface->Data.MemId)
|
||||
free (surface->Data.MemId);
|
||||
_aligned_free (surface->Data.MemId);
|
||||
}
|
||||
g_free (thiz->surfaces);
|
||||
thiz->surfaces = NULL;
|
||||
|
|
|
@ -5,21 +5,35 @@ msdk_sources = [
|
|||
'gstmsdkh265enc.c',
|
||||
'gstmsdkmpeg2enc.c',
|
||||
'gstmsdkvp8enc.c',
|
||||
'msdk_libva.c',
|
||||
'msdk.c',
|
||||
]
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
msdk_sources += 'msdk_d3d.c'
|
||||
else
|
||||
msdk_sources += 'msdk_libva.c'
|
||||
endif
|
||||
|
||||
python3 = find_program('python3')
|
||||
msdk_root = run_command(python3, '-c', 'import os; print(os.environ.get("INTELMEDIASDKROOT", os.environ.get("MFX_HOME", "")))').stdout().strip()
|
||||
|
||||
if msdk_root != ''
|
||||
msdk_libdir = msdk_root + '/lib/lin_x64'
|
||||
msdk_libdir = [msdk_root + '/lib/lin_x64', msdk_root + '/lib/x64']
|
||||
msdk_incdir = include_directories(msdk_root + '/include')
|
||||
msdk_lib = cc.find_library('mfx', dirs: msdk_libdir, required: false)
|
||||
libva_dep = dependency('libva-drm', required: false)
|
||||
libdl_dep = cc.find_library('dl', required: false)
|
||||
msdk_dep = declare_dependency(include_directories: msdk_incdir, dependencies: [msdk_lib, libva_dep, libdl_dep])
|
||||
if host_machine.system() == 'windows'
|
||||
legacy_stdio_dep = cc.find_library('legacy_stdio_definitions', required: false)
|
||||
d3d11_dep = cc.find_library('d3d11', required: false)
|
||||
msdk_dep = declare_dependency(include_directories: msdk_incdir, dependencies: [msdk_lib, d3d11_dep, legacy_stdio_dep])
|
||||
msdk_dep_found = msdk_lib.found() and d3d11_dep.found() and legacy_stdio_dep.found() and cc.get_id() == 'msvc'
|
||||
else
|
||||
libva_dep = dependency('libva-drm', required: false)
|
||||
libdl_dep = cc.find_library('dl', required: false)
|
||||
msdk_dep = declare_dependency(include_directories: msdk_incdir, dependencies: [msdk_lib, libva_dep, libdl_dep])
|
||||
msdk_dep_found = msdk_lib.found() and libva_dep.found() and libdl_dep.found()
|
||||
endif
|
||||
|
||||
if msdk_lib.found() and libva_dep.found() and libdl_dep.found()
|
||||
if msdk_dep_found
|
||||
gstmsdktag = library('gstmsdk',
|
||||
msdk_sources,
|
||||
c_args : gst_plugins_bad_args,
|
||||
|
|
255
sys/msdk/msdk.c
Normal file
255
sys/msdk/msdk.c
Normal file
|
@ -0,0 +1,255 @@
|
|||
/* GStreamer Intel MSDK plugin
|
||||
* Copyright (c) 2016, Oblong Industries, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "msdk.h"
|
||||
|
||||
GST_DEBUG_CATEGORY_EXTERN (gst_msdkenc_debug);
|
||||
#define GST_CAT_DEFAULT gst_msdkenc_debug
|
||||
|
||||
#define INVALID_INDEX ((guint) -1)
|
||||
|
||||
static inline guint
|
||||
msdk_get_free_surface_index (mfxFrameSurface1 * surfaces, guint size)
|
||||
{
|
||||
if (surfaces) {
|
||||
for (guint i = 0; i < size; i++) {
|
||||
if (!surfaces[i].Data.Locked)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
mfxFrameSurface1 *
|
||||
msdk_get_free_surface (mfxFrameSurface1 * surfaces, guint size)
|
||||
{
|
||||
guint idx = INVALID_INDEX;
|
||||
|
||||
/* Poll the pool for a maximum of 20 milisecnds */
|
||||
for (guint i = 0; i < 2000; i++) {
|
||||
idx = msdk_get_free_surface_index (surfaces, size);
|
||||
|
||||
if (idx != INVALID_INDEX)
|
||||
break;
|
||||
|
||||
g_usleep (10);
|
||||
}
|
||||
|
||||
return (idx == INVALID_INDEX ? NULL : &surfaces[idx]);
|
||||
}
|
||||
|
||||
/* FIXME: Only NV12 is supported by now, add other YUV formats */
|
||||
void
|
||||
msdk_frame_to_surface (GstVideoFrame * frame, mfxFrameSurface1 * surface)
|
||||
{
|
||||
guint8 *src, *dst;
|
||||
guint sstride, dstride;
|
||||
guint width, height;
|
||||
|
||||
if (!surface->Data.MemId) {
|
||||
surface->Data.Y = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
|
||||
surface->Data.UV = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
|
||||
surface->Data.Pitch = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Y Plane */
|
||||
width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0);
|
||||
height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0);
|
||||
src = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
|
||||
sstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
|
||||
dst = surface->Data.Y;
|
||||
dstride = surface->Data.Pitch;
|
||||
|
||||
for (guint i = 0; i < height; i++) {
|
||||
memcpy (dst, src, width);
|
||||
src += sstride;
|
||||
dst += dstride;
|
||||
}
|
||||
|
||||
/* UV Plane */
|
||||
height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 1);
|
||||
src = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
|
||||
sstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
|
||||
dst = surface->Data.UV;
|
||||
|
||||
for (guint i = 0; i < height; i++) {
|
||||
memcpy (dst, src, width);
|
||||
src += sstride;
|
||||
dst += dstride;
|
||||
}
|
||||
}
|
||||
|
||||
const gchar *
|
||||
msdk_status_to_string (mfxStatus status)
|
||||
{
|
||||
switch (status) {
|
||||
/* no error */
|
||||
case MFX_ERR_NONE:
|
||||
return "no error";
|
||||
/* reserved for unexpected errors */
|
||||
case MFX_ERR_UNKNOWN:
|
||||
return "unknown error";
|
||||
/* error codes <0 */
|
||||
case MFX_ERR_NULL_PTR:
|
||||
return "null pointer";
|
||||
case MFX_ERR_UNSUPPORTED:
|
||||
return "undeveloped feature";
|
||||
case MFX_ERR_MEMORY_ALLOC:
|
||||
return "failed to allocate memory";
|
||||
case MFX_ERR_NOT_ENOUGH_BUFFER:
|
||||
return "insufficient buffer at input/output";
|
||||
case MFX_ERR_INVALID_HANDLE:
|
||||
return "invalid handle";
|
||||
case MFX_ERR_LOCK_MEMORY:
|
||||
return "failed to lock the memory block";
|
||||
case MFX_ERR_NOT_INITIALIZED:
|
||||
return "member function called before initialization";
|
||||
case MFX_ERR_NOT_FOUND:
|
||||
return "the specified object is not found";
|
||||
case MFX_ERR_MORE_DATA:
|
||||
return "expect more data at input";
|
||||
case MFX_ERR_MORE_SURFACE:
|
||||
return "expect more surface at output";
|
||||
case MFX_ERR_ABORTED:
|
||||
return "operation aborted";
|
||||
case MFX_ERR_DEVICE_LOST:
|
||||
return "lose the HW acceleration device";
|
||||
case MFX_ERR_INCOMPATIBLE_VIDEO_PARAM:
|
||||
return "incompatible video parameters";
|
||||
case MFX_ERR_INVALID_VIDEO_PARAM:
|
||||
return "invalid video parameters";
|
||||
case MFX_ERR_UNDEFINED_BEHAVIOR:
|
||||
return "undefined behavior";
|
||||
case MFX_ERR_DEVICE_FAILED:
|
||||
return "device operation failure";
|
||||
case MFX_ERR_MORE_BITSTREAM:
|
||||
return "expect more bitstream buffers at output";
|
||||
case MFX_ERR_INCOMPATIBLE_AUDIO_PARAM:
|
||||
return "incompatible audio parameters";
|
||||
case MFX_ERR_INVALID_AUDIO_PARAM:
|
||||
return "invalid audio parameters";
|
||||
/* warnings >0 */
|
||||
case MFX_WRN_IN_EXECUTION:
|
||||
return "the previous asynchronous operation is in execution";
|
||||
case MFX_WRN_DEVICE_BUSY:
|
||||
return "the HW acceleration device is busy";
|
||||
case MFX_WRN_VIDEO_PARAM_CHANGED:
|
||||
return "the video parameters are changed during decoding";
|
||||
case MFX_WRN_PARTIAL_ACCELERATION:
|
||||
return "SW is used";
|
||||
case MFX_WRN_INCOMPATIBLE_VIDEO_PARAM:
|
||||
return "incompatible video parameters";
|
||||
case MFX_WRN_VALUE_NOT_CHANGED:
|
||||
return "the value is saturated based on its valid range";
|
||||
case MFX_WRN_OUT_OF_RANGE:
|
||||
return "the value is out of valid range";
|
||||
case MFX_WRN_FILTER_SKIPPED:
|
||||
return "one of requested filters has been skipped";
|
||||
case MFX_WRN_INCOMPATIBLE_AUDIO_PARAM:
|
||||
return "incompatible audio parameters";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "undefiend error";
|
||||
}
|
||||
|
||||
void
|
||||
msdk_close_session (mfxSession session)
|
||||
{
|
||||
mfxStatus status;
|
||||
|
||||
if (!session)
|
||||
return;
|
||||
|
||||
status = MFXClose (session);
|
||||
if (status != MFX_ERR_NONE)
|
||||
GST_ERROR ("Close failed (%s)", msdk_status_to_string (status));
|
||||
}
|
||||
|
||||
mfxSession
|
||||
msdk_open_session (gboolean hardware)
|
||||
{
|
||||
mfxSession session = NULL;
|
||||
mfxVersion version = { {1, 1}
|
||||
};
|
||||
mfxIMPL implementation;
|
||||
mfxStatus status;
|
||||
|
||||
static const gchar *implementation_names[] = {
|
||||
"AUTO", "SOFTWARE", "HARDWARE", "AUTO_ANY", "HARDWARE_ANY", "HARDWARE2",
|
||||
"HARDWARE3", "HARDWARE4", "RUNTIME"
|
||||
};
|
||||
|
||||
status = MFXInit (hardware ? MFX_IMPL_HARDWARE_ANY : MFX_IMPL_SOFTWARE,
|
||||
&version, &session);
|
||||
if (status != MFX_ERR_NONE) {
|
||||
GST_ERROR ("Intel Media SDK not available (%s)",
|
||||
msdk_status_to_string (status));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
MFXQueryIMPL (session, &implementation);
|
||||
if (status != MFX_ERR_NONE) {
|
||||
GST_ERROR ("Query implementation failed (%s)",
|
||||
msdk_status_to_string (status));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
MFXQueryVersion (session, &version);
|
||||
if (status != MFX_ERR_NONE) {
|
||||
GST_ERROR ("Query version failed (%s)", msdk_status_to_string (status));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
GST_INFO ("MSDK implementation: 0x%04x (%s)", implementation,
|
||||
implementation_names[MFX_IMPL_BASETYPE (implementation)]);
|
||||
GST_INFO ("MSDK version: %d.%d", version.Major, version.Minor);
|
||||
|
||||
return session;
|
||||
|
||||
failed:
|
||||
msdk_close_session (session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
msdk_is_available (void)
|
||||
{
|
||||
mfxSession session = msdk_open_session (FALSE);
|
||||
if (!session) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
msdk_close_session (session);
|
||||
return TRUE;
|
||||
}
|
|
@ -33,7 +33,6 @@
|
|||
#define __MSDK_H__
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/video/video.h>
|
||||
|
@ -43,6 +42,9 @@ G_BEGIN_DECLS
|
|||
|
||||
typedef struct _MsdkContext MsdkContext;
|
||||
|
||||
mfxSession msdk_open_session (gboolean hardware);
|
||||
void msdk_close_session (mfxSession session);
|
||||
|
||||
gboolean msdk_is_available (void);
|
||||
|
||||
MsdkContext *msdk_open_context (gboolean hardware);
|
||||
|
|
50
sys/msdk/msdk_d3d.c
Normal file
50
sys/msdk/msdk_d3d.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* GStreamer Intel MSDK plugin
|
||||
* Copyright (c) 2016, Intel Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "msdk.h"
|
||||
|
||||
MsdkContext *
|
||||
msdk_open_context (gboolean hardware)
|
||||
{
|
||||
return (MsdkContext *) msdk_open_session (hardware);
|
||||
}
|
||||
|
||||
void
|
||||
msdk_close_context (MsdkContext * context)
|
||||
{
|
||||
msdk_close_session ((mfxSession) context);
|
||||
}
|
||||
|
||||
mfxSession
|
||||
msdk_context_get_session (MsdkContext * context)
|
||||
{
|
||||
return (mfxSession) context;
|
||||
}
|
|
@ -35,6 +35,7 @@
|
|||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <va/va_drm.h>
|
||||
#include "msdk.h"
|
||||
|
@ -42,8 +43,6 @@
|
|||
GST_DEBUG_CATEGORY_EXTERN (gst_msdkenc_debug);
|
||||
#define GST_CAT_DEFAULT gst_msdkenc_debug
|
||||
|
||||
#define INVALID_INDEX ((guint) -1)
|
||||
|
||||
struct _MsdkContext
|
||||
{
|
||||
mfxSession session;
|
||||
|
@ -51,76 +50,6 @@ struct _MsdkContext
|
|||
VADisplay dpy;
|
||||
};
|
||||
|
||||
static inline void
|
||||
msdk_close_session (mfxSession session)
|
||||
{
|
||||
mfxStatus status;
|
||||
|
||||
if (!session)
|
||||
return;
|
||||
|
||||
status = MFXClose (session);
|
||||
if (status != MFX_ERR_NONE)
|
||||
GST_ERROR ("Close failed (%s)", msdk_status_to_string (status));
|
||||
}
|
||||
|
||||
static inline mfxSession
|
||||
msdk_open_session (gboolean hardware)
|
||||
{
|
||||
mfxSession session = NULL;
|
||||
mfxVersion version = { {1, 1} };
|
||||
mfxIMPL implementation;
|
||||
mfxStatus status;
|
||||
|
||||
static const gchar *implementation_names[] = {
|
||||
"AUTO", "SOFTWARE", "HARDWARE", "AUTO_ANY", "HARDWARE_ANY", "HARDWARE2",
|
||||
"HARDWARE3", "HARDWARE4", "RUNTIME"
|
||||
};
|
||||
|
||||
status = MFXInit (hardware ? MFX_IMPL_HARDWARE_ANY : MFX_IMPL_SOFTWARE,
|
||||
&version, &session);
|
||||
if (status != MFX_ERR_NONE) {
|
||||
GST_ERROR ("Intel Media SDK not available (%s)",
|
||||
msdk_status_to_string (status));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
MFXQueryIMPL (session, &implementation);
|
||||
if (status != MFX_ERR_NONE) {
|
||||
GST_ERROR ("Query implementation failed (%s)",
|
||||
msdk_status_to_string (status));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
MFXQueryVersion (session, &version);
|
||||
if (status != MFX_ERR_NONE) {
|
||||
GST_ERROR ("Query version failed (%s)", msdk_status_to_string (status));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
GST_INFO ("MSDK implementation: 0x%04x (%s)", implementation,
|
||||
implementation_names[MFX_IMPL_BASETYPE (implementation)]);
|
||||
GST_INFO ("MSDK version: %d.%d", version.Major, version.Minor);
|
||||
|
||||
return session;
|
||||
|
||||
failed:
|
||||
msdk_close_session (session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
msdk_is_available (void)
|
||||
{
|
||||
mfxSession session = msdk_open_session (FALSE);
|
||||
if (!session) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
msdk_close_session (session);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
msdk_use_vaapi_on_context (MsdkContext * context)
|
||||
{
|
||||
|
@ -212,150 +141,3 @@ msdk_context_get_session (MsdkContext * context)
|
|||
{
|
||||
return context->session;
|
||||
}
|
||||
|
||||
static inline guint
|
||||
msdk_get_free_surface_index (mfxFrameSurface1 * surfaces, guint size)
|
||||
{
|
||||
if (surfaces) {
|
||||
for (guint i = 0; i < size; i++) {
|
||||
if (!surfaces[i].Data.Locked)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
|
||||
mfxFrameSurface1 *
|
||||
msdk_get_free_surface (mfxFrameSurface1 * surfaces, guint size)
|
||||
{
|
||||
guint idx = INVALID_INDEX;
|
||||
|
||||
/* Poll the pool for a maximum of 20 milisecnds */
|
||||
for (guint i = 0; i < 2000; i++) {
|
||||
idx = msdk_get_free_surface_index (surfaces, size);
|
||||
|
||||
if (idx != INVALID_INDEX)
|
||||
break;
|
||||
|
||||
g_usleep (10);
|
||||
}
|
||||
|
||||
return (idx == INVALID_INDEX ? NULL : &surfaces[idx]);
|
||||
}
|
||||
|
||||
/* FIXME: Only NV12 is supported by now, add other YUV formats */
|
||||
void
|
||||
msdk_frame_to_surface (GstVideoFrame * frame, mfxFrameSurface1 * surface)
|
||||
{
|
||||
guint8 *src, *dst;
|
||||
guint sstride, dstride;
|
||||
guint width, height;
|
||||
|
||||
if (!surface->Data.MemId) {
|
||||
surface->Data.Y = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
|
||||
surface->Data.UV = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
|
||||
surface->Data.Pitch = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Y Plane */
|
||||
width = GST_VIDEO_FRAME_COMP_WIDTH (frame, 0);
|
||||
height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 0);
|
||||
src = GST_VIDEO_FRAME_COMP_DATA (frame, 0);
|
||||
sstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 0);
|
||||
dst = surface->Data.Y;
|
||||
dstride = surface->Data.Pitch;
|
||||
|
||||
for (guint i = 0; i < height; i++) {
|
||||
memcpy (dst, src, width);
|
||||
src += sstride;
|
||||
dst += dstride;
|
||||
}
|
||||
|
||||
/* UV Plane */
|
||||
height = GST_VIDEO_FRAME_COMP_HEIGHT (frame, 1);
|
||||
src = GST_VIDEO_FRAME_COMP_DATA (frame, 1);
|
||||
sstride = GST_VIDEO_FRAME_COMP_STRIDE (frame, 1);
|
||||
dst = surface->Data.UV;
|
||||
|
||||
for (guint i = 0; i < height; i++) {
|
||||
memcpy (dst, src, width);
|
||||
src += sstride;
|
||||
dst += dstride;
|
||||
}
|
||||
}
|
||||
|
||||
const gchar *
|
||||
msdk_status_to_string (mfxStatus status)
|
||||
{
|
||||
switch (status) {
|
||||
/* no error */
|
||||
case MFX_ERR_NONE:
|
||||
return "no error";
|
||||
/* reserved for unexpected errors */
|
||||
case MFX_ERR_UNKNOWN:
|
||||
return "unknown error";
|
||||
/* error codes <0 */
|
||||
case MFX_ERR_NULL_PTR:
|
||||
return "null pointer";
|
||||
case MFX_ERR_UNSUPPORTED:
|
||||
return "undeveloped feature";
|
||||
case MFX_ERR_MEMORY_ALLOC:
|
||||
return "failed to allocate memory";
|
||||
case MFX_ERR_NOT_ENOUGH_BUFFER:
|
||||
return "insufficient buffer at input/output";
|
||||
case MFX_ERR_INVALID_HANDLE:
|
||||
return "invalid handle";
|
||||
case MFX_ERR_LOCK_MEMORY:
|
||||
return "failed to lock the memory block";
|
||||
case MFX_ERR_NOT_INITIALIZED:
|
||||
return "member function called before initialization";
|
||||
case MFX_ERR_NOT_FOUND:
|
||||
return "the specified object is not found";
|
||||
case MFX_ERR_MORE_DATA:
|
||||
return "expect more data at input";
|
||||
case MFX_ERR_MORE_SURFACE:
|
||||
return "expect more surface at output";
|
||||
case MFX_ERR_ABORTED:
|
||||
return "operation aborted";
|
||||
case MFX_ERR_DEVICE_LOST:
|
||||
return "lose the HW acceleration device";
|
||||
case MFX_ERR_INCOMPATIBLE_VIDEO_PARAM:
|
||||
return "incompatible video parameters";
|
||||
case MFX_ERR_INVALID_VIDEO_PARAM:
|
||||
return "invalid video parameters";
|
||||
case MFX_ERR_UNDEFINED_BEHAVIOR:
|
||||
return "undefined behavior";
|
||||
case MFX_ERR_DEVICE_FAILED:
|
||||
return "device operation failure";
|
||||
case MFX_ERR_MORE_BITSTREAM:
|
||||
return "expect more bitstream buffers at output";
|
||||
case MFX_ERR_INCOMPATIBLE_AUDIO_PARAM:
|
||||
return "incompatible audio parameters";
|
||||
case MFX_ERR_INVALID_AUDIO_PARAM:
|
||||
return "invalid audio parameters";
|
||||
/* warnings >0 */
|
||||
case MFX_WRN_IN_EXECUTION:
|
||||
return "the previous asynchronous operation is in execution";
|
||||
case MFX_WRN_DEVICE_BUSY:
|
||||
return "the HW acceleration device is busy";
|
||||
case MFX_WRN_VIDEO_PARAM_CHANGED:
|
||||
return "the video parameters are changed during decoding";
|
||||
case MFX_WRN_PARTIAL_ACCELERATION:
|
||||
return "SW is used";
|
||||
case MFX_WRN_INCOMPATIBLE_VIDEO_PARAM:
|
||||
return "incompatible video parameters";
|
||||
case MFX_WRN_VALUE_NOT_CHANGED:
|
||||
return "the value is saturated based on its valid range";
|
||||
case MFX_WRN_OUT_OF_RANGE:
|
||||
return "the value is out of valid range";
|
||||
case MFX_WRN_FILTER_SKIPPED:
|
||||
return "one of requested filters has been skipped";
|
||||
case MFX_WRN_INCOMPATIBLE_AUDIO_PARAM:
|
||||
return "incompatible audio parameters";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "undefiend error";
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue