[vlc-devel] [PATCH v3 2/2] mmal/vout: Support native interlaced modes
Julian Scheel
julian at jusst.de
Wed Oct 15 10:05:30 CEST 2014
Add a new flag, which can be used to let mmal select ahdmi mode which matches
the video size and interlacing type. Using this with a proper screen one can
playback for example 1080i content using the screens deinterlacing filters.
The videocore is configured to scan out picture on odd/even field only
according to the top_field_first mode of the video in case of interlaced
video. For progressive video a progressive mode is selected.
Signed-off-by: Julian Scheel <julian at jusst.de>
---
Changes in v3:
- Simplify help texts
- Fix struct packing
- Fix response buffer size
modules/hw/mmal/vout.c | 58 ++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 51 insertions(+), 7 deletions(-)
diff --git a/modules/hw/mmal/vout.c b/modules/hw/mmal/vout.c
index 6c4de59..80aa86b 100644
--- a/modules/hw/mmal/vout.c
+++ b/modules/hw/mmal/vout.c
@@ -53,6 +53,11 @@
#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_("Force interlaced video mode.")
+#define MMAL_NATIVE_INTERLACE_LONGTEXT N_("Force the HDMI output into an " \
+ "interlaced video mode for interlaced video content.")
+
/* 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 +73,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()
@@ -115,6 +122,9 @@ struct vout_display_sys_t {
bool need_configure_display;
bool adjust_refresh_rate;
+ bool native_interlaced;
+ bool b_top_field_first;
+ bool b_progressive;
bool opaque;
};
@@ -312,6 +322,7 @@ static void Close(vlc_object_t *object)
{
vout_display_t *vd = (vout_display_t *)object;
vout_display_sys_t *sys = vd->sys;
+ char response[20]; /* answer is hvs_update_fields=%1d */
unsigned i;
vc_tv_unregister_callback_full(tvservice_cb, vd);
@@ -345,6 +356,12 @@ static void Close(vlc_object_t *object)
vlc_cond_destroy(&sys->buffer_cond);
vlc_mutex_destroy(&sys->manage_mutex);
+ if (sys->native_interlaced) {
+ if (vc_gencmd(response, sizeof(response), "hvs_update_fields 0") < 0 ||
+ response[18] != '0')
+ msg_Warn(vd, "Could not reset hvs field mode");
+ }
+
free(sys->pictures);
free(sys);
@@ -412,6 +429,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);
+ sys->native_interlaced = var_InheritBool(vd, MMAL_NATIVE_INTERLACED);
if (sys->adjust_refresh_rate) {
adjust_refresh_rate(vd, fmt);
set_latency_target(vd, true);
@@ -532,7 +550,11 @@ static void vd_display(vout_display_t *vd, picture_t *picture,
MMAL_STATUS_T status;
if (picture->format.i_frame_rate != vd->fmt.i_frame_rate ||
- picture->format.i_frame_rate_base != vd->fmt.i_frame_rate_base) {
+ picture->format.i_frame_rate_base != vd->fmt.i_frame_rate_base ||
+ picture->b_progressive != sys->b_progressive ||
+ picture->b_top_field_first != sys->b_top_field_first) {
+ sys->b_top_field_first = picture->b_top_field_first;
+ sys->b_progressive = picture->b_progressive;
configure_display(vd, NULL, &picture->format);
}
@@ -762,8 +784,10 @@ static int set_latency_target(vout_display_t *vd, bool enable)
static void adjust_refresh_rate(vout_display_t *vd, const video_format_t *fmt)
{
+ vout_display_sys_t *sys = vd->sys;
TV_DISPLAY_STATE_T display_state;
TV_SUPPORTED_MODE_NEW_T supported_modes[VC_TV_MAX_MODE_IDS];
+ char response[20]; /* answer is hvs_update_fields=%1d */
int num_modes;
double frame_rate = (double)fmt->i_frame_rate / fmt->i_frame_rate_base;
int best_id = -1;
@@ -775,11 +799,20 @@ 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 (!sys->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)
+ continue;
+ if (mode->scan_mode != sys->b_progressive ? HDMI_NONINTERLACED : HDMI_INTERLACED)
+ continue;
+ }
score = fmod(supported_modes[i].frame_rate, frame_rate);
if((best_id < 0) || (score < best_score)) {
@@ -788,13 +821,24 @@ 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,
supported_modes[best_id].group,
supported_modes[best_id].code);
}
+
+ if (sys->native_interlaced &&
+ supported_modes[best_id].scan_mode == HDMI_INTERLACED) {
+ char hvs_mode = sys->b_top_field_first ? '1' : '2';
+ if (vc_gencmd(response, sizeof(response), "hvs_update_fields %c",
+ hvs_mode) != 0 || response[18] != hvs_mode)
+ msg_Warn(vd, "Could not set hvs field mode");
+ else
+ msg_Info(vd, "Configured hvs field mode for interlaced %s playback",
+ sys->b_top_field_first ? "tff" : "bff");
+ }
}
}
--
2.1.2
More information about the vlc-devel
mailing list