Hi,everyone.
I test this code.
................................................................................
..............................
#include <fcntl.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <linux/videodev2.h>
#ifndef V4L2_PIX_FMT_VYUY
#define V4L2_PIX_FMT_VYUY v4l2_fourcc('V','Y','U','Y') /* 16 YUV 4:2:2
*/
#endif
struct image {
unsigned int width;
unsigned int height;
unsigned int bytes_per_line;
unsigned int size;
void *buf;
};
static void perror_exit(const char *str)
{
perror(str);
exit(EXIT_FAILURE);
}
static unsigned char clip(int value)
{
if (value < 0)
value = 0;
else if (value > 255)
value = 255;
return value;
}
static void yuv422_to_rgb(unsigned char *src, unsigned char *dst,
unsigned int nr_pixels)
{
unsigned int i;
int y1, y2, u, v;
for (i = 0; i < nr_pixels; i += 2) {
/* Input format is Cr(i)Y(i + 1)Cb(i)Y(i) */
y2 = *src++;
v = *src++;
y1 = *src++;
u = *src++;
y1 -= 16;
u -= 128;
v -= 128;
y2 -= 16;
*dst++ = clip(( 298 * y1 + 409 * v + 128) >> 8);
*dst++ = clip(( 298 * y1 - 100 * u - 208 * v + 128) >> 8);
*dst++ = clip(( 298 * y1 + 516 * u + 128) >> 8);
*dst++ = clip(( 298 * y2 + 409 * v + 128) >> 8);
*dst++ = clip(( 298 * y2 - 100 * u - 208 * v + 128) >> 8);
*dst++ = clip(( 298 * y2 + 516 * u + 128) >> 8);
}
}
static void dump_frame(int fd, const struct image *image)
{
unsigned char *line_rgb;
unsigned char *line_yuv;
unsigned char *p;
unsigned int nlines = image->height;
unsigned int nbytes;
ssize_t ret;
char ppm_header[256];
line_rgb = malloc(image->width * 3);
line_yuv = image->buf;
sprintf(ppm_header, "P6\n%u %u 255\n", image->width, image->height);
for (nbytes = strlen(ppm_header), p = ppm_header; nbytes;
p += ret, nbytes -= ret) {
ret = write(fd, p, nbytes);
if (ret < 0)
perror_exit("write error");
}
while (nlines--) {
yuv422_to_rgb(line_yuv, line_rgb, image->width);
for (nbytes = image->width * 3, p = line_rgb; nbytes;
p += ret, nbytes -= ret) {
ret = write(fd, p, nbytes);
if (ret < 0)
perror_exit("write error");
}
line_yuv += image->bytes_per_line;
}
free(line_rgb);
}
static void grab_frame(int fd, struct image *image)
{
unsigned int nbytes = image->size;
ssize_t ret;
while (nbytes > 0) {
ret = read(fd, image->buf, nbytes);
if (ret < 0)
perror_exit("read error");
nbytes -= ret;
}
}
static void init_videodev(int fd, struct image *image)
{
struct v4l2_capability cap;
struct v4l2_format fmt;
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0)
perror_exit("VIDIOC_QUERYCAP failed");
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
fprintf(stderr, "No video capture capability present\n");
exit(EXIT_FAILURE);
}
if (!(cap.capabilities & V4L2_CAP_READWRITE)) {
fprintf(stderr, "read() interface not supported by driver\n");
exit(EXIT_FAILURE);
}
/* Select video format */
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 320;
fmt.fmt.pix.height = 240;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_VYUY;
if (ioctl(fd, VIDIOC_S_FMT, &fmt))
perror_exit("VIDIOC_S_FMT failed");
image->width = fmt.fmt.pix.width;
image->height = fmt.fmt.pix.height;
image->bytes_per_line = fmt.fmt.pix.bytesperline;
image->size = fmt.fmt.pix.sizeimage;
image->buf = malloc(image->size);
if (!image->buf) {
fprintf(stderr, "Out of memory\n");
exit(EXIT_FAILURE);
}
}
static void show_usage(const char *progname)
{
fprintf(stderr, "Usage: %s [-d videodev] [-o outfile]\n\n",
progname);
fprintf(stderr,
"If no options are given, one frame is grabbed from\n"
"/dev/video0 and written to stdout in PPM format.\n");
}
int main(int argc, char **argv)
{
struct image image;
char *input_name = "/dev/video0";
char *output_name = NULL;
int infd, outfd;
while (1) {
int c;
c = getopt(argc, argv, "d:ho:");
if (c == -1)
break;
switch (c) {
case 'd':
input_name = strdup(optarg);
break;
case 'o':
output_name = strdup(optarg);
break;
case 'h':
case '?':
show_usage(argv[0]);
return EXIT_FAILURE;
default:
abort();
}
}
infd = open(input_name, O_RDONLY);
if (infd < 0) {
perror("Failed to open video device");
return EXIT_FAILURE;
}
outfd = STDOUT_FILENO;
if (output_name) {
outfd = open(output_name, O_WRONLY | O_CREAT | O_TRUNC,
0666);
if (outfd < 0) {
perror("Failed to open output file");
return EXIT_FAILURE;
}
}
init_videodev(infd, &image);
grab_frame(infd, &image);
dump_frame(outfd, &image);
return EXIT_SUCCESS;
}
I have some problem
It not video0 in mini2440.
how to compile this kernel.
thank you .
cmos camara
Hi, The CMOS don't have native video4linux driver, so you can access directly or use an alternative v4l CMOS driver : - Directly see sample there http://www.friendlyarm.net/dl.php?file=linux-examples.tgz - Experimental S3C2440 camera interface linux kernel driver : http://code.google.com/p/mjpg-streamer-mini2440/


