Hi,

this patch (v4l_lockright.patch) has to be applied on my last patch 
(v4lgrab.patch). It solves problems due to locking the destination surface of 
the PlayTo function.
All locking/unlocking is done in an extra function now. The unlocking at 
various places in the code is avoided. The back _and_ the front buffer is 
locked.

Mike

--- idirectfbvideoprovider_v4l.c_grab	Wed Jul 10 14:54:51 2002
+++ idirectfbvideoprovider_v4l.c	Wed Jul 10 19:11:42 2002
@@ -111,6 +111,8 @@
 static DFBResult v4l_stop( IDirectFBVideoProvider_V4L_data *data );
 static void v4l_deinit( IDirectFBVideoProvider_V4L_data *data );
 static void v4l_cleanup( void *data, int emergency );
+static void v4l_lock_surface (CoreSurface *surface);
+static void v4l_unlock_surface (CoreSurface *surface);
 
 
 static void IDirectFBVideoProvider_V4L_Destruct( IDirectFBVideoProvider *thiz )
@@ -247,7 +249,7 @@
 	  ret = dfb_surfacemanager_assure_system( surface->manager, 
 						  surface->back_buffer );
 	  if (!ret)
-	       surface->back_buffer->system.locked++;
+	       v4l_lock_surface( surface );
 
 	  dfb_surfacemanager_unlock( surface->manager );
 
@@ -260,7 +262,7 @@
 	  ret = dfb_surfacemanager_assure_video( surface->manager, 
 						 surface->back_buffer );
 	  if (!ret)
-	       surface->back_buffer->video.locked++;
+	       v4l_lock_surface( surface );
 
 	  dfb_surfacemanager_unlock( surface->manager );
 
@@ -274,9 +276,14 @@
           needs_grab_mode = 1;
 
      if (needs_grab_mode)
-          return v4l_to_surface_grab( surface, &rect, data );
+          ret = v4l_to_surface_grab( surface, &rect, data );
      else
-          return v4l_to_surface_overlay( surface, &rect, data );
+          ret = v4l_to_surface_overlay( surface, &rect, data );
+
+     if (DFB_OK != ret)
+          v4l_unlock_surface (surface);
+
+     return ret;
 }
 
 static DFBResult IDirectFBVideoProvider_V4L_Stop(
@@ -641,7 +648,6 @@
                break;
           default:
                BUG( "unknown pixel format" );
-               buffer->video.locked--;
                return DFB_BUG;
      }
 
@@ -660,7 +666,6 @@
                PERRORMSG( "DirectFB/v4l: "
                           "VIDIOCSFBUF failed, must run being root!\n" );
 
-               buffer->video.locked--;
                return ret;
           }
      }
@@ -672,7 +677,6 @@
 
                PERRORMSG( "DirectFB/v4l: VIDIOCGPICT failed!\n" );
 
-               buffer->video.locked--;
                return ret;
           }
 
@@ -684,7 +688,6 @@
 
                PERRORMSG( "DirectFB/v4l: VIDIOCSPICT failed!\n" );
 
-               buffer->video.locked--;
                return ret;
           }
      }
@@ -705,7 +708,6 @@
 
                PERRORMSG( "DirectFB/v4l: VIDIOCSWIN failed!\n" );
 
-               buffer->video.locked--;
                return ret;
           }
      }
@@ -719,7 +721,6 @@
           PERRORMSG( "DirectFB/v4l: "
                      "Could not start capturing (VIDIOCCAPTURE failed)!\n" );
 
-          buffer->video.locked--;
           return ret;
      }
 
@@ -737,7 +738,6 @@
                                        IDirectFBVideoProvider_V4L_data *data )
 {
      int bpp, palette;
-     SurfaceBuffer *buffer = surface->back_buffer;
 
      if (!data->vmbuf.frames)
           return DFB_UNSUPPORTED;
@@ -778,10 +778,6 @@
                break;
           default:
                BUG( "unknown pixel format" );
-	       if (surface->caps & DSCAPS_SYSTEMONLY)
-		    buffer->system.locked--;
-	       else
-		    buffer->video.locked--;
                return DFB_BUG;
      }
 
@@ -795,10 +791,6 @@
           PERRORMSG("DirectFB/v4l: "
                     "Could not start capturing (VIDIOCMCAPTURE failed)!\n");
 	  
-	  if (surface->caps & DSCAPS_SYSTEMONLY)
-	       buffer->system.locked--;
-	  else
-	       buffer->video.locked--;
           return ret;
      }
 
@@ -836,10 +828,7 @@
      if (!data->destination)
           return DFB_OK;
 
-     if (data->destination->caps & DSCAPS_SYSTEMONLY)
-          data->destination->back_buffer->system.locked--;
-     else
-          data->destination->back_buffer->video.locked--;
+     v4l_unlock_surface (data->destination);
      data->destination = NULL;
 
      return DFB_OK;
@@ -869,3 +858,30 @@
      else
           v4l_deinit( data );
 }
+
+static void v4l_lock_surface (CoreSurface *surface)
+{
+     if (surface->caps & DSCAPS_SYSTEMONLY) {
+          surface->back_buffer->system.locked++;
+	  if (surface->back_buffer != surface->front_buffer)
+	       surface->front_buffer->system.locked++;
+     } else {
+          surface->back_buffer->video.locked++;
+          if (surface->back_buffer != surface->front_buffer)
+	       surface->front_buffer->video.locked++;
+     }
+}
+
+static void v4l_unlock_surface (CoreSurface *surface)
+{
+     if (surface->caps & DSCAPS_SYSTEMONLY) {
+          surface->back_buffer->system.locked--;
+	  if (surface->back_buffer != surface->front_buffer)
+	       surface->front_buffer->system.locked--;
+     } else {
+          surface->back_buffer->video.locked--;
+	  if (surface->back_buffer != surface->front_buffer)
+	       surface->front_buffer->video.locked--;
+     }
+}
+

Reply via email to