From 632d85bad131630c15c48e8216d4bcc016dfbb4e Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Sat, 27 Oct 2001 16:12:21 +0000 Subject: - new dirty and cheap deinterlace method: we give half of the lines to xv driver and let it scale for us - xine_list_demux_plugins update CVS patchset: 894 CVS date: 2001/10/27 16:12:21 --- src/video_out/deinterlace.c | 9 +++- src/video_out/deinterlace.h | 11 ++--- src/video_out/video_out_xv.c | 97 ++++++++++++++++++++++++++++++------------ src/xine-engine/load_plugins.c | 36 ++++++++++++---- 4 files changed, 110 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/video_out/deinterlace.c b/src/video_out/deinterlace.c index 540941c20..ea8964a7b 100644 --- a/src/video_out/deinterlace.c +++ b/src/video_out/deinterlace.c @@ -180,7 +180,8 @@ static void deinterlace_bob_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], /* Deinterlace the latest field, with a tendency to weave rather than bob. Good for high detail on low-movement scenes. - NOT FINISHED! WEIRD OUTPUT!!! + Seems to produce bad output in general case, need to check if this + is normal or if the code is broken. */ static int deinterlace_weave_yuv_mmx( uint8_t *pdst, uint8_t *psrc[], int width, int height ) @@ -689,6 +690,12 @@ void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[], else /* FIXME: provide an alternative? */ abort_mmx_missing(); break; + case DEINTERLACE_ONEFIELDXV: + printf("deinterlace: ONEFIELDXV must be handled by the video driver.\n"); + break; + default: + printf("deinterlace: unknow method %d.\n",method); + break; } } diff --git a/src/video_out/deinterlace.h b/src/video_out/deinterlace.h index 833401259..04153d742 100644 --- a/src/video_out/deinterlace.h +++ b/src/video_out/deinterlace.h @@ -32,10 +32,11 @@ void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[], int width, int height, int method ); -#define DEINTERLACE_NONE 0 -#define DEINTERLACE_BOB 1 -#define DEINTERLACE_WEAVE 2 -#define DEINTERLACE_GREEDY 3 -#define DEINTERLACE_ONEFIELD 4 +#define DEINTERLACE_NONE 0 +#define DEINTERLACE_BOB 1 +#define DEINTERLACE_WEAVE 2 +#define DEINTERLACE_GREEDY 3 +#define DEINTERLACE_ONEFIELD 4 +#define DEINTERLACE_ONEFIELDXV 5 #endif diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index 5283c9ec3..a37c2b197 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.71 2001/10/24 20:45:06 miguelfreitas Exp $ + * $Id: video_out_xv.c,v 1.72 2001/10/27 16:12:21 miguelfreitas Exp $ * * video_out_xv.c, X11 video extension interface for xine * @@ -57,6 +57,7 @@ /* #include "overlay.h" */ #include "alphablend.h" #include "deinterlace.h" +#include "memcpy.h" uint32_t xine_debug; @@ -411,10 +412,13 @@ static void xv_deinterlace_frame (xv_driver_t *this) { uint8_t *recent_bitmaps[VO_NUM_RECENT_FRAMES]; xv_frame_t *frame = this->recent_frames[0]; int i; + int xvscaling; + xvscaling = (this->deinterlace_method == DEINTERLACE_ONEFIELDXV) ? 2 : 1; + if ( !this->deinterlace_frame.image || (frame->width != this->deinterlace_frame.width) - || (frame->height != this->deinterlace_frame.height) + || (frame->height / xvscaling != this->deinterlace_frame.height ) || (frame->format != this->deinterlace_frame.format)) { XLockDisplay (this->display); @@ -423,47 +427,84 @@ static void xv_deinterlace_frame (xv_driver_t *this) { this->deinterlace_frame.image); this->deinterlace_frame.image = create_ximage (this, &this->deinterlace_frame.shminfo, - frame->width,frame->height, frame->format); + frame->width,frame->height / xvscaling, + frame->format); this->deinterlace_frame.width = frame->width; - this->deinterlace_frame.height = frame->height; + this->deinterlace_frame.height = frame->height / xvscaling; this->deinterlace_frame.format = frame->format; XUnlockDisplay (this->display); } + + if ( this->deinterlace_method != DEINTERLACE_ONEFIELDXV ) { #ifdef DEINTERLACE_CROMA - /* I don't think this is the right way to do it (deinterlacing croma by croma info). - DScaler deinterlaces croma together with luma, but it's easier for them because - they have that components 1:1 at the same table. - */ - for( i = 0; i < VO_NUM_RECENT_FRAMES; i++ ) - recent_bitmaps[i] = (this->recent_frames[i]) ? this->recent_frames[i]->image->data - + frame->width*frame->height : NULL; - deinterlace_yuv( this->deinterlace_frame.image->data+frame->width*frame->height, - recent_bitmaps, frame->width/2, frame->height/2, this->deinterlace_method ); - for( i = 0; i < VO_NUM_RECENT_FRAMES; i++ ) - recent_bitmaps[i] = (this->recent_frames[i]) ? this->recent_frames[i]->image->data - + frame->width*frame->height*5/4 : NULL; - deinterlace_yuv( this->deinterlace_frame.image->data+frame->width*frame->height*5/4, - recent_bitmaps, frame->width/2, frame->height/2, this->deinterlace_method ); + /* I don't think this is the right way to do it (deinterlacing croma by croma info). + DScaler deinterlaces croma together with luma, but it's easier for them because + they have that components 1:1 at the same table. + */ + for( i = 0; i < VO_NUM_RECENT_FRAMES; i++ ) + recent_bitmaps[i] = (this->recent_frames[i]) ? this->recent_frames[i]->image->data + + frame->width*frame->height : NULL; + deinterlace_yuv( this->deinterlace_frame.image->data+frame->width*frame->height, + recent_bitmaps, frame->width/2, frame->height/2, this->deinterlace_method ); + for( i = 0; i < VO_NUM_RECENT_FRAMES; i++ ) + recent_bitmaps[i] = (this->recent_frames[i]) ? this->recent_frames[i]->image->data + + frame->width*frame->height*5/4 : NULL; + deinterlace_yuv( this->deinterlace_frame.image->data+frame->width*frame->height*5/4, + recent_bitmaps, frame->width/2, frame->height/2, this->deinterlace_method ); #else - /* 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); + /* know bug: we are not deinterlacing Cb and Cr */ + fast_memcpy(this->deinterlace_frame.image->data + frame->width*frame->height, + frame->image->data + frame->width*frame->height, + frame->width*frame->height*1/2); #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( this->deinterlace_frame.image->data, recent_bitmaps, - frame->width, frame->height, this->deinterlace_method ); + 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( this->deinterlace_frame.image->data, recent_bitmaps, + frame->width, frame->height, this->deinterlace_method ); + } + else { + /* + dirty and cheap deinterlace method: we give half of the lines to xv + driver and let it scale for us. + note that memcpy's below don't seem to impact much on performance, + specially when fast memcpys are available. + */ + uint8_t *dst, *src; + + dst = this->deinterlace_frame.image->data; + src = this->recent_frames[0]->image->data; + for( i = 0; i < frame->height; i+=2 ) { + fast_memcpy(dst,src,frame->width); + dst+=frame->width; + src+=2*frame->width; + } + + dst = this->deinterlace_frame.image->data + frame->width*frame->height/2; + src = this->recent_frames[0]->image->data + frame->width*frame->height; + for( i = 0; i < frame->height; i+=4 ) { + fast_memcpy(dst,src,frame->width/2); + dst+=frame->width/2; + src+=frame->width; + } + + dst = this->deinterlace_frame.image->data + frame->width*frame->height*5/8; + src = this->recent_frames[0]->image->data + frame->width*frame->height*5/4; + for( i = 0; i < frame->height; i+=4 ) { + fast_memcpy(dst,src,frame->width/2); + dst+=frame->width/2; + src+=frame->width; + } + } + this->cur_frame = &this->deinterlace_frame; } diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c index 1f6392c90..4aa820469 100644 --- a/src/xine-engine/load_plugins.c +++ b/src/xine-engine/load_plugins.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: load_plugins.c,v 1.50 2001/10/25 00:47:02 miguelfreitas Exp $ + * $Id: load_plugins.c,v 1.51 2001/10/27 16:12:21 miguelfreitas Exp $ * * * Load input/demux/audio_out/video_out/codec plugins @@ -132,11 +132,17 @@ void load_demux_plugins (xine_t *this, void xine_list_demux_plugins (config_values_t *config, char **identifiers, char **mimetypes) { DIR *dir; - xine_t *this = xmalloc (sizeof (xine_t)); - - *identifiers = xmalloc (1024); - *mimetypes = xmalloc (8192); + xine_t *this; + int sizeid, sizemime; + int incsize; + char *s; + + this = xmalloc (sizeof (xine_t)); + sizeid = sizemime = incsize = 4096; + *identifiers = xmalloc (sizeid); + *mimetypes = xmalloc (sizemime); + this->config = config; xine_debug = config->lookup_int (config, "xine_debug", 0); @@ -176,12 +182,24 @@ void xine_list_demux_plugins (config_values_t *config, dxp = (demux_plugin_t *) initplug(DEMUXER_PLUGIN_IFACE_VERSION, this); if (dxp) { - strcat(*identifiers,dxp->get_identifier()); - strcat(*identifiers,"\n"); - strcat(*mimetypes,dxp->get_mimetypes()); + /* realloc sucks, but it will make this code much simpler */ + s = dxp->get_identifier(); + if( strlen(s) + strlen(*identifiers) + 2 > sizeid ) { + sizeid += incsize; + *identifiers = realloc( *identifiers, sizeid ); + } + strcat(*identifiers, s); + strcat(*identifiers, "\n"); + + s = dxp->get_mimetypes(); + if( strlen(s) + strlen(*mimetypes) + 2 > sizemime ) { + sizemime += incsize; + *identifiers = realloc( *identifiers, sizemime ); + } + strcat(*mimetypes, s); } } - dlclose(plugin); + dlclose(plugin); } } } -- cgit v1.2.3