From abede65bbcaa26df1fdcffe6cca6f49a8b44370f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 22 Dec 2012 19:12:34 +0100 Subject: d3dvideosink: Allocate a new offscreen surface for every buffer This is a preparation for implementing a buffer pool. --- sys/d3dvideosink/d3dhelpers.c | 60 ++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 27 deletions(-) (limited to 'sys/d3dvideosink') diff --git a/sys/d3dvideosink/d3dhelpers.c b/sys/d3dvideosink/d3dhelpers.c index 7f053a671..081d4029d 100644 --- a/sys/d3dvideosink/d3dhelpers.c +++ b/sys/d3dvideosink/d3dhelpers.c @@ -38,7 +38,7 @@ static gboolean d3d_release_swap_chain (GstD3DVideoSink * sink); static gboolean d3d_resize_swap_chain (GstD3DVideoSink * sink); static gboolean d3d_present_swap_chain (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, LPDIRECT3DSURFACE9 back_buffer); static HWND d3d_create_internal_window (GstD3DVideoSink * sink); @@ -819,7 +819,6 @@ d3d_init_swap_chain (GstD3DVideoSink * sink, HWND hWnd) { D3DPRESENT_PARAMETERS present_params; LPDIRECT3DSWAPCHAIN9 d3d_swapchain = NULL; - LPDIRECT3DSURFACE9 d3d_surface = NULL; D3DTEXTUREFILTERTYPE d3d_filtertype; HRESULT hr; GstD3DVideoSinkClass *klass; @@ -859,15 +858,6 @@ d3d_init_swap_chain (GstD3DVideoSink * sink, HWND hWnd) 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, * use the filter type determined when we created the dev and checked the * dev caps. @@ -886,7 +876,6 @@ d3d_init_swap_chain (GstD3DVideoSink * sink, HWND hWnd) sink->d3d.filtertype = d3d_filtertype; sink->d3d.swapchain = d3d_swapchain; - sink->d3d.surface = d3d_surface; ret = TRUE; @@ -894,8 +883,6 @@ error: if (!ret) { if (d3d_swapchain) IDirect3DSwapChain9_Release (d3d_swapchain); - if (d3d_surface) - IDirect3DSurface9_Release (d3d_surface); } UNLOCK_CLASS (sink, klass); @@ -917,23 +904,23 @@ d3d_release_swap_chain (GstD3DVideoSink * sink) CHECK_D3D_DEVICE (klass, sink, end); - if (!sink->d3d.swapchain && !sink->d3d.surface) { + if (!sink->d3d.swapchain) { ret = TRUE; 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) { ref_count = IDirect3DSwapChain9_Release (sink->d3d.swapchain); sink->d3d.swapchain = NULL; 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; end: @@ -1044,7 +1031,8 @@ end: } 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; guint8 *dest; @@ -1063,9 +1051,7 @@ d3d_copy_buffer_to_surface (GstD3DVideoSink * sink, GstBuffer * buffer) goto end; } - CHECK_D3D_SURFACE (sink, end); - - IDirect3DSurface9_LockRect (sink->d3d.surface, &lr, NULL, 0); + IDirect3DSurface9_LockRect (surface, &lr, NULL, 0); dest = (guint8 *) lr.pBits; if (!dest) { @@ -1241,7 +1227,7 @@ unhandled_format: done: ret = TRUE; unlock_surface: - IDirect3DSurface9_UnlockRect (sink->d3d.surface); + IDirect3DSurface9_UnlockRect (surface); gst_video_frame_unmap (&frame); end: @@ -1412,6 +1398,7 @@ d3d_render_buffer (GstD3DVideoSink * sink, GstBuffer * buf) { GstFlowReturn ret = GST_FLOW_OK; GstMapInfo map; + LPDIRECT3DSURFACE9 surface = NULL; g_return_val_if_fail (gst_buffer_map (buf, &map, GST_MAP_READ) != FALSE, GST_FLOW_ERROR); @@ -1441,7 +1428,26 @@ d3d_render_buffer (GstD3DVideoSink * sink, GstBuffer * buf) 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)) { ret = GST_FLOW_ERROR; -- cgit v1.2.1