d3dvideosink: Add support for crop meta

This commit is contained in:
Sebastian Dröge 2013-03-26 14:15:41 +01:00
parent 64ccb0ffe3
commit ff30417bd9
3 changed files with 29 additions and 7 deletions

View file

@ -1689,8 +1689,7 @@ d3d_stretch_and_copy (GstD3DVideoSink * sink, LPDIRECT3DSURFACE9 back_buffer)
{
GstD3DVideoSinkClass *klass = GST_D3DVIDEOSINK_GET_CLASS (sink);
GstVideoRectangle *render_rect = NULL;
RECT *r_ptr = NULL;
RECT r;
RECT r, s;
HRESULT hr;
gboolean ret = FALSE;
@ -1731,24 +1730,27 @@ d3d_stretch_and_copy (GstD3DVideoSink * sink, LPDIRECT3DSURFACE9 back_buffer)
r.top = result.y;
r.right = result.x + result.w;
r.bottom = result.y + result.h;
r_ptr = &r;
} else if (render_rect) {
r.left = 0;
r.top = 0;
r.right = render_rect->w;
r.bottom = render_rect->h;
r_ptr = &r;
}
s.left = sink->crop_rect.x;
s.top = sink->crop_rect.y;
s.right = sink->crop_rect.x + sink->crop_rect.w;
s.bottom = sink->crop_rect.y + sink->crop_rect.h;
/* TODO: StretchRect returns error if the dest rect is outside
* the backbuffer area. So we need to calc how much of the src
* surface is being scaled / copied to the render rect..
*/
hr = IDirect3DDevice9_StretchRect (klass->d3d.device.d3d_device, sink->d3d.surface, /* Source Surface */
NULL, /* Source Surface Rect (NULL: Whole) */
&s, /* Source Surface Rect (NULL: Whole) */
back_buffer, /* Dest Surface */
r_ptr, /* Dest Surface Rect (NULL: Whole) */
&r, /* Dest Surface Rect (NULL: Whole) */
klass->d3d.device.filter_type);
if (hr == D3D_OK) {
@ -1769,6 +1771,7 @@ d3d_render_buffer (GstD3DVideoSink * sink, GstBuffer * buf)
GstFlowReturn ret = GST_FLOW_OK;
GstMemory *mem;
LPDIRECT3DSURFACE9 surface = NULL;
GstVideoCropMeta *crop = NULL;
LOCK_SINK (sink);
@ -1789,7 +1792,20 @@ d3d_render_buffer (GstD3DVideoSink * sink, GstBuffer * buf)
(sink->d3d.window_handle != NULL) ? "Render" : "No Win",
GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
/* Reize swapchain if needed */
crop = gst_buffer_get_video_crop_meta (buf);
if (crop) {
sink->crop_rect.x = crop->x;
sink->crop_rect.y = crop->y;
sink->crop_rect.w = crop->width;
sink->crop_rect.h = crop->height;
} else {
sink->crop_rect.x = 0;
sink->crop_rect.y = 0;
sink->crop_rect.w = sink->info.width;
sink->crop_rect.h = sink->info.height;
}
/* Resize swapchain if needed */
if (!d3d_resize_swap_chain (sink)) {
ret = GST_FLOW_ERROR;
goto end;

View file

@ -349,6 +349,10 @@ gst_d3dvideosink_set_caps (GstBaseSink * bsink, GstCaps * caps)
if (GST_VIDEO_SINK_WIDTH (sink) <= 0 || GST_VIDEO_SINK_HEIGHT (sink) <= 0)
goto no_display_size;
memset (&sink->crop_rect, 0, sizeof (sink->crop_rect));
sink->crop_rect.w = sink->info.width;
sink->crop_rect.h = sink->info.height;
sink->width = video_width;
sink->height = video_height;
@ -465,6 +469,7 @@ gst_d3dvideosink_propose_allocation (GstBaseSink * bsink, GstQuery * query)
}
gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL);
gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL);
GST_OBJECT_LOCK (sink);
pool = sink->pool ? gst_object_ref (sink->pool) : NULL;

View file

@ -56,6 +56,7 @@ struct _GstD3DVideoSink
GstBufferPool *fallback_pool;
GstBuffer *fallback_buffer;
GstVideoRectangle crop_rect;
GstVideoRectangle render_rect;
GRecMutex lock;