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--;
+ }
+}
+