summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2001-09-19 02:40:58 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2001-09-19 02:40:58 +0000
commitab4359a489433aa212b981b9961be3a73eeaf082 (patch)
tree829e849b91e9204043edd5a848078d3c5cac399f
parent4562bf4231063f333ce38498b031a740b1ff811a (diff)
downloadxine-lib-ab4359a489433aa212b981b9961be3a73eeaf082.tar.gz
xine-lib-ab4359a489433aa212b981b9961be3a73eeaf082.tar.bz2
deinterlace update, not finished yet (weave looks broken).
changes to Xv driver to keep a list of the recent frames. (this is needed to support a lot of DScaler algorithms) the driver may not be the ideal place to have the recent frames list as we could give "not so recent" frames to deinterlace code if some are dropped at video_out.c. Though this is better than waste our time deinterlacing frames that will be dropped anyway... CVS patchset: 663 CVS date: 2001/09/19 02:40:58
-rw-r--r--src/video_out/deinterlace.c254
-rw-r--r--src/video_out/deinterlace.h4
-rw-r--r--src/video_out/video_out_xv.c100
-rw-r--r--src/xine-engine/video_out.h14
4 files changed, 308 insertions, 64 deletions
diff --git a/src/video_out/deinterlace.c b/src/video_out/deinterlace.c
index 13217b111..67f932612 100644
--- a/src/video_out/deinterlace.c
+++ b/src/video_out/deinterlace.c
@@ -30,6 +30,7 @@
#include "cpu_accel.h"
#include "deinterlace.h"
+
/*
DeinterlaceFieldBob algorithm
Based on Virtual Dub plugin by Gunnar Thalin
@@ -37,30 +38,30 @@
Linux version for Xine player by Miguel Freitas
Todo: use a MMX optimized memcpy
*/
-static void deinterlace_bob_yuv_mmx( uint8_t *pdst, uint8_t *psrc,
+static void deinterlace_bob_yuv_mmx( uint8_t *pdst, uint8_t *psrc[],
int width, int height )
{
#ifdef ARCH_X86
int Line;
- long long* YVal1;
- long long* YVal2;
- long long* YVal3;
- long long* Dest;
- uint8_t* pEvenLines = psrc;
- uint8_t* pOddLines = psrc+width;
+ uint64_t *YVal1;
+ uint64_t *YVal2;
+ uint64_t *YVal3;
+ uint64_t *Dest;
+ uint8_t* pEvenLines = psrc[0];
+ uint8_t* pOddLines = psrc[0]+width;
int LineLength = width;
- int Pitch = width * 2;
+ int SourcePitch = width * 2;
int IsOdd = 1;
long EdgeDetect = 625;
long JaggieThreshold = 73;
int n;
- unsigned long long qwEdgeDetect;
- unsigned long long qwThreshold;
- const unsigned long long Mask = 0xfefefefefefefefe;
- const unsigned long long YMask = 0x00ff00ff00ff00ff;
+ uint64_t qwEdgeDetect;
+ uint64_t qwThreshold;
+ const uint64_t Mask = 0xfefefefefefefefe;
+ const uint64_t YMask = 0x00ff00ff00ff00ff;
qwEdgeDetect = EdgeDetect;
qwEdgeDetect += (qwEdgeDetect << 48) + (qwEdgeDetect << 32) + (qwEdgeDetect << 16);
@@ -79,17 +80,17 @@ static void deinterlace_bob_yuv_mmx( uint8_t *pdst, uint8_t *psrc,
{
if (IsOdd)
{
- YVal1 = (long long *)(pOddLines + Line * Pitch);
- YVal2 = (long long *)(pEvenLines + (Line + 1) * Pitch);
- YVal3 = (long long *)(pOddLines + (Line + 1) * Pitch);
- Dest = (long long *)(pdst + (Line * 2 + 2) * LineLength);
+ YVal1 = (uint64_t *)(pOddLines + Line * SourcePitch);
+ YVal2 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch);
+ YVal3 = (uint64_t *)(pOddLines + (Line + 1) * SourcePitch);
+ Dest = (uint64_t *)(pdst + (Line * 2 + 2) * LineLength);
}
else
{
- YVal1 = (long long *)(pEvenLines + Line * Pitch);
- YVal2 = (long long *)(pOddLines + Line * Pitch);
- YVal3 = (long long *)(pEvenLines + (Line + 1) * Pitch);
- Dest = (long long *)(pdst + (Line * 2 + 1) * LineLength);
+ YVal1 = (uint64_t *)(pEvenLines + Line * SourcePitch);
+ YVal2 = (uint64_t *)(pOddLines + Line * SourcePitch);
+ YVal3 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch);
+ Dest = (uint64_t *)(pdst + (Line * 2 + 1) * LineLength);
}
// For ease of reading, the comments below assume that we're operating on an odd
@@ -167,7 +168,7 @@ static void deinterlace_bob_yuv_mmx( uint8_t *pdst, uint8_t *psrc,
if (! IsOdd)
{
memcpy(pdst + (height * 2 - 1) * LineLength,
- pOddLines + (height - 1) * Pitch,
+ pOddLines + (height - 1) * SourcePitch,
LineLength);
}
@@ -177,6 +178,193 @@ static void deinterlace_bob_yuv_mmx( uint8_t *pdst, uint8_t *psrc,
#endif
}
+/* Deinterlace the latest field, with a tendency to weave rather than bob.
+ Good for high detail on low-movement scenes.
+ NOT FINISHED! WEIRD OUTPUT!!!
+*/
+static int deinterlace_weave_yuv_mmx( uint8_t *pdst, uint8_t *psrc[],
+ int width, int height )
+{
+#ifdef ARCH_X86
+
+ int Line;
+ uint64_t *YVal1;
+ uint64_t *YVal2;
+ uint64_t *YVal3;
+ uint64_t *YVal4;
+ uint64_t *Dest;
+ uint8_t* pEvenLines = psrc[0];
+ uint8_t* pOddLines = psrc[0]+width;
+ uint8_t* pPrevLines;
+
+ int LineLength = width;
+ int SourcePitch = width * 2;
+ int IsOdd = 1;
+
+ long TemporalTolerance = 300;
+ long SpatialTolerance = 600;
+ long SimilarityThreshold = 25;
+
+ const uint64_t YMask = 0x00ff00ff00ff00ff;
+
+ int n;
+
+ uint64_t qwSpatialTolerance;
+ uint64_t qwTemporalTolerance;
+ uint64_t qwThreshold;
+ const uint64_t Mask = 0xfefefefefefefefe;
+
+
+ // Make sure we have all the data we need.
+ if ( psrc[0] == NULL || psrc[1] == NULL )
+ return 0;
+
+ if (IsOdd)
+ pPrevLines = psrc[1] + width;
+ else
+ pPrevLines = psrc[1];
+
+ // Since the code uses MMX to process 4 pixels at a time, we need our constants
+ // to be represented 4 times per quadword.
+ qwSpatialTolerance = SpatialTolerance;
+ qwSpatialTolerance += (qwSpatialTolerance << 48) + (qwSpatialTolerance << 32) + (qwSpatialTolerance << 16);
+ qwTemporalTolerance = TemporalTolerance;
+ qwTemporalTolerance += (qwTemporalTolerance << 48) + (qwTemporalTolerance << 32) + (qwTemporalTolerance << 16);
+ qwThreshold = SimilarityThreshold;
+ qwThreshold += (qwThreshold << 48) + (qwThreshold << 32) + (qwThreshold << 16);
+
+ // copy first even line no matter what, and the first odd line if we're
+ // processing an even field.
+ memcpy(pdst, pEvenLines, LineLength);
+ if (!IsOdd)
+ memcpy(pdst + LineLength, pOddLines, LineLength);
+
+ height = height / 2;
+ for (Line = 0; Line < height - 1; ++Line)
+ {
+ if (IsOdd)
+ {
+ YVal1 = (uint64_t *)(pEvenLines + Line * SourcePitch);
+ YVal2 = (uint64_t *)(pOddLines + Line * SourcePitch);
+ YVal3 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch);
+ YVal4 = (uint64_t *)(pPrevLines + Line * SourcePitch);
+ Dest = (uint64_t *)(pdst + (Line * 2 + 1) * LineLength);
+ }
+ else
+ {
+ YVal1 = (uint64_t *)(pOddLines + Line * SourcePitch);
+ YVal2 = (uint64_t *)(pEvenLines + (Line + 1) * SourcePitch);
+ YVal3 = (uint64_t *)(pOddLines + (Line + 1) * SourcePitch);
+ YVal4 = (uint64_t *)(pPrevLines + (Line + 1) * SourcePitch);
+ Dest = (uint64_t *)(pdst + (Line * 2 + 2) * LineLength);
+ }
+
+ // For ease of reading, the comments below assume that we're operating on an odd
+ // field (i.e., that bIsOdd is true). The exact same processing is done when we
+ // operate on an even field, but the roles of the odd and even fields are reversed.
+ // It's just too cumbersome to explain the algorithm in terms of "the next odd
+ // line if we're doing an odd field, or the next even line if we're doing an
+ // even field" etc. So wherever you see "odd" or "even" below, keep in mind that
+ // half the time this function is called, those words' meanings will invert.
+
+ // Copy the even scanline below this one to the overlay buffer, since we'll be
+ // adapting the current scanline to the even lines surrounding it. The scanline
+ // above has already been copied by the previous pass through the loop.
+ memcpy((char *)Dest + LineLength, YVal3, LineLength);
+
+ n = LineLength >> 3;
+ while( n-- )
+ {
+ movq_m2r ( *YVal1++, mm0 ); // mm0 = E1
+ movq_m2r ( *YVal2++, mm1 ); // mm1 = O
+ movq_m2r ( *YVal3++, mm2 ); // mm2 = E2
+
+ movq_r2r ( mm0, mm3 ); // mm3 = intensity(E1)
+ movq_r2r ( mm1, mm4 ); // mm4 = intensity(O)
+ movq_r2r ( mm2, mm6 ); // mm6 = intensity(E2)
+
+ pand_m2r ( *&YMask, mm3 );
+ pand_m2r ( *&YMask, mm4 );
+ pand_m2r ( *&YMask, mm6 );
+
+ // Average E1 and E2 for interpolated bobbing.
+ // leave result in mm0
+ pand_m2r ( *&Mask, mm0 ); // mm0 = E1 with lower chroma bit stripped off
+ pand_m2r ( *&Mask, mm2 ); // mm2 = E2 with lower chroma bit stripped off
+ psrlw_i2r ( 01, mm0 ); // mm0 = E1 / 2
+ psrlw_i2r ( 01, mm2 ); // mm2 = E2 / 2
+ paddb_r2r ( mm2, mm0 );
+
+ // The meat of the work is done here. We want to see whether this pixel is
+ // close in luminosity to ANY of: its top neighbor, its bottom neighbor,
+ // or its predecessor. To do this without branching, we use MMX's
+ // saturation feature, which gives us Z(x) = x if x>=0, or 0 if x<0.
+ //
+ // The formula we're computing here is
+ // Z(ST - (E1 - O) ^ 2) + Z(ST - (E2 - O) ^ 2) + Z(TT - (Oold - O) ^ 2)
+ // where ST is spatial tolerance and TT is temporal tolerance. The idea
+ // is that if a pixel is similar to none of its neighbors, the resulting
+ // value will be pretty low, probably zero. A high value therefore indicates
+ // that the pixel had a similar neighbor. The pixel in the same position
+ // in the field before last (Oold) is considered a neighbor since we want
+ // to be able to display 1-pixel-high horizontal lines.
+
+ movq_m2r ( *&qwSpatialTolerance, mm7 );
+ movq_r2r ( mm3, mm5 ); // mm5 = E1
+ psubsw_r2r ( mm4, mm5 ); // mm5 = E1 - O
+ psraw_i2r ( 1, mm5 );
+ pmullw_r2r ( mm5, mm5 ); // mm5 = (E1 - O) ^ 2
+ psubusw_r2r ( mm5, mm7 ); // mm7 = ST - (E1 - O) ^ 2, or 0 if that's negative
+
+ movq_m2r ( *&qwSpatialTolerance, mm3 );
+ movq_r2r ( mm6, mm5 ); // mm5 = E2
+ psubsw_r2r ( mm4, mm5 ); // mm5 = E2 - O
+ psraw_i2r ( 1, mm5 );
+ pmullw_r2r ( mm5, mm5 ); // mm5 = (E2 - O) ^ 2
+ psubusw_r2r ( mm5, mm3 ); // mm0 = ST - (E2 - O) ^ 2, or 0 if that's negative
+ paddusw_r2r ( mm3, mm7 ); // mm7 = (ST - (E1 - O) ^ 2) + (ST - (E2 - O) ^ 2)
+
+ movq_m2r ( *&qwTemporalTolerance, mm3 );
+ movq_m2r ( *YVal4++, mm5 ); // mm5 = Oold
+ pand_m2r ( *&YMask, mm5 );
+ psubsw_r2r ( mm4, mm5 ); // mm5 = Oold - O
+ psraw_i2r ( 1, mm5 ); // XXX
+ pmullw_r2r ( mm5, mm5 ); // mm5 = (Oold - O) ^ 2
+ psubusw_r2r ( mm5, mm3 ); // mm0 = TT - (Oold - O) ^ 2, or 0 if that's negative
+ paddusw_r2r ( mm3, mm7 ); // mm7 = our magic number
+
+ // Now compare the similarity totals against our threshold. The pcmpgtw
+ // instruction will populate the target register with a bunch of mask bits,
+ // filling words where the comparison is true with 1s and ones where it's
+ // false with 0s. A few ANDs and NOTs and an OR later, we have bobbed
+ // values for pixels under the similarity threshold and weaved ones for
+ // pixels over the threshold.
+
+ pcmpgtw_m2r( *&qwThreshold, mm7 ); // mm7 = 0xffff where we're greater than the threshold, 0 elsewhere
+ movq_r2r ( mm7, mm6 ); // mm6 = 0xffff where we're greater than the threshold, 0 elsewhere
+ pand_r2r ( mm1, mm7 ); // mm7 = weaved data where we're greater than the threshold, 0 elsewhere
+ pandn_r2r ( mm0, mm6 ); // mm6 = bobbed data where we're not greater than the threshold, 0 elsewhere
+ por_r2r ( mm6, mm7 ); // mm7 = bobbed and weaved data
+
+ movq_r2m ( mm7, *Dest++ );
+ }
+ }
+
+ // Copy last odd line if we're processing an odd field.
+ if (IsOdd)
+ {
+ memcpy(pdst + (height * 2 - 1) * LineLength,
+ pOddLines + (height - 1) * SourcePitch,
+ LineLength);
+ }
+
+ // clear out the MMX registers ready for doing floating point
+ // again
+ emms();
+
+ return 1;
+#endif
+}
static int check_for_mmx(void)
{
@@ -200,18 +388,34 @@ static void abort_mmx_missing(void)
exit(1);
}
-void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc,
+/* generic YUV deinterlacer
+ pdst -> pointer to destination bitmap
+ psrc -> array of pointers to source bitmaps ([0] = most recent)
+ width,height -> dimension for bitmaps
+ method -> DEINTERLACE_xxx
+*/
+
+void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc[],
int width, int height, int method )
{
switch( method ) {
case DEINTERLACE_NONE:
- memcpy(pdst,psrc,width*height);
+ memcpy(pdst,psrc[0],width*height);
break;
case DEINTERLACE_BOB:
if( check_for_mmx() )
- deinterlace_bob_yuv_mmx(pdst,psrc,width,height);
+ deinterlace_bob_yuv_mmx(pdst,psrc,width,height);
+ else /* FIXME: provide an alternative? */
+ abort_mmx_missing();
+ break;
+ case DEINTERLACE_WEAVE:
+ if( check_for_mmx() )
+ {
+ if( !deinterlace_weave_yuv_mmx(pdst,psrc,width,height) )
+ memcpy(pdst,psrc[0],width*height);
+ }
else /* FIXME: provide an alternative? */
- abort_mmx_missing();
+ abort_mmx_missing();
break;
}
}
diff --git a/src/video_out/deinterlace.h b/src/video_out/deinterlace.h
index fc9e69bd4..a4a3d22ae 100644
--- a/src/video_out/deinterlace.h
+++ b/src/video_out/deinterlace.h
@@ -29,11 +29,11 @@
#include "video_out.h"
-void deinterlace_yuv( uint8_t *pdst, uint8_t *psrc,
+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
#endif
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;
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index cc9d7bb62..1ec2d6147 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.19 2001/09/16 15:21:13 miguelfreitas Exp $
+ * $Id: video_out.h,v 1.20 2001/09/19 02:40:58 miguelfreitas Exp $
*
*
* xine version of video_out.h
@@ -176,6 +176,12 @@ struct vo_instance_s {
#define VO_PROP_SOFT_DEINTERLACE 7
#define VO_NUM_PROPERTIES 8
+/* number of recent frames to keep in memory
+ these frames are needed by some deinterlace algorithms
+ FIXME: we need a method to flush the recent frames (new stream)
+*/
+#define VO_NUM_RECENT_FRAMES 2
+
/* image formats that can be supported by display drivers: */
#define IMGFMT_YV12 0x32315659
@@ -198,7 +204,7 @@ struct vo_instance_s {
/* video driver capabilities */
-/* driver copies image (i.e. converts it to
+/* driver copies image (i.e. converts it to
rgb buffers in the private fields of image buffer) */
#define VO_CAP_COPIES_IMAGE 0x00000001
@@ -227,7 +233,7 @@ struct vo_driver_s {
uint32_t (*get_capabilities) (vo_driver_t *this); /* for constants see above */
- /*
+ /*
* allocate an vo_frame_t struct,
* the driver must supply the copy, field and dispose functions
*/
@@ -317,7 +323,7 @@ vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom) ;
* visual - driver specific info (e.g. Display*)
*
* return value: video_driver_t* in case of success,
- * NULL on failure (e.g. wrong interface version,
+ * NULL on failure (e.g. wrong interface version,
* wrong visual type...)
*
*