mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 22:36:33 +00:00
d3d11videosink: Add support for rotation
Adding "rotate-method" property Fixes: https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/issues/1396 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2708>
This commit is contained in:
parent
4e75ca0351
commit
5f39388ae5
5 changed files with 134 additions and 8 deletions
|
@ -61,6 +61,7 @@ enum
|
|||
PROP_FULLSCREEN_TOGGLE_MODE,
|
||||
PROP_FULLSCREEN,
|
||||
PROP_DRAW_ON_SHARED_TEXTURE,
|
||||
PROP_ROTATE_METHOD,
|
||||
};
|
||||
|
||||
#define DEFAULT_ADAPTER -1
|
||||
|
@ -131,6 +132,13 @@ struct _GstD3D11VideoSink
|
|||
GRecMutex lock;
|
||||
|
||||
gchar *title;
|
||||
|
||||
/* method configured via property */
|
||||
GstVideoOrientationMethod method;
|
||||
/* method parsed from tag */
|
||||
GstVideoOrientationMethod tag_method;
|
||||
/* method currently selected based on "method" and "tag_method" */
|
||||
GstVideoOrientationMethod selected_method;
|
||||
};
|
||||
|
||||
#define GST_D3D11_VIDEO_SINK_GET_LOCK(d) (&(GST_D3D11_VIDEO_SINK_CAST(d)->lock))
|
||||
|
@ -177,10 +185,11 @@ static gboolean gst_d3d11_video_sink_unlock (GstBaseSink * sink);
|
|||
static gboolean gst_d3d11_video_sink_unlock_stop (GstBaseSink * sink);
|
||||
static gboolean gst_d3d11_video_sink_event (GstBaseSink * sink,
|
||||
GstEvent * event);
|
||||
|
||||
static GstFlowReturn
|
||||
gst_d3d11_video_sink_show_frame (GstVideoSink * sink, GstBuffer * buf);
|
||||
static gboolean gst_d3d11_video_sink_prepare_window (GstD3D11VideoSink * self);
|
||||
static void gst_d3d11_video_sink_set_orientation (GstD3D11VideoSink * self,
|
||||
GstVideoOrientationMethod method, gboolean from_tag);
|
||||
|
||||
#define gst_d3d11_video_sink_parent_class parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (GstD3D11VideoSink, gst_d3d11_video_sink,
|
||||
|
@ -269,6 +278,19 @@ gst_d3d11_video_sink_class_init (GstD3D11VideoSinkClass * klass)
|
|||
(GParamFlags) (G_PARAM_READWRITE | GST_PARAM_MUTABLE_READY |
|
||||
G_PARAM_STATIC_STRINGS)));
|
||||
|
||||
/**
|
||||
* GstD3D11VideoSink:rotate-method:
|
||||
*
|
||||
* Video rotation/flip method to use
|
||||
*
|
||||
* Since: 1.22
|
||||
*/
|
||||
g_object_class_install_property (gobject_class, PROP_ROTATE_METHOD,
|
||||
g_param_spec_enum ("rotate-method", "Rotate Method",
|
||||
"Rotate method to use",
|
||||
GST_TYPE_VIDEO_ORIENTATION_METHOD, GST_VIDEO_ORIENTATION_IDENTITY,
|
||||
(GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));
|
||||
|
||||
/**
|
||||
* GstD3D11VideoSink::begin-draw:
|
||||
* @videosink: the #d3d11videosink
|
||||
|
@ -398,6 +420,10 @@ gst_d3d11_videosink_set_property (GObject * object, guint prop_id,
|
|||
case PROP_DRAW_ON_SHARED_TEXTURE:
|
||||
self->draw_on_shared_texture = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_ROTATE_METHOD:
|
||||
gst_d3d11_video_sink_set_orientation (self,
|
||||
(GstVideoOrientationMethod) g_value_get_enum (value), FALSE);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -435,6 +461,9 @@ gst_d3d11_videosink_get_property (GObject * object, guint prop_id,
|
|||
case PROP_DRAW_ON_SHARED_TEXTURE:
|
||||
g_value_set_boolean (value, self->draw_on_shared_texture);
|
||||
break;
|
||||
case PROP_ROTATE_METHOD:
|
||||
g_value_set_enum (value, self->method);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -785,6 +814,8 @@ done:
|
|||
"fullscreen", self->fullscreen,
|
||||
"enable-navigation-events", self->enable_navigation_events, NULL);
|
||||
|
||||
gst_d3d11_window_set_orientation (self->window, self->selected_method);
|
||||
|
||||
g_signal_connect (self->window, "key-event",
|
||||
G_CALLBACK (gst_d3d11_video_sink_key_event), self);
|
||||
g_signal_connect (self->window, "mouse-event",
|
||||
|
@ -981,6 +1012,7 @@ gst_d3d11_video_sink_event (GstBaseSink * sink, GstEvent * event)
|
|||
case GST_EVENT_TAG:{
|
||||
GstTagList *taglist;
|
||||
gchar *title = nullptr;
|
||||
GstVideoOrientationMethod method = GST_VIDEO_ORIENTATION_IDENTITY;
|
||||
|
||||
gst_event_parse_tag (event, &taglist);
|
||||
gst_tag_list_get_string (taglist, GST_TAG_TITLE, &title);
|
||||
|
@ -1006,6 +1038,12 @@ gst_d3d11_video_sink_event (GstBaseSink * sink, GstEvent * event)
|
|||
|
||||
g_free (title);
|
||||
}
|
||||
|
||||
if (gst_video_orientation_from_tag (taglist, &method)) {
|
||||
GST_D3D11_VIDEO_SINK_LOCK (self);
|
||||
gst_d3d11_video_sink_set_orientation (self, method, TRUE);
|
||||
GST_D3D11_VIDEO_SINK_UNLOCK (self);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -1015,6 +1053,31 @@ gst_d3d11_video_sink_event (GstBaseSink * sink, GstEvent * event)
|
|||
return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
|
||||
}
|
||||
|
||||
/* called with lock */
|
||||
static void
|
||||
gst_d3d11_video_sink_set_orientation (GstD3D11VideoSink * self,
|
||||
GstVideoOrientationMethod method, gboolean from_tag)
|
||||
{
|
||||
if (method == GST_VIDEO_ORIENTATION_CUSTOM) {
|
||||
GST_WARNING_OBJECT (self, "Unsupported custom orientation");
|
||||
return;
|
||||
}
|
||||
|
||||
if (from_tag)
|
||||
self->tag_method = method;
|
||||
else
|
||||
self->method = method;
|
||||
|
||||
if (self->method == GST_VIDEO_ORIENTATION_AUTO) {
|
||||
self->selected_method = self->tag_method;
|
||||
} else {
|
||||
self->selected_method = self->method;
|
||||
}
|
||||
|
||||
if (self->window)
|
||||
gst_d3d11_window_set_orientation (self->window, self->selected_method);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_d3d11_video_sink_check_device_update (GstD3D11VideoSink * self,
|
||||
GstBuffer * buf)
|
||||
|
|
|
@ -334,8 +334,20 @@ gst_d3d11_window_on_resize_default (GstD3D11Window * self, guint width,
|
|||
if (self->force_aspect_ratio) {
|
||||
src_rect.x = 0;
|
||||
src_rect.y = 0;
|
||||
src_rect.w = GST_VIDEO_INFO_WIDTH (&self->render_info);
|
||||
src_rect.h = GST_VIDEO_INFO_HEIGHT (&self->render_info);
|
||||
|
||||
switch (self->method) {
|
||||
case GST_VIDEO_ORIENTATION_90R:
|
||||
case GST_VIDEO_ORIENTATION_90L:
|
||||
case GST_VIDEO_ORIENTATION_UL_LR:
|
||||
case GST_VIDEO_ORIENTATION_UR_LL:
|
||||
src_rect.w = GST_VIDEO_INFO_HEIGHT (&self->render_info);
|
||||
src_rect.h = GST_VIDEO_INFO_WIDTH (&self->render_info);
|
||||
break;
|
||||
default:
|
||||
src_rect.w = GST_VIDEO_INFO_WIDTH (&self->render_info);
|
||||
src_rect.h = GST_VIDEO_INFO_HEIGHT (&self->render_info);
|
||||
break;
|
||||
}
|
||||
|
||||
gst_video_sink_center_rect (src_rect, dst_rect, &rst_rect, TRUE);
|
||||
} else {
|
||||
|
@ -677,9 +689,8 @@ gst_d3d11_window_prepare_default (GstD3D11Window * window, guint display_width,
|
|||
/* call resize to allocated resources */
|
||||
klass->on_resize (window, display_width, display_height);
|
||||
|
||||
if (window->requested_fullscreen != window->fullscreen) {
|
||||
if (window->requested_fullscreen != window->fullscreen)
|
||||
klass->change_fullscreen_mode (window);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (window, "New swap chain 0x%p created", window->swap_chain);
|
||||
|
||||
|
@ -800,7 +811,8 @@ gst_d3d111_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
|||
"dest-width",
|
||||
(gint) (self->render_rect.right - self->render_rect.left),
|
||||
"dest-height",
|
||||
(gint) (self->render_rect.bottom - self->render_rect.top), nullptr);
|
||||
(gint) (self->render_rect.bottom - self->render_rect.top),
|
||||
"video-direction", self->method, nullptr);
|
||||
gst_d3d11_overlay_compositor_update_viewport (self->compositor, &viewport);
|
||||
}
|
||||
|
||||
|
@ -974,3 +986,24 @@ gst_d3d11_window_get_native_type_to_string (GstD3D11WindowNativeType type)
|
|||
|
||||
return "none";
|
||||
}
|
||||
|
||||
void
|
||||
gst_d3d11_window_set_orientation (GstD3D11Window * window,
|
||||
GstVideoOrientationMethod method)
|
||||
{
|
||||
if (method == GST_VIDEO_ORIENTATION_AUTO ||
|
||||
method == GST_VIDEO_ORIENTATION_CUSTOM) {
|
||||
return;
|
||||
}
|
||||
|
||||
gst_d3d11_device_lock (window->device);
|
||||
if (window->method != method) {
|
||||
window->method = method;
|
||||
if (window->swap_chain) {
|
||||
GstD3D11WindowClass *klass = GST_D3D11_WINDOW_GET_CLASS (window);
|
||||
|
||||
klass->on_resize (window, window->surface_width, window->surface_height);
|
||||
}
|
||||
}
|
||||
gst_d3d11_device_unlock (window->device);
|
||||
}
|
||||
|
|
|
@ -116,6 +116,8 @@ struct _GstD3D11Window
|
|||
GstBuffer *cached_buffer;
|
||||
gboolean first_present;
|
||||
gboolean allow_tearing;
|
||||
|
||||
GstVideoOrientationMethod method;
|
||||
};
|
||||
|
||||
struct _GstD3D11WindowClass
|
||||
|
@ -177,6 +179,9 @@ void gst_d3d11_window_set_render_rectangle (GstD3D11Window * window,
|
|||
void gst_d3d11_window_set_title (GstD3D11Window * window,
|
||||
const gchar *title);
|
||||
|
||||
void gst_d3d11_window_set_orientation (GstD3D11Window * window,
|
||||
GstVideoOrientationMethod method);
|
||||
|
||||
gboolean gst_d3d11_window_prepare (GstD3D11Window * window,
|
||||
guint display_width,
|
||||
guint display_height,
|
||||
|
|
|
@ -164,6 +164,20 @@ gst_d3d11_window_dummy_on_resize (GstD3D11Window * window,
|
|||
src_rect.w = GST_VIDEO_INFO_WIDTH (&window->render_info);
|
||||
src_rect.h = GST_VIDEO_INFO_HEIGHT (&window->render_info);
|
||||
|
||||
switch (window->method) {
|
||||
case GST_VIDEO_ORIENTATION_90R:
|
||||
case GST_VIDEO_ORIENTATION_90L:
|
||||
case GST_VIDEO_ORIENTATION_UL_LR:
|
||||
case GST_VIDEO_ORIENTATION_UR_LL:
|
||||
src_rect.w = GST_VIDEO_INFO_HEIGHT (&window->render_info);
|
||||
src_rect.h = GST_VIDEO_INFO_WIDTH (&window->render_info);
|
||||
break;
|
||||
default:
|
||||
src_rect.w = GST_VIDEO_INFO_WIDTH (&window->render_info);
|
||||
src_rect.h = GST_VIDEO_INFO_HEIGHT (&window->render_info);
|
||||
break;
|
||||
}
|
||||
|
||||
gst_video_sink_center_rect (src_rect, dst_rect, &rst_rect, TRUE);
|
||||
} else {
|
||||
rst_rect = dst_rect;
|
||||
|
|
|
@ -1036,8 +1036,19 @@ gst_d3d11_window_win32_show (GstD3D11Window * window)
|
|||
GstD3D11WindowWin32 *self = GST_D3D11_WINDOW_WIN32 (window);
|
||||
gint width, height;
|
||||
|
||||
width = GST_VIDEO_INFO_WIDTH (&window->render_info);
|
||||
height = GST_VIDEO_INFO_HEIGHT (&window->render_info);
|
||||
switch (window->method) {
|
||||
case GST_VIDEO_ORIENTATION_90R:
|
||||
case GST_VIDEO_ORIENTATION_90L:
|
||||
case GST_VIDEO_ORIENTATION_UL_LR:
|
||||
case GST_VIDEO_ORIENTATION_UR_LL:
|
||||
width = GST_VIDEO_INFO_HEIGHT (&window->render_info);
|
||||
height = GST_VIDEO_INFO_WIDTH (&window->render_info);
|
||||
break;
|
||||
default:
|
||||
width = GST_VIDEO_INFO_WIDTH (&window->render_info);
|
||||
height = GST_VIDEO_INFO_HEIGHT (&window->render_info);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!self->visible) {
|
||||
/* if no parent the real size has to be set now because this has not been done
|
||||
|
|
Loading…
Reference in a new issue