[vlc-commits] [Git][videolan/vlc][master] mmal/vout: use a window and report the size from there

Steve Lhomme (@robUx4) gitlab at videolan.org
Sun Sep 22 10:13:24 UTC 2024



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
960e5a50 by Steve Lhomme at 2024-09-22T10:01:10+00:00
mmal/vout: use a window and report the size from there

- - - - -


2 changed files:

- include/vlc_window.h
- modules/hw/mmal/vout.c


Changes:

=====================================
include/vlc_window.h
=====================================
@@ -66,6 +66,7 @@ enum vlc_window_type {
     VLC_WINDOW_TYPE_WAYLAND /**< Wayland surface */,
     VLC_WINDOW_TYPE_DCOMP /**< Win32 DirectComposition */,
     VLC_WINDOW_TYPE_KMS /**< DRM KMS CRTC */,
+    VLC_WINDOW_TYPE_MMAL /**< MMAL window */,
 };
 
 /**
@@ -398,6 +399,7 @@ typedef struct vlc_window {
         struct wl_surface *wl;   /**< Wayland surface (client pointer) */
         void     *dcomp_visual;  /**<  Win32 direct composition visual */
         uint32_t crtc;           /**< KMS CRTC identifier */
+        int      display_id;     /**< MMAL display ID */
     } handle;
 
     /** Display server (mandatory)


=====================================
modules/hw/mmal/vout.c
=====================================
@@ -64,6 +64,7 @@
 #define PHASE_CHECK_INTERVAL 100
 
 static int OpenMmalVout(vout_display_t *, video_format_t *, vlc_video_context *);
+static int OpenMmalWindow(vlc_window_t *);
 
 #define SUBS_MAX 4
 
@@ -79,9 +80,13 @@ vlc_module_begin()
                     NULL)
     add_bool(MMAL_NATIVE_INTERLACED, false, MMAL_NATIVE_INTERLACE_TEXT,
                     MMAL_NATIVE_INTERLACE_LONGTEXT)
-    add_string(MMAL_DISPLAY_NAME, "auto", MMAL_DISPLAY_TEXT,
-                    MMAL_DISPLAY_LONGTEXT)
     set_callback_display(OpenMmalVout, 16)  // 1 point better than ASCII art
+
+    add_submodule()
+        set_capability("vout window", 10)
+        set_callback(OpenMmalWindow)
+        add_string(MMAL_DISPLAY_NAME, "auto", MMAL_DISPLAY_TEXT,
+                        MMAL_DISPLAY_LONGTEXT)
 vlc_module_end()
 
 typedef struct vout_subpic_s {
@@ -90,8 +95,6 @@ typedef struct vout_subpic_s {
 } vout_subpic_t;
 
 typedef struct vout_display_sys_t {
-    vlc_mutex_t manage_mutex;
-
     vlc_decoder_device *dec_dev;
     MMAL_COMPONENT_T *component;
     MMAL_PORT_T *input;
@@ -101,10 +104,6 @@ typedef struct vout_display_sys_t {
     int buffers_in_transit; /* number of buffers currently pushed to mmal component */
     unsigned num_buffers; /* number of buffers allocated at mmal port */
 
-    int display_id;
-    unsigned display_width;
-    unsigned display_height;
-
     MMAL_RECT_T dest_rect;      // Output rectangle in display coords
 
     unsigned int i_frame_rate_base; /* cached framerate to detect changes for rate adjustment */
@@ -114,7 +113,6 @@ typedef struct vout_display_sys_t {
     int phase_offset; /* currently applied offset to presentation time in ns */
     int layer; /* the dispman layer (z-index) used for video rendering */
 
-    bool need_configure_display; /* indicates a required display reconfigure to main thread */
     bool adjust_refresh_rate;
     bool native_interlaced;
     bool b_top_field_first; /* cached interlaced settings to detect changes for native mode */
@@ -460,8 +458,6 @@ static MMAL_STATUS_T isp_check(vout_display_t * const vd, vout_display_sys_t * c
 }
 
 /* TV service */
-static void tvservice_cb(void *callback_data, uint32_t reason, uint32_t param1,
-                uint32_t param2);
 static void adjust_refresh_rate(vout_display_t *vd);
 static int set_latency_target(vout_display_t *vd, bool enable);
 
@@ -477,35 +473,6 @@ static void vd_input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buf)
     mmal_buffer_header_release(buf);
 }
 
