[vlc-devel] [PATCH 2/3] linux: Fix CRTC code in KMS plugin.

Juha-Pekka Heikkila juhapekka.heikkila at gmail.com
Fri Aug 10 10:26:29 CEST 2018


Add missed drmModeSetCrtc(..) call. This does two things. Firstly
if requested chroma is not on default CRTC we'll get plane showing
correctly. Secondly this allow exiting gracefully in situtation
where Xserver is running in the background but has released
DRM master for VLC to use.

Added printing out in debug information available connectors.

Small detail fixes.

Signed-off-by: Juha-Pekka Heikkila <juhapekka.heikkila at gmail.com>
---
 modules/video_output/kms.c | 92 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 77 insertions(+), 15 deletions(-)

diff --git a/modules/video_output/kms.c b/modules/video_output/kms.c
index ec03057..e6e26a5 100644
--- a/modules/video_output/kms.c
+++ b/modules/video_output/kms.c
@@ -53,9 +53,11 @@
 #define DEVICE_LONGTEXT \
     "Framebuffer device to use for rendering (usually /dev/dri/card0)."
 
+#define VLC_CHROMA_PARAM "kms-vlc-chroma"
 #define VLC_CHROMA_TEXT "Image format used by VLC"
 #define VLC_CHROMA_LONGTEXT "Chroma fourcc request to VLC for output format"
 
+#define DRM_CHROMA_PARAM "kms-drm-chroma"
 #define DRM_CHROMA_TEXT "Image format used by DRM"
 #define DRM_CHROMA_LONGTEXT "Chroma fourcc override for DRM framebuffer format selection"
 
