diff options
Diffstat (limited to 'src/video_out/video_out_xv.c')
-rw-r--r-- | src/video_out/video_out_xv.c | 100 |
1 files changed, 67 insertions, 33 deletions
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index 25b8f6aa1..13951ad3c 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.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_xv.c,v 1.59 2001/09/16 15:14:30 miguelfreitas Exp $ + * $Id: video_out_xv.c,v 1.60 2001/09/19 02:40:58 miguelfreitas Exp $ * * video_out_xv.c, X11 video extension interface for xine * @@ -27,7 +27,7 @@ * Xv image support by Gerd Knorr <kraxel@goldbach.in-berlin.de> * * xine-specific code by Guenter Bartsch <bartscgr@studbox.uni-stuttgart.de> - * + * * overlay support by James Courtier-Dutton <James@superbug.demon.co.uk> - July 2001 */ @@ -105,6 +105,7 @@ typedef struct { xv_property_t props[VO_NUM_PROPERTIES]; uint32_t capabilities; + xv_frame_t *recent_frames[VO_NUM_RECENT_FRAMES]; xv_frame_t *cur_frame; vo_overlay_t *overlay; @@ -292,7 +293,7 @@ static XvImage *create_ximage (xv_driver_t *this, XShmSegmentInfo *shminfo, shminfo->readOnly = False; image->data = shminfo->shmaddr; - + XShmAttach(this->display, shminfo); XSync(this->display, False); @@ -402,12 +403,12 @@ static void xv_update_frame_format (vo_driver_t *this_gen, frame->ratio_code = ratio_code; } -static void xv_deinterlace_frame (vo_driver_t *this_gen, - vo_frame_t *frame_gen ) { +static void xv_deinterlace_frame (xv_driver_t *this) { - xv_driver_t *this = (xv_driver_t *) this_gen; - xv_frame_t *frame = (xv_frame_t *) frame_gen; - XvImage *imgtmp; + XvImage *imgtmp; + uint8_t *recent_bitmaps[VO_NUM_RECENT_FRAMES]; + xv_frame_t *frame = this->recent_frames[0]; + int i; if ( !this->deinterlace_frame.image || (frame->width != this->deinterlace_frame.width) @@ -428,20 +429,29 @@ static void xv_deinterlace_frame (vo_driver_t *this_gen, XUnlockDisplay (this->display); } + + /* know bug: we are not deinterlacing Cb and Cr */ memcpy(this->deinterlace_frame.image->data + frame->width*frame->height, frame->image->data + frame->width*frame->height, frame->width*frame->height*1/2); +#if 0 imgtmp = this->deinterlace_frame.image; this->deinterlace_frame.image = frame->image; frame->image = imgtmp; frame->vo_frame.base[0] = frame->image->data; frame->vo_frame.base[1] = frame->image->data + frame->width * frame->height * 5 / 4; frame->vo_frame.base[2] = frame->image->data + frame->width * frame->height; +#endif + for( i = 0; i < VO_NUM_RECENT_FRAMES; i++ ) + recent_bitmaps[i] = (this->recent_frames[i]) ? this->recent_frames[i]->image->data : + NULL; - deinterlace_yuv( frame->image->data, this->deinterlace_frame.image->data, + deinterlace_yuv( this->deinterlace_frame.image->data, recent_bitmaps, frame->width, frame->height, this->deinterlace_method ); + + this->cur_frame = &this->deinterlace_frame; } @@ -461,7 +471,7 @@ static void xv_adapt_to_output_area (xv_driver_t *this, this->output_yoffset = dest_y + (dest_height - this->output_height) / 2; } else { - + this->output_width = (double) dest_height * this->ratio_factor ; this->output_height = dest_height; this->output_xoffset = dest_x + (dest_width - this->output_width) / 2; @@ -490,10 +500,10 @@ static void xv_adapt_to_output_area (xv_driver_t *this, this->output_xoffset+this->output_width, dest_y, dest_width - this->output_xoffset - this->output_width, dest_height); - XUnlockDisplay (this->display); + XUnlockDisplay (this->display); } -static void xv_calc_format (xv_driver_t *this, +static void xv_calc_format (xv_driver_t *this, int width, int height, int ratio_code) { double image_ratio, desired_ratio; @@ -577,7 +587,7 @@ static void xv_calc_format (xv_driver_t *this, * ask gui to adapt to this size */ - this->request_dest_size (ideal_width, ideal_height, + this->request_dest_size (ideal_width, ideal_height, &dest_x, &dest_y, &dest_width, &dest_height); xv_adapt_to_output_area (this, dest_x, dest_y, dest_width, dest_height); @@ -599,6 +609,36 @@ static void xv_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_o } } +static void xv_add_recent_frame (xv_driver_t *this, xv_frame_t *frame) { + int i; + + i = VO_NUM_RECENT_FRAMES-1; + if( this->recent_frames[i] ) + this->recent_frames[i]->vo_frame.displayed + (&this->recent_frames[i]->vo_frame); + + for( ; i ; i-- ) + this->recent_frames[i] = this->recent_frames[i-1]; + + this->recent_frames[0] = frame; +} + +/* currently not used - we could have a method to call this from video loop */ +#if 0 +static void xv_flush_recent_frames (xv_driver_t *this) { + + int i; + + for( i=0; i < VO_NUM_RECENT_FRAMES; i++ ) + { + if( this->recent_frames[i] ) + this->recent_frames[i]->vo_frame.displayed + (&this->recent_frames[i]->vo_frame); + this->recent_frames[i] = NULL; + } +} +#endif + /* * */ @@ -609,16 +649,12 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { if (this->expecting_event) { - this->expecting_event--; frame->vo_frame.displayed (&frame->vo_frame); + this->expecting_event--; } else { - - if (this->cur_frame) { - this->cur_frame->vo_frame.displayed (&this->cur_frame->vo_frame); - this->cur_frame = NULL; - } - + xv_add_recent_frame (this, frame); + this->cur_frame = frame; if ( (frame->width != this->delivered_width) || (frame->height != this->delivered_height) @@ -632,24 +668,22 @@ static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { // } if( this->deinterlace_method ) - xv_deinterlace_frame (this_gen, frame_gen ); + xv_deinterlace_frame (this); XLockDisplay (this->display); - this->cur_frame = frame; - if (this->use_shm) { XvShmPutImage(this->display, this->xv_port, - this->drawable, this->gc, frame->image, - 0, 0, frame->width, frame->height-5, + this->drawable, this->gc, this->cur_frame->image, + 0, 0, this->cur_frame->width, this->cur_frame->height-5, this->output_xoffset, this->output_yoffset, this->output_width, this->output_height, True); this->expecting_event = 10; } else { XvPutImage(this->display, this->xv_port, - this->drawable, this->gc, frame->image, - 0, 0, frame->width, frame->height-5, + this->drawable, this->gc, this->cur_frame->image, + 0, 0, this->cur_frame->width, this->cur_frame->height-5, this->output_xoffset, this->output_yoffset, this->output_width, this->output_height); } @@ -724,7 +758,7 @@ static void xv_get_property_min_max (vo_driver_t *this_gen, *max = this->props[property].max; } -static int xv_gui_data_exchange (vo_driver_t *this_gen, +static int xv_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { xv_driver_t *this = (xv_driver_t *) this_gen; @@ -767,7 +801,7 @@ static int xv_gui_data_exchange (vo_driver_t *this_gen, this->output_xoffset, this->output_yoffset, this->output_width, this->output_height, False); } else { - XvPutImage(this->display, this->xv_port, + XvPutImage(this->display, this->xv_port, this->drawable, this->gc, this->cur_frame->image, 0, 0, this->cur_frame->width, this->cur_frame->height-5, this->output_xoffset, this->output_yoffset, @@ -836,7 +870,7 @@ static void xv_check_capability (xv_driver_t *this, this->props[property].max = attr.max_value; this->props[property].atom = XInternAtom (this->display, str_prop, False); this->props[property].key = str_prop; - + XvGetPortAttribute (this->display, this->xv_port, this->props[property].atom, &nDefault); @@ -995,7 +1029,7 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { printf("XV_HUE "); } else if(!strcmp(attr[k].name, "XV_SATURATION")) { - xv_check_capability (this, VO_CAP_SATURATION, + xv_check_capability (this, VO_CAP_SATURATION, VO_PROP_SATURATION, attr[k], adaptor_info[adaptor_num].base_id, "XV_SATURATION"); printf("XV_SATURATION "); @@ -1039,8 +1073,8 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { this->xv_format_rgb = 0; for(i = 0; i < formats; i++) { - xprintf(VERBOSE|VIDEO, "video_out_xv: Xv image format: 0x%x (%4.4s) %s\n", - fo[i].id, (char*)&fo[i].id, + xprintf(VERBOSE|VIDEO, "video_out_xv: Xv image format: 0x%x (%4.4s) %s\n", + fo[i].id, (char*)&fo[i].id, (fo[i].format == XvPacked) ? "packed" : "planar"); if (fo[i].id == IMGFMT_YV12) { this->xv_format_yv12 = fo[i].id; |