summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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...)
*
*