mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +00:00
msdkenc: Directly import dmabuf memory as mfx surface
When input buffer is of dmabuf memory but not a msdk buffer (i.e., the allocator is not msdk_allocator), then we can try to get fd of this mem, create the corresponding va surface and wrap it as mfx surface. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2498>
This commit is contained in:
parent
b2e18f7f88
commit
956dc40fb8
1 changed files with 31 additions and 22 deletions
|
@ -1650,12 +1650,16 @@ import_dmabuf_to_msdk_surface (GstMsdkEnc * thiz, GstBuffer * buf,
|
||||||
GstVideoMeta *vmeta;
|
GstVideoMeta *vmeta;
|
||||||
GstMsdkMemoryID *msdk_mid = NULL;
|
GstMsdkMemoryID *msdk_mid = NULL;
|
||||||
mfxFrameSurface1 *mfx_surface = NULL;
|
mfxFrameSurface1 *mfx_surface = NULL;
|
||||||
|
mfxMemId *mfx_mid = NULL;
|
||||||
|
VASurfaceID *va_surface = NULL;
|
||||||
|
mfxFrameInfo frame_info = { {0,}, 0, };
|
||||||
gint fd, i;
|
gint fd, i;
|
||||||
mem = gst_buffer_peek_memory (buf, 0);
|
mem = gst_buffer_peek_memory (buf, 0);
|
||||||
fd = gst_dmabuf_memory_get_fd (mem);
|
fd = gst_dmabuf_memory_get_fd (mem);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
va_surface = g_slice_new0 (VASurfaceID);
|
||||||
vinfo = thiz->input_state->info;
|
vinfo = thiz->input_state->info;
|
||||||
/* Update offset/stride/size if there is VideoMeta attached to
|
/* Update offset/stride/size if there is VideoMeta attached to
|
||||||
* the buffer */
|
* the buffer */
|
||||||
|
@ -1688,16 +1692,26 @@ import_dmabuf_to_msdk_surface (GstMsdkEnc * thiz, GstBuffer * buf,
|
||||||
if (GST_VIDEO_INFO_SIZE (&vinfo) < GST_VIDEO_INFO_SIZE (&thiz->aligned_info))
|
if (GST_VIDEO_INFO_SIZE (&vinfo) < GST_VIDEO_INFO_SIZE (&thiz->aligned_info))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
mfx_surface = msdk_surface->surface;
|
|
||||||
msdk_mid = (GstMsdkMemoryID *) mfx_surface->Data.MemId;
|
|
||||||
|
|
||||||
/* release the internal memory storage of associated mfxSurface */
|
|
||||||
gst_msdk_replace_mfx_memid (thiz->context, mfx_surface, VA_INVALID_ID);
|
|
||||||
|
|
||||||
/* export dmabuf to vasurface */
|
/* export dmabuf to vasurface */
|
||||||
if (!gst_msdk_export_dmabuf_to_vasurface (thiz->context, &vinfo, fd,
|
if (!gst_msdk_export_dmabuf_to_vasurface (thiz->context, &vinfo, fd,
|
||||||
msdk_mid->surface))
|
va_surface)) {
|
||||||
|
g_slice_free (VASurfaceID, va_surface);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
msdk_mid = g_slice_new0 (GstMsdkMemoryID);
|
||||||
|
msdk_mid->surface = g_slice_new0 (VASurfaceID);
|
||||||
|
mfx_surface = g_slice_new0 (mfxFrameSurface1);
|
||||||
|
|
||||||
|
msdk_mid->surface = va_surface;
|
||||||
|
mfx_mid = (mfxMemId *) msdk_mid;
|
||||||
|
mfx_surface->Data.MemId = mfx_mid;
|
||||||
|
|
||||||
|
gst_msdk_set_mfx_frame_info_from_video_info (&frame_info, &vinfo);
|
||||||
|
mfx_surface->Info = frame_info;
|
||||||
|
|
||||||
|
msdk_surface->surface = mfx_surface;
|
||||||
|
msdk_surface->buf = gst_buffer_ref (buf);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1762,29 +1776,24 @@ gst_msdkenc_get_surface_from_frame (GstMsdkEnc * thiz,
|
||||||
else
|
else
|
||||||
g_slice_free (MsdkSurface, msdk_surface);
|
g_slice_free (MsdkSurface, msdk_surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mem = gst_buffer_peek_memory (inbuf, 0);
|
||||||
|
if (gst_is_dmabuf_memory (mem)) {
|
||||||
|
msdk_surface = g_slice_new0 (MsdkSurface);
|
||||||
|
if (import_dmabuf_to_msdk_surface (thiz, inbuf, msdk_surface))
|
||||||
|
return msdk_surface;
|
||||||
|
else
|
||||||
|
g_slice_free (MsdkSurface, msdk_surface);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If upstream hasn't accpeted the proposed msdk bufferpool,
|
/* If upstream hasn't accpeted the proposed msdk bufferpool,
|
||||||
* just copy frame (if not dmabuf backed )to msdk buffer and take a surface from it.
|
* just copy frame to msdk buffer and take a surface from it.
|
||||||
*/
|
*/
|
||||||
if (!(msdk_surface =
|
if (!(msdk_surface =
|
||||||
gst_msdkenc_get_surface_from_pool (thiz, thiz->msdk_pool, NULL)))
|
gst_msdkenc_get_surface_from_pool (thiz, thiz->msdk_pool, NULL)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
/************ dmabuf-import ************* */
|
|
||||||
/* if upstream provided a dmabuf backed memory, but not an msdk
|
|
||||||
* buffer, we could try to export the dmabuf to underlined vasurface */
|
|
||||||
mem = gst_buffer_peek_memory (inbuf, 0);
|
|
||||||
if (gst_is_dmabuf_memory (mem)) {
|
|
||||||
if (import_dmabuf_to_msdk_surface (thiz, inbuf, msdk_surface))
|
|
||||||
return msdk_surface;
|
|
||||||
else
|
|
||||||
GST_INFO_OBJECT (thiz, "Upstream dmabuf-backed memory is not imported"
|
|
||||||
"to the msdk surface, fall back to the copy input frame method");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!gst_video_frame_map (&src_frame, &thiz->input_state->info, inbuf,
|
if (!gst_video_frame_map (&src_frame, &thiz->input_state->info, inbuf,
|
||||||
GST_MAP_READ)) {
|
GST_MAP_READ)) {
|
||||||
GST_ERROR_OBJECT (thiz, "failed to map the frame for source");
|
GST_ERROR_OBJECT (thiz, "failed to map the frame for source");
|
||||||
|
|
Loading…
Reference in a new issue