summaryrefslogtreecommitdiff
path: root/src/xine-engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/xine-engine')
-rw-r--r--src/xine-engine/video_out.c100
-rw-r--r--src/xine-engine/video_out.h8
-rw-r--r--src/xine-engine/vo_scale.c63
-rw-r--r--src/xine-engine/vo_scale.h11
4 files changed, 147 insertions, 35 deletions
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index eacc59dd5..dfc6aa5b7 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.c,v 1.205 2004/07/19 22:45:48 miguelfreitas Exp $
+ * $Id: video_out.c,v 1.206 2004/09/22 20:29:17 miguelfreitas Exp $
*
* frame allocation / queuing / scheduling / output functions
*/
@@ -59,6 +59,8 @@
#define FIRST_FRAME_POLL_DELAY 3000
#define FIRST_FRAME_MAX_POLL 10 /* poll n times at most */
+static vo_frame_t * crop_frame( xine_video_port_t *this_gen, vo_frame_t *img );
+
typedef struct {
vo_frame_t *first;
vo_frame_t *last;
@@ -329,7 +331,11 @@ static vo_frame_t *vo_get_frame (xine_video_port_t *this_gen,
img->progressive_frame = 0;
img->repeat_first_field = 0;
img->top_field_first = 1;
- img->macroblocks = NULL;
+ img->crop_left = 0;
+ img->crop_right = 0;
+ img->crop_top = 0;
+ img->crop_bottom = 0;
+ img->macroblocks = NULL;
_x_extra_info_reset ( img->extra_info );
/* let driver ensure this image has the right format */
@@ -425,7 +431,18 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) {
if (!img->bad_frame) {
-
+
+ int dispose_img = 0;
+
+ /* perform cropping when vo driver does not support it */
+ if( (img->crop_left || img->crop_top ||
+ img->crop_right || img->crop_bottom) &&
+ (this->grab_only ||
+ !(this->driver->get_capabilities (this->driver) & VO_CAP_CROP)) ) {
+ img = crop_frame( img->port, img );
+ dispose_img = 1;
+ }
+
/* do not call proc_*() for frames that will be dropped */
if( !frames_to_skip && !img->proc_called )
vo_frame_driver_proc(img);
@@ -461,6 +478,9 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) {
vo_frame_inc_lock( img );
vo_append_to_img_buf_queue (this->display_img_buf_queue, img);
+
+ if( dispose_img )
+ vo_frame_dec_lock( img );
} else {
lprintf ("bad_frame\n");
@@ -560,7 +580,6 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) {
static vo_frame_t * duplicate_frame( vos_t *this, vo_frame_t *img ) {
vo_frame_t *dupl;
- int image_size;
if( !this->free_img_buf_queue->first)
return NULL;
@@ -583,14 +602,19 @@ static vo_frame_t * duplicate_frame( vos_t *this, vo_frame_t *img ) {
dupl->ratio = img->ratio;
dupl->format = img->format;
dupl->flags = img->flags | VO_BOTH_FIELDS;
+ dupl->progressive_frame = img->progressive_frame;
+ dupl->repeat_first_field = img->repeat_first_field;
+ dupl->top_field_first = img->top_field_first;
+ dupl->crop_left = img->crop_left;
+ dupl->crop_right = img->crop_right;
+ dupl->crop_top = img->crop_top;
+ dupl->crop_bottom = img->crop_bottom;
this->driver->update_frame_format (this->driver, dupl, dupl->width, dupl->height,
dupl->ratio, dupl->format, dupl->flags);
pthread_mutex_unlock (&dupl->mutex);
- image_size = img->pitches[0] * img->height;
-
switch (img->format) {
case XINE_IMGFMT_YV12:
yv12_to_yv12(
@@ -1176,6 +1200,7 @@ int xine_get_next_video_frame (xine_video_port_t *this_gen,
frame->height = img->height;
frame->pos_stream = img->extra_info->input_normpos;
frame->pos_time = img->extra_info->input_time;
+ frame->frame_number = img->extra_info->frame_number;
frame->aspect_ratio = img->ratio;
frame->colorspace = img->format;
frame->data = img->base[0];
@@ -1508,6 +1533,69 @@ static void vo_flush (xine_video_port_t *this_gen) {
}
}
+/* crop_frame() will allocate a new frame to copy in the given image
+ * while cropping. maybe someday this will be an automatic post plugin.
+ */
+static vo_frame_t * crop_frame( xine_video_port_t *this_gen, vo_frame_t *img ) {
+
+ vo_frame_t *dupl;
+
+ dupl = vo_get_frame ( this_gen,
+ img->width - img->crop_left - img->crop_right,
+ img->height - img->crop_top - img->crop_bottom,
+ img->ratio, img->format, img->flags | VO_BOTH_FIELDS);
+
+ dupl->progressive_frame = img->progressive_frame;
+ dupl->repeat_first_field = img->repeat_first_field;
+ dupl->top_field_first = img->top_field_first;
+
+ switch (img->format) {
+ case XINE_IMGFMT_YV12:
+ yv12_to_yv12(
+ /* Y */
+ img->base[0] + img->crop_top * img->pitches[0] +
+ img->crop_left, img->pitches[0],
+ dupl->base[0], dupl->pitches[0],
+ /* U */
+ img->base[1] + img->crop_top/2 * img->pitches[1] +
+ img->crop_left/2, img->pitches[1],
+ dupl->base[1], dupl->pitches[1],
+ /* V */
+ img->base[2] + img->crop_top/2 * img->pitches[2] +
+ img->crop_left/2, img->pitches[2],
+ dupl->base[2], dupl->pitches[2],
+ /* width x height */
+ dupl->width, dupl->height);
+ break;
+ case XINE_IMGFMT_YUY2:
+ yuy2_to_yuy2(
+ /* src */
+ img->base[0] + img->crop_top * img->pitches[0] +
+ img->crop_left/2, img->pitches[0],
+ /* dst */
+ dupl->base[0], dupl->pitches[0],
+ /* width x height */
+ dupl->width, dupl->height);
+ break;
+ }
+
+ dupl->bad_frame = 0;
+ dupl->pts = img->pts;
+ dupl->vpts = img->vpts;
+ dupl->proc_called = 0;
+
+ dupl->duration = img->duration;
+ dupl->is_first = img->is_first;
+
+ dupl->stream = img->stream;
+ memcpy( dupl->extra_info, img->extra_info, sizeof(extra_info_t) );
+
+ /* delay frame processing for now, we might not even need it (eg. frame will be discarded) */
+ /* vo_frame_driver_proc(dupl); */
+
+ return dupl;
+}
+
xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly) {
vos_t *this;
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index fa4600c5d..0b70998e2 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.h,v 1.108 2004/07/06 22:53:23 miguelfreitas Exp $
+ * $Id: video_out.h,v 1.109 2004/09/22 20:29:17 miguelfreitas Exp $
*
*
* xine version of video_out.h
@@ -146,6 +146,9 @@ struct vo_frame_s {
*/
int progressive_frame;
int picture_coding_type;
+
+ /* cropping to be done */
+ int crop_left, crop_right, crop_top, crop_bottom;
/* extra info coming from input or demuxers */
extra_info_t *extra_info;
@@ -289,6 +292,7 @@ struct xine_video_port_s {
#define VO_CAP_XVMC_MOCOMP 0x00000004 /* driver can use XvMC motion compensation */
#define VO_CAP_XVMC_IDCT 0x00000008 /* driver can use XvMC idct acceleration */
#define VO_CAP_UNSCALED_OVERLAY 0x00000010 /* driver can blend overlay at output resolution */
+#define VO_CAP_CROP 0x00000020 /* driver can crop */
/* macroblock modes */
#define XINE_MACROBLOCK_INTRA 1
@@ -325,7 +329,7 @@ struct xine_video_port_s {
* from generic vo functions.
*/
-#define VIDEO_OUT_DRIVER_IFACE_VERSION 19
+#define VIDEO_OUT_DRIVER_IFACE_VERSION 20
struct vo_driver_s {
diff --git a/src/xine-engine/vo_scale.c b/src/xine-engine/vo_scale.c
index 5704a1c8c..021ca72c3 100644
--- a/src/xine-engine/vo_scale.c
+++ b/src/xine-engine/vo_scale.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: vo_scale.c,v 1.31 2004/05/11 02:21:16 miguelfreitas Exp $
+ * $Id: vo_scale.c,v 1.32 2004/09/22 20:29:17 miguelfreitas Exp $
*
* Contains common code to calculate video scaling parameters.
* In short, it will map frame dimensions to screen/window size.
@@ -56,7 +56,8 @@ void _x_vo_scale_compute_ideal_size (vo_scale_t *this) {
* aspect ratio
*/
- image_ratio = (double) this->delivered_width / (double) this->delivered_height;
+ image_ratio = (double) (this->delivered_width - (this->crop_left + this->crop_right)) /
+ (double) (this->delivered_height - (this->crop_top + this->crop_bottom));
switch (this->user_ratio) {
case XINE_VO_ASPECT_AUTO:
@@ -105,18 +106,22 @@ void _x_vo_scale_compute_ideal_size (vo_scale_t *this) {
void _x_vo_scale_compute_output_size (vo_scale_t *this) {
+ int cropped_width, cropped_height;
double x_factor, y_factor, aspect;
- aspect = this->video_pixel_aspect / this->gui_pixel_aspect;
- x_factor = (double) this->gui_width / (double) (this->delivered_width * aspect);
- y_factor = (double) (this->gui_height * aspect) / (double) this->delivered_height;
+ cropped_width = this->delivered_width - (this->crop_left + this->crop_right);
+ cropped_height = this->delivered_height - (this->crop_top + this->crop_bottom);
+ aspect = this->video_pixel_aspect / this->gui_pixel_aspect;
+ x_factor = (double) this->gui_width / (double) (cropped_width * aspect);
+ y_factor = (double) (this->gui_height * aspect) / (double) cropped_height;
+
if (this->scaling_disabled) {
- this->output_width = this->delivered_width;
- this->output_height = this->delivered_height;
- this->displayed_width = this->delivered_width;
- this->displayed_height = this->delivered_height;
+ this->output_width = cropped_width;
+ this->output_height = cropped_height;
+ this->displayed_width = cropped_width;
+ this->displayed_height = cropped_height;
} else {
@@ -128,44 +133,44 @@ void _x_vo_scale_compute_output_size (vo_scale_t *this) {
* black borders to use.
* - exceding zoom shall be accounted by reducing displayed image.
*/
- if (((double)this->gui_width - (double)this->delivered_width * y_factor) < ((double)this->gui_height - (double)this->delivered_height * x_factor)) {
+ if (((double)this->gui_width - (double)cropped_width * y_factor) < ((double)this->gui_height - (double)cropped_height * x_factor)) {
this->output_width = this->gui_width;
- this->displayed_width = (double)this->delivered_width / this->zoom_factor_x + 0.5;
+ this->displayed_width = (double)cropped_width / this->zoom_factor_x + 0.5;
- this->output_height = (double)this->delivered_height * x_factor + 0.5;
+ this->output_height = (double)cropped_height * x_factor + 0.5;
if( this->output_height * this->zoom_factor_y <= this->gui_height ) {
- this->displayed_height = this->delivered_height;
+ this->displayed_height = cropped_height;
this->output_height = (double)this->output_height * this->zoom_factor_y + 0.5;
} else {
- this->displayed_height = (double) this->delivered_height *
+ this->displayed_height = (double)cropped_height *
this->gui_height / this->output_height / this->zoom_factor_y + 0.5;
this->output_height = this->gui_height;
}
} else {
this->output_height = this->gui_height;
- this->displayed_height = (double)this->delivered_height / this->zoom_factor_y + 0.5;
+ this->displayed_height = (double)cropped_height / this->zoom_factor_y + 0.5;
- this->output_width = (double)this->delivered_width * y_factor + 0.5;
+ this->output_width = (double)cropped_width * y_factor + 0.5;
if( this->output_width * this->zoom_factor_x <= this->gui_width ) {
- this->displayed_width = this->delivered_width;
+ this->displayed_width = cropped_width;
this->output_width = (double)this->output_width * this->zoom_factor_x + 0.5;
} else {
- this->displayed_width = (double) this->delivered_width *
+ this->displayed_width = (double)cropped_width *
this->gui_width / this->output_width / this->zoom_factor_x + 0.5;
this->output_width = this->gui_width;
}
}
} else {
- if (((double)this->gui_width - (double)this->delivered_width * y_factor) < ((double)this->gui_height - (double)this->delivered_height * x_factor)) {
+ if (((double)this->gui_width - (double)cropped_width * y_factor) < ((double)this->gui_height - (double)cropped_height * x_factor)) {
this->output_width = (double) this->gui_width;
- this->output_height = (double) this->delivered_height * x_factor + 0.5;
+ this->output_height = (double) cropped_height * x_factor + 0.5;
} else {
- this->output_width = (double) this->delivered_width * y_factor + 0.5;
+ this->output_width = (double) cropped_width * y_factor + 0.5;
this->output_height = (double) this->gui_height;
}
- this->displayed_width = this->delivered_width;
- this->displayed_height = this->delivered_height;
+ this->displayed_width = cropped_width;
+ this->displayed_height = cropped_height;
}
}
@@ -188,8 +193,8 @@ void _x_vo_scale_compute_output_size (vo_scale_t *this) {
this->output_yoffset =
(this->gui_height - this->output_height) * this->output_vertical_position + this->gui_y;
- this->displayed_xoffset = (this->delivered_width - this->displayed_width) / 2;
- this->displayed_yoffset = (this->delivered_height - this->displayed_height) / 2;
+ this->displayed_xoffset = ((cropped_width - this->displayed_width) / 2) + this->crop_left;
+ this->displayed_yoffset = ((cropped_height - this->displayed_height) / 2) + this->crop_top;
lprintf ("frame source %d x %d (%d x %d) => screen output %d x %d\n",
this->delivered_width, this->delivered_height,
@@ -244,7 +249,8 @@ int _x_vo_scale_redraw_needed (vo_scale_t *this) {
if( this->frame_output_cb ) {
this->frame_output_cb (this->user_data,
- this->delivered_width, this->delivered_height,
+ this->delivered_width - (this->crop_left + this->crop_right),
+ this->delivered_height - (this->crop_top + this->crop_bottom),
this->video_pixel_aspect,
&gui_x, &gui_y, &gui_width, &gui_height,
&gui_pixel_aspect, &gui_win_x, &gui_win_y );
@@ -365,6 +371,11 @@ void _x_vo_scale_init(vo_scale_t *this, int support_zoom, int scaling_disabled,
this->user_ratio = XINE_VO_ASPECT_AUTO;
this->delivered_ratio = 0.0;
+ this->crop_left = 0;
+ this->crop_right = 0;
+ this->crop_top = 0;
+ this->crop_bottom = 0;
+
this->output_horizontal_position =
config->register_range(config, "video.horizontal_position", 50, 0, 100,
_("horizontal image position in the output window"), NULL, 10,
diff --git a/src/xine-engine/vo_scale.h b/src/xine-engine/vo_scale.h
index 736e50fbd..a5fd8d9e4 100644
--- a/src/xine-engine/vo_scale.h
+++ b/src/xine-engine/vo_scale.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: vo_scale.h,v 1.12 2004/04/25 14:50:32 komadori Exp $
+ * $Id: vo_scale.h,v 1.13 2004/09/22 20:29:18 miguelfreitas Exp $
*
* vo_scale.h
*
@@ -65,6 +65,15 @@ struct vo_scale_s {
int delivered_width;
int delivered_height;
double delivered_ratio;
+
+ /*
+ * required cropping:
+ * units: frame pixels
+ */
+ int crop_left;
+ int crop_right;
+ int crop_top;
+ int crop_bottom;
/*
* displayed part of delivered images,