]> git.sesse.net Git - vlc/commitdiff
Clean up crop/aspect ratio changes and associated video format.
authorLaurent Aimar <fenrir@videolan.org>
Mon, 10 May 2010 18:26:07 +0000 (20:26 +0200)
committerLaurent Aimar <fenrir@videolan.org>
Mon, 10 May 2010 19:52:42 +0000 (21:52 +0200)
src/video_output/control.h
src/video_output/display.c
src/video_output/video_output.c
src/video_output/vout_internal.h
src/video_output/vout_intf.c
src/video_output/vout_wrapper.c

index a8010d0a32acaec89b3718105db2b42845e98a00..168b5e78ad7c2ae37aedeabe48a23ce621c09f16 100644 (file)
@@ -40,10 +40,6 @@ enum {
 
     /* Controls */
 
-    VOUT_CONTROL_SOURCE_ASPECT,
-    VOUT_CONTROL_SOURCE_CROP_BORDER,
-    VOUT_CONTROL_SOURCE_CROP_RATIO,
-    VOUT_CONTROL_SOURCE_CROP_WINDOW,
 
     /* OSD */
     VOUT_CONTROL_OSD_MESSAGE,
@@ -64,6 +60,11 @@ enum {
     VOUT_CONTROL_ON_TOP,                /* bool */
     VOUT_CONTROL_DISPLAY_FILLED,        /* bool */
     VOUT_CONTROL_ZOOM,                  /* pair */
+
+    VOUT_CONTROL_ASPECT_RATIO,          /* pair */
+    VOUT_CONTROL_CROP_BORDER,           /* border */
+    VOUT_CONTROL_CROP_RATIO,            /* pair */
+    VOUT_CONTROL_CROP_WINDOW,           /* window */
 };
 
 typedef struct {
@@ -86,17 +87,6 @@ typedef struct {
             int channel;
             char *string;
         } message;
-#if 0
-        struct {
-            int channel;
-            char *string;
-            text_style_t *style;
-            int flags;
-            int hmargin;
-            int vmargin;
-            mtime_t start;
-            mtime_t stop;
-        } text;
         struct {
             unsigned left;
             unsigned top;
@@ -109,17 +99,6 @@ typedef struct {
             unsigned width;
             unsigned height;
         } window;
-        struct {
-            int   channel;
-            int   type;
-            float position;
-        } slider;
-        struct {
-            int channel;
-            int icon;
-        } icon;
-        subpicture_t *subpicture;
-#endif
     } u;
 } vout_control_cmd_t;
 
index 6ea51326248f2fafe594bf8f872f53da2fdeabd2..7d747c215b4946f243f7882c83c0d2c51d5ec34b 100644 (file)
@@ -525,9 +525,6 @@ static void VoutDisplayEventMouse(vout_display_t *vd, int event, va_list args)
     if (!vd->info.has_hide_mouse)
         osys->mouse.last_moved = mdate();
 
-    /* */
-    vlc_mutex_unlock(&osys->lock);
-
     /* */
     vout_SendEventMouseVisible(osys->vout);
 #ifdef ALLOW_DUMMY_VOUT
@@ -535,6 +532,7 @@ static void VoutDisplayEventMouse(vout_display_t *vd, int event, va_list args)
 #else
     vout_SendDisplayEventMouse(osys->vout, &m);
 #endif
+    vlc_mutex_unlock(&osys->lock);
 }
 
 static void VoutDisplayEvent(vout_display_t *vd, int event, va_list args)
@@ -1412,7 +1410,7 @@ void vout_SendDisplayEventMouse(vout_thread_t *vout, const vlc_mouse_t *m)
     vlc_mouse_t tmp;
 
     /* The check on p_spu is needed as long as ALLOW_DUMMY_VOUT is defined */
-    if (vout->p->p_spu && spu_ProcessMouse( vout->p->p_spu, m, &vout->p->fmt_out))
+    if (vout->p->p_spu && spu_ProcessMouse( vout->p->p_spu, m, &vout->p->display.vd->source))
         return;
 
     vlc_mutex_lock( &vout->p->vfilter_lock );
index 5069d7c5cfa11498ae006fd360f96e18ee82c981..8d82a419a19c661b088f822143badbfa34a300fe 100644 (file)
@@ -161,11 +161,7 @@ vout_thread_t *vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout,
             free( psz_filter_chain );
         }
 
