PROP_FULLSCREEN_TOGGLE_MODE,
PROP_FULLSCREEN,
PROP_DRAW_ON_SHARED_TEXTURE,
+ PROP_ROTATE_METHOD,
};
#define DEFAULT_ADAPTER -1
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))
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,
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
*
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;
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;
"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",
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);
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:
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)
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 {
/* 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);
"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);
}
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);
+}