@@ -93,6 +95,10 @@ struct vout_display_sys_t {
 /*
  * modeset information
  */
+    uint32_t        connector_id;
+    drmModeModeInfo used_mode;
+    uint32_t        old_crtc_id;
+    drmModeCrtc     *old_crtc;
     uint32_t        crtc;
     uint32_t        plane_id;
 
@@ -252,9 +258,8 @@ static deviceRval FindCRTC(vout_display_t *vd, drmModeRes const *res,
     for (i = 0; i < conn->count_encoders; i++) {
         enc = drmModeGetEncoder(sys->drm_fd, conn->encoders[i]);
 
-        for (j = 0; enc && j < res->count_crtcs; ++j) {
-            if (ffs(enc->possible_crtcs) == j && res->crtcs[j]) {
-                msg_Dbg(vd, "Got CRTC %d", res->crtcs[j]);
+        for (j = 0; enc && j < res->count_crtcs; j++) {
+            if (enc->possible_crtcs & (1 << j)) {
                 sys->crtc = res->crtcs[j];
                 drmModeFreeEncoder(enc);
                 return drvSuccess;
@@ -278,10 +283,10 @@ static deviceRval SetupDevice(vout_display_t *vd, drmModeRes const *res,
     if (conn->connection != DRM_MODE_CONNECTED || conn->count_modes == 0)
         return drvTryNext;
 
-    sys->width = conn->modes[0].hdisplay;
-    sys->height = conn->modes[0].vdisplay;
-    msg_Dbg(vd, "Mode resolution for connector %u is %ux%u",
-            conn->connector_id, sys->width, sys->height);
+    memcpy(&sys->used_mode, &conn->modes[0], sizeof(sys->used_mode));
+    sys->width = sys->used_mode.hdisplay;
+    sys->height = sys->used_mode.vdisplay;
+    msg_Dbg(vd, "Mode resolution is %ux%u", sys->width, sys->height);
 
     ret = FindCRTC(vd, res, conn);
     if (ret != drvSuccess) {
@@ -302,6 +307,7 @@ static deviceRval SetupDevice(vout_display_t *vd, drmModeRes const *res,
             msg_Dbg(vd, "Created HW framebuffer %d/%d", c+1, MAXHWBUF);
         }
     }
+    sys->connector_id = conn->connector_id;
     return drvSuccess;
 }
 
@@ -505,8 +511,34 @@ static int OpenDisplay(vout_display_t *vd)
     drmModeConnector *conn;
     drmModeRes *modeRes;
     int c;
+    uint32_t i;
     bool found_connector = false;
 
+    static const struct
+    {
+        uint32_t    type;
+        const char* name;
+    } connectors[] = {
+        { .type = DRM_MODE_CONNECTOR_VGA, .name = "vga"},
+        { .type = DRM_MODE_CONNECTOR_DVII, .name = "DVII"},
+        { .type = DRM_MODE_CONNECTOR_DVID, .name = "DVID"},
+        { .type = DRM_MODE_CONNECTOR_DVIA, .name = "DVIA"},
+        { .type = DRM_MODE_CONNECTOR_Composite, .name = "Composite"},
+        { .type = DRM_MODE_CONNECTOR_SVIDEO, .name = "SVIDEO"},
+        { .type = DRM_MODE_CONNECTOR_LVDS, .name = "LVDS"},
+        { .type = DRM_MODE_CONNECTOR_Component, .name = ""},
+        { .type = DRM_MODE_CONNECTOR_9PinDIN, .name = "Component"},
+        { .type = DRM_MODE_CONNECTOR_DisplayPort, .name = "DisplayPort"},
+        { .type = DRM_MODE_CONNECTOR_HDMIA, .name = "HDMIA"},
+        { .type = DRM_MODE_CONNECTOR_HDMIB, .name = "HDMIB"},
+        { .type = DRM_MODE_CONNECTOR_TV, .name = "TV"},
+        { .type = DRM_MODE_CONNECTOR_eDP, .name = "embedded DisplayPort"},
+        { .type = DRM_MODE_CONNECTOR_VIRTUAL, .name = "VIRTUAL"},
+        { .type = DRM_MODE_CONNECTOR_DSI, .name = "DSI"},
+        { .type = DRM_MODE_CONNECTOR_DPI, .name = "DPI"},
+        { .type = DRM_MODE_CONNECTOR_Unknown, .name = "Unknown"}
+    };
+
     /*
      * Open framebuffer device
      */
@@ -544,12 +576,22 @@ static int OpenDisplay(vout_display_t *vd)
         goto err_out;
     }
 
-    for (c = 0; c < modeRes->count_connectors && sys->crtc == 0; c++) {
-
+    for (c = 0; c < modeRes->count_connectors; c++) {
         conn = drmModeGetConnector(sys->drm_fd, modeRes->connectors[c]);
         if (conn == NULL)
             continue;
 
+        for (i = 0; i < ARRAY_SIZE(connectors)-1; i++) {
+            if (conn->connector_type == connectors[i].type)
+                break;
+        }
+        msg_Dbg(vd, "** Connector #%d type %s, connected [%c]", c,
+                connectors[i].name,
+                (conn->connection==DRM_MODE_CONNECTED)?'X':' ');
+
+        if (sys->crtc != 0)
+            continue;
+
         found_connector = true;
 
         ret = SetupDevice(vd, modeRes, conn);
@@ -618,6 +660,15 @@ static picture_pool_t *Pool(vout_display_t *vd, unsigned count)
     int i;
 
     if (!sys->pool && !sys->picture) {
+        sys->old_crtc = drmModeGetCrtc(sys->drm_fd, sys->crtc);
+        if(drmModeSetCrtc(sys->drm_fd, sys->crtc, sys->old_crtc->buffer_id,
+                          0, 0,
+                          &sys->connector_id, 1,
+                          &sys->used_mode)) {
+            msg_Err(vd, "Cannot do modesetting");
+            return NULL;
+        }
+
         memset(&rsc, 0, sizeof(rsc));
 
         for (i = 0; i < PICTURE_PLANE_MAX; i++) {
@@ -680,8 +731,20 @@ static void CloseDisplay(vout_display_t *vd)
 {
     vout_display_sys_t *sys = vd->sys;
 
-    if (sys->pool)
+    if (sys->pool) {
+        if(drmModeSetCrtc(sys->drm_fd,
+                   sys->old_crtc->crtc_id,
+                   sys->old_crtc->buffer_id,
+                   sys->old_crtc->x,
+                   sys->old_crtc->y,
+                   &sys->connector_id,
+                   1,
+                   &sys->old_crtc->mode))
+            msg_Err(vd, "error modeset xit");
+        drmModeFreeCrtc(sys->old_crtc);
+
         picture_pool_Release(sys->pool);
+    }
 
     if (sys->drm_fd)
         drmDropMaster(sys->drm_fd);
@@ -723,7 +786,7 @@ static int Open(vlc_object_t *object)
     if (!sys)
         return VLC_ENOMEM;
 
-    chroma = var_InheritString(vd, "kms-vlc-chroma");
+    chroma = var_InheritString(vd, VLC_CHROMA_PARAM);
     if (chroma) {
         local_vlc_chroma = vlc_fourcc_GetCodecFromString(VIDEO_ES, chroma);
 
@@ -739,10 +802,9 @@ static int Open(vlc_object_t *object)
         chroma = NULL;
     } else {
         sys->vlc_fourcc = vd->fmt.i_chroma;
-        msg_Dbg(vd, "Chroma %4s invalid, using default", chroma);
     }
 
-    chroma = var_InheritString(vd, "kms-drm-chroma");
+    chroma = var_InheritString(vd, DRM_CHROMA_PARAM);
     if (chroma) {
         local_drm_chroma = VLC_FOURCC(chroma[0], chroma[1], chroma[2],
                                       chroma[3]);
@@ -790,9 +852,9 @@ vlc_module_begin ()
     set_subcategory(SUBCAT_VIDEO_VOUT)
     add_loadfile(KMS_VAR, "/dev/dri/card0", DEVICE_TEXT, DEVICE_LONGTEXT)
 
-    add_string( "kms-vlc-chroma", NULL, VLC_CHROMA_TEXT, VLC_CHROMA_LONGTEXT,
+    add_string(VLC_CHROMA_PARAM, NULL, VLC_CHROMA_TEXT, VLC_CHROMA_LONGTEXT,
                 true)
-    add_string( "kms-drm-chroma", NULL, DRM_CHROMA_TEXT, DRM_CHROMA_LONGTEXT,
+    add_string(DRM_CHROMA_PARAM, NULL, DRM_CHROMA_TEXT, DRM_CHROMA_LONGTEXT,
                 true)
     set_description("Linux kernel mode setting video output")
     set_capability("vout display", 30)
-- 
2.7.4



More information about the vlc-devel mailing list