mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-19 00:01:23 +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
|
if USE_MSDK_LIBVA
|
||||||
libgstmsdk_la_SOURCES += \
|
libgstmsdk_la_SOURCES += \
|
||||||
|
msdk.c \
|
||||||
msdk_libva.c
|
msdk_libva.c
|
||||||
libgstmsdk_la_CFLAGS += \
|
libgstmsdk_la_CFLAGS += \
|
||||||
$(LIBVA_DRM_CFLAGS)
|
$(LIBVA_DRM_CFLAGS)
|
||||||
|
|
|
@ -38,11 +38,31 @@
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
# include <config.h>
|
# include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef _WIN32
|
||||||
|
# include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "gstmsdkenc.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);
|
static void gst_msdkenc_close_encoder (GstMsdkEnc * thiz);
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_EXTERN (gst_msdkenc_debug);
|
GST_DEBUG_CATEGORY_EXTERN (gst_msdkenc_debug);
|
||||||
|
@ -231,8 +251,8 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
||||||
gsize size = Y_size + (Y_size >> 1);
|
gsize size = Y_size + (Y_size >> 1);
|
||||||
for (i = 0; i < thiz->num_surfaces; i++) {
|
for (i = 0; i < thiz->num_surfaces; i++) {
|
||||||
mfxFrameSurface1 *surface = &thiz->surfaces[i];
|
mfxFrameSurface1 *surface = &thiz->surfaces[i];
|
||||||
mfxU8 *data;
|
mfxU8 *data = _aligned_alloc (32, size);
|
||||||
if (posix_memalign ((void **) &data, 32, size) != 0) {
|
if (!data) {
|
||||||
GST_ERROR_OBJECT (thiz, "Memory allocation failed");
|
GST_ERROR_OBJECT (thiz, "Memory allocation failed");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
@ -272,8 +292,9 @@ gst_msdkenc_init_encoder (GstMsdkEnc * thiz)
|
||||||
thiz->num_tasks = thiz->param.AsyncDepth;
|
thiz->num_tasks = thiz->param.AsyncDepth;
|
||||||
thiz->tasks = g_new0 (MsdkEncTask, thiz->num_tasks);
|
thiz->tasks = g_new0 (MsdkEncTask, thiz->num_tasks);
|
||||||
for (i = 0; i < thiz->num_tasks; i++) {
|
for (i = 0; i < thiz->num_tasks; i++) {
|
||||||
if (posix_memalign ((void **) &thiz->tasks[i].output_bitstream.Data, 32,
|
thiz->tasks[i].output_bitstream.Data = _aligned_alloc (32,
|
||||||
thiz->param.mfx.BufferSizeInKB * 1024) != 0) {
|
thiz->param.mfx.BufferSizeInKB * 1024);
|
||||||
|
if (!thiz->tasks[i].output_bitstream.Data) {
|
||||||
GST_ERROR_OBJECT (thiz, "Memory allocation failed");
|
GST_ERROR_OBJECT (thiz, "Memory allocation failed");
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
@ -316,7 +337,7 @@ gst_msdkenc_close_encoder (GstMsdkEnc * thiz)
|
||||||
for (i = 0; i < thiz->num_tasks; i++) {
|
for (i = 0; i < thiz->num_tasks; i++) {
|
||||||
MsdkEncTask *task = &thiz->tasks[i];
|
MsdkEncTask *task = &thiz->tasks[i];
|
||||||
if (task->output_bitstream.Data) {
|
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++) {
|
for (i = 0; i < thiz->num_surfaces; i++) {
|
||||||
mfxFrameSurface1 *surface = &thiz->surfaces[i];
|
mfxFrameSurface1 *surface = &thiz->surfaces[i];
|
||||||
if (surface->Data.MemId)
|
if (surface->Data.MemId)
|
||||||
free (surface->Data.MemId);
|
_aligned_free (surface->Data.MemId);
|
||||||
}
|
}
|
||||||
g_free (thiz->surfaces);
|
g_free (thiz->surfaces);
|
||||||
thiz->surfaces = NULL;
|
thiz->surfaces = NULL;
|
||||||
|
|
|
@ -5,21 +5,35 @@ msdk_sources = [
|
||||||
'gstmsdkh265enc.c',
|
'gstmsdkh265enc.c',
|
||||||
'gstmsdkmpeg2enc.c',
|
'gstmsdkmpeg2enc.c',
|
||||||
'gstmsdkvp8enc.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')
|
python3 = find_program('python3')
|
||||||
msdk_root = run_command(python3, '-c', 'import os; print(os.environ.get("INTELMEDIASDKROOT", os.environ.get("MFX_HOME", "")))').stdout().strip()
|
msdk_root = run_command(python3, '-c', 'import os; print(os.environ.get("INTELMEDIASDKROOT", os.environ.get("MFX_HOME", "")))').stdout().strip()
|
||||||
|
|
||||||
if msdk_root != ''
|
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_incdir = include_directories(msdk_root + '/include')
|
||||||
msdk_lib = cc.find_library('mfx', dirs: msdk_libdir, required: false)
|
msdk_lib = cc.find_library('mfx', dirs: msdk_libdir, required: false)
|
||||||
|
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)
|
libva_dep = dependency('libva-drm', required: false)
|
||||||
libdl_dep = cc.find_library('dl', 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 = 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',
|
gstmsdktag = library('gstmsdk',
|
||||||
msdk_sources,
|
msdk_sources,
|
||||||
c_args : gst_plugins_bad_args,
|
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__
|
#define __MSDK_H__
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
|
@ -43,6 +42,9 @@ G_BEGIN_DECLS
|
||||||
|
|
||||||
typedef struct _MsdkContext MsdkContext;
|
typedef struct _MsdkContext MsdkContext;
|
||||||
|
|
||||||
|
mfxSession msdk_open_session (gboolean hardware);
|
||||||
|
void msdk_close_session (mfxSession session);
|
||||||
|
|
||||||
gboolean msdk_is_available (void);
|
gboolean msdk_is_available (void);
|
||||||
|
|
||||||
MsdkContext *msdk_open_context (gboolean hardware);
|
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 <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <va/va_drm.h>
|
#include <va/va_drm.h>
|
||||||
#include "msdk.h"
|
#include "msdk.h"
|
||||||
|
@ -42,8 +43,6 @@
|
||||||
GST_DEBUG_CATEGORY_EXTERN (gst_msdkenc_debug);
|
GST_DEBUG_CATEGORY_EXTERN (gst_msdkenc_debug);
|
||||||
#define GST_CAT_DEFAULT gst_msdkenc_debug
|
#define GST_CAT_DEFAULT gst_msdkenc_debug
|
||||||
|
|
||||||
#define INVALID_INDEX ((guint) -1)
|
|
||||||
|
|
||||||
struct _MsdkContext
|
struct _MsdkContext
|
||||||
{
|
{
|
||||||
mfxSession session;
|
mfxSession session;
|
||||||
|
@ -51,76 +50,6 @@ struct _MsdkContext
|
||||||
VADisplay dpy;
|
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
|
static gboolean
|
||||||
msdk_use_vaapi_on_context (MsdkContext * context)
|
msdk_use_vaapi_on_context (MsdkContext * context)
|
||||||
{
|
{
|
||||||
|
@ -212,150 +141,3 @@ msdk_context_get_session (MsdkContext * context)
|
||||||
{
|
{
|
||||||
return context->session;
|
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