文档库 最新最全的文档下载
当前位置:文档库 › V4L2readwrite

V4L2readwrite

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "jpeglib.h"


#define OUTPUT_BUF_SIZE 4096
#define CLEAR(x) memset(&(x), 0, sizeof(x))
//#define WIDTH 320
//#define HEIGHT 240
#define WIDTH 720
#define HEIGHT 576

#define FILE_VIDEO "/dev/video0"
#define BMP "./camera.bmp"
#define JPG "./camera.jpg"
typedef struct mybuffer
{
unsigned char start[WIDTH*HEIGHT*2];
unsigned int length;
}ImageBuffer;

struct bufferr {
void *start;
size_t length;
};

typedef struct {
struct jpeg_destination_mgr pub;
JOCTET * buffer;
unsigned char *outbuffer;
int outbuffer_size;
unsigned char *outbuffer_cursor;
int *written;
}mjpg_destination_mgr;

typedef mjpg_destination_mgr *mjpg_dest_ptr;


struct buffer
{
void * start;
unsigned int length;
}*buffers;


int close_camera(int fd)
{
int v_fd;
v_fd = fd;
close(v_fd);
return 0;
}

METHODDEF(void) init_destination(j_compress_ptr cinfo)
{
mjpg_dest_ptr dest =(mjpg_dest_ptr) cinfo->dest;
dest->buffer =(JOCTET *)(*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_IMAGE, OUTPUT_BUF_SIZE*sizeof(JOCTET));
*(dest->written) = 0;
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
}

METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo)
{
mjpg_dest_ptr dest =(mjpg_dest_ptr) cinfo->dest;
memcpy(dest->outbuffer_cursor, dest->buffer, OUTPUT_BUF_SIZE);
dest->outbuffer_cursor += OUTPUT_BUF_SIZE;
*(dest->written) += OUTPUT_BUF_SIZE;
dest->pub.next_output_byte = dest->buffer;
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
return TRUE;
}

METHODDEF(void) term_destination(j_compress_ptr cinfo)
{
mjpg_dest_ptr dest =(mjpg_dest_ptr) cinfo->dest;
size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
memcpy(dest->outbuffer_cursor, dest->buffer, datacount);
dest->outbuffer_cursor += datacount;
*(dest->written) += datacount;
}



void dest_buffer(j_compress_ptr cinfo, unsigned char *buffer, int size, int *written)
{

mjpg_dest_ptr dest;
if(cinfo->dest == NULL)
{
cinfo->dest =(struct jpeg_destination_mgr *)(*cinfo->mem->alloc_small)((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(mjpg_destination_mgr));
}

dest =(mjpg_dest_ptr)cinfo->dest;
dest->pub.init_destination = init_destination;
dest->pub.empty_output_buffer = empty_output_buffer;
dest->pub.term_destination = term_destination;
dest->outbuffer = buffer;
dest->outbuffer_size = size;
dest->outbuffer_cursor = buffer;
dest->written = written;
}

int yuv_jpg(unsigned char *buf, unsigned char *buffer, int size, int quality)
{
st

ruct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer[1];
unsigned char *line_buffer, *yuyv;
int z;
static int written;
line_buffer = calloc(WIDTH * 3, 1);
yuyv = buf;

cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);

dest_buffer(&cinfo, buffer, size, &written);
cinfo.image_width = WIDTH;
cinfo.image_height = HEIGHT;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
z = 0;

while(cinfo.next_scanline < HEIGHT)
{
int x;
unsigned char *ptr = line_buffer;
for(x = 0; x < WIDTH; x++)
{
int r, g, b;
int y, u, v;
if(!z)
y = yuyv[0] << 8;
else
y = yuyv[2] << 8;
u = yuyv[1] - 128;
v = yuyv[3] - 128;
r =(y +(359 * v)) >> 8;
g =(y -(88 * u) -(183 * v)) >> 8;
b =(y +(454 * u)) >> 8;
*(ptr++) =(r > 255) ? 255 :((r < 0) ? 0 : r);
*(ptr++) =(g > 255) ? 255 :((g < 0) ? 0 : g);
*(ptr++) =(b > 255) ? 255 :((b < 0) ? 0 : b);
if(z++)
{
z = 0;
yuyv += 4;
}
}

row_pointer[0] = line_buffer;
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
free(line_buffer);
return(written);
}

int get_camera_jpg(int fd, ImageBuffer *jpg_buf)
{
unsigned char **buffers1;
int bufsize = 1658880;
buffers1=malloc(bufsize);
int fd1 = fd;
if(!buffers1)
{
perror("Can't allocate buffer!\n");
return 1;
}

if((buffers1[0]=malloc(bufsize))==NULL)
{
printf("cant allocate buffer");
return;
}

#if 0
for (;;)
{
fd_set fds;
struct timeval tv;
int r;

FD_ZERO (&fds);
FD_SET (fd1, &fds);

/* Timeout. */
https://www.wendangku.net/doc/665473975.html,_sec = 3;
https://www.wendangku.net/doc/665473975.html,_usec = 0;

r = select (fd + 1, &fds, NULL, NULL, &tv);

if (-1 == r)
{
if (EINTR == errno)
continue;
printf ("select\n");
}

if (0 == r)
{
fprintf (stderr, "select timeout\n");
exit (EXIT_FAILURE);
}
if (read (fd, buffers1[0], bufsize))
{
printf("%d\n",bufsize);
break;
}

}

#endif
sleep(1);
int ret;
ret = read(fd,buffers1[0],10);
printf("ret = %d\n",ret);

jpg_buf->length=yuv_jpg(buffers1[0],jpg_buf->start,(WIDTH*HEIGHT), 80);

free(buffers1[0]);
return 0;

}

int init_camera()
{

struct v4l2_capability cap;
struct v4l2_fmtdesc fmtdesc;
struct v4l2_format fmt;
struct v4l2_streamparm setfps;
struct v4l2_requestbuffers req;
struct v4l2_buffer buf;
enum v4l2_buf_type type;
static unsigned int n_buffers;

int fd;

if ((fd = open(FILE_VIDEO, O_RDWR|O_NONBLOCK ,0)) == -1)
{
printf("Error opening V4L interface\n");
exit(1);
}

CLEAR(cap);
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1)
{
printf("Error opening device %s: unable to query device.\n",FILE_VIDEO);
exit(-1);
}

else
{

printf("driver:\t\t%s\n",cap.driver);
printf("card:\t\t%s\n",cap.card);
printf("bus_info:\t%s\n",cap.bus_info);
printf("version:\t%d\n",cap.version);
printf("capabilities:\t%x\n",cap.capabilities);

if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == V4L2_CAP_VIDEO_CAPTURE)
{
printf("Device %s: supports capture.\n",FILE_VIDEO);
}
if((cap.capabilities & V4L2_CAP_READWRITE )==V4L2_CAP_READWRITE )
{

printf("Device %s: supports I/O\n",FILE_VIDEO);
}
else
printf("is not supports I/O\n",FILE_VIDEO);


if ((cap.capabilities & V4L2_CAP_STREAMING) == V4L2_CAP_STREAMING)
{
printf("Device %s: supports streaming.\n",FILE_VIDEO);
}
}

