[MPlayer-dev-eng] [patch] vo_directfb.c and cz language file

pl p_l at tfz.net
Tue Jan 8 12:53:12 CET 2002


Hi,

I was just reading my pending mails/bugs/patches/whatever mbox and found
this mail dated back 15 days, without any reply so far on the list.


On Mon, Dec 24, 2001 at 03:09:43AM +0100, pl wrote:
> On Mon, Dec 24, 2001 at 12:12:57AM +0100, Ji?í Svoboda wrote:
...
> > here is patch which includes:
> 
> Your patch does not apply off the mail (there are ctl-M chars :/) I had
> to dos2nix it before trying and applying it.
...
> > -adding support for flip thread in vo_directfb.c (-flip_thread 0-2
> > option)
> > -improved compatibility with older DIrectFB versions (DSPF declarations)
> Not applied as it uses pthread, maybe it's OK but I'd prefer somebody
> more aware about this to apply it.
...

I've seen NAS uses simple pthread primitives (mutex join).  So, I guess
it's OK to do pthread stuff within a ao/vo module ?  Won't it be
problematic if NAS+directfb are used at the same time?

I attach the previous patch for review (slightly edited but may not
apply), if it's OK, patch should be resent to apply to latest cvs (and
without ctl-M at the end of lines).

-- 
Best regards,
  pl
-------------- next part --------------
diff -Naurdb MPlayer-20011221/cfg-mplayer.h main/cfg-mplayer.h
--- MPlayer-20011221/cfg-mplayer.h	Thu Dec 20 16:30:22 2001
+++ main/cfg-mplayer.h	Sat Dec 22 16:22:41 2001
@@ -18,6 +18,9 @@
 extern char *fb_dev_name;
 #endif
 #endif
+#ifdef HAVE_DIRECTFB
+extern int flip_thread;
+#endif
 #ifdef HAVE_PNG
 extern int z_compression;
 #endif
@@ -134,6 +137,9 @@
 	{"fb", &fb_dev_name, CONF_TYPE_STRING, 0, 0, 0},
 #endif
 #endif
+#ifdef HAVE_DIRECTFB
+	{"flip_thread", &flip_thread, CONF_TYPE_INT, CONF_RANGE, 0, 2},
+#endif
 //	{"encode", &encode_name, CONF_TYPE_STRING, 0, 0, 0},
 #ifdef USE_SUB
 	{"sub", &sub_name, CONF_TYPE_STRING, 0, 0, 0},
diff -Naurdb MPlayer-20011221/libvo/vo_directfb.c main/libvo/vo_directfb.c
--- MPlayer-20011221/libvo/vo_directfb.c	Sat Dec 22 10:00:18 2001
+++ main/libvo/vo_directfb.c	Sun Dec 23 22:15:23 2001
@@ -36,6 +36,15 @@
 
 #include <directfb.h>
 
+// workabout for older versions of DirectFB
+#ifndef DSPF_YUY2
+#define DSPF_YUY2 0x00021007
+#endif
+
+#ifndef DSPF_UYVY
+#define DSPF_UYVY 0x00021009
+#endif
+
 // other things
 
 #include <stdio.h>
@@ -70,6 +79,17 @@
 
 extern int verbose;
 
+// flip_thread variables
+#include "pthread.h"
+#define FB_MAX_BUF 4
+pthread_t dfb_playback_thread;
+pthread_mutex_t valid_mutex;
+pthread_cond_t buffer_filled[FB_MAX_BUF];
+static int valid[FB_MAX_BUF];
+static int currentframe=0;
+static int frametoplay=0;
+static int exit_playback;
+
 /******************************
 *	   directfb 	      *
 ******************************/
@@ -103,7 +123,7 @@
  * The frame is to be loaded into a surface that we can blit from.
  */
 
-static IDirectFBSurface *frame = NULL;
+static IDirectFBSurface *frame[FB_MAX_BUF];
 
 /*
  * A buffer for input events.
@@ -120,6 +140,7 @@
 #else
 char *fb_dev_name;
 #endif
+int flip_thread = 0;
 
 static void (*draw_alpha_p)(int w, int h, unsigned char *src,
 		unsigned char *srca, int stride, unsigned char *dst,
@@ -144,6 +165,55 @@
 static int no_yuy2=1;
 static int no_uyvy_support=1;
 
+static void *playback_thread(void * arg)
+{
+//      current_module="Playback thread";
+        if (verbose > 0)
 printf("software playback thread spawned !\n");
+	/* Allow easy shutting down by other processes... */
+	pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL );
+	pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
+        if (verbose > 0)
 printf("\nplayback thread: setup complete, now looping !\n");