-#warning "FIXME: Check RGB masks in vout_Request"
-        /* FIXME: check RGB masks */
-        if( p_vout->p->fmt_render.i_chroma != vlc_fourcc_GetCodec( VIDEO_ES, p_fmt->i_chroma ) ||
-            p_vout->p->fmt_render.i_width != p_fmt->i_width ||
-            p_vout->p->fmt_render.i_height != p_fmt->i_height ||
+        if( !video_format_IsSimilar( &p_vout->p->original, p_fmt ) ||
             p_vout->p->b_filter_change )
         {
             vlc_mutex_unlock( &p_vout->p->change_lock );
@@ -178,32 +174,6 @@ vout_thread_t *vout_Request( vlc_object_t *p_this, vout_thread_t *p_vout,
         else
         {
             /* This video output is cool! Hijack it. */
-            /* Correct aspect ratio on change
-             * FIXME factorize this code with other aspect ration related code */
-            unsigned int i_sar_num;
-            unsigned int i_sar_den;
-            vlc_ureduce( &i_sar_num, &i_sar_den,
-                         p_fmt->i_sar_num, p_fmt->i_sar_den, 50000 );
-#if 0
-            /* What's that, it does not seems to be used correcly everywhere */
-            if( p_vout->i_par_num > 0 && p_vout->i_par_den > 0 )
-            {
-                i_sar_num *= p_vout->i_par_den;
-                i_sar_den *= p_vout->i_par_num;
-            }
-#endif
-
-            if( i_sar_num > 0 && i_sar_den > 0 &&
-                ( i_sar_num != p_vout->p->fmt_render.i_sar_num ||
-                  i_sar_den != p_vout->p->fmt_render.i_sar_den ) )
-            {
-                p_vout->p->fmt_in.i_sar_num = i_sar_num;
-                p_vout->p->fmt_in.i_sar_den = i_sar_den;
-
-                p_vout->p->fmt_render.i_sar_num = i_sar_num;
-                p_vout->p->fmt_render.i_sar_den = i_sar_den;
-                p_vout->p->i_changes |= VOUT_ASPECT_CHANGE;
-            }
             vlc_mutex_unlock( &p_vout->p->change_lock );
 
             vlc_object_release( p_vout );
@@ -272,17 +242,12 @@ vout_thread_t * (vout_Create)( vlc_object_t *p_parent, video_format_t *p_fmt )
     }
 
     /* */
-    p_vout->p->fmt_render        = *p_fmt;   /* FIXME palette */
-    p_vout->p->fmt_in            = *p_fmt;   /* FIXME palette */
-
-    p_vout->p->fmt_render.i_chroma = 
-    p_vout->p->fmt_in.i_chroma     = i_chroma;
-    video_format_FixRgb( &p_vout->p->fmt_render );
-    video_format_FixRgb( &p_vout->p->fmt_in );
+    p_vout->p->original = *p_fmt;   /* FIXME palette */
+    p_vout->p->original.i_chroma = i_chroma;
+    video_format_FixRgb( &p_vout->p->original );
 
     /* Initialize misc stuff */
     vout_control_Init( &p_vout->p->control );
-    p_vout->p->i_changes    = 0;
     vout_chrono_Init( &p_vout->p->render, 5, 10000 ); /* Arbitrary initial time */
     vout_statistic_Init( &p_vout->p->statistic );
     p_vout->p->b_filter_change = 0;
@@ -593,6 +558,42 @@ void vout_ControlChangeZoom(vout_thread_t *vout, int num, int den)
     vout_control_PushPair(&vout->p->control, VOUT_CONTROL_ZOOM,
                           num, den);
 }
+void vout_ControlChangeSampleAspectRatio(vout_thread_t *vout,
+                                         unsigned num, unsigned den)
+{
+    vout_control_PushPair(&vout->p->control, VOUT_CONTROL_ASPECT_RATIO,
+                          num, den);
+}
+void vout_ControlChangeCropRatio(vout_thread_t *vout,
+                                 unsigned num, unsigned den)
+{
+    vout_control_PushPair(&vout->p->control, VOUT_CONTROL_CROP_RATIO,
+                          num, den);
+}
+void vout_ControlChangeCropWindow(vout_thread_t *vout,
+                                  int x, int y, int width, int height)
+{
+    vout_control_cmd_t cmd;
+    vout_control_cmd_Init(&cmd, VOUT_CONTROL_CROP_WINDOW);
+    cmd.u.window.x      = x;
+    cmd.u.window.y      = y;
+    cmd.u.window.width  = width;
+    cmd.u.window.height = height;
+
+    vout_control_Push(&vout->p->control, &cmd);
+}
+void vout_ControlChangeCropBorder(vout_thread_t *vout,
+                                  int left, int top, int right, int bottom)
+{
+    vout_control_cmd_t cmd;
+    vout_control_cmd_Init(&cmd, VOUT_CONTROL_CROP_BORDER);
+    cmd.u.border.left   = left;
+    cmd.u.border.top    = top;
+    cmd.u.border.right  = right;
+    cmd.u.border.bottom = bottom;
+
+    vout_control_Push(&vout->p->control, &cmd);
+}
 
 /*****************************************************************************
  * InitThread: initialize video output thread
@@ -613,19 +614,14 @@ static int ThreadInit(vout_thread_t *vout)
 
     /* print some usefull debug info about different vout formats
      */
-    PrintVideoFormat(vout, "pic render", &vout->p->fmt_render);
-    PrintVideoFormat(vout, "pic in",     &vout->p->fmt_in);
-    PrintVideoFormat(vout, "pic out",    &vout->p->fmt_out);
-
-    assert(vout->p->fmt_out.i_width  == vout->p->fmt_render.i_width &&
-           vout->p->fmt_out.i_height == vout->p->fmt_render.i_height &&
-           vout->p->fmt_out.i_chroma == vout->p->fmt_render.i_chroma);
+    PrintVideoFormat(vout, "pic render", &vout->p->original);
     return VLC_SUCCESS;
 }
 
 static int ThreadDisplayPicture(vout_thread_t *vout,
                                 bool now, mtime_t *deadline)
 {
+    vout_display_t *vd = vout->p->display.vd;
     int displayed_count = 0;
     int lost_count = 0;
 
@@ -743,7 +739,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
             (vout->p->decoder_pool != vout->p->display_pool || subpic)) {
             picture_t *render;
             if (vout->p->is_decoder_pool_slow)
-                render = picture_NewFromFormat(&vout->p->fmt_out);
+                render = picture_NewFromFormat(&vd->source);
             else if (vout->p->decoder_pool != vout->p->display_pool)
                 render = picture_pool_Get(vout->p->display_pool);
             else
@@ -753,8 +749,8 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
                 picture_Copy(render, filtered);
 
                 spu_RenderSubpictures(vout->p->p_spu,
-                                      render, &vout->p->fmt_out,
-                                      subpic, &vout->p->fmt_in, spu_render_time);
+                                      render, &vd->source,
+                                      subpic, &vd->source, spu_render_time);
             }
             if (vout->p->is_decoder_pool_slow) {
                 direct = picture_pool_Get(vout->p->display_pool);
@@ -775,7 +771,7 @@ static int ThreadDisplayPicture(vout_thread_t *vout,
          * Take a snapshot if requested
          */
         if (direct && do_snapshot)
-            vout_snapshot_Set(&vout->p->snapshot, &vout->p->fmt_out, direct);
+            vout_snapshot_Set(&vout->p->snapshot, &vd->source, direct);
 
         /* Render the direct buffer returned by vout_RenderPicture */
         if (direct) {
@@ -857,8 +853,8 @@ static void ThreadDisplayOsdTitle(vout_thread_t *vout, const char *string)
 static void ThreadChangeFilters(vout_thread_t *vout, const char *filters)
 {
     es_format_t fmt;
-    es_format_Init(&fmt, VIDEO_ES, vout->p->fmt_render.i_chroma);
-    fmt.video = vout->p->fmt_render;
+    es_format_Init(&fmt, VIDEO_ES, vout->p->original.i_chroma);
+    fmt.video = vout->p->original;
 
     vlc_mutex_lock(&vout->p->vfilter_lock);
 
@@ -975,6 +971,79 @@ static void ThreadChangeZoom(vout_thread_t *vout, int num, int den)
     vout_SetDisplayZoom(vout->p->display.vd, num, den);
 }
 
+static void ThreadChangeAspectRatio(vout_thread_t *vout,
+                                    unsigned num, unsigned den)
+{
+    const video_format_t *source = &vout->p->original;
+
+    if (num > 0 && den > 0) {
+        num *= source->i_visible_height;
+        den *= source->i_visible_width;
+        vlc_ureduce(&num, &den, num, den, 0);
+    }
+    vout_SetDisplayAspect(vout->p->display.vd, num, den);
+}
+
+
+static void ThreadExecuteCropWindow(vout_thread_t *vout,
+                                    unsigned crop_num, unsigned crop_den,
+                                    unsigned x, unsigned y,
+                                    unsigned width, unsigned height)
+{
+    const video_format_t *source = &vout->p->original;
+
+    vout_SetDisplayCrop(vout->p->display.vd,
+                        crop_num, crop_den,
+                        source->i_x_offset + x,
+                        source->i_y_offset + y,
+                        width, height);
+}
+static void ThreadExecuteCropBorder(vout_thread_t *vout,
+                                    unsigned left, unsigned top,
+                                    unsigned right, unsigned bottom)
+{
+    const video_format_t *source = &vout->p->original;
+    ThreadExecuteCropWindow(vout, 0, 0,
+                            left,
+                            top,
+                            /* At worst, it becomes < 0 (but unsigned) and will be rejected */
+                            source->i_visible_width  - (left + right),
+                            source->i_visible_height - (top  + bottom));
+}
+
+static void ThreadExecuteCropRatio(vout_thread_t *vout,
+                                   unsigned num, unsigned den)
+{
+    const video_format_t *source = &vout->p->original;
+
+    int x, y;
+    int width, height;
+    if (num <= 0 || den <= 0) {
+        num = 0;
+        den = 0;
+        x   = 0;
+        y   = 0;
+        width  = source->i_visible_width;
+        height = source->i_visible_height;
+    } else {
+        unsigned scaled_width  = (uint64_t)source->i_visible_height * num * source->i_sar_den / den / source->i_sar_num;
+        unsigned scaled_height = (uint64_t)source->i_visible_width  * den * source->i_sar_num / num / source->i_sar_den;
+
+        if (scaled_width < source->i_visible_width) {
+            x      = (source->i_visible_width - scaled_width) / 2;
+            y      = 0;
+            width  = scaled_width;
+            height = source->i_visible_height;
+        } else {
+            x      = 0;
+            y      = (source->i_visible_height - scaled_height) / 2;
+            width  = source->i_visible_width;
+            height = scaled_height;
+        }
+    }
+    ThreadExecuteCropWindow(vout, num, den, x, y, width, height);
+}
+
 static void ThreadClean(vout_thread_t *vout)
 {
     /* Destroy translation tables */
@@ -1070,6 +1139,22 @@ static void *Thread(void *object)
             case VOUT_CONTROL_ZOOM:
                 ThreadChangeZoom(vout, cmd.u.pair.a, cmd.u.pair.b);
                 break;
+            case VOUT_CONTROL_ASPECT_RATIO:
+                ThreadChangeAspectRatio(vout, cmd.u.pair.a, cmd.u.pair.b);
+                break;
+           case VOUT_CONTROL_CROP_RATIO:
+                ThreadExecuteCropRatio(vout, cmd.u.pair.a, cmd.u.pair.b);
+                break;
+            case VOUT_CONTROL_CROP_WINDOW:
+                ThreadExecuteCropWindow(vout, 0, 0,
+                                        cmd.u.window.x, cmd.u.window.y,
+                                        cmd.u.window.width, cmd.u.window.height);
+                break;
+            case VOUT_CONTROL_CROP_BORDER:
+                ThreadExecuteCropBorder(vout,
+                                        cmd.u.border.left,  cmd.u.border.top,
+                                        cmd.u.border.right, cmd.u.border.bottom);
+                break;
             default:
                 break;
             }
index 6367727493186697a63e4bcf8373c2a3f76558af..f8baf521147b95744c81a5177dc688a6c172cd16 100644 (file)
@@ -49,9 +49,7 @@ struct vout_thread_sys_t
     config_chain_t *p_cfg;
 
     /* */
-    video_format_t  fmt_render;      /* render format (from the decoder) */
-    video_format_t  fmt_in;            /* input (modified render) format */
-    video_format_t  fmt_out;     /* output format (for the video output) */
+    video_format_t  original; /* Original format ie coming from the decoder */
 
     /* Thread & synchronization */
     vlc_thread_t    thread;
@@ -129,27 +127,17 @@ struct vout_thread_sys_t
     vout_chrono_t       render;           /**< picture render time estimator */
 
     vlc_mutex_t         change_lock;                 /**< thread change lock */
-
-    uint16_t            i_changes;          /**< changes made to the thread.
-                                                      \see \ref vout_changes */
 };
 
-/** \defgroup vout_changes Flags for changes
- * These flags are set in the vout_thread_t::i_changes field when another
- * thread changed a variable
- * @{
- */
-/** cropping parameters changed */
-#define VOUT_CROP_CHANGE        0x1000
-/** aspect ratio changed */
-#define VOUT_ASPECT_CHANGE      0x2000
-/**@}*/
-
 /* TODO to move them to vlc_vout.h */
 void vout_ControlChangeFullscreen(vout_thread_t *, bool fullscreen);
 void vout_ControlChangeOnTop(vout_thread_t *, bool is_on_top);
 void vout_ControlChangeDisplayFilled(vout_thread_t *, bool is_filled);
 void vout_ControlChangeZoom(vout_thread_t *, int num, int den);
+void vout_ControlChangeSampleAspectRatio(vout_thread_t *, unsigned num, unsigned den);
+void vout_ControlChangeCropRatio(vout_thread_t *, unsigned num, unsigned den);
+void vout_ControlChangeCropWindow(vout_thread_t *, int x, int y, int width, int height);
+void vout_ControlChangeCropBorder(vout_thread_t *, int left, int top, int right, int bottom);
 
 /* */
 void vout_IntfInit( vout_thread_t * );
index a06762ac72b97920cd0c9303b4174611562a9ce0..c0fca4ed713a85e82a23d98608751c22032a1fae 100644 (file)
@@ -57,6 +57,8 @@ static int ZoomCallback( vlc_object_t *, char const *,
                          vlc_value_t, vlc_value_t, void * );
 static int CropCallback( vlc_object_t *, char const *,
                          vlc_value_t, vlc_value_t, void * );
+static int CropBorderCallback( vlc_object_t *, char const *,
+                               vlc_value_t, vlc_value_t, void * );
 static int AspectCallback( vlc_object_t *, char const *,
                            vlc_value_t, vlc_value_t, void * );
 static int ScalingCallback( vlc_object_t *, char const *,
@@ -212,10 +214,10 @@ void vout_IntfInit( vout_thread_t *p_vout )
     var_Create( p_vout, "crop-right", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
     var_Create( p_vout, "crop-bottom", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
 
-    var_AddCallback( p_vout, "crop-left", CropCallback, NULL );
-    var_AddCallback( p_vout, "crop-top", CropCallback, NULL );
-    var_AddCallback( p_vout, "crop-right", CropCallback, NULL );
-    var_AddCallback( p_vout, "crop-bottom", CropCallback, NULL );
+    var_AddCallback( p_vout, "crop-left", CropBorderCallback, NULL );
+    var_AddCallback( p_vout, "crop-top", CropBorderCallback, NULL );
+    var_AddCallback( p_vout, "crop-right", CropBorderCallback, NULL );
+    var_AddCallback( p_vout, "crop-bottom", CropBorderCallback, NULL );
 
     /* Crop object var */
     var_Create( p_vout, "crop", VLC_VAR_STRING | VLC_VAR_ISCOMMAND |
@@ -627,224 +629,59 @@ static int ZoomCallback( vlc_object_t *p_this, char const *psz_cmd,
     return var_SetFloat( p_this, "scale", newval.f_float );
 }
 
-static int CropCallback( vlc_object_t *p_this, char const *psz_cmd,
-                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
+static int CropCallback( vlc_object_t *object, char const *cmd,
+                         vlc_value_t oldval, vlc_value_t newval, void *data )
 {
-    vout_thread_t *p_vout = (vout_thread_t *)p_this;
-    int64_t i_aspect_num, i_aspect_den;
-    unsigned int i_width, i_height;
-
-    (void)oldval; (void)p_data;
-
-    /* Restore defaults */
-    p_vout->p->fmt_in.i_x_offset = p_vout->p->fmt_render.i_x_offset;
-    p_vout->p->fmt_in.i_visible_width = p_vout->p->fmt_render.i_visible_width;
-    p_vout->p->fmt_in.i_y_offset = p_vout->p->fmt_render.i_y_offset;
-    p_vout->p->fmt_in.i_visible_height = p_vout->p->fmt_render.i_visible_height;
-
-    if( !strcmp( psz_cmd, "crop" ) )
-    {
-        char *psz_end = NULL, *psz_parser = strchr( newval.psz_string, ':' );
-        if( psz_parser )
-        {
-            /* We're using the 3:4 syntax */
-            i_aspect_num = strtol( newval.psz_string, &psz_end, 10 );
-            if( psz_end == newval.psz_string || !i_aspect_num ) goto crop_end;
-
-            i_aspect_den = strtol( ++psz_parser, &psz_end, 10 );
-            if( psz_end == psz_parser || !i_aspect_den ) goto crop_end;
-
-            i_width = p_vout->p->fmt_in.i_sar_den*p_vout->p->fmt_render.i_visible_height *
-                i_aspect_num / i_aspect_den / p_vout->p->fmt_in.i_sar_num;
-            i_height = p_vout->p->fmt_render.i_visible_width*p_vout->p->fmt_in.i_sar_num *
-                i_aspect_den / i_aspect_num / p_vout->p->fmt_in.i_sar_den;
-
-            if( i_width < p_vout->p->fmt_render.i_visible_width )
-            {
-                p_vout->p->fmt_in.i_x_offset = p_vout->p->fmt_render.i_x_offset +
-                    (p_vout->p->fmt_render.i_visible_width - i_width) / 2;
-                p_vout->p->fmt_in.i_visible_width = i_width;
-            }
-            else
-            {
-                p_vout->p->fmt_in.i_y_offset = p_vout->p->fmt_render.i_y_offset +
-                    (p_vout->p->fmt_render.i_visible_height - i_height) / 2;
-                p_vout->p->fmt_in.i_visible_height = i_height;
-            }
-        }
-        else
-        {
-            psz_parser = strchr( newval.psz_string, 'x' );
-            if( psz_parser )
-            {
-                /* Maybe we're using the <width>x<height>+<left>+<top> syntax */
-                unsigned int i_crop_width, i_crop_height, i_crop_top, i_crop_left;
-
-                i_crop_width = strtol( newval.psz_string, &psz_end, 10 );
-                if( psz_end != psz_parser ) goto crop_end;
-
-                psz_parser = strchr( ++psz_end, '+' );
-                i_crop_height = strtol( psz_end, &psz_end, 10 );
-                if( psz_end != psz_parser ) goto crop_end;
-
-                psz_parser = strchr( ++psz_end, '+' );
-                i_crop_left = strtol( psz_end, &psz_end, 10 );
-                if( psz_end != psz_parser ) goto crop_end;
-
-                psz_end++;
-                i_crop_top = strtol( psz_end, &psz_end, 10 );
-                if( *psz_end != '\0' ) goto crop_end;
-
-                if( i_crop_top + i_crop_height >= p_vout->p->fmt_render.i_visible_height ||
-                    i_crop_left + i_crop_width >= p_vout->p->fmt_render.i_visible_width )
-                {
-                    msg_Err( p_vout, "Unable to crop over picture boundaries");
-                    return VLC_EGENERIC;
-                }
-
-                i_width = i_crop_width;
-                p_vout->p->fmt_in.i_visible_width = i_width;
-
-                i_height = i_crop_height;
-                p_vout->p->fmt_in.i_visible_height = i_height;
-
-                p_vout->p->fmt_in.i_x_offset = i_crop_left;
-                p_vout->p->fmt_in.i_y_offset = i_crop_top;
-            }
-            else
-            {
-                /* Maybe we're using the <left>+<top>+<right>+<bottom> syntax */
-                unsigned int i_crop_top, i_crop_left, i_crop_bottom, i_crop_right;
-
-                psz_parser = strchr( newval.psz_string, '+' );
-                i_crop_left = strtol( newval.psz_string, &psz_end, 10 );
-                if( psz_end != psz_parser ) goto crop_end;
-
-                psz_parser = strchr( ++psz_end, '+' );
-                i_crop_top = strtol( psz_end, &psz_end, 10 );
-                if( psz_end != psz_parser ) goto crop_end;
-
-                psz_parser = strchr( ++psz_end, '+' );
-                i_crop_right = strtol( psz_end, &psz_end, 10 );
-                if( psz_end != psz_parser ) goto crop_end;
-
-                psz_end++;
-                i_crop_bottom = strtol( psz_end, &psz_end, 10 );
-                if( *psz_end != '\0' ) goto crop_end;
-
-                if( i_crop_top + i_crop_bottom >= p_vout->p->fmt_render.i_visible_height ||
-                    i_crop_right + i_crop_left >= p_vout->p->fmt_render.i_visible_width )
-                {
-                    msg_Err( p_vout, "Unable to crop over picture boundaries" );
-                    return VLC_EGENERIC;
-                }
-
-                i_width = p_vout->p->fmt_render.i_visible_width
-                          - i_crop_left - i_crop_right;
-                p_vout->p->fmt_in.i_visible_width = i_width;
-
-                i_height = p_vout->p->fmt_render.i_visible_height
-                           - i_crop_top - i_crop_bottom;
-                p_vout->p->fmt_in.i_visible_height = i_height;
-
-                p_vout->p->fmt_in.i_x_offset = i_crop_left;
-                p_vout->p->fmt_in.i_y_offset = i_crop_top;
-            }
-        }
+    vout_thread_t *vout = (vout_thread_t *)object;
+    VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(data);
+    unsigned num, den;
+    unsigned y, x;
+    unsigned width, height;
+    unsigned left, top, right, bottom;
+
+    if (sscanf(newval.psz_string, "%u:%u", &num, &den) == 2) {
+        vout_ControlChangeCropRatio(vout, num, den);
+    } else if (sscanf(newval.psz_string, "%ux%u+%u+%u",
+                      &width, &height, &x, &y) == 4) {
+        vout_ControlChangeCropWindow(vout, x, y, width, height);
+    } else if (sscanf(newval.psz_string, "%u+%u+%u+%u",
+                    &left, &top, &right, &bottom) == 4) {
+        vout_ControlChangeCropBorder(vout, left, top, right, bottom);
+    } else if (*newval.psz_string == '\0') {
+        vout_ControlChangeCropRatio(vout, 0, 0);
+    } else {
+        msg_Err(object, "Unknown crop format (%s)", newval.psz_string);
     }
-    else if( !strcmp( psz_cmd, "crop-top" )
-          || !strcmp( psz_cmd, "crop-left" )
-          || !strcmp( psz_cmd, "crop-bottom" )
-          || !strcmp( psz_cmd, "crop-right" ) )
-    {
-        unsigned int i_crop_top, i_crop_left, i_crop_bottom, i_crop_right;
-
-        i_crop_top = var_GetInteger( p_vout, "crop-top" );
-        i_crop_left = var_GetInteger( p_vout, "crop-left" );
-        i_crop_right = var_GetInteger( p_vout, "crop-right" );
-        i_crop_bottom = var_GetInteger( p_vout, "crop-bottom" );
-
-        if( i_crop_top + i_crop_bottom >= p_vout->p->fmt_render.i_visible_height ||
-            i_crop_right + i_crop_left >= p_vout->p->fmt_render.i_visible_width )
-        {
-            msg_Err( p_vout, "Unable to crop over picture boundaries" );
-            return VLC_EGENERIC;
-        }
-
-        i_width = p_vout->p->fmt_render.i_visible_width
-                  - i_crop_left - i_crop_right;
-        p_vout->p->fmt_in.i_visible_width = i_width;
-
-        i_height = p_vout->p->fmt_render.i_visible_height
-                   - i_crop_top - i_crop_bottom;
-        p_vout->p->fmt_in.i_visible_height = i_height;
-
-        p_vout->p->fmt_in.i_x_offset = i_crop_left;
-        p_vout->p->fmt_in.i_y_offset = i_crop_top;
-    }
-
- crop_end:
-    p_vout->p->i_changes |= VOUT_CROP_CHANGE;
-
-    msg_Dbg( p_vout, "cropping picture %ix%i to %i,%i,%ix%i",
-             p_vout->p->fmt_in.i_width, p_vout->p->fmt_in.i_height,
-             p_vout->p->fmt_in.i_x_offset, p_vout->p->fmt_in.i_y_offset,
-             p_vout->p->fmt_in.i_visible_width,
-             p_vout->p->fmt_in.i_visible_height );
-
-    var_TriggerCallback( p_vout, "crop-update" );
-
     return VLC_SUCCESS;
 }
 
-static int AspectCallback( vlc_object_t *p_this, char const *psz_cmd,
-                         vlc_value_t oldval, vlc_value_t newval, void *p_data )
+static int CropBorderCallback(vlc_object_t *object, char const *cmd,
+                              vlc_value_t oldval, vlc_value_t newval, void *data)
 {
-    vout_thread_t *p_vout = (vout_thread_t *)p_this;
-    unsigned int i_aspect_num, i_aspect_den, i_sar_num, i_sar_den;
-    vlc_value_t val;
-
-    char *psz_end, *psz_parser = strchr( newval.psz_string, ':' );
-    (void)psz_cmd; (void)oldval; (void)p_data;
-
-    /* Restore defaults */
-    p_vout->p->fmt_in.i_sar_num = p_vout->p->fmt_render.i_sar_num;
-    p_vout->p->fmt_in.i_sar_den = p_vout->p->fmt_render.i_sar_den;
-
-    if( !psz_parser ) goto aspect_end;
-
-    i_aspect_num = strtol( newval.psz_string, &psz_end, 10 );
-    if( psz_end == newval.psz_string || !i_aspect_num ) goto aspect_end;
-
-    i_aspect_den = strtol( ++psz_parser, &psz_end, 10 );
-    if( psz_end == psz_parser || !i_aspect_den ) goto aspect_end;
-
-    i_sar_num = i_aspect_num * p_vout->p->fmt_render.i_visible_height;
-    i_sar_den = i_aspect_den * p_vout->p->fmt_render.i_visible_width;
-    vlc_ureduce( &i_sar_num, &i_sar_den, i_sar_num, i_sar_den, 0 );
-    p_vout->p->fmt_in.i_sar_num = i_sar_num;
-    p_vout->p->fmt_in.i_sar_den = i_sar_den;
-
- aspect_end:
-    if( p_vout->p->i_par_num && p_vout->p->i_par_den )
-    {
-        p_vout->p->fmt_in.i_sar_num *= p_vout->p->i_par_den;
-        p_vout->p->fmt_in.i_sar_den *= p_vout->p->i_par_num;
-    }
-
-    p_vout->p->i_changes |= VOUT_ASPECT_CHANGE;
-
-    msg_Dbg( p_vout, "new aspect-ratio %i:%i, sample aspect-ratio %i:%i",
-             p_vout->p->fmt_in.i_sar_num * p_vout->p->fmt_in.i_width,
-             p_vout->p->fmt_in.i_sar_den * p_vout->p->fmt_in.i_height,
-             p_vout->p->fmt_in.i_sar_num, p_vout->p->fmt_in.i_sar_den );
-
-    if( var_Get( p_vout, "crop", &val ) )
-        return VLC_EGENERIC;
+    vout_thread_t *vout = (vout_thread_t *)object;
+    VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(data); VLC_UNUSED(newval);
+
+    vout_ControlChangeCropBorder(vout,
+                                 var_GetInteger(object, "crop-left"),
+                                 var_GetInteger(object, "crop-top"),
+                                 var_GetInteger(object, "crop-right"),
+                                 var_GetInteger(object, "crop-bottom"));
+    return VLC_SUCCESS;
+}
 
-    int i_ret = CropCallback( p_this, "crop", val, val, 0 );
-    free( val.psz_string );
-    return i_ret;
+static int AspectCallback( vlc_object_t *object, char const *cmd,
+                         vlc_value_t oldval, vlc_value_t newval, void *data )
+{
+    vout_thread_t *vout = (vout_thread_t *)object;
+    VLC_UNUSED(cmd); VLC_UNUSED(oldval); VLC_UNUSED(data);
+    unsigned num, den;
+
+    if (sscanf(newval.psz_string, "%u:%u", &num, &den) == 2 &&
+        (num > 0) == (den > 0))
+        vout_ControlChangeSampleAspectRatio(vout, num, den);
+    else if (*newval.psz_string == '\0')
+        vout_ControlChangeSampleAspectRatio(vout, 0, 0);
+    return VLC_SUCCESS;
 }
 
 static int ScalingCallback( vlc_object_t *p_this, char const *psz_cmd,
index eebe517b109186a4f75127d0439fae470e13f5d7..5130e9dc73e20930c35e5d606eb98d39db2b8027 100644 (file)
@@ -66,7 +66,7 @@ int vout_OpenWrapper(vout_thread_t *vout, const char *name)
     sys->display.title = var_CreateGetNonEmptyString(vout, "video-title");
 
     /* */
-    video_format_t source   = vout->p->fmt_render;
+    video_format_t source   = vout->p->original;
     source.i_visible_width  = source.i_width;
     source.i_visible_height = source.i_height;
     source.i_x_offset       = 0;
@@ -131,37 +131,8 @@ int vout_InitWrapper(vout_thread_t *vout)
 {
     vout_thread_sys_t *sys = vout->p;
     vout_display_t *vd = sys->display.vd;
-
-    /* */
     video_format_t source = vd->source;
 
-    vout->p->fmt_out.i_chroma         = source.i_chroma;
-    vout->p->fmt_out.i_width          =
-    vout->p->fmt_out.i_visible_width  = source.i_width;
-    vout->p->fmt_out.i_height         =
-    vout->p->fmt_out.i_visible_height = source.i_height;
-    if (source.i_sar_num > 0 && source.i_sar_den > 0) {
-        vlc_ureduce(&vout->p->fmt_out.i_sar_num, &vout->p->fmt_out.i_sar_den,
-                    source.i_sar_num, source.i_sar_den, 0);
-    } else {
-        vout->p->fmt_out.i_sar_num    = 1;
-        vout->p->fmt_out.i_sar_den    = 1;
-    }
-    vout->p->fmt_out.i_sar_num        = source.i_sar_num;
-    vout->p->fmt_out.i_sar_den        = source.i_sar_den;
-    vout->p->fmt_out.i_x_offset       = 0;
-    vout->p->fmt_out.i_y_offset       = 0;
-    vout->p->fmt_out.i_rmask          = source.i_rmask;
-    vout->p->fmt_out.i_gmask          = source.i_gmask;
-    vout->p->fmt_out.i_bmask          = source.i_bmask;
-    video_format_FixRgb(&vout->p->fmt_out);
-
-    if (vout->p->fmt_in.i_visible_width  != source.i_visible_width ||
-        vout->p->fmt_in.i_visible_height != source.i_visible_height ||
-        vout->p->fmt_in.i_x_offset       != source.i_x_offset ||
-        vout->p->fmt_in.i_y_offset       != source.i_y_offset )
-        sys->i_changes |= VOUT_CROP_CHANGE;
-
     /* XXX For non dr case, the current vout implementation force us to
      * create at most 1 direct picture (otherwise the buffers will be kept
      * referenced even through the Init/End.
@@ -213,44 +184,6 @@ int vout_ManageWrapper(vout_thread_t *vout)
     vout_thread_sys_t *sys = vout->p;
     vout_display_t *vd = sys->display.vd;
 
-    while (sys->i_changes & (VOUT_ASPECT_CHANGE |
-                              VOUT_CROP_CHANGE)) {
-        /* */
-        if (sys->i_changes & VOUT_ASPECT_CHANGE) {
-            vout->p->fmt_out.i_sar_num = vout->p->fmt_in.i_sar_num;
-            vout->p->fmt_out.i_sar_den = vout->p->fmt_in.i_sar_den;
-
-            vout_SetDisplayAspect(vd, vout->p->fmt_in.i_sar_num, vout->p->fmt_in.i_sar_den);
-
-            sys->i_changes &= ~VOUT_ASPECT_CHANGE;
-        }
-        if (sys->i_changes & VOUT_CROP_CHANGE) {
-            const video_format_t crop = vout->p->fmt_in;
-            const video_format_t org = vout->p->fmt_render;
-            /* FIXME because of rounding errors, the reconstructed ratio is wrong */
-            unsigned num = 0;
-            unsigned den = 0;
-            if (crop.i_x_offset == org.i_x_offset &&
-                crop.i_visible_width == org.i_visible_width &&
-                crop.i_y_offset == org.i_y_offset + (org.i_visible_height - crop.i_visible_height)/2) {
-                vlc_ureduce(&num, &den,
-                            crop.i_visible_width * crop.i_sar_num,
-                            crop.i_visible_height * crop.i_sar_den, 0);
-            } else if (crop.i_y_offset == org.i_y_offset &&
-                       crop.i_visible_height == org.i_visible_height &&
-                       crop.i_x_offset == org.i_x_offset + (org.i_visible_width - crop.i_visible_width)/2) {
-                vlc_ureduce(&num, &den,
-                            crop.i_visible_width * crop.i_sar_num,
-                            crop.i_visible_height * crop.i_sar_den, 0);
-            }
-            vout_SetDisplayCrop(vd, num, den,
-                                crop.i_x_offset, crop.i_y_offset,
-                                crop.i_visible_width, crop.i_visible_height);
-            sys->i_changes &= ~VOUT_CROP_CHANGE;
-        }
-
-    }
-
     bool reset_display_pool = sys->display.use_dr && vout_AreDisplayPicturesInvalid(vd);
     vout_ManageDisplay(vd, !sys->display.use_dr || reset_display_pool);