[vlc-devel] [PATCH 04/11] Display: Support rotated movies.

Matthias Keiser matthias at tristan-inc.com
Thu Mar 6 01:12:25 CET 2014


---
 include/vlc_vout_display.h |  13 ++++++
 src/libvlccore.sym         |   1 +
 src/video_output/display.c | 101 +++++++++++++++++++++++++++++++++++++++------
 3 files changed, 103 insertions(+), 12 deletions(-)

diff --git a/include/vlc_vout_display.h b/include/vlc_vout_display.h
index d99cf7e..f5f6817 100644
--- a/include/vlc_vout_display.h
+++ b/include/vlc_vout_display.h
@@ -436,5 +436,18 @@ typedef struct {
  */
 VLC_API void vout_display_PlacePicture(vout_display_place_t *place, const video_format_t *source, const vout_display_cfg_t *cfg, bool do_clipping);
 
+
+/**
+ * Helper function that applies the necessary transforms to the mouse position
+ * and then calls vout_display_SendEventMouseMoved.
+ *
+ * \param vd vout_display_t.
+ * \param orient_display The orientation of the picture as seen on screen (probably ORIENT_NORMAL).
+ * \param m_x Mouse x position (relative to place, origin is top left).
+ * \param m_y Mouse y position (relative to place, origin is top left).
+ * \param place Place of the picture.
+ */
+VLC_API void vout_display_SendMouseMovedDisplayCoordinates(vout_display_t *vd, video_orientation_t orient_display, int m_x, int m_y,
+                                                           vout_display_place_t *place);
 #endif /* VLC_VOUT_DISPLAY_H */
 
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index e2c2008..e6cbaf9 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -635,6 +635,7 @@ vout_SetDisplayAspect
 vout_SetDisplayCrop
 vout_display_GetDefaultDisplaySize
 vout_display_PlacePicture
+vout_display_SendMouseMovedDisplayCoordinates
 xml_Create
 text_style_Copy
 text_style_Delete
diff --git a/src/video_output/display.c b/src/video_output/display.c
index 906bca0..967133f 100644
--- a/src/video_output/display.c
+++ b/src/video_output/display.c
@@ -197,6 +197,13 @@ void vout_display_GetDefaultDisplaySize(unsigned *width, unsigned *height,
 
     *width  = *width  * cfg->zoom.num / cfg->zoom.den;
     *height = *height * cfg->zoom.num / cfg->zoom.den;
+
+    if (ORIENT_IS_SWAP(source->orientation)) {
+
+        unsigned store = *width;
+        *width = *height;
+        *height = store;
+    }
 }
 
 /* */
@@ -214,6 +221,10 @@ void vout_display_PlacePicture(vout_display_place_t *place,
     unsigned display_width;
     unsigned display_height;
 
+    video_format_t source_rot;
+    video_format_ApplyRotation(source, &source_rot);
+    source = &source_rot;
+
     if (cfg->is_display_filled) {
         display_width  = cfg->display.width;
         display_height = cfg->display.height;
@@ -273,6 +284,62 @@ void vout_display_PlacePicture(vout_display_place_t *place,
     }
 }
 
+void vout_display_SendMouseMovedDisplayCoordinates(vout_display_t *vd, video_orientation_t orient_display, int m_x, int m_y, vout_display_place_t *place)
+{
+    video_format_t source_rot = vd->source;
+    video_format_TransformTo(&source_rot, orient_display);
+
+    if (place->width > 0 && place->height > 0) {
+
+        int x = (int)(source_rot.i_x_offset +
+                            (int64_t)(m_x - place->x) * source_rot.i_visible_width / place->width);
+        int y = (int)(source_rot.i_y_offset +
+                            (int64_t)(m_y - place->y) * source_rot.i_visible_height/ place->height);
+
+        video_transform_t transform = video_format_GetTransform(vd->source.orientation, orient_display);
+
+        int store;
+
+        switch (transform) {
+
+            case TRANSFORM_R90:
+                store = x;
+                x = y;
+                y = vd->source.i_visible_height - store;
+                break;
+            case TRANSFORM_R180:
+                x = vd->source.i_visible_width - x;
+                y = vd->source.i_visible_height - y;
+                break;
+            case TRANSFORM_R270:
+                store = x;
+                x = vd->source.i_visible_width - y;
+                y = store;
+                break;
+            case TRANSFORM_HFLIP:
+                x = vd->source.i_visible_width - x;
+                break;
+            case TRANSFORM_VFLIP:
+                y = vd->source.i_visible_height - y;
+                break;
+            case TRANSFORM_TRANSPOSE:
+                store = x;
+                x = y;
+                y = store;
+                break;
+            case TRANSFORM_ANTI_TRANSPOSE:
+                store = x;
+                x = vd->source.i_visible_width - y;
+                y = vd->source.i_visible_height - store;
+                break;
+            default:
+                break;
+        }
+
+        vout_display_SendEventMouseMoved (vd, x, y);
+    }
+}
+
 struct vout_display_owner_sys_t {
     vout_thread_t   *vout;
     bool            is_wrapper;  /* Is the current display a wrapper */
@@ -385,6 +452,11 @@ static void VoutDisplayCreateRender(vout_display_t *vd)
     v_dst.i_sar_num = 0;
     v_dst.i_sar_den = 0;
 
+    es_format_t src;
+    es_format_InitFromVideo(&src, &v_src);
+
+    filter_t *filter;
+
     video_format_t v_dst_cmp = v_dst;
     if ((v_src.i_chroma == VLC_CODEC_J420 && v_dst.i_chroma == VLC_CODEC_I420) ||
         (v_src.i_chroma == VLC_CODEC_J422 && v_dst.i_chroma == VLC_CODEC_I422) ||
@@ -393,34 +465,39 @@ static void VoutDisplayCreateRender(vout_display_t *vd)
         v_dst_cmp.i_chroma = v_src.i_chroma;
 
     const bool convert = memcmp(&v_src, &v_dst_cmp, sizeof(v_src)) != 0;
-    if (!convert)
+
+    if (!convert) {
+        es_format_Clean(&src);
         return;
+    }
 
     msg_Dbg(vd, "A filter to adapt decoder to display is needed");
 
-    osys->filters = filter_chain_New(vd, "video filter2", false,
-                                     FilterAllocationInit,
-                                     FilterAllocationClean, vd);
-    assert(osys->filters); /* TODO critical */
-
     /* */
-    es_format_t src;
-    es_format_InitFromVideo(&src, &v_src);
+    if (!osys->filters)
+        osys->filters = filter_chain_New(vd, "video filter2", true,
+                                         FilterAllocationInit,
+                                         FilterAllocationClean, vd);
 
-    /* */
-    es_format_t dst;
+    assert(osys->filters); /* TODO critical */
 
-    filter_t *filter;
     for (int i = 0; i < 1 + (v_dst_cmp.i_chroma != v_dst.i_chroma); i++) {
 
+        es_format_t dst;
+
         es_format_InitFromVideo(&dst, i == 0 ? &v_dst : &v_dst_cmp);
 
-        filter_chain_Reset(osys->filters, &src, &dst);
         filter = filter_chain_AppendFilter(osys->filters,
                                            NULL, NULL, &src, &dst);
+
+        es_format_Clean(&dst);
+
         if (filter)
             break;
     }
+
+    es_format_Clean(&src);
+
     if (!filter)
         msg_Err(vd, "Failed to adapt decoder format to display");
 }
-- 
1.8.3.4 (Apple Git-47)




More information about the vlc-devel mailing list