/* 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,
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 {
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;
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;
if (!vd->info.has_hide_mouse)
osys->mouse.last_moved = mdate();
- /* */
- vlc_mutex_unlock(&osys->lock);
-
/* */
vout_SendEventMouseVisible(osys->vout);
#ifdef ALLOW_DUMMY_VOUT
#else
vout_SendDisplayEventMouse(osys->vout, &m);
#endif
+ vlc_mutex_unlock(&osys->lock);
}
static void VoutDisplayEvent(vout_display_t *vd, int event, va_list args)
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 );
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 );
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 );
}
/* */
- 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;
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
/* 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;
(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
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);
* 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) {
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);
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 */
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;
}
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;
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 * );
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 *,
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 |
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,
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;
{
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.
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);