]> git.sesse.net Git - vlc/blobdiff - modules/video_output/wrapper.c
Fixed initial crop parameters in vout (close #3376).
[vlc] / modules / video_output / wrapper.c
index 5a51ba52184e6f60e1e884e35e1dbcb213dfd436..558db233cb21a95136354330f52024872fa305d1 100644 (file)
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
-static int  Open (vlc_object_t *, const char *module);
+static int  Open (vlc_object_t *);
 static void Close(vlc_object_t *);
 
-#define DECLARE_OPEN(name) \
-        static int Open##name(vlc_object_t *object) { return Open(object, #name); }
-
-DECLARE_OPEN(none);
-
-#undef DECLARE_OPEN
-
-#define DECLARE_MODULE(name, priority)                  \
-    set_description( "Video display "#name" wrapper" )  \
-    set_shortname( "Video display "#name" wrapper" )    \
-    set_capability( "video output", priority )          \
-    set_callbacks( Open##name, Close )                  \
-    add_shortcut( #name )
-
 vlc_module_begin()
     set_category( CAT_VIDEO )
     set_subcategory( SUBCAT_VIDEO_VOUT )
 
-    DECLARE_MODULE(none, 0)
+    set_description( "Transitional video display wrapper" )
+    set_shortname( "Video display wrapper" )
+    set_capability( "video output", 210 )
+    set_callbacks( Open, Close )
 
 vlc_module_end()
 
-#undef DECLARE_MODULE
-
 /*****************************************************************************
  *
  *****************************************************************************/
@@ -90,16 +77,20 @@ static void Display(vout_thread_t *, picture_t *);
 
 static void VoutGetDisplayCfg(vout_thread_t *,
                               vout_display_cfg_t *, const char *title);
+#ifdef WIN32
+static int  Forward(vlc_object_t *, char const *,
+                    vlc_value_t, vlc_value_t, void *);
+#endif
 
 /*****************************************************************************
  *
  *****************************************************************************/
-static int Open(vlc_object_t *object, const char *module)
+static int Open(vlc_object_t *object)
 {
     vout_thread_t *vout = (vout_thread_t *)object;
     vout_sys_t *sys;
 
-    msg_Err(vout, "Opening vout display wrapper");
+    msg_Dbg(vout, "Opening vout display wrapper");
 
     /* */
     sys = malloc(sizeof(*sys));
@@ -124,7 +115,7 @@ static int Open(vlc_object_t *object, const char *module)
     const mtime_t double_click_timeout = 300000;
     const mtime_t hide_timeout = var_CreateGetInteger(vout, "mouse-hide-timeout") * 1000;
 
-    sys->vd = vout_NewDisplay(vout, &source, &state, module,
+    sys->vd = vout_NewDisplay(vout, &source, &state, "$vout",
                               double_click_timeout, hide_timeout);
     if (!sys->vd) {
         free(sys->title);
@@ -132,6 +123,14 @@ static int Open(vlc_object_t *object, const char *module)
         return VLC_EGENERIC;
     }
 
+    /* */
+#ifdef WIN32
+    var_Create(vout, "direct3d-desktop", VLC_VAR_BOOL|VLC_VAR_DOINHERIT);
+    var_AddCallback(vout, "direct3d-desktop", Forward, NULL);
+    var_Create(vout, "video-wallpaper", VLC_VAR_BOOL|VLC_VAR_DOINHERIT);
+    var_AddCallback(vout, "video-wallpaper", Forward, NULL);
+#endif
+
     /* */
     vout->pf_init    = Init;
     vout->pf_end     = End;
@@ -152,8 +151,11 @@ static void Close(vlc_object_t *object)
     vout_thread_t *vout = (vout_thread_t *)object;
     vout_sys_t *sys = vout->p_sys;
 
-    if (sys->vd)
-        vout_DeleteDisplay(sys->vd, NULL);
+#ifdef WIN32
+    var_DelCallback(vout, "direct3d-desktop", Forward, NULL);
+    var_DelCallback(vout, "video-wallpaper", Forward, NULL);
+#endif
+    vout_DeleteDisplay(sys->vd, NULL);
     free(sys->title);
     free(sys );
 }
@@ -172,7 +174,7 @@ static int Init(vout_thread_t *vout)
     vout->output.i_chroma = source.i_chroma;
     vout->output.i_width  = source.i_width;
     vout->output.i_height = source.i_height;
-    vout->output.i_aspect = source.i_aspect;
+    vout->output.i_aspect = (int64_t)source.i_sar_num * source.i_width * VOUT_ASPECT_FACTOR / source.i_sar_den / source.i_height;
     vout->output.i_rmask  = source.i_rmask;
     vout->output.i_gmask  = source.i_gmask;
     vout->output.i_bmask  = source.i_bmask;
@@ -184,22 +186,19 @@ static int Init(vout_thread_t *vout)
     vout->fmt_out.i_visible_width  = vout->output.i_width;
     vout->fmt_out.i_height         =
     vout->fmt_out.i_visible_height = vout->output.i_height;
-    vout->fmt_out.i_aspect         = vout->output.i_aspect;
+    vout->fmt_out.i_sar_num        = vout->output.i_aspect * vout->output.i_height;
+    vout->fmt_out.i_sar_den        = VOUT_ASPECT_FACTOR    * vout->output.i_width;
     vout->fmt_out.i_x_offset       = 0;
     vout->fmt_out.i_y_offset       = 0;
 
-    /* TODO */
-#if 0
-    if (p_vout->fmt_render.i_visible_width  != source.i_visible_width ||
-        p_vout->fmt_render.i_visible_height != source.i_visible_height ||
-        p_vout->fmt_render.i_x_offset != source.i_x_offset ||
-        p_vout->fmt_render.i_y_offset != source.i_y_offset )
-    {
-        p_vout->i_changes |= VOUT_CROP_CHANGE;
-    }
-#endif
+    if (vout->fmt_in.i_visible_width  != source.i_visible_width ||
+        vout->fmt_in.i_visible_height != source.i_visible_height ||
+        vout->fmt_in.i_x_offset       != source.i_x_offset ||
+        vout->fmt_in.i_y_offset       != source.i_y_offset )
+        vout->i_changes |= VOUT_CROP_CHANGE;
+
     if (vout->b_on_top)
-        vout_SetDisplayOnTop(vd, true);
+        vout_SetWindowState(vd, VOUT_WINDOW_STATE_ABOVE);
 
     /* XXX For non dr case, the current vout implementation force us to
      * create at most 1 direct picture (otherwise the buffers will be kept
@@ -226,7 +225,10 @@ static int Init(vout_thread_t *vout)
         picture->p_sys = malloc(sizeof(*picture->p_sys));
 
         if (sys->use_dr) {
-            picture_t *direct = vout_display_Get(vd);
+            picture_pool_t *pool = vout_display_Pool(vd, picture_max);
+            if (!pool)
+                break;
+            picture_t *direct = picture_pool_Get(pool);
             if (!direct)
                 break;
             picture->format = direct->format;
@@ -240,7 +242,7 @@ static int Init(vout_thread_t *vout)
             vout_AllocatePicture(VLC_OBJECT(vd), picture,
                                  vd->source.i_chroma,
                                  vd->source.i_width, vd->source.i_height,
-                                 vd->source.i_aspect);
+                                 vd->source.i_sar_num, vd->source.i_sar_den);
             if (!picture->i_planes)
                 break;
             picture->p_sys->direct = NULL;
@@ -271,7 +273,11 @@ static void End(vout_thread_t *vout)
         if (!sys->use_dr)
             free(picture->p_data_orig);
         free(picture->p_sys);
+
+        picture->i_status = FREE_PICTURE;
     }
+    if (sys->use_dr && vout_AreDisplayPicturesInvalid(sys->vd))
+        vout_ManageDisplay(sys->vd, true);
 }
 
 /*****************************************************************************
@@ -297,8 +303,8 @@ static int Manage(vout_thread_t *vout)
             vout->i_changes &= ~VOUT_FULLSCREEN_CHANGE;
         }
         if (vout->i_changes & VOUT_ASPECT_CHANGE) {
-            vout->output.i_aspect   =
-            vout->fmt_out.i_aspect  = vout->fmt_in.i_aspect;
+            vout->output.i_aspect   = (int64_t)vout->fmt_in.i_sar_num * vout->fmt_in.i_width * VOUT_ASPECT_FACTOR /
+                                      vout->fmt_in.i_sar_den / vout->fmt_in.i_height;
             vout->fmt_out.i_sar_num = vout->fmt_in.i_sar_num;
             vout->fmt_out.i_sar_den = vout->fmt_in.i_sar_den;
 
@@ -328,7 +334,9 @@ static int Manage(vout_thread_t *vout)
             vout->i_changes &= ~VOUT_SCALE_CHANGE;
         }
         if (vout->i_changes & VOUT_ON_TOP_CHANGE) {
-            vout_SetDisplayOnTop(vd, vout->b_on_top);
+            vout_SetWindowState(vd, vout->b_on_top
+                ? VOUT_WINDOW_STATE_ABOVE
+                : VOUT_WINDOW_STATE_NORMAL);
 
             vout->i_changes &= ~VOUT_ON_TOP_CHANGE;
         }
@@ -362,8 +370,7 @@ static int Manage(vout_thread_t *vout)
     if (sys->use_dr && vout_AreDisplayPicturesInvalid(vd)) {
         vout->i_changes |= VOUT_PICTURE_BUFFERS_CHANGE;
     }
-
-    vout_ManageDisplay(vd);
+    vout_ManageDisplay(vd, !sys->use_dr);
     return VLC_SUCCESS;
 }
 
@@ -376,21 +383,15 @@ static void Render(vout_thread_t *vout, picture_t *picture)
     vout_display_t *vd = sys->vd;
 
     assert(sys->use_dr || !picture->p_sys->direct);
+    assert(vout_IsDisplayFiltered(vd) == !sys->use_dr);
 
     if (sys->use_dr) {
-        assert(!vout_IsDisplayFiltered(vd));
         assert(picture->p_sys->direct);
-
         vout_display_Prepare(vd, picture->p_sys->direct);
     } else {
-        picture_t *filtered = vout_FilterDisplay(vd, picture);
-        if (filtered) {
-            picture_t *direct = picture->p_sys->direct = vout_display_Get(vd);
-            if (direct) {
-                picture_Copy(direct, filtered);
-                vout_display_Prepare(vd, direct);
-            }
-            picture_Release(filtered);
+        picture_t *direct = picture->p_sys->direct = vout_FilterDisplay(vd, picture);
+        if (direct) {
+            vout_display_Prepare(vd, direct);
         }
     }
 }
@@ -413,8 +414,15 @@ static void Display(vout_thread_t *vout, picture_t *picture)
 
      vout_display_Display(vd, direct);
 
-     if (!sys->use_dr)
+     if (sys->use_dr) {
+         for (int i = 0; i < picture->i_planes; i++) {
+             picture->p[i].p_pixels = direct->p[i].p_pixels;
+             picture->p[i].i_pitch  = direct->p[i].i_pitch;
+             picture->p[i].i_lines  = direct->p[i].i_lines;
+         }
+     } else {
          picture->p_sys->direct = NULL;
+     }
 }
 
 static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, const char *title)
@@ -422,8 +430,10 @@ static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, cons
     /* Load configuration */
     cfg->is_fullscreen = var_CreateGetBool(vout, "fullscreen");
     cfg->display.title = title;
-    cfg->display.width   = var_CreateGetInteger(vout, "width");
-    cfg->display.height  = var_CreateGetInteger(vout, "height");
+    const int display_width = var_CreateGetInteger(vout, "width");
+    const int display_height = var_CreateGetInteger(vout, "height");
+    cfg->display.width   = display_width > 0  ? display_width  : 0;
+    cfg->display.height  = display_height > 0 ? display_height : 0;
     cfg->is_display_filled  = var_CreateGetBool(vout, "autoscale");
     cfg->display.sar.num = 1; /* TODO monitor AR */
     cfg->display.sar.den = 1;
@@ -445,3 +455,14 @@ static void VoutGetDisplayCfg(vout_thread_t *vout, vout_display_cfg_t *cfg, cons
         cfg->align.horizontal = VOUT_DISPLAY_ALIGN_BOTTOM;
 }
 
+#ifdef WIN32
+static int Forward(vlc_object_t *object, char const *var,
+                   vlc_value_t oldval, vlc_value_t newval, void *data)
+{
+    vout_thread_t *vout = (vout_thread_t*)object;
+
+    VLC_UNUSED(oldval);
+    VLC_UNUSED(data);
+    return var_Set(vout->p_sys->vd, var, newval);
+}
+#endif