Lines 47-53
Link Here
|
47 |
and Copyright (C) 1999-2002, Torrey Searle <tsearle@uci.edu> |
47 |
and Copyright (C) 1999-2002, Torrey Searle <tsearle@uci.edu> |
48 |
*/ |
48 |
*/ |
49 |
|
49 |
|
50 |
# include "gyacheupload.h" |
50 |
#ifdef HAVE_CONFIG_H |
|
|
51 |
# include "config.h" |
52 |
#endif |
53 |
|
54 |
#include "gyacheupload.h" |
51 |
|
55 |
|
52 |
/* ******************************* */ |
56 |
/* ******************************* */ |
53 |
/* PATCHES BELOW for webcams with OV519 sensors and |
57 |
/* PATCHES BELOW for webcams with OV519 sensors and |
Lines 71-77
Link Here
|
71 |
/* Uncomment the line below to enable contributed but UNTESTED patch to support |
75 |
/* Uncomment the line below to enable contributed but UNTESTED patch to support |
72 |
cameras with OV519 chips - includes double-buffering support */ |
76 |
cameras with OV519 chips - includes double-buffering support */ |
73 |
|
77 |
|
74 |
/* #define USE_VIDEO_OV519 1 */ |
78 |
#define USE_MULTICAM_SUPPORT 1 |
75 |
|
79 |
|
76 |
|
80 |
|
77 |
/* Uncomment the following definition to enable the use of the |
81 |
/* Uncomment the following definition to enable the use of the |
Lines 81-90
Link Here
|
81 |
* modify the definitions of INCLUDE and gyach_LDADD in the Makefile |
85 |
* modify the definitions of INCLUDE and gyach_LDADD in the Makefile |
82 |
* to refer to the ccvt source and built libraries. |
86 |
* to refer to the ccvt source and built libraries. |
83 |
*/ |
87 |
*/ |
84 |
/* #define USE_CCVT 1 */ |
|
|
85 |
|
88 |
|
86 |
#ifdef USE_CCVT |
89 |
/* NC: should be detected automatically from ./configure */ |
87 |
#include "ccvt.h" |
90 |
|
|
|
91 |
/* #define HAVE_LIBCCVT 1 */ |
92 |
|
93 |
#ifdef HAVE_LIBCCVT |
94 |
# include "ccvt.h" |
88 |
#endif |
95 |
#endif |
89 |
|
96 |
|
90 |
int exit_on_error=0; |
97 |
int exit_on_error=0; |
Lines 95-101
Link Here
|
95 |
struct video_capability grab_cap; |
102 |
struct video_capability grab_cap; |
96 |
struct video_mmap grab_buf; |
103 |
struct video_mmap grab_buf; |
97 |
|
104 |
|
98 |
#ifdef USE_VIDEO_OV519 |
105 |
#ifdef USE_MULTICAM_SUPPORT |
99 |
static struct video_mbuf mbuf; |
106 |
static struct video_mbuf mbuf; |
100 |
#endif |
107 |
#endif |
101 |
|
108 |
|
Lines 105-123
Link Here
|
105 |
int pnm_size; |
112 |
int pnm_size; |
106 |
unsigned char *rgb_buf; |
113 |
unsigned char *rgb_buf; |
107 |
|
114 |
|
|
|
115 |
static char webcamrc_path[256]; |
108 |
extern int app_debugger; |
116 |
extern int app_debugger; |
109 |
|
117 |
|
110 |
/* Hard-coding my own favorite cam settings into here... |
|
|
111 |
everybody else can update theirs from the config window */ |
112 |
|
113 |
int fix_color=0; |
118 |
int fix_color=0; |
|
|
119 |
int skip_rgb24 = 0; |
114 |
|
120 |
|
115 |
|
121 |
/* #ifdef USE_MULTICAM_SUPPORT |
116 |
#ifdef USE_VIDEO_OV519 |
|
|
117 |
int hue=32767, contrast=32767, brightness=32767, colour=32767; |
122 |
int hue=32767, contrast=32767, brightness=32767, colour=32767; |
118 |
#else |
123 |
#else */ |
119 |
int hue=47104, contrast=65280, brightness=65280, colour=17152; |
124 |
int hue=47104, contrast=65280, brightness=65280, colour=17152; |
120 |
#endif |
125 |
/* #endif */ |
|
|
126 |
|
127 |
#define dir_exists(x) (access((x), R_OK) == 0) |
121 |
|
128 |
|
122 |
unsigned char* grab_one(int *, int *); |
129 |
unsigned char* grab_one(int *, int *); |
123 |
int grab_init(); |
130 |
int grab_init(); |
Lines 183-195
Link Here
|
183 |
return; |
190 |
return; |
184 |
} |
191 |
} |
185 |
|
192 |
|
186 |
|
|
|
187 |
#ifdef USE_VIDEO_OV519 |
188 |
current_pixbuf=gdk_pixbuf_new_from_data(grabit,GDK_COLORSPACE_RGB,FALSE,8,x,y,x*grab_pic.depth/8,NULL,NULL); |
193 |
current_pixbuf=gdk_pixbuf_new_from_data(grabit,GDK_COLORSPACE_RGB,FALSE,8,x,y,x*grab_pic.depth/8,NULL,NULL); |
189 |
#else |
|
|
190 |
current_pixbuf=gdk_pixbuf_new_from_data(grabit,GDK_COLORSPACE_RGB,FALSE,8,320,240,320*grab_pic.depth/8,NULL,NULL); |
191 |
#endif |
192 |
|
193 |
|
194 |
|
194 |
gtk_image_set_from_pixbuf(GTK_IMAGE(current_image), current_pixbuf); |
195 |
gtk_image_set_from_pixbuf(GTK_IMAGE(current_image), current_pixbuf); |
195 |
gdk_pixbuf_unref(current_pixbuf); |
196 |
gdk_pixbuf_unref(current_pixbuf); |
Lines 242-263
Link Here
|
242 |
if (brightness > -1) grab_pic.brightness=brightness; |
243 |
if (brightness > -1) grab_pic.brightness=brightness; |
243 |
if (colour > -1) grab_pic.colour=colour; |
244 |
if (colour > -1) grab_pic.colour=colour; |
244 |
|
245 |
|
245 |
#ifdef USE_VIDEO_OV519 |
246 |
/* first we try RGB24 */ |
246 |
/* hardcoded... */ |
|
|
247 |
grab_pic.depth = 24; |
247 |
grab_pic.depth = 24; |
248 |
grab_pic.palette = VIDEO_PALETTE_RGB24; |
248 |
grab_pic.palette = VIDEO_PALETTE_RGB24; |
249 |
#endif |
249 |
if (ioctl(grab_fd, VIDIOCSPICT, &grab_pic) < 0 || skip_rgb24) { |
|
|
250 |
/* RGB24 not supported we try YUV420P */ |
251 |
grab_pic.palette = VIDEO_PALETTE_YUV420P; |
252 |
if (ioctl(grab_fd, VIDIOCSPICT, &grab_pic) < 0) { |
253 |
/* try other palettes here... */ |
254 |
} else return; |
255 |
} else return; |
250 |
|
256 |
|
251 |
if (ioctl(grab_fd, VIDIOCSPICT, &grab_pic) == -1) { |
|
|
252 |
show_error_dialog("An error occurred at 'ioctl VIDIOCSPICT'.\nCould not set camera properties."); |
257 |
show_error_dialog("An error occurred at 'ioctl VIDIOCSPICT'.\nCould not set camera properties."); |
253 |
return; |
|
|
254 |
} |
255 |
} |
258 |
} |
256 |
|
259 |
|
257 |
void set_video_device(char *myvdev) { |
260 |
void set_video_device(char *myvdev) { |
258 |
v_device=strdup(myvdev); |
261 |
v_device=strdup(myvdev); |
259 |
} |
262 |
} |
260 |
|
263 |
|
|
|
264 |
/* read webcamrc configuration file */ |
265 |
void read_webcamrc () { |
266 |
FILE *f; |
267 |
char line[256]; |
268 |
|
269 |
snprintf(webcamrc_path, sizeof(webcamrc_path), |
270 |
"%s/.yahoorc/gyach/webcamrc", getenv("HOME")); |
271 |
|
272 |
if ((f = fopen(webcamrc_path, "r")) == NULL) { |
273 |
/* noconfig available */ |
274 |
return; |
275 |
} |
276 |
while (fgets(line, sizeof(line), f)) { |
277 |
char *p, *key, *value; |
278 |
/* strip comments */ |
279 |
if ((p = strchr(line, '#'))) *p = '\0'; |
280 |
if ( (key = strtok(line, "=")) && (value = strtok(NULL, "\n"))) { |
281 |
if (strcmp(key,"width")==0) |
282 |
x = atoi(value); |
283 |
|
284 |
else if (strcmp(key,"height") == 0) |
285 |
y = atoi(value); |
286 |
|
287 |
else if (strcmp(key, "fix_color") == 0) |
288 |
fix_color = atoi(value); |
289 |
|
290 |
else if (strcmp(key, "hue") == 0) |
291 |
hue = atoi(value); |
292 |
|
293 |
else if (strcmp(key, "contrast") == 0) |
294 |
contrast = atoi(value); |
295 |
|
296 |
else if (strcmp(key, "brightness") == 0) |
297 |
brightness = atoi(value); |
298 |
|
299 |
else if (strcmp(key, "colour") == 0) |
300 |
colour = atoi(value); |
301 |
|
302 |
else if (strcmp(key, "skip_rgb24") == 0) |
303 |
skip_rgb24 = atoi(value); |
304 |
|
305 |
} else { |
306 |
fprintf(stderr, "Problems in %s\n", webcamrc_path); |
307 |
} |
308 |
} |
309 |
fclose(f); |
310 |
} |
311 |
|
312 |
void write_webcamrc() { |
313 |
FILE *f; |
314 |
|
315 |
/* create ~/.yahoorc/gyach dir if it does not exist (it should) */ |
316 |
snprintf(webcamrc_path, sizeof(webcamrc_path), "%s/.yahoorc", |
317 |
getenv("HOME")); |
318 |
if (!dir_exists(webcamrc_path)) |
319 |
mkdir(webcamrc_path, 0700); |
320 |
|
321 |
snprintf(webcamrc_path, sizeof(webcamrc_path), "%s/.yahoorc/gyach", |
322 |
getenv("HOME")); |
323 |
if (!dir_exists(webcamrc_path)) |
324 |
mkdir(webcamrc_path, 0700); |
325 |
|
326 |
snprintf(webcamrc_path, sizeof(webcamrc_path), |
327 |
"%s/.yahoorc/gyach/webcamrc", getenv("HOME")); |
328 |
|
329 |
if ((f = fopen(webcamrc_path, "w")) == NULL) { |
330 |
fprintf(stderr, "Problems when writing configuration to %s\n", |
331 |
webcamrc_path); |
332 |
return; |
333 |
} |
334 |
fprintf(f, "width=%i\n" |
335 |
"height=%i\n" |
336 |
"fix_color=%i\n" |
337 |
"hue=%i\n" |
338 |
"contrast=%i\n" |
339 |
"brightness=%i\n" |
340 |
"colour=%i\n" |
341 |
"skip_rgb24=%i\n", |
342 |
x, y, fix_color, hue, contrast, brightness, colour, skip_rgb24); |
343 |
fclose(f); |
344 |
} |
345 |
|
346 |
|
261 |
void init_cam () { |
347 |
void init_cam () { |
262 |
signal (SIGINT, _sighandler); |
348 |
signal (SIGINT, _sighandler); |
263 |
if (!v_device) { |
349 |
if (!v_device) { |
Lines 268-279
Link Here
|
268 |
show_error_dialog("No Video4Linux device was specified."); |
354 |
show_error_dialog("No Video4Linux device was specified."); |
269 |
return; |
355 |
return; |
270 |
} |
356 |
} |
|
|
357 |
read_webcamrc(); |
271 |
grab_init(); |
358 |
grab_init(); |
272 |
set_picture(); |
359 |
set_picture(); |
273 |
} |
360 |
} |
274 |
|
361 |
|
275 |
|
362 |
|
276 |
#ifdef USE_VIDEO_OV519 |
363 |
#ifdef USE_MULTICAM_SUPPORT |
277 |
int grab_init() { |
364 |
int grab_init() { |
278 |
if ((grab_fd = open(v_device,O_RDWR)) == -1 ) { |
365 |
if ((grab_fd = open(v_device,O_RDWR)) == -1 ) { |
279 |
show_error_dialog("Could not open Video4Linux device.\nThe device may already be in use."); |
366 |
show_error_dialog("Could not open Video4Linux device.\nThe device may already be in use."); |
Lines 283-320
Link Here
|
283 |
show_error_dialog("An error occurred at 'ioctl VIDIOCGCAP'.\nWrong device."); |
370 |
show_error_dialog("An error occurred at 'ioctl VIDIOCGCAP'.\nWrong device."); |
284 |
return 0; |
371 |
return 0; |
285 |
} |
372 |
} |
|
|
373 |
if (!(grab_cap.type & VID_TYPE_CAPTURE)) { |
374 |
show_error_dialog("Fatal: grab device does not handle capture\n"); |
375 |
return 0; |
376 |
} |
377 |
|
286 |
memset (&grab_pic, 0, sizeof(struct video_picture)); |
378 |
memset (&grab_pic, 0, sizeof(struct video_picture)); |
287 |
snprintf(webcam_description, 3, "%s", ""); |
379 |
memset(webcam_description, '\0', sizeof(webcam_description)); |
288 |
strncpy(webcam_description, grab_cap.name ,28); |
380 |
snprintf(webcam_description, sizeof(webcam_description), "%s %s", |
289 |
strcat(webcam_description, " V4L1"); |
381 |
grab_cap.name, " V4L1"); |
|
|
382 |
|
290 |
if (ioctl (grab_fd, VIDIOCGPICT, &grab_pic) == -1) { |
383 |
if (ioctl (grab_fd, VIDIOCGPICT, &grab_pic) == -1) { |
291 |
show_error_dialog("An error occurred at 'ioctl VIDIOCGPICT'."); |
384 |
show_error_dialog("An error occurred at 'ioctl VIDIOCGPICT'."); |
292 |
return 0; |
385 |
return 0; |
293 |
} |
386 |
} |
294 |
|
387 |
|
295 |
|
|
|
296 |
/* The line below cannot work: we must force use of RGB24 for |
297 |
PNM image creation */ |
298 |
/* grab_buf.format=grab_pic.palette; */ |
299 |
|
300 |
/* A V4L device supporting the VIDEO_PALETTE_RGB24 |
301 |
( 24bit RGB) color palette is REQUIRED, Gdk-Pixbuf |
302 |
can only handle RGB Color spaces, so no support for |
303 |
greyscale palettes or cams using non-standard, weirdo palettes |
304 |
at this time */ |
305 |
|
306 |
grab_buf.format = VIDEO_PALETTE_RGB24; |
307 |
grab_buf.frame = 0; |
308 |
grab_buf.width = x; |
309 |
grab_buf.height = y; |
310 |
grab_size = x * y * w; |
311 |
set_picture(); |
312 |
|
313 |
if (ioctl (grab_fd, VIDIOCGMBUF, &mbuf) < 0) { |
388 |
if (ioctl (grab_fd, VIDIOCGMBUF, &mbuf) < 0) { |
314 |
show_error_dialog("An error occurred at 'ioctl VIDIOCGMBUF'."); |
389 |
show_error_dialog("An error occurred at 'ioctl VIDIOCGMBUF'."); |
315 |
return 0; |
390 |
return 0; |
316 |
} |
391 |
} |
317 |
printf("frames per capture: %i\n", mbuf.frames); |
|
|
318 |
if ((grab_data = mmap(0, mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, |
392 |
if ((grab_data = mmap(0, mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, |
319 |
grab_fd,0)) == MAP_FAILED) { |
393 |
grab_fd,0)) == MAP_FAILED) { |
320 |
perror("mmap"); |
394 |
perror("mmap"); |
Lines 322-334
Link Here
|
322 |
return 0; |
396 |
return 0; |
323 |
} |
397 |
} |
324 |
|
398 |
|
|
|
399 |
grab_buf.frame = 0; |
400 |
grab_buf.width = x; |
401 |
grab_buf.height = y; |
402 |
grab_size = x * y * w; |
403 |
set_picture(); |
404 |
|
325 |
/* grab first frame */ |
405 |
/* grab first frame */ |
|
|
406 |
grab_buf.format = VIDEO_PALETTE_RGB24; |
407 |
if (ioctl(grab_fd,VIDIOCMCAPTURE,&grab_buf) <0 || skip_rgb24) { |
408 |
/* some cam's don't support grabbing RBG24. try YUV420P */ |
409 |
grab_buf.format = VIDEO_PALETTE_YUV420P; |
410 |
if (-1 == ioctl(grab_fd,VIDIOCMCAPTURE,&grab_buf)) { |
411 |
#ifdef HAVE_LIBCCVT |
412 |
/* try YUV422 before we give up if we have CCVT */ |
413 |
/* grab_buf.format = VIDEO_PALETTE_YUV422; |
326 |
if (-1 == ioctl(grab_fd,VIDIOCMCAPTURE,&grab_buf)) { |
414 |
if (-1 == ioctl(grab_fd,VIDIOCMCAPTURE,&grab_buf)) { |
327 |
show_error_dialog("An error occurred at 'ioctl VIDIOCMCAPTURE'."); |
415 |
show_error_dialog("An error occurred at 'ioctl VIDIOCMCAPTURE'."); |
328 |
return 0; |
416 |
return 0; |
329 |
} |
417 |
} |
|
|
418 |
*/ |
419 |
#else |
420 |
show_error_dialog("An error occurred at 'ioctl VIDIOCMCAPTURE'."); |
421 |
return 0; |
422 |
#endif |
423 |
} |
424 |
} |
330 |
if (mbuf.frames > 1) grab_buf.frame = 1 - grab_buf.frame; |
425 |
if (mbuf.frames > 1) grab_buf.frame = 1 - grab_buf.frame; |
331 |
|
426 |
init_pnm_buf(); |
332 |
return(1); |
427 |
return(1); |
333 |
} |
428 |
} |
334 |
|
429 |
|
Lines 384-392
Link Here
|
384 |
brightness=tbrightness; |
479 |
brightness=tbrightness; |
385 |
fix_color=tfc; |
480 |
fix_color=tfc; |
386 |
set_picture(); |
481 |
set_picture(); |
|
|
482 |
write_webcamrc(); |
387 |
} |
483 |
} |
388 |
|
484 |
|
389 |
#ifndef USE_CCVT |
485 |
#ifndef HAVE_LIBCCVT |
390 |
|
486 |
|
391 |
/* The following conversion routines were taken from drivers/usb/ov511.c |
487 |
/* The following conversion routines were taken from drivers/usb/ov511.c |
392 |
* in the Mandrake Linux 2.4.21 kernel. |
488 |
* in the Mandrake Linux 2.4.21 kernel. |
Lines 495-507
Link Here
|
495 |
} |
591 |
} |
496 |
} |
592 |
} |
497 |
|
593 |
|
498 |
#endif /* !USE_CCVT */ |
594 |
#endif /* !HAVE_LIBCCVT */ |
499 |
|
595 |
|
500 |
|
596 |
|
501 |
|
597 |
|
502 |
#ifdef USE_VIDEO_OV519 |
598 |
#ifdef USE_MULTICAM_SUPPORT |
503 |
|
599 |
|
504 |
unsigned char* grab_one(int *width, int *height) { |
600 |
unsigned char* grab_one(int *width, int *height) { |
|
|
601 |
char *frame_buf; |
505 |
set_picture(); |
602 |
set_picture(); |
506 |
|
603 |
|
507 |
if (-1 == ioctl(grab_fd,VIDIOCMCAPTURE,&grab_buf)) { |
604 |
if (-1 == ioctl(grab_fd,VIDIOCMCAPTURE,&grab_buf)) { |
Lines 509-523
Link Here
|
509 |
return NULL; |
606 |
return NULL; |
510 |
} |
607 |
} |
511 |
|
608 |
|
|
|
609 |
/* switch frame if cam support double buf */ |
512 |
if (mbuf.frames > 1) grab_buf.frame = 1 - grab_buf.frame; |
610 |
if (mbuf.frames > 1) grab_buf.frame = 1 - grab_buf.frame; |
|
|
611 |
// if (mbuf.frames > 1) grab_buf.frame = 1 - grab_buf.frame; |
513 |
if (-1 == ioctl(grab_fd,VIDIOCSYNC,&grab_buf)) { |
612 |
if (-1 == ioctl(grab_fd,VIDIOCSYNC,&grab_buf)) { |
514 |
show_error_dialog("An error occurred at 'ioctl VIDIOCSYNC'."); |
613 |
show_error_dialog("An error occurred at 'ioctl VIDIOCSYNC'."); |
515 |
return NULL; |
614 |
return NULL; |
516 |
} |
615 |
} |
517 |
if (fix_color) {fix_colour(grab_data + mbuf.offsets[grab_buf.frame], x, y); } |
616 |
|
|
|
617 |
frame_buf = grab_data + mbuf.offsets[grab_buf.frame]; |
518 |
*width = grab_buf.width; |
618 |
*width = grab_buf.width; |
519 |
*height = grab_buf.height; |
619 |
*height = grab_buf.height; |
520 |
return grab_data + mbuf.offsets[grab_buf.frame]; |
620 |
|
|
|
621 |
#ifdef HAVE_LIBCCVT |
622 |
switch (grab_buf.format) { |
623 |
/* if we have ccvt we must check the yuyv converting also */ |
624 |
|
625 |
/* |
626 |
case VIDEO_PALETTE_YUV422: { |
627 |
if (fix_color) |
628 |
ccvt_yuyv_bgr24(*width, *height, frame_buf, rgb_buf); |
629 |
else |
630 |
ccvt_yuyv_rgb24(*width, *height, frame_buf, rgb_buf); |
631 |
break; |
632 |
} |
633 |
*/ |
634 |
case VIDEO_PALETTE_YUV420P: { |
635 |
/* let ccvt do the bgr->rgb convertion */ |
636 |
if (fix_color) |
637 |
ccvt_420p_bgr24(*width, *height, frame_buf, rgb_buf); |
638 |
else |
639 |
ccvt_420p_rgb24(*width, *height, frame_buf, rgb_buf); |
640 |
return rgb_buf; |
641 |
} |
642 |
|
643 |
case VIDEO_PALETTE_RGB24: { |
644 |
if (fix_color) fix_colour(frame_buf, x, y); |
645 |
return frame_buf; |
646 |
} |
647 |
default: { |
648 |
printf("oups...\n"); |
649 |
return NULL; |
650 |
} |
651 |
} /* switch */ |
652 |
|
653 |
#else /* HAVE_LIBCCVT */ |
654 |
|
655 |
switch (grab_buf.format) { |
656 |
case VIDEO_PALETTE_YUV420P: { |
657 |
yuv420p_to_rgb(frame_buf, rgb_buf, 24); |
658 |
if (fix_color) fix_colour(rgb_buf, x, y); |
659 |
break; |
660 |
} |
661 |
case VIDEO_PALETTE_RGB24: { |
662 |
if (fix_color) fix_colour(frame_buf, x, y); |
663 |
return frame_buf; |
664 |
} |
665 |
default: { |
666 |
printf("oups...\n"); |
667 |
return NULL; |
668 |
} |
669 |
|
670 |
} /* switch */ |
671 |
|
672 |
#endif /* HAVE_LIBCCVT */ |
673 |
|
674 |
return rgb_buf; |
521 |
} |
675 |
} |
522 |
|
676 |
|
523 |
#else |
677 |
#else |
Lines 529-534
Link Here
|
529 |
set_picture(); |
683 |
set_picture(); |
530 |
|
684 |
|
531 |
for (;;) { |
685 |
for (;;) { |
|
|
686 |
grab_buf.format = VIDEO_PALETTE_RGB24; |
532 |
ret = ioctl(grab_fd,VIDIOCMCAPTURE,&grab_buf); |
687 |
ret = ioctl(grab_fd,VIDIOCMCAPTURE,&grab_buf); |
533 |
if (ret == -1) { |
688 |
if (ret == -1) { |
534 |
/* Some drivers (such as pwc) don't support capturing |
689 |
/* Some drivers (such as pwc) don't support capturing |
Lines 553-559
Link Here
|
553 |
*height = grab_buf.height; |
708 |
*height = grab_buf.height; |
554 |
if (grab_buf.format == VIDEO_PALETTE_YUV420P) { |
709 |
if (grab_buf.format == VIDEO_PALETTE_YUV420P) { |
555 |
/* Convert from YUV420P to RGB24. */ |
710 |
/* Convert from YUV420P to RGB24. */ |
556 |
#ifdef USE_CCVT |
711 |
#ifdef HAVE_LIBCCVT |
557 |
ccvt_420p_rgb24(grab_buf.width, |
712 |
ccvt_420p_rgb24(grab_buf.width, |
558 |
grab_buf.height, |
713 |
grab_buf.height, |
559 |
grab_data, |
714 |
grab_data, |