mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
d3dvideosink: Allocate a new offscreen surface for every buffer
This is a preparation for implementing a buffer pool.
This commit is contained in:
parent
65cb59912b
commit
abede65bbc
1 changed files with 33 additions and 27 deletions
|
@ -38,7 +38,7 @@ static gboolean d3d_release_swap_chain (GstD3DVideoSink * sink);
|
||||||
static gboolean d3d_resize_swap_chain (GstD3DVideoSink * sink);
|
static gboolean d3d_resize_swap_chain (GstD3DVideoSink * sink);
|
||||||
static gboolean d3d_present_swap_chain (GstD3DVideoSink * sink);
|
static gboolean d3d_present_swap_chain (GstD3DVideoSink * sink);
|
||||||
static gboolean d3d_copy_buffer_to_surface (GstD3DVideoSink * sink,
|
static gboolean d3d_copy_buffer_to_surface (GstD3DVideoSink * sink,
|
||||||
GstBuffer * buffer);
|
LPDIRECT3DSURFACE9 surface, GstBuffer * buffer);
|
||||||
static gboolean d3d_stretch_and_copy (GstD3DVideoSink * sink,
|
static gboolean d3d_stretch_and_copy (GstD3DVideoSink * sink,
|
||||||
LPDIRECT3DSURFACE9 back_buffer);
|
LPDIRECT3DSURFACE9 back_buffer);
|
||||||
static HWND d3d_create_internal_window (GstD3DVideoSink * sink);
|
static HWND d3d_create_internal_window (GstD3DVideoSink * sink);
|
||||||
|
@ -819,7 +819,6 @@ d3d_init_swap_chain (GstD3DVideoSink * sink, HWND hWnd)
|
||||||
{
|
{
|
||||||
D3DPRESENT_PARAMETERS present_params;
|
D3DPRESENT_PARAMETERS present_params;
|
||||||
LPDIRECT3DSWAPCHAIN9 d3d_swapchain = NULL;
|
LPDIRECT3DSWAPCHAIN9 d3d_swapchain = NULL;
|
||||||
LPDIRECT3DSURFACE9 d3d_surface = NULL;
|
|
||||||
D3DTEXTUREFILTERTYPE d3d_filtertype;
|
D3DTEXTUREFILTERTYPE d3d_filtertype;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
GstD3DVideoSinkClass *klass;
|
GstD3DVideoSinkClass *klass;
|
||||||
|
@ -859,15 +858,6 @@ d3d_init_swap_chain (GstD3DVideoSink * sink, HWND hWnd)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IDirect3DDevice9_CreateOffscreenPlainSurface (klass->d3d.
|
|
||||||
device.d3d_device, GST_VIDEO_SINK_WIDTH (sink),
|
|
||||||
GST_VIDEO_SINK_HEIGHT (sink), sink->d3d.format, D3DPOOL_DEFAULT,
|
|
||||||
&d3d_surface, NULL);
|
|
||||||
if (hr != D3D_OK) {
|
|
||||||
GST_ERROR_OBJECT (sink, "Failed to create D3D surface");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine texture filtering support. If it's supported for this format,
|
/* Determine texture filtering support. If it's supported for this format,
|
||||||
* use the filter type determined when we created the dev and checked the
|
* use the filter type determined when we created the dev and checked the
|
||||||
* dev caps.
|
* dev caps.
|
||||||
|
@ -886,7 +876,6 @@ d3d_init_swap_chain (GstD3DVideoSink * sink, HWND hWnd)
|
||||||
|
|
||||||
sink->d3d.filtertype = d3d_filtertype;
|
sink->d3d.filtertype = d3d_filtertype;
|
||||||
sink->d3d.swapchain = d3d_swapchain;
|
sink->d3d.swapchain = d3d_swapchain;
|
||||||
sink->d3d.surface = d3d_surface;
|
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
|
@ -894,8 +883,6 @@ error:
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
if (d3d_swapchain)
|
if (d3d_swapchain)
|
||||||
IDirect3DSwapChain9_Release (d3d_swapchain);
|
IDirect3DSwapChain9_Release (d3d_swapchain);
|
||||||
if (d3d_surface)
|
|
||||||
IDirect3DSurface9_Release (d3d_surface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UNLOCK_CLASS (sink, klass);
|
UNLOCK_CLASS (sink, klass);
|
||||||
|
@ -917,23 +904,23 @@ d3d_release_swap_chain (GstD3DVideoSink * sink)
|
||||||
|
|
||||||
CHECK_D3D_DEVICE (klass, sink, end);
|
CHECK_D3D_DEVICE (klass, sink, end);
|
||||||
|
|
||||||
if (!sink->d3d.swapchain && !sink->d3d.surface) {
|
if (!sink->d3d.swapchain) {
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sink->d3d.surface) {
|
|
||||||
ref_count = IDirect3DSurface9_Release (sink->d3d.surface);
|
|
||||||
sink->d3d.surface = NULL;
|
|
||||||
GST_DEBUG_OBJECT (sink, "D3D surface released. Ref count: %d", ref_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sink->d3d.swapchain) {
|
if (sink->d3d.swapchain) {
|
||||||
ref_count = IDirect3DSwapChain9_Release (sink->d3d.swapchain);
|
ref_count = IDirect3DSwapChain9_Release (sink->d3d.swapchain);
|
||||||
sink->d3d.swapchain = NULL;
|
sink->d3d.swapchain = NULL;
|
||||||
GST_DEBUG_OBJECT (sink, "D3D swapchain released. Ref count: %d", ref_count);
|
GST_DEBUG_OBJECT (sink, "D3D swapchain released. Ref count: %d", ref_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sink->d3d.surface) {
|
||||||
|
ref_count = IDirect3DSurface9_Release (sink->d3d.surface);
|
||||||
|
sink->d3d.surface = NULL;
|
||||||
|
GST_DEBUG_OBJECT (sink, "D3D surface released. Ref count: %d", ref_count);
|
||||||
|
}
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -1044,7 +1031,8 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
d3d_copy_buffer_to_surface (GstD3DVideoSink * sink, GstBuffer * buffer)
|
d3d_copy_buffer_to_surface (GstD3DVideoSink * sink, LPDIRECT3DSURFACE9 surface,
|
||||||
|
GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
D3DLOCKED_RECT lr;
|
D3DLOCKED_RECT lr;
|
||||||
guint8 *dest;
|
guint8 *dest;
|
||||||
|
@ -1063,9 +1051,7 @@ d3d_copy_buffer_to_surface (GstD3DVideoSink * sink, GstBuffer * buffer)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_D3D_SURFACE (sink, end);
|
IDirect3DSurface9_LockRect (surface, &lr, NULL, 0);
|
||||||
|
|
||||||
IDirect3DSurface9_LockRect (sink->d3d.surface, &lr, NULL, 0);
|
|
||||||
dest = (guint8 *) lr.pBits;
|
dest = (guint8 *) lr.pBits;
|
||||||
|
|
||||||
if (!dest) {
|
if (!dest) {
|
||||||
|
@ -1241,7 +1227,7 @@ unhandled_format:
|
||||||
done:
|
done:
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
unlock_surface:
|
unlock_surface:
|
||||||
IDirect3DSurface9_UnlockRect (sink->d3d.surface);
|
IDirect3DSurface9_UnlockRect (surface);
|
||||||
gst_video_frame_unmap (&frame);
|
gst_video_frame_unmap (&frame);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -1412,6 +1398,7 @@ d3d_render_buffer (GstD3DVideoSink * sink, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
GstMapInfo map;
|
GstMapInfo map;
|
||||||
|
LPDIRECT3DSURFACE9 surface = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (gst_buffer_map (buf, &map, GST_MAP_READ) != FALSE,
|
g_return_val_if_fail (gst_buffer_map (buf, &map, GST_MAP_READ) != FALSE,
|
||||||
GST_FLOW_ERROR);
|
GST_FLOW_ERROR);
|
||||||
|
@ -1441,7 +1428,26 @@ d3d_render_buffer (GstD3DVideoSink * sink, GstBuffer * buf)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
d3d_copy_buffer_to_surface (sink, buf);
|
if (!surface) {
|
||||||
|
HRESULT hr;
|
||||||
|
GstD3DVideoSinkClass *klass = GST_D3DVIDEOSINK_GET_CLASS (sink);
|
||||||
|
|
||||||
|
hr = IDirect3DDevice9_CreateOffscreenPlainSurface (klass->d3d.
|
||||||
|
device.d3d_device, GST_VIDEO_SINK_WIDTH (sink),
|
||||||
|
GST_VIDEO_SINK_HEIGHT (sink), sink->d3d.format, D3DPOOL_DEFAULT,
|
||||||
|
&surface, NULL);
|
||||||
|
if (hr != D3D_OK || surface == NULL) {
|
||||||
|
GST_ERROR_OBJECT (sink, "Failed to create D3D surface");
|
||||||
|
ret = GST_FLOW_ERROR;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
d3d_copy_buffer_to_surface (sink, surface, buf);
|
||||||
|
if (sink->d3d.surface)
|
||||||
|
IDirect3DSurface9_Release (sink->d3d.surface);
|
||||||
|
IDirect3DSurface9_AddRef (surface);
|
||||||
|
sink->d3d.surface = surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!d3d_present_swap_chain (sink)) {
|
if (!d3d_present_swap_chain (sink)) {
|
||||||
ret = GST_FLOW_ERROR;
|
ret = GST_FLOW_ERROR;
|
||||||
|
|
Loading…
Reference in a new issue