mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
msdkdec: Apply the modified memory allocation logic
We did several things to enable the new memory logic in msdkdec: (1) We always use video memory for decoder in linux path; (2) We give negotiated pool to alloc_pool stored in GstMsdkContext which will be used in callback mfxFrameAllocator:Alloc to alloc surfaces as MediaSDK needs, and this pool is also available for decoder itself; (3) We modify decide_allocation process, that is we make pool negotiaion before gst_msdk_init_decoder to ensure the pool is decided and ready for use in mfxFrameAllocator:Alloc callback; then we will consider the case when we need to do the gpu to cpu copy. (4) In gst_msdkdec_finish_task, we modify the way for copy following the logic in (3). Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3439>
This commit is contained in:
parent
75efb204e5
commit
3062f1b6b0
5 changed files with 164 additions and 576 deletions
|
@ -45,7 +45,7 @@ struct _GstMsdkMemoryID {
|
||||||
mfxU32 fourcc;
|
mfxU32 fourcc;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
VASurfaceID *surface;
|
VASurfaceID surface;
|
||||||
VAImage image;
|
VAImage image;
|
||||||
VADRMPRIMESurfaceDescriptor desc;
|
VADRMPRIMESurfaceDescriptor desc;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -44,222 +44,6 @@
|
||||||
mfxStatus
|
mfxStatus
|
||||||
gst_msdk_frame_alloc (mfxHDL pthis, mfxFrameAllocRequest * req,
|
gst_msdk_frame_alloc (mfxHDL pthis, mfxFrameAllocRequest * req,
|
||||||
mfxFrameAllocResponse * resp)
|
mfxFrameAllocResponse * resp)
|
||||||
{
|
|
||||||
VAStatus va_status;
|
|
||||||
mfxStatus status = MFX_ERR_NONE;
|
|
||||||
gint i;
|
|
||||||
guint format;
|
|
||||||
guint va_fourcc = 0;
|
|
||||||
VASurfaceID *surfaces = NULL;
|
|
||||||
VASurfaceAttrib attribs[2];
|
|
||||||
guint num_attribs = 0;
|
|
||||||
mfxMemId *mids = NULL;
|
|
||||||
GstMsdkContext *context = (GstMsdkContext *) pthis;
|
|
||||||
GstMsdkMemoryID *msdk_mids = NULL;
|
|
||||||
GstMsdkAllocResponse *msdk_resp = NULL;
|
|
||||||
mfxU32 fourcc = req->Info.FourCC;
|
|
||||||
mfxU16 surfaces_num = req->NumFrameSuggested;
|
|
||||||
|
|
||||||
/* MFX_MAKEFOURCC('V','P','8','S') is used for MFX_FOURCC_VP9_SEGMAP surface
|
|
||||||
* in MSDK and this surface is an internal surface. The external allocator
|
|
||||||
* shouldn't be used for this surface allocation
|
|
||||||
*
|
|
||||||
* See https://github.com/Intel-Media-SDK/MediaSDK/issues/762
|
|
||||||
*/
|
|
||||||
if (req->Type & MFX_MEMTYPE_INTERNAL_FRAME
|
|
||||||
&& fourcc == MFX_MAKEFOURCC ('V', 'P', '8', 'S'))
|
|
||||||
return MFX_ERR_UNSUPPORTED;
|
|
||||||
|
|
||||||
if (req->Type & MFX_MEMTYPE_EXTERNAL_FRAME) {
|
|
||||||
GstMsdkAllocResponse *cached =
|
|
||||||
gst_msdk_context_get_cached_alloc_responses_by_request (context, req);
|
|
||||||
if (cached) {
|
|
||||||
/* check if enough frames were allocated */
|
|
||||||
if (req->NumFrameSuggested > cached->response.NumFrameActual)
|
|
||||||
return MFX_ERR_MEMORY_ALLOC;
|
|
||||||
|
|
||||||
*resp = cached->response;
|
|
||||||
g_atomic_int_inc (&cached->refcount);
|
|
||||||
return MFX_ERR_NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The VA API does not define any surface types and the application can use either
|
|
||||||
* MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET or
|
|
||||||
* MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET to indicate data in video memory.
|
|
||||||
*/
|
|
||||||
if (!(req->Type & (MFX_MEMTYPE_VIDEO_MEMORY_DECODER_TARGET |
|
|
||||||
MFX_MEMTYPE_VIDEO_MEMORY_PROCESSOR_TARGET)))
|
|
||||||
return MFX_ERR_UNSUPPORTED;
|
|
||||||
|
|
||||||
va_fourcc = gst_msdk_get_va_fourcc_from_mfx_fourcc (fourcc);
|
|
||||||
|
|
||||||
msdk_mids =
|
|
||||||
(GstMsdkMemoryID *) g_slice_alloc0 (surfaces_num *
|
|
||||||
sizeof (GstMsdkMemoryID));
|
|
||||||
mids = (mfxMemId *) g_slice_alloc0 (surfaces_num * sizeof (mfxMemId));
|
|
||||||
surfaces =
|
|
||||||
(VASurfaceID *) g_slice_alloc0 (surfaces_num * sizeof (VASurfaceID));
|
|
||||||
msdk_resp =
|
|
||||||
(GstMsdkAllocResponse *) g_slice_alloc0 (sizeof (GstMsdkAllocResponse));
|
|
||||||
|
|
||||||
if (va_fourcc != VA_FOURCC_P208) {
|
|
||||||
attribs[0].type = VASurfaceAttribPixelFormat;
|
|
||||||
attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
|
|
||||||
attribs[0].value.type = VAGenericValueTypeInteger;
|
|
||||||
attribs[0].value.value.i = va_fourcc;
|
|
||||||
num_attribs = 1;
|
|
||||||
|
|
||||||
/* set VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER flag for encoding */
|
|
||||||
#if (MFX_VERSION >= 1025)
|
|
||||||
if ((req->Type & MFX_MEMTYPE_VIDEO_MEMORY_ENCODER_TARGET) &&
|
|
||||||
(req->Type & MFX_MEMTYPE_FROM_ENCODE)) {
|
|
||||||
attribs[1].type = VASurfaceAttribUsageHint;
|
|
||||||
attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
|
|
||||||
attribs[1].value.type = VAGenericValueTypeInteger;
|
|
||||||
attribs[1].value.value.i = VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER;
|
|
||||||
num_attribs = 2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
format =
|
|
||||||
gst_msdk_get_va_rt_format_from_mfx_rt_format (req->Info.ChromaFormat);
|
|
||||||
|
|
||||||
if (format == VA_RT_FORMAT_YUV420 && va_fourcc == VA_FOURCC_P010)
|
|
||||||
#if VA_CHECK_VERSION(1, 2, 0)
|
|
||||||
format = VA_RT_FORMAT_YUV420_10;
|
|
||||||
#else
|
|
||||||
format = VA_RT_FORMAT_YUV420_10BPP;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if VA_CHECK_VERSION(1, 4, 1)
|
|
||||||
if (format == VA_RT_FORMAT_YUV444 && va_fourcc == VA_FOURCC_A2R10G10B10)
|
|
||||||
format = VA_RT_FORMAT_RGB32_10;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ((MFX_VERSION >= 1027) && VA_CHECK_VERSION(1, 2, 0))
|
|
||||||
if (format == VA_RT_FORMAT_YUV422 && va_fourcc == VA_FOURCC_Y210)
|
|
||||||
format = VA_RT_FORMAT_YUV422_10;
|
|
||||||
else if (format == VA_RT_FORMAT_YUV444 && va_fourcc == VA_FOURCC_Y410)
|
|
||||||
format = VA_RT_FORMAT_YUV444_10;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ((MFX_VERSION >= 1031) && VA_CHECK_VERSION(1, 2, 0))
|
|
||||||
if (format == VA_RT_FORMAT_YUV420 && va_fourcc == VA_FOURCC_P016)
|
|
||||||
format = VA_RT_FORMAT_YUV420_12;
|
|
||||||
|
|
||||||
if (format == VA_RT_FORMAT_YUV422 && va_fourcc == VA_FOURCC_Y216)
|
|
||||||
format = VA_RT_FORMAT_YUV422_12;
|
|
||||||
|
|
||||||
if (format == VA_RT_FORMAT_YUV444 && va_fourcc == VA_FOURCC_Y416)
|
|
||||||
format = VA_RT_FORMAT_YUV444_12;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (MFX_VERSION >= 2004)
|
|
||||||
if (format == VA_RT_FORMAT_YUV444 && (va_fourcc == VA_FOURCC_RGBP
|
|
||||||
|| va_fourcc == VA_FOURCC_BGRP))
|
|
||||||
format = VA_RT_FORMAT_RGBP;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
va_status = vaCreateSurfaces (gst_msdk_context_get_handle (context),
|
|
||||||
format,
|
|
||||||
req->Info.Width, req->Info.Height, surfaces, surfaces_num, attribs,
|
|
||||||
num_attribs);
|
|
||||||
|
|
||||||
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
|
||||||
if (status != MFX_ERR_NONE) {
|
|
||||||
GST_WARNING ("failed to create VA surface");
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < surfaces_num; i++) {
|
|
||||||
/* Get dmabuf handle if MFX_MEMTYPE_EXPORT_FRAME */
|
|
||||||
if (req->Type & MFX_MEMTYPE_EXPORT_FRAME) {
|
|
||||||
VADRMPRIMESurfaceDescriptor va_desc = { 0 };
|
|
||||||
uint32_t export_flags = VA_EXPORT_SURFACE_SEPARATE_LAYERS |
|
|
||||||
VA_EXPORT_SURFACE_READ_WRITE;
|
|
||||||
|
|
||||||
va_status =
|
|
||||||
vaExportSurfaceHandle (gst_msdk_context_get_handle (context),
|
|
||||||
surfaces[i], VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, export_flags,
|
|
||||||
&va_desc);
|
|
||||||
|
|
||||||
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
|
||||||
|
|
||||||
if (MFX_ERR_NONE != status) {
|
|
||||||
GST_ERROR ("Failed to export surface");
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_assert (va_desc.num_objects);
|
|
||||||
|
|
||||||
/* This plugin supports single object only */
|
|
||||||
if (va_desc.num_objects > 1) {
|
|
||||||
GST_ERROR ("Can not support multiple objects");
|
|
||||||
return MFX_ERR_UNSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
msdk_mids[i].desc = va_desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't use image for DMABuf */
|
|
||||||
msdk_mids[i].image.image_id = VA_INVALID_ID;
|
|
||||||
msdk_mids[i].image.buf = VA_INVALID_ID;
|
|
||||||
|
|
||||||
msdk_mids[i].surface = &surfaces[i];
|
|
||||||
mids[i] = (mfxMemId *) & msdk_mids[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* This is requested from the driver when h265 encoding.
|
|
||||||
* These buffers will be used inside the driver and released by
|
|
||||||
* gst_msdk_frame_free functions. Application doesn't need to handle these buffers.
|
|
||||||
*
|
|
||||||
* See https://github.com/Intel-Media-SDK/samples/issues/13 for more details.
|
|
||||||
*/
|
|
||||||
VAContextID context_id = req->AllocId;
|
|
||||||
gint width32 = 32 * ((req->Info.Width + 31) >> 5);
|
|
||||||
gint height32 = 32 * ((req->Info.Height + 31) >> 5);
|
|
||||||
guint64 codedbuf_size = (width32 * height32) * 400LL / (16 * 16);
|
|
||||||
|
|
||||||
for (i = 0; i < surfaces_num; i++) {
|
|
||||||
VABufferID coded_buf;
|
|
||||||
|
|
||||||
va_status = vaCreateBuffer (gst_msdk_context_get_handle (context),
|
|
||||||
context_id, VAEncCodedBufferType, codedbuf_size, 1, NULL, &coded_buf);
|
|
||||||
|
|
||||||
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
|
||||||
if (status < MFX_ERR_NONE) {
|
|
||||||
GST_ERROR ("failed to create buffer");
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
surfaces[i] = coded_buf;
|
|
||||||
msdk_mids[i].surface = &surfaces[i];
|
|
||||||
msdk_mids[i].fourcc = fourcc;
|
|
||||||
|
|
||||||
/* Don't use image for P208 */
|
|
||||||
msdk_mids[i].image.image_id = VA_INVALID_ID;
|
|
||||||
msdk_mids[i].image.buf = VA_INVALID_ID;
|
|
||||||
|
|
||||||
mids[i] = (mfxMemId *) & msdk_mids[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resp->mids = mids;
|
|
||||||
resp->NumFrameActual = surfaces_num;
|
|
||||||
|
|
||||||
msdk_resp->response = *resp;
|
|
||||||
msdk_resp->request = *req;
|
|
||||||
msdk_resp->refcount = 1;
|
|
||||||
|
|
||||||
gst_msdk_context_add_alloc_response (context, msdk_resp);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
mfxStatus
|
|
||||||
gst_msdk_frame_alloc_2 (mfxHDL pthis, mfxFrameAllocRequest * req,
|
|
||||||
mfxFrameAllocResponse * resp)
|
|
||||||
{
|
{
|
||||||
mfxStatus status = MFX_ERR_NONE;
|
mfxStatus status = MFX_ERR_NONE;
|
||||||
gint i;
|
gint i;
|
||||||
|
@ -439,11 +223,6 @@ mfxStatus
|
||||||
gst_msdk_frame_free (mfxHDL pthis, mfxFrameAllocResponse * resp)
|
gst_msdk_frame_free (mfxHDL pthis, mfxFrameAllocResponse * resp)
|
||||||
{
|
{
|
||||||
GstMsdkContext *context = (GstMsdkContext *) pthis;
|
GstMsdkContext *context = (GstMsdkContext *) pthis;
|
||||||
VAStatus va_status = VA_STATUS_SUCCESS;
|
|
||||||
mfxStatus status;
|
|
||||||
GstMsdkMemoryID *mem_id;
|
|
||||||
VADisplay dpy;
|
|
||||||
gint i;
|
|
||||||
GstMsdkAllocResponse *cached = NULL;
|
GstMsdkAllocResponse *cached = NULL;
|
||||||
|
|
||||||
cached = gst_msdk_context_get_cached_alloc_responses (context, resp);
|
cached = gst_msdk_context_get_cached_alloc_responses (context, resp);
|
||||||
|
@ -457,45 +236,9 @@ gst_msdk_frame_free (mfxHDL pthis, mfxFrameAllocResponse * resp)
|
||||||
if (!gst_msdk_context_remove_alloc_response (context, resp))
|
if (!gst_msdk_context_remove_alloc_response (context, resp))
|
||||||
return MFX_ERR_NONE;
|
return MFX_ERR_NONE;
|
||||||
|
|
||||||
mem_id = resp->mids[0];
|
|
||||||
dpy = gst_msdk_context_get_handle (context);
|
|
||||||
|
|
||||||
if (mem_id->fourcc != MFX_FOURCC_P8) {
|
|
||||||
/* Make sure that all the vaImages are destroyed */
|
|
||||||
for (i = 0; i < resp->NumFrameActual; i++) {
|
|
||||||
GstMsdkMemoryID *mem = resp->mids[i];
|
|
||||||
|
|
||||||
/* Release prime fd if used */
|
|
||||||
if (mem->desc.num_objects) {
|
|
||||||
g_assert (mem->desc.num_objects == 1);
|
|
||||||
close (mem->desc.objects[0].fd);
|
|
||||||
mem->desc.num_objects = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mem->image.image_id != VA_INVALID_ID &&
|
|
||||||
vaDestroyImage (dpy, mem->image.image_id) == VA_STATUS_SUCCESS) {
|
|
||||||
mem_id->image.image_id = VA_INVALID_ID;
|
|
||||||
mem_id->image.buf = VA_INVALID_ID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
va_status =
|
|
||||||
vaDestroySurfaces (dpy, (VASurfaceID *) mem_id->surface,
|
|
||||||
resp->NumFrameActual);
|
|
||||||
} else {
|
|
||||||
VASurfaceID *surfaces = mem_id->surface;
|
|
||||||
|
|
||||||
for (i = 0; i < resp->NumFrameActual; i++) {
|
|
||||||
va_status = vaDestroyBuffer (dpy, surfaces[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_slice_free1 (resp->NumFrameActual * sizeof (VASurfaceID), mem_id->surface);
|
|
||||||
g_slice_free1 (resp->NumFrameActual * sizeof (GstMsdkMemoryID), mem_id);
|
|
||||||
g_slice_free1 (resp->NumFrameActual * sizeof (mfxMemId), resp->mids);
|
g_slice_free1 (resp->NumFrameActual * sizeof (mfxMemId), resp->mids);
|
||||||
|
|
||||||
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
return MFX_ERR_NONE;
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mfxStatus
|
mfxStatus
|
||||||
|
@ -505,7 +248,7 @@ gst_msdk_frame_lock (mfxHDL pthis, mfxMemId mid, mfxFrameData * data)
|
||||||
VAStatus va_status;
|
VAStatus va_status;
|
||||||
mfxStatus status;
|
mfxStatus status;
|
||||||
mfxU8 *buf = NULL;
|
mfxU8 *buf = NULL;
|
||||||
VASurfaceID *va_surface;
|
VASurfaceID va_surface;
|
||||||
VADisplay dpy;
|
VADisplay dpy;
|
||||||
GstMsdkMemoryID *mem_id;
|
GstMsdkMemoryID *mem_id;
|
||||||
|
|
||||||
|
@ -519,7 +262,7 @@ gst_msdk_frame_lock (mfxHDL pthis, mfxMemId mid, mfxFrameData * data)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mem_id->fourcc != MFX_FOURCC_P8) {
|
if (mem_id->fourcc != MFX_FOURCC_P8) {
|
||||||
va_status = vaDeriveImage (dpy, *va_surface, &mem_id->image);
|
va_status = vaDeriveImage (dpy, va_surface, &mem_id->image);
|
||||||
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
||||||
|
|
||||||
if (status != MFX_ERR_NONE) {
|
if (status != MFX_ERR_NONE) {
|
||||||
|
@ -647,7 +390,7 @@ gst_msdk_frame_lock (mfxHDL pthis, mfxMemId mid, mfxFrameData * data)
|
||||||
} else {
|
} else {
|
||||||
VACodedBufferSegment *coded_buffer_segment;
|
VACodedBufferSegment *coded_buffer_segment;
|
||||||
va_status =
|
va_status =
|
||||||
vaMapBuffer (dpy, *va_surface, (void **) (&coded_buffer_segment));
|
vaMapBuffer (dpy, va_surface, (void **) (&coded_buffer_segment));
|
||||||
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
||||||
if (MFX_ERR_NONE == status)
|
if (MFX_ERR_NONE == status)
|
||||||
data->Y = (mfxU8 *) coded_buffer_segment->buf;
|
data->Y = (mfxU8 *) coded_buffer_segment->buf;
|
||||||
|
@ -679,7 +422,7 @@ gst_msdk_frame_unlock (mfxHDL pthis, mfxMemId mid, mfxFrameData * ptr)
|
||||||
mem_id->image.buf = VA_INVALID_ID;
|
mem_id->image.buf = VA_INVALID_ID;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
va_status = vaUnmapBuffer (dpy, *(mem_id->surface));
|
va_status = vaUnmapBuffer (dpy, mem_id->surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
||||||
|
@ -696,7 +439,7 @@ gst_msdk_frame_get_hdl (mfxHDL pthis, mfxMemId mid, mfxHDL * hdl)
|
||||||
return MFX_ERR_INVALID_HANDLE;
|
return MFX_ERR_INVALID_HANDLE;
|
||||||
|
|
||||||
mem_id = mid;
|
mem_id = mid;
|
||||||
*hdl = mem_id->surface;
|
*hdl = &mem_id->surface;
|
||||||
|
|
||||||
return MFX_ERR_NONE;
|
return MFX_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
@ -970,8 +713,7 @@ gst_msdk_import_to_msdk_surface (GstBuffer * buf, GstMsdkContext * msdk_context,
|
||||||
mfx_surface = g_slice_new0 (mfxFrameSurface1);
|
mfx_surface = g_slice_new0 (mfxFrameSurface1);
|
||||||
msdk_mid = g_slice_new0 (GstMsdkMemoryID);
|
msdk_mid = g_slice_new0 (GstMsdkMemoryID);
|
||||||
|
|
||||||
msdk_mid->surface = g_slice_new0 (VASurfaceID);
|
msdk_mid->surface = va_surface;
|
||||||
*msdk_mid->surface = va_surface;
|
|
||||||
|
|
||||||
mfx_surface->Data.MemId = (mfxMemId) msdk_mid;
|
mfx_surface->Data.MemId = (mfxMemId) msdk_mid;
|
||||||
|
|
||||||
|
@ -1003,7 +745,7 @@ gst_msdk_replace_mfx_memid (GstMsdkContext * context,
|
||||||
{
|
{
|
||||||
GstMsdkMemoryID *msdk_mid = NULL;
|
GstMsdkMemoryID *msdk_mid = NULL;
|
||||||
VADisplay dpy;
|
VADisplay dpy;
|
||||||
VASurfaceID *old_surface_id;
|
VASurfaceID old_surface_id;
|
||||||
VAStatus va_status;
|
VAStatus va_status;
|
||||||
mfxStatus status = MFX_ERR_NONE;
|
mfxStatus status = MFX_ERR_NONE;
|
||||||
|
|
||||||
|
@ -1024,14 +766,14 @@ gst_msdk_replace_mfx_memid (GstMsdkContext * context,
|
||||||
|
|
||||||
/* Destroy the associated VASurface */
|
/* Destroy the associated VASurface */
|
||||||
old_surface_id = msdk_mid->surface;
|
old_surface_id = msdk_mid->surface;
|
||||||
if (*old_surface_id != VA_INVALID_ID) {
|
if (old_surface_id != VA_INVALID_ID) {
|
||||||
va_status = vaDestroySurfaces (dpy, old_surface_id, 1);
|
va_status = vaDestroySurfaces (dpy, &old_surface_id, 1);
|
||||||
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
status = gst_msdk_get_mfx_status_from_va_status (va_status);
|
||||||
if (status != MFX_ERR_NONE)
|
if (status != MFX_ERR_NONE)
|
||||||
goto error_destroy_va_surface;
|
goto error_destroy_va_surface;
|
||||||
}
|
}
|
||||||
|
|
||||||
*msdk_mid->surface = surface_id;
|
msdk_mid->surface = surface_id;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -1042,7 +784,7 @@ error_destroy_va_image:
|
||||||
}
|
}
|
||||||
error_destroy_va_surface:
|
error_destroy_va_surface:
|
||||||
{
|
{
|
||||||
GST_ERROR ("Failed to Destroy the VASurfaceID %x", *old_surface_id);
|
GST_ERROR ("Failed to Destroy the VASurfaceID %x", old_surface_id);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -736,25 +736,6 @@ gst_msdk_context_get_cached_alloc_responses_by_request (GstMsdkContext *
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
create_surfaces (GstMsdkContext * context, GstMsdkAllocResponse * resp)
|
|
||||||
{
|
|
||||||
gint i;
|
|
||||||
mfxMemId *mem_id;
|
|
||||||
mfxFrameSurface1 *surface;
|
|
||||||
|
|
||||||
for (i = 0; i < resp->response.NumFrameActual; i++) {
|
|
||||||
mem_id = resp->response.mids[i];
|
|
||||||
surface = (mfxFrameSurface1 *) g_slice_new0 (mfxFrameSurface1);
|
|
||||||
if (!surface) {
|
|
||||||
GST_ERROR ("failed to allocate surface");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
surface->Data.MemId = mem_id;
|
|
||||||
resp->surfaces_avail = g_list_prepend (resp->surfaces_avail, surface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_surface (gpointer surface)
|
free_surface (gpointer surface)
|
||||||
{
|
{
|
||||||
|
@ -775,8 +756,6 @@ gst_msdk_context_add_alloc_response (GstMsdkContext * context,
|
||||||
{
|
{
|
||||||
context->priv->cached_alloc_responses =
|
context->priv->cached_alloc_responses =
|
||||||
g_list_prepend (context->priv->cached_alloc_responses, resp);
|
g_list_prepend (context->priv->cached_alloc_responses, resp);
|
||||||
|
|
||||||
create_surfaces (context, resp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "gstmsdkvideomemory.h"
|
#include "gstmsdkvideomemory.h"
|
||||||
#include "gstmsdksystemmemory.h"
|
#include "gstmsdksystemmemory.h"
|
||||||
#include "gstmsdkcontextutil.h"
|
#include "gstmsdkcontextutil.h"
|
||||||
|
#include "gstmsdkallocator.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <gst/va/gstvaallocator.h>
|
#include <gst/va/gstvaallocator.h>
|
||||||
|
@ -72,17 +73,9 @@ static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
#define gst_msdkdec_parent_class parent_class
|
#define gst_msdkdec_parent_class parent_class
|
||||||
G_DEFINE_TYPE (GstMsdkDec, gst_msdkdec, GST_TYPE_VIDEO_DECODER);
|
G_DEFINE_TYPE (GstMsdkDec, gst_msdkdec, GST_TYPE_VIDEO_DECODER);
|
||||||
|
|
||||||
typedef struct _MsdkSurface
|
|
||||||
{
|
|
||||||
mfxFrameSurface1 *surface;
|
|
||||||
GstBuffer *buf;
|
|
||||||
GstVideoFrame data;
|
|
||||||
GstVideoFrame copy;
|
|
||||||
} MsdkSurface;
|
|
||||||
|
|
||||||
struct _MsdkDecTask
|
struct _MsdkDecTask
|
||||||
{
|
{
|
||||||
MsdkSurface *surface;
|
GstMsdkSurface *surface;
|
||||||
mfxSyncPoint sync_point;
|
mfxSyncPoint sync_point;
|
||||||
|
|
||||||
gboolean decode_only;
|
gboolean decode_only;
|
||||||
|
@ -155,39 +148,22 @@ gst_msdkdec_get_oldest_frame (GstVideoDecoder * decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
free_surface (MsdkSurface * s)
|
free_surface (GstMsdkSurface * s)
|
||||||
{
|
{
|
||||||
gst_buffer_unref (s->buf);
|
gst_buffer_unref (s->buf);
|
||||||
g_slice_free (MsdkSurface, s);
|
g_slice_free (GstMsdkSurface, s);
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
unmap_frame (GstMsdkDec * thiz, MsdkSurface * s)
|
|
||||||
{
|
|
||||||
if (s->copy.buffer) {
|
|
||||||
/* we allocate this buffer from down stream, we need ref-1 for it */
|
|
||||||
gst_buffer_unref (s->copy.buffer);
|
|
||||||
gst_video_frame_unmap (&s->copy);
|
|
||||||
s->copy.buffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s->data.buffer) {
|
|
||||||
gst_video_frame_unmap (&s->data);
|
|
||||||
s->data.buffer = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_msdkdec_free_unlocked_msdk_surfaces (GstMsdkDec * thiz)
|
gst_msdkdec_free_unlocked_msdk_surfaces (GstMsdkDec * thiz)
|
||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
MsdkSurface *surface;
|
GstMsdkSurface *surface;
|
||||||
|
|
||||||
for (l = thiz->locked_msdk_surfaces; l;) {
|
for (l = thiz->locked_msdk_surfaces; l;) {
|
||||||
GList *next = l->next;
|
GList *next = l->next;
|
||||||
surface = l->data;
|
surface = l->data;
|
||||||
if (surface->surface->Data.Locked == 0) {
|
if (surface->surface->Data.Locked == 0) {
|
||||||
unmap_frame (thiz, surface);
|
|
||||||
free_surface (surface);
|
free_surface (surface);
|
||||||
thiz->locked_msdk_surfaces =
|
thiz->locked_msdk_surfaces =
|
||||||
g_list_delete_link (thiz->locked_msdk_surfaces, l);
|
g_list_delete_link (thiz->locked_msdk_surfaces, l);
|
||||||
|
@ -196,101 +172,6 @@ gst_msdkdec_free_unlocked_msdk_surfaces (GstMsdkDec * thiz)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
|
||||||
allocate_output_buffer (GstMsdkDec * thiz, GstBuffer ** buffer)
|
|
||||||
{
|
|
||||||
GstFlowReturn flow;
|
|
||||||
GstVideoCodecFrame *frame;
|
|
||||||
GstVideoDecoder *decoder = GST_VIDEO_DECODER (thiz);
|
|
||||||
|
|
||||||
frame = gst_msdkdec_get_oldest_frame (decoder);
|
|
||||||
if (!frame) {
|
|
||||||
if (GST_PAD_IS_FLUSHING (decoder->srcpad))
|
|
||||||
return GST_FLOW_FLUSHING;
|
|
||||||
else
|
|
||||||
return GST_FLOW_CUSTOM_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!frame->output_buffer) {
|
|
||||||
/* Free un-unsed msdk surfaces firstly, hence the associated mfx
|
|
||||||
* surfaces will be moved from used list to available list */
|
|
||||||
gst_msdkdec_free_unlocked_msdk_surfaces (thiz);
|
|
||||||
|
|
||||||
flow = gst_video_decoder_allocate_output_frame (decoder, frame);
|
|
||||||
if (flow != GST_FLOW_OK) {
|
|
||||||
gst_video_codec_frame_unref (frame);
|
|
||||||
return flow;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*buffer = gst_buffer_ref (frame->output_buffer);
|
|
||||||
gst_buffer_replace (&frame->output_buffer, NULL);
|
|
||||||
gst_video_codec_frame_unref (frame);
|
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MsdkSurface *
|
|
||||||
get_surface (GstMsdkDec * thiz, GstBuffer * buffer)
|
|
||||||
{
|
|
||||||
MsdkSurface *i;
|
|
||||||
GstVideoCodecState *output_state = NULL;
|
|
||||||
gboolean success;
|
|
||||||
|
|
||||||
i = g_slice_new0 (MsdkSurface);
|
|
||||||
|
|
||||||
if (gst_msdk_is_msdk_buffer (buffer)) {
|
|
||||||
i->surface = gst_msdk_get_surface_from_buffer (buffer);
|
|
||||||
i->buf = buffer;
|
|
||||||
} else {
|
|
||||||
/* Confirm to activate the side pool */
|
|
||||||
if (!gst_buffer_pool_is_active (thiz->pool) &&
|
|
||||||
!gst_buffer_pool_set_active (thiz->pool, TRUE)) {
|
|
||||||
g_slice_free (MsdkSurface, i);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!gst_video_frame_map (&i->copy, &thiz->non_msdk_pool_info, buffer,
|
|
||||||
GST_MAP_WRITE))
|
|
||||||
goto failed_unref_buffer;
|
|
||||||
|
|
||||||
if (gst_buffer_pool_acquire_buffer (thiz->pool, &buffer,
|
|
||||||
NULL) != GST_FLOW_OK)
|
|
||||||
goto failed_unmap_copy;
|
|
||||||
|
|
||||||
i->surface = gst_msdk_get_surface_from_buffer (buffer);
|
|
||||||
i->buf = buffer;
|
|
||||||
|
|
||||||
output_state =
|
|
||||||
gst_video_decoder_get_output_state (GST_VIDEO_DECODER (thiz));
|
|
||||||
success =
|
|
||||||
gst_video_frame_map (&i->data, &output_state->info, buffer,
|
|
||||||
GST_MAP_READWRITE);
|
|
||||||
gst_video_codec_state_unref (output_state);
|
|
||||||
if (!success)
|
|
||||||
goto failed_unref_buffer2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!thiz->sfc)
|
|
||||||
gst_msdk_update_mfx_frame_info_from_mfx_video_param (&i->surface->Info,
|
|
||||||
&thiz->param);
|
|
||||||
|
|
||||||
thiz->locked_msdk_surfaces = g_list_append (thiz->locked_msdk_surfaces, i);
|
|
||||||
return i;
|
|
||||||
|
|
||||||
failed_unref_buffer2:
|
|
||||||
gst_buffer_unref (buffer);
|
|
||||||
buffer = i->data.buffer;
|
|
||||||
failed_unmap_copy:
|
|
||||||
gst_video_frame_unmap (&i->copy);
|
|
||||||
failed_unref_buffer:
|
|
||||||
gst_buffer_unref (buffer);
|
|
||||||
g_slice_free (MsdkSurface, i);
|
|
||||||
|
|
||||||
GST_ERROR_OBJECT (thiz, "failed to handle buffer");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstMsdkSurface *
|
static GstMsdkSurface *
|
||||||
allocate_output_surface (GstMsdkDec * thiz)
|
allocate_output_surface (GstMsdkDec * thiz)
|
||||||
{
|
{
|
||||||
|
@ -697,7 +578,7 @@ static gboolean
|
||||||
gst_msdkdec_set_src_caps (GstMsdkDec * thiz, gboolean need_allocation)
|
gst_msdkdec_set_src_caps (GstMsdkDec * thiz, gboolean need_allocation)
|
||||||
{
|
{
|
||||||
GstVideoCodecState *output_state;
|
GstVideoCodecState *output_state;
|
||||||
GstVideoInfo *vinfo;
|
GstVideoInfo vinfo;
|
||||||
GstVideoAlignment align;
|
GstVideoAlignment align;
|
||||||
GstCaps *allocation_caps = NULL;
|
GstCaps *allocation_caps = NULL;
|
||||||
GstCaps *allowed_caps = NULL, *temp_caps;
|
GstCaps *allowed_caps = NULL, *temp_caps;
|
||||||
|
@ -820,13 +701,13 @@ gst_msdkdec_set_src_caps (GstMsdkDec * thiz, gboolean need_allocation)
|
||||||
|
|
||||||
/* Ensure output_state->caps and info have same width and height
|
/* Ensure output_state->caps and info have same width and height
|
||||||
* Also, mandate 32 bit alignment */
|
* Also, mandate 32 bit alignment */
|
||||||
vinfo = &output_state->info;
|
vinfo = output_state->info;
|
||||||
if (width == out_width || height == out_height)
|
if (width == out_width || height == out_height)
|
||||||
gst_msdk_set_video_alignment (vinfo, 0, 0, &align);
|
gst_msdk_set_video_alignment (&vinfo, 0, 0, &align);
|
||||||
else
|
else
|
||||||
gst_msdk_set_video_alignment (vinfo, alloc_w, alloc_h, &align);
|
gst_msdk_set_video_alignment (&vinfo, alloc_w, alloc_h, &align);
|
||||||
gst_video_info_align (vinfo, &align);
|
gst_video_info_align (&vinfo, &align);
|
||||||
output_state->caps = gst_video_info_to_caps (vinfo);
|
output_state->caps = gst_video_info_to_caps (&vinfo);
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
if (pad_accept_memory (thiz, GST_CAPS_FEATURE_MEMORY_VA, output_state->caps)) {
|
if (pad_accept_memory (thiz, GST_CAPS_FEATURE_MEMORY_VA, output_state->caps)) {
|
||||||
gst_caps_set_features (output_state->caps, 0,
|
gst_caps_set_features (output_state->caps, 0,
|
||||||
|
@ -906,7 +787,7 @@ gst_msdkdec_set_latency (GstMsdkDec * thiz)
|
||||||
static gint
|
static gint
|
||||||
_find_msdk_surface (gconstpointer msdk_surface, gconstpointer comp_surface)
|
_find_msdk_surface (gconstpointer msdk_surface, gconstpointer comp_surface)
|
||||||
{
|
{
|
||||||
MsdkSurface *cached_surface = (MsdkSurface *) msdk_surface;
|
GstMsdkSurface *cached_surface = (GstMsdkSurface *) msdk_surface;
|
||||||
mfxFrameSurface1 *_surface = (mfxFrameSurface1 *) comp_surface;
|
mfxFrameSurface1 *_surface = (mfxFrameSurface1 *) comp_surface;
|
||||||
|
|
||||||
return cached_surface ? cached_surface->surface != _surface : -1;
|
return cached_surface ? cached_surface->surface != _surface : -1;
|
||||||
|
@ -915,11 +796,8 @@ _find_msdk_surface (gconstpointer msdk_surface, gconstpointer comp_surface)
|
||||||
static void
|
static void
|
||||||
finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
|
finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
|
||||||
{
|
{
|
||||||
MsdkSurface *surface = task->surface;
|
GstMsdkSurface *surface = task->surface;
|
||||||
if (surface) {
|
if (surface) {
|
||||||
if (G_UNLIKELY (surface->copy.buffer)) {
|
|
||||||
unmap_frame (thiz, surface);
|
|
||||||
}
|
|
||||||
thiz->locked_msdk_surfaces =
|
thiz->locked_msdk_surfaces =
|
||||||
g_list_append (thiz->locked_msdk_surfaces, surface);
|
g_list_append (thiz->locked_msdk_surfaces, surface);
|
||||||
}
|
}
|
||||||
|
@ -959,13 +837,76 @@ gst_msdkdec_frame_corruption_report (GstMsdkDec * thiz, mfxU16 corruption)
|
||||||
("[Corruption] Corrupted reference list!"), (NULL));
|
("[Corruption] Corrupted reference list!"), (NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_copy_to_sys_mem (GstMsdkDec * thiz, GstMsdkSurface * surface,
|
||||||
|
GstVideoCodecFrame * frame)
|
||||||
|
{
|
||||||
|
GstBuffer *buffer = NULL;
|
||||||
|
GstVideoFrame src_frame;
|
||||||
|
GstVideoFrame dst_frame;
|
||||||
|
GstVideoInfo *src_info;
|
||||||
|
GstVideoInfo dst_info;
|
||||||
|
GstVideoCodecState *output_state =
|
||||||
|
gst_video_decoder_get_output_state (GST_VIDEO_DECODER (thiz));
|
||||||
|
|
||||||
|
src_info = &output_state->info;
|
||||||
|
gst_video_info_set_format (&dst_info, GST_VIDEO_INFO_FORMAT (src_info),
|
||||||
|
GST_VIDEO_INFO_WIDTH (src_info), GST_VIDEO_INFO_HEIGHT (src_info));
|
||||||
|
|
||||||
|
if (!gst_buffer_pool_is_active (thiz->other_pool) &&
|
||||||
|
!gst_buffer_pool_set_active (thiz->other_pool, TRUE)) {
|
||||||
|
GST_ERROR_OBJECT (thiz, "Failed to activate buffer pool");
|
||||||
|
goto error_active;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_buffer_pool_acquire_buffer (thiz->other_pool, &buffer, NULL)
|
||||||
|
!= GST_FLOW_OK) {
|
||||||
|
GST_ERROR ("Failed to acquire buffer from pool");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_video_frame_map (&src_frame, src_info, surface->buf, GST_MAP_READ)) {
|
||||||
|
GST_ERROR_OBJECT (thiz, "Failed to map buf to src frame");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_video_frame_map (&dst_frame, &dst_info, buffer, GST_MAP_WRITE)) {
|
||||||
|
GST_ERROR_OBJECT (thiz, "Failed to map buf to dst frame");
|
||||||
|
gst_video_frame_unmap (&src_frame);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_video_frame_copy (&dst_frame, &src_frame)) {
|
||||||
|
GST_ERROR_OBJECT (thiz, "Failed to copy surface data");
|
||||||
|
gst_video_frame_unmap (&src_frame);
|
||||||
|
gst_video_frame_unmap (&dst_frame);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
frame->output_buffer = buffer;
|
||||||
|
gst_video_frame_unmap (&src_frame);
|
||||||
|
gst_video_frame_unmap (&dst_frame);
|
||||||
|
gst_video_codec_state_unref (output_state);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
error:
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
gst_buffer_pool_set_active (thiz->other_pool, FALSE);
|
||||||
|
gst_object_unref (thiz->other_pool);
|
||||||
|
|
||||||
|
error_active:
|
||||||
|
gst_video_codec_state_unref (output_state);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
|
gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
|
||||||
{
|
{
|
||||||
GstVideoDecoder *decoder = GST_VIDEO_DECODER (thiz);
|
GstVideoDecoder *decoder = GST_VIDEO_DECODER (thiz);
|
||||||
GstFlowReturn flow;
|
GstFlowReturn flow;
|
||||||
GstVideoCodecFrame *frame;
|
GstVideoCodecFrame *frame;
|
||||||
MsdkSurface *surface;
|
GstMsdkSurface *surface;
|
||||||
mfxStatus status;
|
mfxStatus status;
|
||||||
guint64 pts = MFX_TIMESTAMP_UNKNOWN;
|
guint64 pts = MFX_TIMESTAMP_UNKNOWN;
|
||||||
|
|
||||||
|
@ -1004,16 +945,17 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (G_LIKELY (frame)) {
|
if (G_LIKELY (frame)) {
|
||||||
if (G_LIKELY (surface->copy.buffer == NULL)) {
|
if (!thiz->do_copy) {
|
||||||
/* gst_video_decoder_finish_frame will call gst_buffer_make_writable
|
/* gst_video_decoder_finish_frame will call gst_buffer_make_writable
|
||||||
* we need this to avoid copy buffer */
|
* we need this to avoid copy buffer */
|
||||||
GST_MINI_OBJECT_FLAG_SET (surface->buf, GST_MINI_OBJECT_FLAG_LOCKABLE);
|
GST_MINI_OBJECT_FLAG_SET (surface->buf, GST_MINI_OBJECT_FLAG_LOCKABLE);
|
||||||
frame->output_buffer = gst_buffer_ref (surface->buf);
|
frame->output_buffer = gst_buffer_ref (surface->buf);
|
||||||
} else {
|
} else {
|
||||||
gst_video_frame_copy (&surface->copy, &surface->data);
|
/* We need to do the copy from video memory to system memory */
|
||||||
frame->output_buffer = gst_buffer_ref (surface->copy.buffer);
|
if (!_copy_to_sys_mem (thiz, surface, frame))
|
||||||
unmap_frame (thiz, surface);
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (thiz, "surface %p TimeStamp: %" G_GUINT64_FORMAT
|
GST_DEBUG_OBJECT (thiz, "surface %p TimeStamp: %" G_GUINT64_FORMAT
|
||||||
" frame %p TimeStamp: %" G_GUINT64_FORMAT,
|
" frame %p TimeStamp: %" G_GUINT64_FORMAT,
|
||||||
surface->surface, (guint64) surface->surface->Data.TimeStamp,
|
surface->surface, (guint64) surface->surface->Data.TimeStamp,
|
||||||
|
@ -1035,6 +977,7 @@ gst_msdkdec_finish_task (GstMsdkDec * thiz, MsdkDecTask * task)
|
||||||
return flow;
|
return flow;
|
||||||
}
|
}
|
||||||
finish_task (thiz, task);
|
finish_task (thiz, task);
|
||||||
|
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1142,6 +1085,10 @@ gst_msdkdec_stop (GstVideoDecoder * decoder)
|
||||||
gst_object_unref (thiz->pool);
|
gst_object_unref (thiz->pool);
|
||||||
thiz->pool = NULL;
|
thiz->pool = NULL;
|
||||||
}
|
}
|
||||||
|
if (thiz->other_pool) {
|
||||||
|
gst_object_unref (thiz->other_pool);
|
||||||
|
thiz->other_pool = NULL;
|
||||||
|
}
|
||||||
gst_video_info_init (&thiz->non_msdk_pool_info);
|
gst_video_info_init (&thiz->non_msdk_pool_info);
|
||||||
|
|
||||||
gst_msdkdec_close_decoder (thiz, TRUE);
|
gst_msdkdec_close_decoder (thiz, TRUE);
|
||||||
|
@ -1177,13 +1124,12 @@ static void
|
||||||
release_msdk_surfaces (GstMsdkDec * thiz)
|
release_msdk_surfaces (GstMsdkDec * thiz)
|
||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
MsdkSurface *surface;
|
GstMsdkSurface *surface;
|
||||||
gint locked = 0;
|
gint locked = 0;
|
||||||
gst_msdkdec_free_unlocked_msdk_surfaces (thiz);
|
gst_msdkdec_free_unlocked_msdk_surfaces (thiz);
|
||||||
|
|
||||||
for (l = thiz->locked_msdk_surfaces; l; l = l->next) {
|
for (l = thiz->locked_msdk_surfaces; l; l = l->next) {
|
||||||
surface = (MsdkSurface *) l->data;
|
surface = (GstMsdkSurface *) l->data;
|
||||||
unmap_frame (thiz, surface);
|
|
||||||
free_surface (surface);
|
free_surface (surface);
|
||||||
locked++;
|
locked++;
|
||||||
}
|
}
|
||||||
|
@ -1283,7 +1229,7 @@ find_msdk_surface (GstMsdkDec * thiz, MsdkDecTask * task,
|
||||||
GST_ERROR_OBJECT (thiz, "msdk return an invalid surface %p", out_surface);
|
GST_ERROR_OBJECT (thiz, "msdk return an invalid surface %p", out_surface);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
task->surface = (MsdkSurface *) l->data;
|
task->surface = (GstMsdkSurface *) l->data;
|
||||||
thiz->locked_msdk_surfaces =
|
thiz->locked_msdk_surfaces =
|
||||||
g_list_delete_link (thiz->locked_msdk_surfaces, l);
|
g_list_delete_link (thiz->locked_msdk_surfaces, l);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -1356,11 +1302,11 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
|
||||||
GstMsdkDec *thiz = GST_MSDKDEC (decoder);
|
GstMsdkDec *thiz = GST_MSDKDEC (decoder);
|
||||||
GstMsdkDecClass *klass = GST_MSDKDEC_GET_CLASS (thiz);
|
GstMsdkDecClass *klass = GST_MSDKDEC_GET_CLASS (thiz);
|
||||||
GstFlowReturn flow;
|
GstFlowReturn flow;
|
||||||
GstBuffer *buffer, *input_buffer = NULL;
|
GstBuffer *input_buffer = NULL;
|
||||||
GstVideoInfo alloc_info;
|
GstVideoInfo alloc_info;
|
||||||
MsdkDecTask *task = NULL;
|
MsdkDecTask *task = NULL;
|
||||||
mfxBitstream bitstream;
|
mfxBitstream bitstream;
|
||||||
MsdkSurface *surface = NULL;
|
GstMsdkSurface *surface = NULL;
|
||||||
mfxFrameSurface1 *out_surface = NULL;
|
mfxFrameSurface1 *out_surface = NULL;
|
||||||
mfxSession session;
|
mfxSession session;
|
||||||
mfxStatus status;
|
mfxStatus status;
|
||||||
|
@ -1530,13 +1476,7 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
flow = allocate_output_buffer (thiz, &buffer);
|
surface = allocate_output_surface (thiz);
|
||||||
if (flow == GST_FLOW_CUSTOM_SUCCESS) {
|
|
||||||
flow = GST_FLOW_OK;
|
|
||||||
break;
|
|
||||||
} else if (flow != GST_FLOW_OK)
|
|
||||||
goto error;
|
|
||||||
surface = get_surface (thiz, buffer);
|
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
/* Can't get a surface for some reason; finish tasks, then see if
|
/* Can't get a surface for some reason; finish tasks, then see if
|
||||||
a surface becomes available. */
|
a surface becomes available. */
|
||||||
|
@ -1546,7 +1486,7 @@ gst_msdkdec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
|
||||||
flow = gst_msdkdec_finish_task (thiz, task);
|
flow = gst_msdkdec_finish_task (thiz, task);
|
||||||
if (flow != GST_FLOW_OK)
|
if (flow != GST_FLOW_OK)
|
||||||
goto error;
|
goto error;
|
||||||
surface = get_surface (thiz, buffer);
|
surface = allocate_output_surface (thiz);
|
||||||
if (surface)
|
if (surface)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1711,91 +1651,6 @@ gst_msdkdec_parse (GstVideoDecoder * decoder, GstVideoCodecFrame * frame,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstBufferPool *
|
|
||||||
gst_msdkdec_create_buffer_pool (GstMsdkDec * thiz, GstVideoInfo * info,
|
|
||||||
guint num_buffers)
|
|
||||||
{
|
|
||||||
GstBufferPool *pool = NULL;
|
|
||||||
GstStructure *config;
|
|
||||||
GstAllocator *allocator = NULL;
|
|
||||||
GstVideoAlignment align;
|
|
||||||
GstCaps *caps = NULL;
|
|
||||||
GstAllocationParams params = { 0, 31, 0, 0, };
|
|
||||||
mfxFrameAllocResponse *alloc_resp = NULL;
|
|
||||||
|
|
||||||
g_return_val_if_fail (info, NULL);
|
|
||||||
g_return_val_if_fail (GST_VIDEO_INFO_WIDTH (info)
|
|
||||||
&& GST_VIDEO_INFO_HEIGHT (info), NULL);
|
|
||||||
|
|
||||||
alloc_resp = &thiz->alloc_resp;
|
|
||||||
|
|
||||||
pool = gst_msdk_buffer_pool_new (thiz->context, alloc_resp);
|
|
||||||
if (!pool)
|
|
||||||
goto error_no_pool;
|
|
||||||
|
|
||||||
caps = gst_video_info_to_caps (info);
|
|
||||||
|
|
||||||
/* allocators should use the same width/height/stride/height_alignment of
|
|
||||||
* negotiated output caps, which is what we configure in msdk_allocator */
|
|
||||||
if (thiz->use_dmabuf)
|
|
||||||
allocator = gst_msdk_dmabuf_allocator_new (thiz->context, info, alloc_resp);
|
|
||||||
else if (thiz->use_video_memory)
|
|
||||||
allocator = gst_msdk_video_allocator_new (thiz->context, info, alloc_resp);
|
|
||||||
else
|
|
||||||
allocator = gst_msdk_system_allocator_new (info);
|
|
||||||
|
|
||||||
if (!allocator) {
|
|
||||||
gst_caps_unref (caps);
|
|
||||||
goto error_no_allocator;
|
|
||||||
}
|
|
||||||
|
|
||||||
config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool));
|
|
||||||
/* we need register all bufffers when we create the msdk context, so the buffer pool is not resize able */
|
|
||||||
gst_buffer_pool_config_set_params (config, caps,
|
|
||||||
GST_VIDEO_INFO_SIZE (info), num_buffers, num_buffers);
|
|
||||||
gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META);
|
|
||||||
gst_buffer_pool_config_add_option (config,
|
|
||||||
GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
|
|
||||||
gst_caps_unref (caps);
|
|
||||||
|
|
||||||
if (thiz->use_video_memory) {
|
|
||||||
gst_buffer_pool_config_add_option (config,
|
|
||||||
GST_BUFFER_POOL_OPTION_MSDK_USE_VIDEO_MEMORY);
|
|
||||||
if (thiz->use_dmabuf)
|
|
||||||
gst_buffer_pool_config_add_option (config,
|
|
||||||
GST_BUFFER_POOL_OPTION_MSDK_USE_DMABUF);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
gst_buffer_pool_config_set_video_alignment (config, &align);
|
|
||||||
gst_buffer_pool_config_set_allocator (config, allocator, ¶ms);
|
|
||||||
gst_object_unref (allocator);
|
|
||||||
|
|
||||||
if (!gst_buffer_pool_set_config (pool, config))
|
|
||||||
goto error_pool_config;
|
|
||||||
|
|
||||||
return pool;
|
|
||||||
|
|
||||||
error_no_pool:
|
|
||||||
{
|
|
||||||
GST_INFO_OBJECT (thiz, "failed to create bufferpool");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
error_no_allocator:
|
|
||||||
{
|
|
||||||
GST_INFO_OBJECT (thiz, "failed to create allocator");
|
|
||||||
gst_object_unref (pool);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
error_pool_config:
|
|
||||||
{
|
|
||||||
GST_INFO_OBJECT (thiz, "failed to set config");
|
|
||||||
gst_object_unref (pool);
|
|
||||||
gst_object_unref (allocator);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
static GstBufferPool *
|
static GstBufferPool *
|
||||||
gst_msdk_create_va_pool (GstMsdkDec * thiz, GstVideoInfo * info,
|
gst_msdk_create_va_pool (GstMsdkDec * thiz, GstVideoInfo * info,
|
||||||
|
@ -1840,7 +1695,7 @@ gst_msdk_create_va_pool (GstMsdkDec * thiz, GstVideoInfo * info,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static GstBufferPool *
|
static GstBufferPool *
|
||||||
gst_msdkdec_create_buffer_pool2 (GstMsdkDec * thiz, GstVideoInfo * info,
|
gst_msdkdec_create_buffer_pool (GstMsdkDec * thiz, GstVideoInfo * info,
|
||||||
guint num_buffers)
|
guint num_buffers)
|
||||||
{
|
{
|
||||||
GstBufferPool *pool = NULL;
|
GstBufferPool *pool = NULL;
|
||||||
|
@ -1903,7 +1758,7 @@ gst_msdkdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
GstStructure *pool_config = NULL;
|
GstStructure *pool_config = NULL;
|
||||||
GstCaps *pool_caps /*, *negotiated_caps */ ;
|
GstCaps *pool_caps /*, *negotiated_caps */ ;
|
||||||
guint size, min_buffers, max_buffers;
|
guint size, min_buffers, max_buffers;
|
||||||
GstAllocator *allocator = NULL;
|
gboolean has_videometa, has_video_alignment;
|
||||||
|
|
||||||
if (!thiz->param.mfx.FrameInfo.Width || !thiz->param.mfx.FrameInfo.Height)
|
if (!thiz->param.mfx.FrameInfo.Width || !thiz->param.mfx.FrameInfo.Height)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1918,6 +1773,11 @@ gst_msdkdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
|
gst_query_parse_nth_allocation_pool (query, 0, &pool, NULL, NULL, NULL);
|
||||||
pool_config = gst_buffer_pool_get_config (pool);
|
pool_config = gst_buffer_pool_get_config (pool);
|
||||||
|
|
||||||
|
has_videometa = gst_query_find_allocation_meta
|
||||||
|
(query, GST_VIDEO_META_API_TYPE, NULL);
|
||||||
|
has_video_alignment = gst_buffer_pool_has_option
|
||||||
|
(pool, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT);
|
||||||
|
|
||||||
/* Get the caps of pool and increase the min and max buffers by async_depth.
|
/* Get the caps of pool and increase the min and max buffers by async_depth.
|
||||||
* We will always have that number of decode operations in-flight */
|
* We will always have that number of decode operations in-flight */
|
||||||
gst_buffer_pool_config_get_params (pool_config, &pool_caps, &size,
|
gst_buffer_pool_config_get_params (pool_config, &pool_caps, &size,
|
||||||
|
@ -1933,21 +1793,8 @@ gst_msdkdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
thiz->min_prealloc_buffers = min_buffers;
|
thiz->min_prealloc_buffers = min_buffers;
|
||||||
|
|
||||||
if (_gst_caps_has_feature (pool_caps, GST_CAPS_FEATURE_MEMORY_DMABUF)) {
|
if (_gst_caps_has_feature (pool_caps, GST_CAPS_FEATURE_MEMORY_DMABUF)) {
|
||||||
GST_INFO_OBJECT (decoder, "This MSDK decoder uses DMABuf memory");
|
thiz->use_dmabuf = TRUE;
|
||||||
thiz->use_video_memory = thiz->use_dmabuf = TRUE;
|
}
|
||||||
} else if (thiz->sfc)
|
|
||||||
thiz->use_video_memory = TRUE;
|
|
||||||
|
|
||||||
/* Initialize MSDK decoder before new bufferpool tries to alloc each buffer,
|
|
||||||
* which requires information about frame allocation.
|
|
||||||
* No effect if already initialized.
|
|
||||||
*/
|
|
||||||
if (!gst_msdkdec_init_decoder (thiz))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* get the updated min_buffers, which account for the msdk requirement as well */
|
|
||||||
min_buffers = thiz->min_prealloc_buffers;
|
|
||||||
|
|
||||||
/* Decoder always use its own pool. So we create a pool if msdk APIs
|
/* Decoder always use its own pool. So we create a pool if msdk APIs
|
||||||
* previously requested for allocation (do_realloc = TRUE) */
|
* previously requested for allocation (do_realloc = TRUE) */
|
||||||
if (thiz->do_realloc || !thiz->pool) {
|
if (thiz->do_realloc || !thiz->pool) {
|
||||||
|
@ -1963,24 +1810,22 @@ gst_msdkdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
goto failed_to_create_pool;
|
goto failed_to_create_pool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef _WIN32
|
||||||
|
GstAllocator *allocator = NULL;
|
||||||
if (gst_query_get_n_allocation_params (query) > 0) {
|
if (gst_query_get_n_allocation_params (query) > 0) {
|
||||||
gst_query_parse_nth_allocation_param (query, 0, &allocator, NULL);
|
gst_query_parse_nth_allocation_param (query, 0, &allocator, NULL);
|
||||||
if (!(GST_IS_MSDK_VIDEO_ALLOCATOR (allocator) ||
|
if (!(GST_IS_VA_ALLOCATOR (allocator) ||
|
||||||
GST_IS_MSDK_DMABUF_ALLOCATOR (allocator) ||
|
GST_IS_VA_DMABUF_ALLOCATOR (allocator)))
|
||||||
GST_IS_MSDK_SYSTEM_ALLOCATOR (allocator)))
|
thiz->ds_has_known_allocator = FALSE;
|
||||||
thiz->ds_has_no_msdk_allocator = TRUE;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If downstream supports video meta and video alignment,
|
/* If downstream supports video meta and video alignment, or downstream
|
||||||
* or downstream doesn't have msdk_allocator, we can replace
|
* doesn't have known allocator (known allocator refers to va allocator
|
||||||
* with our own msdk bufferpool and use it.
|
* or d3d allocator), we replace with our own bufferpool and use it.
|
||||||
*/
|
*/
|
||||||
if ((gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)
|
if ((has_videometa && has_video_alignment)
|
||||||
&& gst_buffer_pool_has_option
|
|| !thiz->ds_has_known_allocator) {
|
||||||
(pool, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT))
|
|
||||||
|| thiz->ds_has_no_msdk_allocator) {
|
|
||||||
GstStructure *config;
|
GstStructure *config;
|
||||||
GstAllocator *allocator;
|
GstAllocator *allocator;
|
||||||
|
|
||||||
|
@ -1997,9 +1842,9 @@ gst_msdkdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
gst_query_set_nth_allocation_param (query, 0, allocator, NULL);
|
gst_query_set_nth_allocation_param (query, 0, allocator, NULL);
|
||||||
gst_structure_free (config);
|
gst_structure_free (config);
|
||||||
} else {
|
} else {
|
||||||
/* Unfortunately, downstream doesn't have videometa or alignment support,
|
/* When downstream doesn't have videometa or alignment support,
|
||||||
* we keep msdk pool as a side-pool that will be decoded into and
|
* or downstream pool is va/d3d pool,we will use downstream pool
|
||||||
* then copied from.
|
* and keep decoder's own pool as side-pool.
|
||||||
*/
|
*/
|
||||||
GstVideoCodecState *output_state = NULL;
|
GstVideoCodecState *output_state = NULL;
|
||||||
|
|
||||||
|
@ -2023,9 +1868,33 @@ gst_msdkdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
GST_VIDEO_INFO_HEIGHT (&thiz->non_msdk_pool_info) =
|
GST_VIDEO_INFO_HEIGHT (&thiz->non_msdk_pool_info) =
|
||||||
GST_VIDEO_INFO_HEIGHT (&output_state->info);
|
GST_VIDEO_INFO_HEIGHT (&output_state->info);
|
||||||
|
|
||||||
/* When downstream allocator is unknown and negotiaed caps is raw,
|
gst_video_codec_state_unref (output_state);
|
||||||
* we need to create other pool with system memory for copy use
|
}
|
||||||
|
|
||||||
|
gst_msdk_context_set_alloc_pool (thiz->context, pool);
|
||||||
|
|
||||||
|
/* Initialize MSDK decoder before new bufferpool tries to alloc each buffer,
|
||||||
|
* which requires information about frame allocation.
|
||||||
|
* No effect if already initialized.
|
||||||
|
*/
|
||||||
|
if (!gst_msdkdec_init_decoder (thiz))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* get the updated min_buffers, which account for the msdk requirement as well */
|
||||||
|
min_buffers = thiz->min_prealloc_buffers;
|
||||||
|
|
||||||
|
if (!has_videometa && !thiz->ds_has_known_allocator
|
||||||
|
&& _gst_caps_has_feature (pool_caps,
|
||||||
|
GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY)) {
|
||||||
|
/* We need to create other pool with system memory for copy use under conditions:
|
||||||
|
* (1) downstream has no videometa; (2) downstream allocator is unknown;
|
||||||
|
* (3) negotiated caps is raw.
|
||||||
*/
|
*/
|
||||||
|
thiz->do_copy = TRUE;
|
||||||
|
GstVideoCodecState *output_state =
|
||||||
|
gst_video_decoder_get_output_state (GST_VIDEO_DECODER (thiz));
|
||||||
|
thiz->other_pool =
|
||||||
|
gst_msdkdec_create_buffer_pool (thiz, &output_state->info, min_buffers);
|
||||||
gst_video_codec_state_unref (output_state);
|
gst_video_codec_state_unref (output_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2035,7 +1904,6 @@ gst_msdkdec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query)
|
||||||
if (pool)
|
if (pool)
|
||||||
gst_object_unref (pool);
|
gst_object_unref (pool);
|
||||||
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
failed_to_create_pool:
|
failed_to_create_pool:
|
||||||
|
@ -2056,9 +1924,8 @@ gst_msdkdec_drain (GstVideoDecoder * decoder)
|
||||||
{
|
{
|
||||||
GstMsdkDec *thiz = GST_MSDKDEC (decoder);
|
GstMsdkDec *thiz = GST_MSDKDEC (decoder);
|
||||||
GstFlowReturn flow;
|
GstFlowReturn flow;
|
||||||
GstBuffer *buffer;
|
|
||||||
MsdkDecTask *task;
|
MsdkDecTask *task;
|
||||||
MsdkSurface *surface = NULL;
|
GstMsdkSurface *surface = NULL;
|
||||||
mfxFrameSurface1 *out_surface;
|
mfxFrameSurface1 *out_surface;
|
||||||
mfxSession session;
|
mfxSession session;
|
||||||
mfxStatus status;
|
mfxStatus status;
|
||||||
|
@ -2078,10 +1945,7 @@ gst_msdkdec_drain (GstVideoDecoder * decoder)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!surface) {
|
if (!surface) {
|
||||||
flow = allocate_output_buffer (thiz, &buffer);
|
surface = allocate_output_surface (thiz);
|
||||||
if (flow != GST_FLOW_OK)
|
|
||||||
return flow;
|
|
||||||
surface = get_surface (thiz, buffer);
|
|
||||||
if (!surface)
|
if (!surface)
|
||||||
return GST_FLOW_ERROR;
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
@ -2384,9 +2248,12 @@ gst_msdkdec_init (GstMsdkDec * thiz)
|
||||||
thiz->force_reset_on_res_change = TRUE;
|
thiz->force_reset_on_res_change = TRUE;
|
||||||
thiz->report_error = FALSE;
|
thiz->report_error = FALSE;
|
||||||
thiz->sfc = FALSE;
|
thiz->sfc = FALSE;
|
||||||
thiz->ds_has_no_msdk_allocator = FALSE;
|
thiz->ds_has_known_allocator = TRUE;
|
||||||
thiz->adapter = gst_adapter_new ();
|
thiz->adapter = gst_adapter_new ();
|
||||||
thiz->input_state = NULL;
|
thiz->input_state = NULL;
|
||||||
thiz->pool = NULL;
|
thiz->pool = NULL;
|
||||||
thiz->context = NULL;
|
thiz->context = NULL;
|
||||||
|
#ifndef _WIN32
|
||||||
|
thiz->use_video_memory = TRUE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ struct _GstMsdkDec
|
||||||
gboolean do_copy;
|
gboolean do_copy;
|
||||||
gboolean initialized;
|
gboolean initialized;
|
||||||
gboolean sfc;
|
gboolean sfc;
|
||||||
gboolean ds_has_no_msdk_allocator;
|
gboolean ds_has_known_allocator;
|
||||||
|
|
||||||
/* for packetization */
|
/* for packetization */
|
||||||
GstAdapter *adapter;
|
GstAdapter *adapter;
|
||||||
|
|
Loading…
Reference in a new issue