changeset 6758:ecc71f27bfd7

DR1 IP/IPB supoprt (I/P only with -double) -- OSD *must be* disabled! :) note: playing IPB mpeg (-vc ffmpeg12) looks broken due to bad frame display order (differs from frame decoding order) - requires workaround or PUT_IMAGE implementation...
author arpi
date Sat, 20 Jul 2002 15:49:38 +0000
parents f72fc85934e5
children 415be01747ae
files libvo/vo_xv.c
diffstat 1 files changed, 33 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/libvo/vo_xv.c	Sat Jul 20 14:26:38 2002 +0000
+++ b/libvo/vo_xv.c	Sat Jul 20 15:49:38 2002 +0000
@@ -1,7 +1,20 @@
 
 // Number of buffers _FOR_DOUBLEBUFFERING_MODE_
 // Use option -double to enable double buffering! (default: single buffer)
-#define NUM_BUFFERS 2
+#define NUM_BUFFERS 3
+
+/*
+Buffer allocation:
+
+-nodr:
+  1: TEMP
+  2: 2*TEMP
+
+-dr:
+  1: TEMP
+  3: 2*STATIC+TEMP
+*/
+
 
 /*
  * vo_xv.c, X11 Xv interface
@@ -72,6 +85,7 @@
 static XvImageFormatValues  *fo;
 
 static int current_buf=0;
+static int current_ip_buf=0;
 static int num_buffers=1; // default
 static XvImage* xvimage[NUM_BUFFERS];
 
@@ -348,7 +362,7 @@
  if( flags&0x02 ) vm = 1;
 #endif
  flip_flag=flags&8;
- num_buffers=vo_doublebuffering?NUM_BUFFERS:1;
+ num_buffers=vo_doublebuffering?(vo_directrendering?NUM_BUFFERS:2):1;
 
    /* check image formats */
      fo = XvListImageFormats(mDisplay, xv_port, (int*)&formats);
@@ -479,6 +493,7 @@
        allocate_xvimage(current_buf);
 
      current_buf=0;
+     current_ip_buf=0;
 
      set_gamma_correction();
 
@@ -620,7 +635,7 @@
          drwX-(vo_panscan_x>>1),drwY-(vo_panscan_y>>1),vo_dwidth+vo_panscan_x,(vo_fs?vo_dheight - 1:vo_dheight)+vo_panscan_y);
   }
  if (num_buffers>1){
-    current_buf=(current_buf+1)%num_buffers;
+    current_buf=vo_directrendering?0:((current_buf+1)%num_buffers);
     XFlush(mDisplay);
  } else
     XSync(mDisplay, False);   
@@ -733,15 +748,25 @@
 }
 
 static uint32_t get_image(mp_image_t *mpi){
+    int buf=current_buf; // we shouldn't change current_buf unless we do DR!
     if(mpi->type==MP_IMGTYPE_STATIC && num_buffers>1) return VO_FALSE; // it is not static
-    if(mpi->type==MP_IMGTYPE_IPB && num_buffers<3 && mpi->flags&MP_IMGFLAG_READABLE) return VO_FALSE; // not enough
-    if(mpi->type==MP_IMGTYPE_IP  && num_buffers<2 && mpi->flags&MP_IMGFLAG_READABLE) return VO_FALSE; // not enough
     if(mpi->imgfmt!=image_format || mpi->imgfmt==IMGFMT_BGR24) return VO_FALSE; // needs conversion :(
-    if(mpi->height > xvimage[current_buf]->height) return VO_FALSE; //buffer to small
-    if(mpi->width*(mpi->bpp/8) > xvimage[current_buf]->pitches[0]) return VO_FALSE; //buffer to small
 //    if(mpi->flags&MP_IMGFLAG_READABLE) return VO_FALSE; // slow video ram
+    if(mpi->flags&MP_IMGFLAG_READABLE &&
+	(mpi->type==MP_IMGTYPE_IPB || mpi->type==MP_IMGTYPE_IP)){
+	// reference (I/P) frame of IP or IPB:
+	if(num_buffers<2) return VO_FALSE; // not enough
+	current_ip_buf^=1;
+	// for IPB with 2 buffers we can DR only one of the 2 P frames:
+	if(mpi->type==MP_IMGTYPE_IPB && num_buffers<3 && current_ip_buf) return VO_FALSE;
+	buf=current_ip_buf;
+	if(mpi->type==MP_IMGTYPE_IPB) ++buf; // preserve space for B
+    }
+    if(mpi->height > xvimage[buf]->height) return VO_FALSE; //buffer to small
+    if(mpi->width*(mpi->bpp/8) > xvimage[buf]->pitches[0]) return VO_FALSE; //buffer to small
     if( (mpi->flags&(MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_ACCEPT_WIDTH)) ||
-	(mpi->width*(mpi->bpp/8)==xvimage[current_buf]->pitches[0]) ){
+	(mpi->width*(mpi->bpp/8)==xvimage[buf]->pitches[0]) ){
+	current_buf=buf;
 	mpi->planes[0]=xvimage[current_buf]->data+xvimage[current_buf]->offsets[0];
 	mpi->stride[0]=xvimage[current_buf]->pitches[0];
 	mpi->width=mpi->stride[0]/(mpi->bpp/8);