[vlc-devel] [PATCH 3/3] mmal/vout: Support native interlaced modes

Julian Scheel julian at jusst.de
Thu Oct 9 14:49:41 CEST 2014


Add a new flag, which can be used to let mmal select an interlaced hdmi mode
which matches the video size. Using this with a proper screen one can playback
for example 1080i content using the screens deinterlacing filters.
Right now the code is not making many sanity checks but just requests an
interlaced mode matching the video size. It might be extended by checking for
actual interlaced content later on.

Signed-off-by: Julian Scheel <julian at jusst.de>
---
 modules/hw/mmal/vout.c | 34 +++++++++++++++++++++++++---------
 1 file changed, 25 insertions(+), 9 deletions(-)

diff --git a/modules/hw/mmal/vout.c b/modules/hw/mmal/vout.c
index a79ba33..faed47e 100644
--- a/modules/hw/mmal/vout.c
+++ b/modules/hw/mmal/vout.c
@@ -53,6 +53,10 @@
 #define MMAL_ADJUST_REFRESHRATE_TEXT N_("Adjust HDMI refresh rate to the video.")
 #define MMAL_ADJUST_REFRESHRATE_LONGTEXT N_("Adjust HDMI refresh rate to the video.")
 
+#define MMAL_NATIVE_INTERLACED "mmal-native-interlaced"
+#define MMAL_NATIVE_INTERLACE_TEXT N_("Try to render interlaced video in native mode.")
+#define MMAL_NATIVE_INTERLACE_LONGTEXT N_("Tries to setup an interlaced video mode which matches the video format. This allows the connected display to handle the deinterlacing.")
+
 /* Ideal rendering phase target is at rough 25% of frame duration */
 #define PHASE_OFFSET_TARGET ((double)0.25)
 #define PHASE_CHECK_INTERVAL 100
@@ -68,6 +72,8 @@ vlc_module_begin()
     add_integer(MMAL_LAYER_NAME, 1, MMAL_LAYER_TEXT, MMAL_LAYER_LONGTEXT, false)
     add_bool(MMAL_ADJUST_REFRESHRATE_NAME, false, MMAL_ADJUST_REFRESHRATE_TEXT,
                     MMAL_ADJUST_REFRESHRATE_LONGTEXT, false)
+    add_bool(MMAL_NATIVE_INTERLACED, false, MMAL_NATIVE_INTERLACE_TEXT,
+                    MMAL_NATIVE_INTERLACE_LONGTEXT, false)
     set_callbacks(Open, Close)
 vlc_module_end()
 
@@ -144,7 +150,8 @@ static void input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer);
 static int query_resolution(vout_display_t *vd, unsigned *width, unsigned *height);
 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, const video_format_t *fmt);
+static void adjust_refresh_rate(vout_display_t *vd, const video_format_t *fmt,
+                bool native_interlaced);
 static int set_latency_target(vout_display_t *vd, bool enable);
 
 /* DispManX */
@@ -412,7 +419,7 @@ static int configure_display(vout_display_t *vd, const vout_display_cfg_t *cfg,
     show_background(vd, cfg->is_fullscreen);
     sys->adjust_refresh_rate = var_InheritBool(vd, MMAL_ADJUST_REFRESHRATE_NAME);
     if (sys->adjust_refresh_rate) {
-        adjust_refresh_rate(vd, fmt);
+        adjust_refresh_rate(vd, fmt, var_InheritBool(vd, MMAL_NATIVE_INTERLACED));
         set_latency_target(vd, true);
     }
 
@@ -754,7 +761,8 @@ static int set_latency_target(vout_display_t *vd, bool enable)
     return VLC_SUCCESS;
 }
 
-static void adjust_refresh_rate(vout_display_t *vd, const video_format_t *fmt)
+static void adjust_refresh_rate(vout_display_t *vd, const video_format_t *fmt,
+        bool native_interlaced)
 {
     TV_DISPLAY_STATE_T display_state;
     TV_SUPPORTED_MODE_NEW_T supported_modes[VC_TV_MAX_MODE_IDS];
@@ -769,11 +777,19 @@ static void adjust_refresh_rate(vout_display_t *vd, const video_format_t *fmt)
         num_modes = vc_tv_hdmi_get_supported_modes_new(display_state.display.hdmi.group,
                         supported_modes, VC_TV_MAX_MODE_IDS, NULL, NULL);
 
-        for(i = 0; i < num_modes; ++i) {
-            if(supported_modes[i].width != display_state.display.hdmi.width ||
-                            supported_modes[i].height != display_state.display.hdmi.height ||
-                            supported_modes[i].scan_mode != display_state.display.hdmi.scan_mode)
-                continue;
+        for (i = 0; i < num_modes; ++i) {
+            TV_SUPPORTED_MODE_NEW_T *mode = &supported_modes[i];
+            if (!native_interlaced) {
+                if (mode->width != display_state.display.hdmi.width ||
+                                mode->height != display_state.display.hdmi.height ||
+                                mode->scan_mode == HDMI_INTERLACED)
+                    continue;
+            } else {
+                if (mode->width != vd->fmt.i_visible_width ||
+                        mode->height != vd->fmt.i_visible_height ||
+                        mode->scan_mode != HDMI_INTERLACED)
+                    continue;
+            }
 
             score = fmod(supported_modes[i].frame_rate, frame_rate);
             if((best_id < 0) || (score < best_score)) {
@@ -782,7 +798,7 @@ static void adjust_refresh_rate(vout_display_t *vd, const video_format_t *fmt)
             }
         }
 
-        if((best_id >= 0) && (display_state.display.hdmi.frame_rate != supported_modes[best_id].frame_rate)) {
+        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(HDMI_MODE_HDMI,
-- 
2.1.2




More information about the vlc-devel mailing list