-static int query_resolution(vout_display_t *vd, const int display_id, unsigned *width, unsigned *height)
-{
-    TV_DISPLAY_STATE_T display_state = {0};
-    int ret = 0;
-
-    if (vc_tv_get_display_state_id(display_id, &display_state) == 0) {
-        msg_Dbg(vd, "State=%#x", display_state.state);
-        if (display_state.state & 0xFF) {
-            msg_Dbg(vd, "HDMI: %dx%d", display_state.display.hdmi.width, display_state.display.hdmi.height);
-            *width = display_state.display.hdmi.width;
-            *height = display_state.display.hdmi.height;
-            vout_display_SetSize(vd, *width, *height);
-        } else if (display_state.state & 0xFF00) {
-            msg_Dbg(vd, "SDTV: %dx%d", display_state.display.sdtv.width, display_state.display.sdtv.height);
-            *width = display_state.display.sdtv.width;
-            *height = display_state.display.sdtv.height;
-            vout_display_SetSize(vd, *width, *height);
-        } else {
-            msg_Warn(vd, "Invalid display state %"PRIx32, display_state.state);
-            ret = -1;
-        }
-    } else {
-        msg_Warn(vd, "Failed to query display resolution");
-        ret = -1;
-    }
-
-    return ret;
-}
-
 static MMAL_RECT_T
 place_to_mmal_rect(const vout_display_place_t place)
 {
@@ -521,14 +488,9 @@ static void
 place_dest(vout_display_t *vd)
 {
     vout_display_sys_t * const sys = vd->sys;
-    // Ignore what VLC thinks might be going on with display size
-    struct vout_display_placement dp = vd->cfg->display;
     vout_display_place_t place;
 
-    dp.width = sys->display_width;
-    dp.height = sys->display_height;
-    dp.fitting = VLC_VIDEO_FIT_SMALLER;
-    vout_display_PlacePicture(&place, vd->source, &dp);
+    vout_display_PlacePicture(&place, vd->source, &vd->cfg->display);
 
     sys->dest_rect = place_to_mmal_rect(place);
 }
@@ -704,27 +666,6 @@ static int vd_control(vout_display_t *vd, int query)
     return ret;
 }
 