+	while (!exit_playback)
+        {
+		pthread_mutex_lock(&valid_mutex);
+		while (valid[frametoplay] == 0)
+		{
+                        if (verbose > 0)
 printf("\nplayback thread: Sleeping for new frames (waiting for frame %d))\n",currentframe);
+			pthread_cond_wait(&buffer_filled[currentframe], &valid_mutex);
+			if (exit_playback) // Ok, we shall exit, that's the reason for the wakeup
+			{
+				printf("playback thread: Was told to exit\n");
+				pthread_exit(NULL);
+			}
+		}
+		pthread_mutex_unlock(&valid_mutex);
+      /* There is one buffer to play - get ready to rock ! */
+		 { 
+		    DFBSurfaceBlittingFlags flags=DSBLIT_NOFX;
+
+		    DFBCHECK (primary->SetBlittingFlags(primary,flags));
+
+    		    if (stretch) {
+        		DFBRectangle rect;
+        		rect.x=xoffset;
+	    		rect.y=yoffset;
+	    		rect.w=out_width;
+	    		rect.h=out_height;
+
+            		DFBCHECK (primary->StretchBlit(primary,frame[frametoplay],NULL,&rect));
+            		}
+    		    else    {
+            		DFBCHECK (primary->Blit(primary,frame[frametoplay],NULL,xoffset,yoffset));
+            	    };
+		//      DFBCHECK (primary->Flip (primary, NULL, DSFLIP_WAITFORSYNC));
+		 }
+		pthread_mutex_lock(&valid_mutex);
+		valid[frametoplay] = 0;
+		pthread_mutex_unlock(&valid_mutex);
+        }
+        if (verbose > 0)
 printf("playback thread: Was told to exit");
+	pthread_exit(NULL);
+}
 
 DFBEnumerationResult enum_modes_callback( unsigned int width,unsigned int height,unsigned int bpp, void *data)
 {
@@ -348,6 +418,8 @@
 	in_width = width;
 	in_height = height;
 
+        currentframe = 0; /* the first buffer to play from */
+
         if (d_width) {
 		out_width = d_width;
 		out_height = d_height;
@@ -513,9 +585,29 @@
   /*
    * Create a surface based on the description of the source frame
    */
-  DFBCHECK (dfb->CreateSurface( dfb, &dsc, &frame));
+  if (flip_thread) { 
+    unsigned int i;
+    for (i=0;i<FB_MAX_BUF;i++) {
+	DFBCHECK (dfb->CreateSurface( dfb, &dsc, &frame[i])); 
+	pthread_cond_init(&buffer_filled[i], NULL);
+	if (verbose > 0) {
+		printf("buffer init: %d\n",i);
+		}	
+	valid[i]=0;
+    }
+    pthread_mutex_init(&valid_mutex, NULL);
+	       /* Now do the thread magic */
+    exit_playback = 0; 
 
-  DFBCHECK (frame->GetPixelFormat (frame, &frame_format));
+    if (pthread_create(&dfb_playback_thread, NULL, 
playback_thread, NULL)) {
+		   printf("Could not create software playback thread\n");
+		   return 1;
+	}
+  } else { 
+    DFBCHECK (dfb->CreateSurface( dfb, &dsc, &frame[0]));
+  };
+
  //hopefully all frames are same
+  DFBCHECK (frame[0]->GetPixelFormat (frame[0], &frame_format));
 
 
   switch (frame_format) {
                 case DSPF_ARGB:  //printf("Directfb frame format ARGB\n");
@@ -640,7 +732,7 @@
         int pitch;
 	int len;
 
-        DFBCHECK (frame->Lock(frame,DSLF_WRITE,&dst,&pitch));
+        DFBCHECK (frame[currentframe]->Lock(frame[currentframe],DSLF_WRITE,&dst,&pitch));
 
 	switch(frame_format) {
                 case DSPF_RGB32:
@@ -668,7 +760,7 @@
     			vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) dst) + pitch*y0 + frame_pixel_size*x0 + 1,pitch);
 		break;
 		}
-        DFBCHECK (frame->Unlock(frame));
+        DFBCHECK (frame[currentframe]->Unlock(frame[currentframe]));
 }
 
 static uint32_t draw_frame(uint8_t *src[])
@@ -677,7 +769,7 @@
         int pitch;
 	int len;
 
-        DFBCHECK (frame->Lock(frame,DSLF_WRITE,&dst,&pitch));
+        DFBCHECK (frame[currentframe]->Lock(frame[currentframe],DSLF_WRITE,&dst,&pitch));
 
         switch (frame_format) {
                 case DSPF_ARGB:
@@ -694,7 +786,7 @@
                                         yuv2rgb(dst+1,src[0]+2,src[0]+1,src[0]+3,1,in_height*in_width/2,frame_pixel_size*2,4,4); //even pixels
                                         break;*/
 				// RGB - just copy
-                                default:    if (source_pixel_size==frame_pixel_size) {memcpy(dst,src[0],in_width * in_height * frame_pixel_size);};
+                                default:    if (source_pixel_size==frame_pixel_size) {fast_memcpy(dst,src[0],in_width * in_height * frame_pixel_size);};
 
                                 }
                         break;
