diff options
Diffstat (limited to 'recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0029-kmssink-support-videooverlay-interface.patch')
-rw-r--r-- | recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0029-kmssink-support-videooverlay-interface.patch | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0029-kmssink-support-videooverlay-interface.patch b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0029-kmssink-support-videooverlay-interface.patch new file mode 100644 index 0000000..7bf995f --- /dev/null +++ b/recipes-multimedia/gstreamer/gstreamer1.0-plugins-bad/0029-kmssink-support-videooverlay-interface.patch @@ -0,0 +1,343 @@ +From a1affa1293e31870d6fb9dda85e4c648cc4dd247 Mon Sep 17 00:00:00 2001 +From: Haihua Hu <jared.hu@nxp.com> +Date: Tue, 20 Jun 2017 13:11:27 +0800 +Subject: [PATCH 2/3] [MMFMWK-7567] kmssink: support videooverlay interface + +Implement videooverlay interface in kmssink, divided into two cases: +when driver supports scale, then we do refresh in show_frame(); if +not, send a reconfigure event to upstream and re-negotiate, using the +new size. + +Upstream-Status: Backport [1.13.1] +https://bugzilla.gnome.org/show_bug.cgi?id=784599 +--- + sys/kms/gstkmssink.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++++--- + sys/kms/gstkmssink.h | 12 ++++ + 2 files changed, 167 insertions(+), 9 deletions(-) + +diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c +index e91c211..6d9b765 100644 +--- a/sys/kms/gstkmssink.c ++++ b/sys/kms/gstkmssink.c +@@ -43,6 +43,7 @@ + #endif + + #include <gst/video/video.h> ++#include <gst/video/videooverlay.h> + #include <gst/allocators/gstdmabuf.h> + + #include <drm.h> +@@ -66,11 +67,17 @@ GST_DEBUG_CATEGORY_STATIC (gst_kms_sink_debug); + GST_DEBUG_CATEGORY_STATIC (CAT_PERFORMANCE); + #define GST_CAT_DEFAULT gst_kms_sink_debug + ++static GstFlowReturn gst_kms_sink_show_frame (GstVideoSink * vsink, ++ GstBuffer * buf); ++static void gst_kms_sink_video_overlay_init (GstVideoOverlayInterface * iface); ++ + #define parent_class gst_kms_sink_parent_class + G_DEFINE_TYPE_WITH_CODE (GstKMSSink, gst_kms_sink, GST_TYPE_VIDEO_SINK, + GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, GST_PLUGIN_NAME, 0, + GST_PLUGIN_DESC); +- GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE")); ++ GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE"); ++ G_IMPLEMENT_INTERFACE (GST_TYPE_VIDEO_OVERLAY, ++ gst_kms_sink_video_overlay_init)); + + enum + { +@@ -83,6 +90,79 @@ enum + + static GParamSpec *g_properties[PROP_N] = { NULL, }; + ++static void ++gst_kms_sink_set_render_rectangle (GstVideoOverlay * overlay, ++ gint x, gint y, gint width, gint height) ++{ ++ GstKMSSink *self = GST_KMS_SINK (overlay); ++ ++ if (width <= 0 || height <= 0) { ++ if (width == -1 && height == -1) { ++ x = 0; ++ y = 0; ++ width = self->hdisplay; ++ height = self->vdisplay; ++ goto commit; ++ } ++ return; ++ } ++ ++commit: ++ GST_OBJECT_LOCK (self); ++ if (self->can_scale) { ++ self->preferred_rect.x = x; ++ self->preferred_rect.y = y; ++ self->preferred_rect.w = width; ++ self->preferred_rect.h = height; ++ } else { ++ GstVideoRectangle src = { 0, }; ++ GstVideoRectangle dst = { 0, }; ++ GstVideoRectangle result; ++ ++ src.w = self->original_width; ++ src.h = self->original_heigth; ++ ++ dst.w = width; ++ dst.h = height; ++ ++ gst_video_sink_center_rect (src, dst, &result, TRUE); ++ ++ self->pending_rect.x = x + result.x; ++ self->pending_rect.y = y + result.y; ++ self->pending_rect.w = result.w; ++ self->pending_rect.h = result.h; ++ ++ GST_DEBUG_OBJECT (self, "pending resize to (%d,%d)-(%dx%d)", ++ self->pending_rect.x, self->pending_rect.y, ++ self->pending_rect.w, self->pending_rect.h); ++ } ++ GST_OBJECT_UNLOCK (self); ++} ++ ++static void ++gst_kms_sink_expose (GstVideoOverlay * overlay) ++{ ++ GstKMSSink *self = GST_KMS_SINK (overlay); ++ ++ if (self->can_scale) { ++ gst_kms_sink_show_frame (GST_VIDEO_SINK (self), NULL); ++ } else { ++ GST_OBJECT_LOCK (self); ++ self->reconfigure = TRUE; ++ GST_OBJECT_UNLOCK (self); ++ ++ gst_pad_push_event (GST_BASE_SINK (self)->sinkpad, ++ gst_event_new_reconfigure ()); ++ } ++} ++ ++static void ++gst_kms_sink_video_overlay_init (GstVideoOverlayInterface * iface) ++{ ++ iface->expose = gst_kms_sink_expose; ++ iface->set_render_rectangle = gst_kms_sink_set_render_rectangle; ++} ++ + static int + kms_open (gchar ** driver) + { +@@ -539,7 +619,7 @@ gst_kms_sink_start (GstBaseSink * bsink) + if (!get_drm_caps (self)) + goto bail; + +- self->can_scale = TRUE; ++ //self->can_scale = TRUE; + + res = drmModeGetResources (self->fd); + if (!res) +@@ -588,8 +668,10 @@ retry_find_plane: + GST_INFO_OBJECT (self, "connector id = %d / crtc id = %d / plane id = %d", + self->conn_id, self->crtc_id, self->plane_id); + +- self->hdisplay = crtc->mode.hdisplay; +- self->vdisplay = crtc->mode.vdisplay; ++ self->preferred_rect.x = 0; ++ self->preferred_rect.y = 0; ++ self->hdisplay = self->preferred_rect.w = crtc->mode.hdisplay; ++ self->vdisplay = self->preferred_rect.h = crtc->mode.vdisplay; + self->buffer_id = crtc->buffer_id; + + self->mm_width = conn->mmWidth; +@@ -602,6 +684,9 @@ retry_find_plane: + gst_poll_add_fd (self->poll, &self->pollfd); + gst_poll_fd_ctl_read (self->poll, &self->pollfd, TRUE); + ++ self->original_width = -1; ++ self->original_heigth = -1; ++ + ret = TRUE; + + bail: +@@ -731,17 +816,29 @@ static GstCaps * + gst_kms_sink_get_caps (GstBaseSink * bsink, GstCaps * filter) + { + GstKMSSink *self; +- GstCaps *caps, *out_caps; ++ GstCaps *caps, *out_caps, *tmp; + + self = GST_KMS_SINK (bsink); + + caps = gst_kms_sink_get_allowed_caps (self); ++ ++ GST_OBJECT_LOCK (self); ++ if (caps && self->reconfigure) { ++ tmp = gst_caps_copy (caps); ++ gst_caps_set_simple (tmp, "width", G_TYPE_INT, self->pending_rect.w, ++ "height", G_TYPE_INT, self->pending_rect.h, NULL); ++ gst_caps_append (tmp, caps); ++ caps = tmp; ++ } ++ GST_OBJECT_UNLOCK (self); ++ + if (caps && filter) { + out_caps = gst_caps_intersect_full (caps, filter, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (caps); + } else { + out_caps = caps; + } ++ GST_DEBUG_OBJECT (self, "out caps %" GST_PTR_FORMAT, out_caps); + + return out_caps; + } +@@ -880,6 +977,19 @@ gst_kms_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) + + self->vinfo = vinfo; + ++ GST_OBJECT_LOCK (self); ++ if (self->reconfigure) { ++ self->reconfigure = FALSE; ++ self->preferred_rect = self->pending_rect; ++ } ++ GST_OBJECT_UNLOCK (self); ++ ++ /* initialize original video size */ ++ if (self->original_width < 0) { ++ self->original_width = GST_VIDEO_INFO_WIDTH (&self->vinfo); ++ self->original_heigth = GST_VIDEO_INFO_HEIGHT (&self->vinfo); ++ } ++ + GST_DEBUG_OBJECT (self, "negotiated caps = %" GST_PTR_FORMAT, caps); + + return TRUE; +@@ -1258,7 +1368,13 @@ gst_kms_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf) + + res = GST_FLOW_ERROR; + +- buffer = gst_kms_sink_get_input_buffer (self, buf); ++ buffer = NULL; ++ ++ if (buf) ++ buffer = gst_kms_sink_get_input_buffer (self, buf); ++ else if (self->last_buffer) ++ buffer = gst_buffer_ref (self->last_buffer); ++ + if (!buffer) + return GST_FLOW_ERROR; + fb_id = gst_kms_memory_get_fb_id (gst_buffer_peek_memory (buffer, 0)); +@@ -1267,6 +1383,7 @@ gst_kms_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf) + + GST_TRACE_OBJECT (self, "displaying fb %d", fb_id); + ++ GST_OBJECT_LOCK (self); + if (self->modesetting_enabled) { + self->buffer_id = fb_id; + goto sync_frame; +@@ -1287,12 +1404,15 @@ gst_kms_sink_show_frame (GstVideoSink * vsink, GstBuffer * buf) + src.w = GST_VIDEO_SINK_WIDTH (self); + src.h = GST_VIDEO_SINK_HEIGHT (self); + +- dst.w = self->hdisplay; +- dst.h = self->vdisplay; ++ dst.w = self->preferred_rect.w; ++ dst.h = self->preferred_rect.h; + + retry_set_plane: + gst_video_sink_center_rect (src, dst, &result, self->can_scale); + ++ result.x += self->preferred_rect.x; ++ result.y += self->preferred_rect.y; ++ + if (crop) { + src.w = crop->width; + src.h = crop->height; +@@ -1301,6 +1421,27 @@ retry_set_plane: + src.h = GST_VIDEO_INFO_HEIGHT (&self->vinfo); + } + ++ /* handle out of screen case */ ++ if ((result.x + result.w) > self->hdisplay) ++ src.w = self->hdisplay - result.x; ++ ++ if ((result.y + result.h) > self->vdisplay) ++ src.h = self->vdisplay - result.y; ++ ++ if (src.w <= 0 || src.h <= 0) { ++ GST_WARNING_OBJECT (self, "video is out of display range"); ++ goto sync_frame; ++ } ++ GST_TRACE_OBJECT (self, ++ "before drmModeSetPlane at (%i,%i) %ix%i sourcing at (%i,%i) %ix%i", ++ result.x, result.y, result.w, result.h, src.x, src.y, src.w, src.h); ++ ++ /* to make sure it can be show when driver don't support scale */ ++ if (!self->can_scale) { ++ result.w = src.w; ++ result.h = src.h; ++ } ++ + GST_TRACE_OBJECT (self, + "drmModeSetPlane at (%i,%i) %ix%i sourcing at (%i,%i) %ix%i", + result.x, result.y, result.w, result.h, src.x, src.y, src.w, src.h); +@@ -1322,9 +1463,11 @@ sync_frame: + if (!gst_kms_sink_sync (self)) + goto bail; + +- gst_buffer_replace (&self->last_buffer, buffer); ++ if (buffer != self->last_buffer) ++ gst_buffer_replace (&self->last_buffer, buffer); + g_clear_pointer (&self->tmp_kmsmem, gst_memory_unref); + ++ GST_OBJECT_UNLOCK (self); + res = GST_FLOW_OK; + + bail: +@@ -1339,6 +1482,7 @@ buffer_invalid: + } + set_plane_failed: + { ++ GST_OBJECT_UNLOCK (self); + GST_DEBUG_OBJECT (self, "result = { %d, %d, %d, %d} / " + "src = { %d, %d, %d %d } / dst = { %d, %d, %d %d }", result.x, result.y, + result.w, result.h, src.x, src.y, src.w, src.h, dst.x, dst.y, dst.w, +@@ -1349,6 +1493,7 @@ set_plane_failed: + } + no_disp_ratio: + { ++ GST_OBJECT_UNLOCK (self); + GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, (NULL), + ("Error calculating the output display ratio of the video.")); + goto bail; +@@ -1427,6 +1572,7 @@ gst_kms_sink_init (GstKMSSink * sink) + sink->fd = -1; + sink->conn_id = -1; + sink->plane_id = -1; ++ sink->can_scale = TRUE; + gst_poll_fd_init (&sink->pollfd); + sink->poll = gst_poll_new (TRUE); + gst_video_info_init (&sink->vinfo); +diff --git a/sys/kms/gstkmssink.h b/sys/kms/gstkmssink.h +index f2ab4d4..44476e1 100644 +--- a/sys/kms/gstkmssink.h ++++ b/sys/kms/gstkmssink.h +@@ -79,6 +79,18 @@ struct _GstKMSSink { + + GstPoll *poll; + GstPollFD pollfd; ++ ++ /* preferred video rectangle */ ++ GstVideoRectangle preferred_rect; ++ ++ /* reconfigure info if driver doesn't scale */ ++ GstVideoRectangle pending_rect; ++ gboolean reconfigure; ++ ++ /* kept original video size */ ++ gint original_width; ++ gint original_heigth; ++ + }; + + struct _GstKMSSinkClass { +-- +1.9.1 + |