On Thu, Jun 27, 2002 at 10:05:43PM +0200, Denis Oliver Kropp wrote:
> I haven't tested it, but committed it to CVS already as the code seems to
> have no impact on the previous implementation.
Yep. At least it works both ways here.
> I suggest to have a "FrameThread" version for each capturing method.
Patch attached. Is it OK?
> Also thanks to Mike Pieper who did a grabbing-only version that can be enabled
> at configure time.
>
> > Anyone care to beat it to a decent shape? It's 4:30 in the morining so I
> > think I'll sleep for a while...
>
> Someone could add the missing bits by using Mike's code.
Is the code available somewhere? Chances are he knows more about v4l than
I do so I'd like to take a look.
PS. There seems to be some kind of encoding problem with my name.
--
Ville Syrj�l�
[EMAIL PROTECTED]
http://www.sci.fi/~syrjala/
Index: interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c
===================================================================
RCS file:
/cvs/directfb/DirectFB/interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c,v
retrieving revision 1.31
diff -u -r1.31 idirectfbvideoprovider_v4l.c
--- interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c 27 Jun 2002
19:34:38 -0000 1.31
+++ interfaces/IDirectFBVideoProvider/idirectfbvideoprovider_v4l.c 27 Jun 2002
+20:32:12 -0000
@@ -409,69 +409,79 @@
/*****************/
/*
+ * thread to capture data from v4l buffers and generate callback
+ */
+static void* SystemThread( void *ctx )
+{
+ IDirectFBVideoProvider_V4L_data *data =
+ (IDirectFBVideoProvider_V4L_data*)ctx;
+ int field = 0;
+ __u8 *src, *dst;
+ int src_pitch = DFB_BYTES_PER_LINE( data->destination->format,
+data->destination->width );
+ int dst_pitch = data->destination->back_buffer->system.pitch *
+(data->destination->caps & DSCAPS_INTERLACED ? 2 : 1);
+ int h;
+
+ while (1) {
+ data->vmmap.frame = field;
+ ioctl( data->fd, VIDIOCSYNC, &field );
+ pthread_testcancel();
+
+ ioctl( data->fd, VIDIOCMCAPTURE, &data->vmmap );
+
+ src = (__u8 *) data->buffer + data->vmbuf.offsets[field];
+ dst = (__u8 *) data->destination->back_buffer->system.addr;
+ h = data->destination->height;
+ if (data->destination->caps & DSCAPS_INTERLACED) {
+ dst += field * data->destination->back_buffer->system.pitch;
+ h += field ? 0 : 1;
+ h /= 2;
+ }
+
+ while (h--) {
+ memcpy( dst, src, src_pitch );
+ src += src_pitch;
+ dst += dst_pitch;
+ }
+ if (data->destination->caps & DSCAPS_INTERLACED) {
+ dfb_surface_notify_listeners( data->destination,
+ field ? CSNF_SET_ODD : CSNF_SET_EVEN );
+ field = !field;
+ }
+
+ if (data->callback)
+ data->callback(data->ctx);
+ }
+
+ return NULL;
+}
+
+/*
* bogus thread to generate callback,
* because video4linux does not support syncing in overlay mode
*/
-static void* FrameThread( void *ctx )
+static void* VideoThread( void *ctx )
{
IDirectFBVideoProvider_V4L_data *data =
(IDirectFBVideoProvider_V4L_data*)ctx;
- int field = 0;
+ int field = 0;
+ struct timeval tv;
- if (data->destination->caps & DSCAPS_SYSTEMONLY) {
- __u8 *src, *dst;
- int src_pitch = DFB_BYTES_PER_LINE( data->destination->format,
data->destination->width );
- int dst_pitch = data->destination->back_buffer->system.pitch *
(data->destination->caps & DSCAPS_INTERLACED ? 2 : 1);
- int h;
- while (1) {
- data->vmmap.frame = field;
- ioctl( data->fd, VIDIOCSYNC, &field );
- pthread_testcancel();
-
- ioctl( data->fd, VIDIOCMCAPTURE, &data->vmmap );
-
- src = (__u8 *) data->buffer + data->vmbuf.offsets[field];
- dst = (__u8 *) data->destination->back_buffer->system.addr;
- h = data->destination->height;
- if (data->destination->caps & DSCAPS_INTERLACED) {
- dst += field * data->destination->back_buffer->system.pitch;
- h += field ? 0 : 1;
- h /= 2;
- }
-
- while (h--) {
- memcpy( dst, src, src_pitch );
- src += src_pitch;
- dst += dst_pitch;
- }
- if (data->destination->caps & DSCAPS_INTERLACED) {
- dfb_surface_notify_listeners( data->destination,
- field ? CSNF_SET_ODD :
CSNF_SET_EVEN );
- field = !field;
- }
- if (data->callback)
- data->callback(data->ctx);
+ while (1) {
+ tv.tv_sec = 0;
+ tv.tv_usec = 20000;
+ select( 0, 0, 0, 0, &tv );
+
+ pthread_testcancel();
+
+ if (data->destination->caps & DSCAPS_INTERLACED) {
+ dfb_surface_notify_listeners( data->destination,
+ field ? CSNF_SET_ODD : CSNF_SET_EVEN );
+ field = !field;
}
- } else {
- struct timeval tv;
- while (1) {
- tv.tv_sec = 0;
- tv.tv_usec = 20000;
- select( 0, 0, 0, 0, &tv );
-
- pthread_testcancel();
-
- if (data->destination->caps & DSCAPS_INTERLACED) {
- dfb_surface_notify_listeners( data->destination,
- field ? CSNF_SET_ODD :
CSNF_SET_EVEN );
- field = !field;
- }
-
- if (data->callback)
- data->callback( data->ctx );
- }
+ if (data->callback)
+ data->callback( data->ctx );
}
return NULL;
@@ -682,8 +692,10 @@
reactor_attach( surface->reactor, v4l_surface_listener, data );
- if (data->callback || surface->caps & DSCAPS_INTERLACED || surface->caps &
DSCAPS_SYSTEMONLY)
- pthread_create( &data->thread, NULL, FrameThread, data );
+ if (surface->caps & DSCAPS_SYSTEMONLY)
+ pthread_create( &data->thread, NULL, SystemThread, data );
+ else if (data->callback || surface->caps & DSCAPS_INTERLACED)
+ pthread_create( &data->thread, NULL, VideoThread, data );
return DFB_OK;
}