/****************************************************************************
# spcav4l: v4l library. #
#This package work with the spca5xx based webcam with the raw jpeg feature. #
#All the decoding is in user space with the help of libjpeg. #
#. #
# Copyright (C) 2003 2004 2005 Michel Xhaard #
# #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation; either version 2 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program; if not, write to the Free Software #
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
# #
****************************************************************************/
/* MOFIFIED by MX for Acme FOX Eltrax 100LX and Arm9 only accept jpeg webcam */
#include "spcaframe.h"
#include "spcav4l.h"
#include "utils.h"
#define OUTFRMNUMB 4
static int debug = 0;
static int init_v4l (struct vdIn *vd);
#if 0
static int checkpalette (struct vdIn *vd);
static int check_palettesize(struct vdIn *vd );
static int probePalette ( struct vdIn *vd );
static int probeSize ( struct vdIn *vd );
#endif
static int isSpcaChip ( const char * BridgeName );
/* return Bridge otherwhise -1 */
static int GetStreamId ( const char * BridgeName );
/* return Stream_id otherwhise -1 */
static int
GetDepth (int format);
static struct bridge_list Blist[]={
{BRIDGE_SPCA505,"SPCA505"},
{BRIDGE_SPCA506,"SPCA506"},
{BRIDGE_SPCA501,"SPCA501"},
{BRIDGE_SPCA508,"SPCA508"},
{BRIDGE_SPCA504,"SPCA504"},
{BRIDGE_SPCA500,"SPCA500"},
{BRIDGE_SPCA504B,"SPCA504B"},
{BRIDGE_SPCA533,"SPCA533"},
{BRIDGE_SPCA504C,"SPCA504C"},
{BRIDGE_SPCA561,"SPCA561"},
{BRIDGE_SPCA536,"SPCA536"},
{BRIDGE_SONIX,"SN9C102"},
{BRIDGE_ZR364XX,"ZR364XX"},
{BRIDGE_ZC3XX,"ZC301-2"},
{BRIDGE_CX11646,"CX11646"},
{BRIDGE_TV8532,"TV8532"},
{BRIDGE_ETOMS,"ET61XX51"},
{BRIDGE_SN9CXXX,"SN9CXXX"},
{BRIDGE_MR97311,"MR97311"},
{BRIDGE_UNKNOW,"UNKNOW"},
{-1,NULL}
};
#if 0
/* Camera type jpeg yuvy yyuv yuyv grey gbrg*/
static struct palette_list Plist[] ={
{JPEG,"JPEG"},
{YUVY,"YUVY"},
{YYUV,"YYUV"},
{YUYV,"YUYV"},
{GREY,"GREY"},
{GBRG,"GBRG"},
{SN9C,"SN9C"},
{GBGR,"GBGR"},
{UNOW,"UNOW"},
{-1,NULL}
};
#endif
/****************************************************************************
* Public
****************************************************************************/
int
init_videoIn (struct vdIn *vd, char *device, int width, int height,
int format, int grabmethod)
{
int err = -1;
int i;
if (vd == NULL || device == NULL)
return -1;
if (width == 0 || height == 0)
return -1;
if(grabmethod < 0 || grabmethod > 1)
grabmethod = 1; //read by default;
// check format
vd->videodevice = NULL;
vd->cameraname = NULL;
vd->videodevice = NULL;
vd->videodevice = (char *) realloc (vd->videodevice, 16);
vd->cameraname = (char *) realloc (vd->cameraname, 32);
snprintf (vd->videodevice, 12, "%s", device);
if(debug) printf("video %s \n",vd->videodevice);
memset (vd->cameraname, 0, sizeof (vd->cameraname));
memset(vd->bridge, 0, sizeof(vd->bridge));
vd->signalquit = 1;
vd->hdrwidth = width;
vd->hdrheight = height;
/* compute the max frame size */
vd->formatIn = format;
vd->bppIn = GetDepth (vd->formatIn);
vd->grabMethod = grabmethod; //mmap or read
vd->pFramebuffer = NULL;
/* init and check all setting */
err = init_v4l (vd);
/* allocate the 4 frames output buffer */
for (i = 0; i < OUTFRMNUMB; i++)
{
vd->ptframe[i] = NULL;
vd->ptframe[i] =
(unsigned char *) realloc (vd->ptframe[i], sizeof(struct frame_t) + (size_t) vd->framesizeIn );
vd->framelock[i] = 0;
}
vd->frame_cour = 0;
pthread_mutex_init (&vd->grabmutex, NULL);
return err;
}
int
close_v4l (struct vdIn *vd)
{
int i;
if (vd->grabMethod)
{
if(debug) printf ("unmapping frame buffer\n");
munmap (vd->pFramebuffer, vd->mmapsize);
} else {
free(vd->pFramebuffer);
vd->pFramebuffer = NULL;
}
if(debug) printf ("close video_device\n");
close (vd->fd);
/* dealloc the whole buffers */
if (vd->videodevice)
{
free (vd->videodevice);
vd->videodevice = NULL;
}
if (vd->cameraname)
{
free (vd->cameraname);
vd->cameraname = NULL;
}
for (i = 0; i < OUTFRMNUMB; i++)
{
if (vd->ptframe[i])
{
free (vd->ptframe[i]);
vd->ptframe[i] = NULL;
vd->framelock[i] = 0;
if(debug) printf ("freeing output buffer %d\n",i);
}
}
pthread_mutex_destroy (&vd->grabmutex);
}
int
convertframe(unsigned char *dst,unsigned char *src, int width,int height, int formatIn, int size)
{
int jpegsize =0;
switch (formatIn){
case VIDEO_PALETTE_JPEG:
jpegsize = get_jpegsize(src, size);
if (jpegsize < 0) break;
memcpy(dst,src,jpegsize);
break;
default:
break;
}
return jpegsize;
}
int
v4lGrab (struct vdIn *vd )
{
static int frame = 0;
int len;
int size;
int erreur = 0;
int jpegsize = 0;
struct frame_t *headerframe;
double timecourant =0;
double temps = 0;
timecourant = ms_time();
if (vd->grabMethod)
{
vd->vmmap.height = vd->hdrheight;
vd->vmmap.width = vd->hdrwidth;
vd->vmmap.format = vd->formatIn;
if (ioctl (vd->fd, VIDIOCSYNC, &vd->vmmap.frame) < 0)
{
perror ("cvsync err\n");
erreur = -1;
}
/* Is there someone using the frame */
while((vd->framelock[vd->frame_cour] != 0) && vd->signalquit)
usleep(1000);
pthread_mutex_lock (&vd->grabmutex);
/*
memcpy (vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t), vd->pFramebuffer +
vd->videombuf.offsets[vd->vmmap.frame] , vd->framesizeIn);
jpegsize =jpeg_compress(vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t),vd->framesizeIn,
vd->pFramebuffer + vd->videombuf.offsets[vd->vmmap.frame] ,vd->hdrwidth, vd->hdrheight, qualite);
*/
temps = ms_time();
jpegsize= convertframe(vd->ptframe[vd->frame_cour]+ sizeof(struct frame_t),
vd->pFramebuffer + vd->videombuf.offsets[vd->vmmap.frame],
vd->hdrwidth,vd->hdrheight,vd->formatIn,vd->framesizeIn);
headerframe=(struct frame_t*)vd->ptframe[vd->frame_cour];
snprintf(headerframe->header,5,"%s","SPCA");
headerframe->seqtimes = ms_time();
headerframe->deltatimes=(int)(headerframe->seqtimes-timecourant);
headerframe->w = vd->hdrwidth;
headerframe->h = vd->hdrheight;
headerframe->size = (( jpegsize < 0)?0:jpegsize);
headerframe->format = vd->formatIn;
headerframe->nbframe = frame++;
// printf("compress frame %d times %f\n",frame, headerframe->seqtimes-temps);
pthread_mutex_unlock (&vd->grabmutex);
/************************************/
if ((ioctl (vd->fd, VIDIOCMCAPTURE, &(vd->vmmap))) < 0)
{
perror ("cmcapture");
if(debug) printf (">>cmcapture err \n");
erreur = -1;
}
vd->vmmap.frame = (vd->vmmap.frame + 1) % vd->videombuf.frames;
vd->frame_cour = (vd->frame_cour +1) % OUTFRMNUMB;
//if(debug) printf("frame nb %d\n",vd->vmmap.frame);
}
e
评论1