fmtdesc.index=0;
fmtdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
printf("Support format:\n");
while(ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc)!=-1)
{
printf("\t%d.%s\n",fmtdesc.index+1,fmtdesc.description);
fmtdesc.index++;
}

fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.height = HEIGHT;
fmt.fmt.pix.width = WIDTH;
//sfmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
fmt.fmt.pix.field = V4L2_FIELD_NONE;
if(ioctl(fd, VIDIOC_S_FMT, &fmt) == -1)
{
printf("Unable to set format\n");
exit(-1);
}
if(ioctl(fd, VIDIOC_G_FMT, &fmt) == -1)
{
printf("unable to get format\n");
exit(-1);
}
printf("fmt.type:\t\t%d\n",fmt.type);
printf("pix.pixelformat:\t%c%c%c%c\n",fmt.fmt.pix.pixelformat & 0xFF, (fmt.fmt.pix.pixelformat >> 8) & 0xFF,(fmt.fmt.pix.pixelformat >> 16) & 0xFF, (fmt.fmt.pix.pixelformat >> 24) & 0xFF);
printf("pix.height:\t\t%d\n",fmt.fmt.pix.height);
printf("pix.width:\t\t%d\n",fmt.fmt.pix.width);
printf("pix.field:\t\t%d\n",fmt.fmt.pix.field);
printf("pix.imagesize:\t\t%d\n",fmt.fmt.pix.sizeimage);

printf("start video\n");
fflush(stdout);

sleep(10);
void *buff = malloc(1024 * 1024);
int size = read(fd, buff, 1024 * 1024);
printf("read size is %d\n",size);

int filefd;
filefd = open("./capture.jpg", O_WRONLY|O_CREAT|O_TRUNC,0644);
if(-1 == filefd)
printf("error\n");
write(filefd, buff, 1024*1024);
printf("save jpg ok\n");
return fd;
}

int main(int argc, char **argv)
{
int fd;

fd = init_camera();

ImageBuffer jpg_buf;
int jpg_len = get_camera_jpg(fd,&jpg_buf);

unsigned char jdest[jpg_buf.length+1];
memcpy(jdest, jpg_buf.start, jpg_buf.length);

int jpg_fd = open(JPG,O_WRONLY|O_CREAT|O_TRUNC,0644);
if(0>jpg_fd)
{
perror("open");
return -1;
}
printf("jpg len is %d\n",jpg_buf.length);
write(jpg_fd, jdest, jpg_buf.length);
printf("jpg is ok!\n");
close(jpg_fd);


close_camera(fd);
}

相关文档