@@ -705,17 +797,17 @@
 	                        case IMGFMT_YUY2: {
                                                 int i;
                                                 for (i=0;i<in_height;i++) {
-                                                        memcpy(dst+i*pitch,src[0]+i*in_width*2,in_width*2);
+                                                        fast_memcpy(dst+i*pitch,src[0]+i*in_width*2,in_width*2);
                                                          }
                                                 }
                                                 /*len = in_width * in_height * pitch;
-			                        memcpy(dst,src[0],len);*/
+			                        fast_memcpy(dst,src[0],len);*/
 		        	                break;
                                 // hopefully there will be no RGB in this case otherwise convert - not implemented
 	                                }
                         break;
         }
-        DFBCHECK (frame->Unlock(frame));
+        DFBCHECK (frame[currentframe]->Unlock(frame[currentframe]));
         return 0;
 }
 
@@ -728,7 +820,7 @@
         int pitch;
 	int i;
 
-        err = frame->Lock(frame,DSLF_WRITE,&dst,&pitch);
+        err = frame[currentframe]->Lock(frame[currentframe],DSLF_WRITE,&dst,&pitch);
 
 //        printf("Drawslice\n");
 
@@ -756,7 +848,7 @@
                                                         dst += x * frame_pixel_size;
 				                        s = src[0];
 				                        for (i=y;i<=(y+h);i++) {
-					                        memcpy(dst,s,w);
+					                        fast_memcpy(dst,s,w);
 					                        dst += (pitch);
 					                        s += stride[0];
 					                        };
@@ -773,7 +865,7 @@
 				                        dst += x * frame_pixel_size;
 				                        s = src[0];
 				                        for (i=y;i<=(y+h);i++) {
-					                        memcpy(dst,s,w);
+					                        fast_memcpy(dst,s,w);
 					                        dst += (pitch);
 					                        s += stride[0];
 					                        };
@@ -784,7 +876,7 @@
                          break;
         };
 
-        frame->Unlock(frame);
+        frame[currentframe]->Unlock(frame[currentframe]);
 
 	return 0;
 }
@@ -840,6 +932,8 @@
 
 static void flip_page(void)
 {
+    if (!flip_thread)
+	{
 	DFBSurfaceBlittingFlags flags=DSBLIT_NOFX;
 
 	DFBCHECK (primary->SetBlittingFlags(primary,flags));
@@ -851,19 +945,32 @@
 	        rect.w=out_width;
 	        rect.h=out_height;
 
-                DFBCHECK (primary->StretchBlit(primary,frame,NULL,&rect));
+                DFBCHECK (primary->StretchBlit(primary,frame[0],NULL,&rect));
                 }
         else    {
-                DFBCHECK (primary->Blit(primary,frame,NULL,xoffset,yoffset));
+                DFBCHECK (primary->Blit(primary,frame[0],NULL,xoffset,yoffset));
                 };
 //      DFBCHECK (primary->Flip (primary, NULL, DSFLIP_WAITFORSYNC));
+	} else {
+	    pthread_mutex_lock(&valid_mutex);
+    	    frametoplay=currentframe;
+    	    valid[frametoplay] = 1;
+    	    currentframe = (currentframe +1) % FB_MAX_BUF;
+    	    pthread_cond_broadcast(&buffer_filled[frametoplay]);
+    	    pthread_mutex_unlock(&valid_mutex);
+	}
 }
 
 static void uninit(void)
 {
-	if (verbose > 0)
-		printf("uninit\n");
+  if (verbose > 0)
 printf("uninit\n");
 
+  if (flip_thread) {
+    exit_playback = 1;
+    pthread_cancel(dfb_playback_thread);
+    if (pthread_join(dfb_playback_thread, NULL))
+		  printf("Failure deleting software playback thread\n");
+
  }
   /*
    * (Release)
    */
@@ -872,8 +979,14 @@
 //  printf("Release keyb\n");
   keyboard->Release (keyboard);
 //  printf("Release frame\n");
-  frame->Release (frame);
-
+  if (flip_thread) {
+    unsigned int i;
+    for (i=1;i<FB_MAX_BUF;i++) {
+	frame[i]->Release (frame[i]);
+    }
+  } else {
+    frame[0]->Release (frame[0]);
+
  };
 // we will not release dfb and layer because there could be a new film
 
 //  printf("Release primary\n");


More information about the MPlayer-dev-eng mailing list