-static void vd_manage(vout_display_t *vd)
-{
-    vout_display_sys_t *sys = vd->sys;
-    unsigned width, height;
-
-    vlc_mutex_lock(&sys->manage_mutex);
-
-    if (sys->need_configure_display) {
-        if (query_resolution(vd, sys->display_id, &width, &height) >= 0) {
-            sys->display_width = width;
-            sys->display_height = height;
-//            vlc_window_ReportSize(vd->cfg->window, width, height);
-        }
-
-        sys->need_configure_display = false;
-    }
-
-    vlc_mutex_unlock(&sys->manage_mutex);
-}
-
-
 static int attach_subpics(vout_display_t * const vd, vout_display_sys_t * const sys,
                           const vlc_render_subpicture * const spic)
 {
@@ -773,8 +714,6 @@ static void vd_prepare(vout_display_t *vd, picture_t *p_pic,
     VLC_UNUSED(date);
     vout_display_sys_t * const sys = vd->sys;
 
-    vd_manage(vd);
-
     if (sys->force_config ||
         p_pic->format.i_frame_rate != sys->i_frame_rate ||
         p_pic->format.i_frame_rate_base != sys->i_frame_rate_base ||
@@ -833,20 +772,6 @@ static void vd_control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer)
     mmal_buffer_header_release(buffer);
 }
 
-static void tvservice_cb(void *callback_data, uint32_t reason, uint32_t param1, uint32_t param2)
-{
-    VLC_UNUSED(reason);
-    VLC_UNUSED(param1);
-    VLC_UNUSED(param2);
-
-    vout_display_t *vd = (vout_display_t *)callback_data;
-    vout_display_sys_t *sys = vd->sys;
-
-    vlc_mutex_lock(&sys->manage_mutex);
-    sys->need_configure_display = true;
-    vlc_mutex_unlock(&sys->manage_mutex);
-}
-
 static int set_latency_target(vout_display_t *vd, bool enable)
 {
     vout_display_sys_t *sys = vd->sys;
@@ -885,9 +810,9 @@ static void adjust_refresh_rate(vout_display_t *vd)
     double best_score, score;
     int i;
 
-    vc_tv_get_display_state_id(sys->display_id, &display_state);
+    vc_tv_get_display_state_id(vd->cfg->window->handle.display_id, &display_state);
     if(display_state.display.hdmi.mode != HDMI_MODE_OFF) {
-        num_modes = vc_tv_hdmi_get_supported_modes_new_id(sys->display_id, display_state.display.hdmi.group,
+        num_modes = vc_tv_hdmi_get_supported_modes_new_id(vd->cfg->window->handle.display_id, display_state.display.hdmi.group,
                         supported_modes, VC_TV_MAX_MODE_IDS, NULL, NULL);
 
         for (i = 0; i < num_modes; ++i) {
@@ -915,7 +840,7 @@ static void adjust_refresh_rate(vout_display_t *vd)
         if((best_id >= 0) && (display_state.display.hdmi.mode != supported_modes[best_id].code)) {
             msg_Info(vd, "Setting HDMI refresh rate to %"PRIu32,
                             supported_modes[best_id].frame_rate);
-            vc_tv_hdmi_power_on_explicit_new_id(sys->display_id, HDMI_MODE_HDMI,
+            vc_tv_hdmi_power_on_explicit_new_id(vd->cfg->window->handle.display_id, HDMI_MODE_HDMI,
                             supported_modes[best_id].group,
                             supported_modes[best_id].code);
         }
@@ -987,8 +912,6 @@ static void CloseMmalVout(vout_display_t * vd)
     vout_display_sys_t * const sys = vd->sys;
     char response[20]; /* answer is hvs_update_fields=%1d */
 
-    vc_tv_unregister_callback_full(tvservice_cb, vd);
-
     // Shouldn't be anything here - but just in case
     for (unsigned int i = 0; i != SUBS_MAX; ++i)
         if (sys->subpic_bufs[i] != NULL)
@@ -1074,6 +997,9 @@ static const struct vlc_display_operations ops = {
 static int OpenMmalVout(vout_display_t *vd,
                         video_format_t *fmtp, vlc_video_context *vctx)
 {
+    if (vd->cfg->window->type != VLC_WINDOW_TYPE_MMAL)
+        return VLC_ENOTSUP;
+
     vout_display_sys_t *sys;
     MMAL_DISPLAYREGION_T display_region;
     MMAL_STATUS_T status;
@@ -1106,26 +1032,8 @@ static int OpenMmalVout(vout_display_t *vd,
         goto fail;
     }
 
-    vlc_mutex_init(&sys->manage_mutex);
-
-    vc_tv_register_callback(tvservice_cb, vd);
-
     sys->layer = var_InheritInteger(vd, MMAL_LAYER_NAME);
 
-    {
-        const char *display_name = var_InheritString(vd, MMAL_DISPLAY_NAME);
-        int qt_num = -1;
-        int display_id = find_display_num(display_name);
-//        sys->display_id = display_id < 0 ? vc_tv_get_default_display_id() : display_id;
-        sys->display_id = display_id >= 0 ? display_id : DISPMANX_ID_HDMI;
-        if (display_id < -1)
-            msg_Warn(vd, "Unknown display device: '%s'", display_name);
-        else
-            msg_Dbg(vd, "Display device: %s, qt=%d id=%d display=%d", display_name,
-                    qt_num, display_id, sys->display_id);
-        free(display_name);
-    }
-
     status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &sys->component);
     if (status != MMAL_SUCCESS) {
         msg_Err(vd, "Failed to create MMAL component %s (status=%"PRIx32" %s)",
@@ -1178,17 +1086,11 @@ static int OpenMmalVout(vout_display_t *vd,
         }
     }
 
-    if (query_resolution(vd, sys->display_id, &sys->display_width, &sys->display_height) < 0)
-    {
-        sys->display_width = vd->cfg->display.width;
-        sys->display_height = vd->cfg->display.height;
-    }
-
     place_dest(vd);  // Sets sys->dest_rect
 
     display_region.hdr.id = MMAL_PARAMETER_DISPLAYREGION;
     display_region.hdr.size = sizeof(MMAL_DISPLAYREGION_T);
-    display_region.display_num = sys->display_id;
+    display_region.display_num = vd->cfg->window->handle.display_id;
     display_region.fullscreen = MMAL_FALSE;
     display_src_rect(vd, &display_region.src_rect);
     display_region.dest_rect = sys->dest_rect;
@@ -1238,7 +1140,7 @@ static int OpenMmalVout(vout_display_t *vd,
             goto fail;
         }
         if ((status = hw_mmal_subpic_open(VLC_OBJECT(vd), &sub->sub, sub->component->input[0],
-                                          sys->display_id, sys->layer + i + 1)) != MMAL_SUCCESS) {
+                                          vd->cfg->window->handle.display_id, sys->layer + i + 1)) != MMAL_SUCCESS) {
             msg_Dbg(vd, "Failed to open subpic %d", i);
             goto fail;
         }
@@ -1265,3 +1167,81 @@ fail:
 
     return ret;
 }
+
+///////////////////////////////
+
+static int send_resolution(vlc_window_t *wnd)
+{
+    TV_DISPLAY_STATE_T display_state = {0};
+    int ret = VLC_SUCCESS;
+
+    if (vc_tv_get_display_state_id(wnd->handle.display_id, &display_state) == 0) {
+        msg_Dbg(wnd, "State=%#x", display_state.state);
+        if (display_state.state & 0xFF) {
+            msg_Dbg(wnd, "HDMI: %dx%d", display_state.display.hdmi.width, display_state.display.hdmi.height);
+            vlc_window_ReportSize(wnd, display_state.display.hdmi.width, display_state.display.hdmi.height);
+        } else if (display_state.state & 0xFF00) {
+            msg_Dbg(wnd, "SDTV: %dx%d", display_state.display.sdtv.width, display_state.display.sdtv.height);
+            vlc_window_ReportSize(wnd, display_state.display.sdtv.width, display_state.display.sdtv.height);
+        } else {
+            msg_Warn(wnd, "Invalid display state %"PRIx32, display_state.state);
+            ret = VLC_EINVAL;
+        }
+    } else {
+        msg_Warn(wnd, "Failed to query display resolution");
+        ret = VLC_EACCES;
+    }
+
+    return ret;
+}
+
+static void tvservice_cb(void *callback_data, uint32_t reason, uint32_t param1, uint32_t param2)
+{
+    VLC_UNUSED(reason);
+    VLC_UNUSED(param1);
+    VLC_UNUSED(param2);
+
+    vlc_window_t *wnd = callback_data;
+    send_resolution(wnd);
+}
+
+static int EnableWindow(vlc_window_t *wnd, const vlc_window_cfg_t *cfg)
+{
+    int err = send_resolution(wnd);
+    if (err != VLC_SUCCESS)
+        return err;
+
+    vc_tv_register_callback(tvservice_cb, wnd);
+    return VLC_SUCCESS;
+}
+
+static void DisableWindow(vlc_window_t *wnd)
+{
+    vc_tv_unregister_callback_full(tvservice_cb, wnd);
+}
+
+static int OpenMmalWindow(vlc_window_t *wnd)
+{
+    {
+        char *display_name = var_InheritString(wnd, MMAL_DISPLAY_NAME);
+        int qt_num = -1;
+        int display_id = find_display_num(display_name);
+//        wnd->handle.display_id = display_id < 0 ? vc_tv_get_default_display_id() : display_id;
+        wnd->handle.display_id = display_id >= 0 ? display_id : DISPMANX_ID_HDMI;
+        if (display_id < -1)
+            msg_Warn(wnd, "Unknown display device: '%s'", display_name);
+        else
+            msg_Dbg(wnd, "Display device: %s, qt=%d id=%d display=%d", display_name,
+                    qt_num, display_id, wnd->handle.display_id);
+        free(display_name);
+    }
+
+    static const struct vlc_window_operations ops = {
+        .enable = EnableWindow,
+        .disable = DisableWindow,
+    };
+
+    wnd->type = VLC_WINDOW_TYPE_MMAL;
+    wnd->ops = &ops;
+    return VLC_SUCCESS;
+}



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/960e5a50b924112c19fe6ab62c411417cade556b

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/960e5a50b924112c19fe6ab62c411417cade556b
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list