00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <sys/time.h>
00026 #include <sys/mman.h>
00027 #include <sys/ioctl.h>
00028 #include <errno.h>
00029 #include <stdio.h>
00030
00031 #include <player/error.h>
00032
00033
00034 #include "v4l2capture.h"
00035
00036 #include <string.h>
00037 #include <math.h>
00038
00039
00040
00041
00042
00043
00044
00045
00046 #define FREE_ME(x) if (x) free(x); x = NULL;
00047 #define CLEAR(x) memset(&x, 0, sizeof(x))
00048
00049
00050 #define PERROR(str_err) PLAYER_ERROR2("%s: %s", (str_err), strerror(errno))
00051
00052
00054 static int discover_inputs(FRAMEGRABBER2* fg);
00055
00057 static void printControl(struct v4l2_queryctrl *queryctrl);
00058
00060 static int discover_controls(FRAMEGRABBER2* fg);
00061
00063 static void getPixelFormat(FRAMEGRABBER2 *fg);
00064
00066 static int usePixelFormat(FRAMEGRABBER2 *fg);
00067
00069 static int assignMBufs(FRAMEGRABBER2 *fg);
00070
00072 static void releaseMBufs(FRAMEGRABBER2* fg);
00073
00075 static void wyczyscStan(FRAMEGRABBER2* fg);
00076
00078 static void fg2_close(FRAMEGRABBER2* fg);
00079
00080
00081
00082
00083
00084
00085
00090 FRAMEGRABBER2* fg2_createFrameGrabber()
00091 {
00092 FRAMEGRABBER2* fg = (FRAMEGRABBER2*)malloc( sizeof( FRAMEGRABBER2 ) );
00093
00094 fg->device = 0;
00095 fg->fd = -1;
00096
00097 fg->numOfIn = 0;
00098 fg->sources = 0;
00099 fg->source = 0;
00100
00101 fg->numOfCtls = 0;
00102 fg->controls = 0;
00103
00104 fg->buffers = 0;
00105 fg->n_buffers = 0;
00106
00107 fg->isCapturing = 0;
00108 fg->pix_fmt = V4L2_PIX_FMT_RGB24;
00109 fg->width = 640;
00110 fg->height = 480;
00111 fg->field = V4L2_FIELD_ANY;
00112 fg->altField = V4L2_FIELD_TOP;
00113
00114 fg->cur_frame=-1;
00115
00116
00117 return fg;
00118 }
00119
00120
00121
00126 void fg2_delete(FRAMEGRABBER2** fg)
00127 {
00128 fg2_close(*fg);
00129 FREE_ME(*fg);
00130 }
00131
00132
00140 int fg2_open( FRAMEGRABBER2* fg, const char *dev)
00141 {
00142
00143 if (fg->device) {
00144 PLAYER_WARN("Device already opened?");
00145 }
00146
00147
00148 if ( dev != NULL )
00149 {
00150 fg->device = strdup( dev );
00151 }
00152 else
00153 {
00154 fg->device = strdup( FG_DEFAULT_DEVICE );
00155 }
00156
00157
00158 fg->fd = open( fg->device, O_RDWR );
00159 if ( fg->fd == -1 )
00160 {
00161 PERROR( "fg2_open(): open video device failed" );
00162 free( fg->device );
00163 fg->device = 0;
00164
00165 return -1;
00166 }
00167 PLAYER_MSG0(2,"opened v4l2 device");
00168
00169
00170 fcntl( fg->fd, F_SETFD, FD_CLOEXEC );
00171
00172
00173 fg->cur_frame = -1;
00174
00175
00176 if( ioctl( fg->fd, VIDIOC_QUERYCAP, &(fg->caps) ) < 0 )
00177 {
00178 PERROR( "fg2_open(): query capabilities failed" );
00179 fg2_close(fg);
00180
00181 return -1;
00182 }
00183
00184 if( ! (fg->caps.capabilities && V4L2_CAP_VIDEO_CAPTURE) ){
00185 PLAYER_ERROR("V4L2_CAP_VIDEO_CAPTURE not supported");
00186 fg2_close(fg);
00187 return -1;
00188 }
00189 if( ! (fg->caps.capabilities && V4L2_CAP_STREAMING) ){
00190 PLAYER_ERROR("V4L2_CAP_STREAMING not supported");
00191 fg2_close(fg);
00192 return -1;
00193 }
00194 PLAYER_MSG2(1,"Found %s card with %s v4l2 driver", fg->caps.card, fg->caps.driver);
00195
00196
00197
00198 discover_inputs(fg);
00199 if (fg->numOfIn<=0){
00200 PLAYER_ERROR("No Inputs found");
00201 fg2_close(fg);
00202 return -1;
00203 }
00204
00205 return 0;
00206 }
00207
00208
00209
00210
00211
00212
00217 int fg2_startCapture(FRAMEGRABBER2* fg)
00218 {
00219 unsigned int i;
00220 enum v4l2_buf_type type;
00221
00222 if (fg->isCapturing) {
00223 PLAYER_WARN("Already capturing");
00224 return -1;
00225 }
00226
00227
00228 PLAYER_MSG0(2,"Assigning buffers");
00229 if (assignMBufs(fg)!=0){
00230 PERROR( "fg2_startCapture(): assignMBufs" );
00231 return -1;
00232 }
00233
00234 PLAYER_MSG0(2,"Adding buffers to dirver Queue");
00235 for (i = 0; i < fg->n_buffers; ++i)
00236 {
00237 struct v4l2_buffer buf;
00238
00239 CLEAR (buf);
00240
00241 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00242 buf.memory = V4L2_MEMORY_MMAP;
00243 buf.index = i;
00244
00245 if (-1 == ioctl (fg->fd, VIDIOC_QBUF, &buf)) {
00246 PERROR("VIDIOC_QBUF");
00247 return -1;
00248 }
00249 }
00250
00251 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00252
00253 PLAYER_MSG0(2,"Turning streaming on");
00254 if (-1 == ioctl (fg->fd, VIDIOC_STREAMON, &type)) {
00255 PERROR ("VIDIOC_STREAMON");
00256 return -1;
00257 }
00258 fg->isCapturing = 1;
00259 PLAYER_MSG0(0,"Capturing started");
00260 return 0;
00261 }
00262
00268 int fg2_stopCapture(FRAMEGRABBER2* fg)
00269 {
00270 enum v4l2_buf_type type;
00271
00272 PLAYER_MSG0(2,"stopping capturing");
00273 if (!fg->isCapturing){
00274 PLAYER_WARN("Capturing not started yet");
00275 return -1;
00276 }
00277 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00278
00279
00280 PLAYER_MSG0(2,"stopping streaminfg");
00281 if (-1 == ioctl (fg->fd, VIDIOC_STREAMOFF, &type)) {
00282 PERROR ("VIDIOC_STREAMOFF");
00283
00284 }
00285 PLAYER_MSG0(2,"Releasing buffers");
00286 releaseMBufs(fg);
00287 PLAYER_MSG0(0,"capture stopped");
00288 fg->isCapturing = 0;
00289 return 0;
00290 }
00291
00292
00293
00300 struct my_buffer *getFrameBuffer( FRAMEGRABBER2* fg )
00301 {
00302 static struct v4l2_buffer buf;
00303 int rv;
00304
00305
00306 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00307 buf.memory = V4L2_MEMORY_MMAP;
00308 buf.field = fg->altField;
00309 if (buf.field == V4L2_FIELD_TOP)
00310 buf.field = V4L2_FIELD_BOTTOM;
00311 else
00312 buf.field = V4L2_FIELD_TOP;
00313
00314 rv = ioctl(fg->fd, VIDIOC_DQBUF, &buf);
00315 if (rv==-1)
00316 {
00317 switch (errno)
00318 {
00319 case EAGAIN:
00320 PERROR("VIDIOC_DQBUF, eagain");
00321 return NULL;
00322 default:
00323 PERROR("VIDIOC_DQBUF");
00324 return NULL;
00325 }
00326 }
00327
00328 if (buf.index >= fg->n_buffers) {
00329 PLAYER_ERROR2("Something wrong: buf.index(%d) >= n_buffers(%d)", buf.index, fg->n_buffers);
00330 if (-1 == ioctl (fg->fd, VIDIOC_QBUF, &buf)) {
00331 PERROR("VIDIOC_QBUF");
00332 }
00333 return NULL;
00334 }
00335
00336 fg->buffers[buf.index].buf = &buf;
00337
00338 return fg->buffers + buf.index;
00339 }
00340
00341
00347 void giveBackFrameBuffer( FRAMEGRABBER2* fg, struct my_buffer *mBuff)
00348 {
00349 if (mBuff==NULL)
00350 return;
00351 if (-1 == ioctl (fg->fd, VIDIOC_QBUF, mBuff->buf)) {
00352 PERROR("VIDIOC_QBUF");
00353 }
00354 }
00355
00356
00357
00358
00359
00360
00364 int fg2_get_source_count( FRAMEGRABBER2* fg )
00365 {
00366 return fg->numOfIn;
00367 }
00368
00372 int fg2_get_source_id( FRAMEGRABBER2* fg)
00373 {
00374 int out=0;
00375
00376 if ( ioctl( fg->fd, VIDIOC_G_INPUT, &out ) < 0 )
00377 {
00378 PERROR( "fg2_get_source_id(): VIDIOC_G_INPUT failed" );
00379 return -1;
00380 }
00381 return out;
00382 }
00383
00387 const char* fg2_get_source_name( FRAMEGRABBER2* fg)
00388 {
00389 return fg2_get_id_source_name(fg, fg2_get_source_id(fg));
00390 }
00391
00395 const char* fg2_get_id_source_name( FRAMEGRABBER2* fg, int src )
00396 {
00397 if ( src<0 || (unsigned int)src > fg->numOfIn )
00398 {
00399 PLAYER_ERROR("fg2_get_source_name(): Invalid src number!" );
00400 return NULL;
00401 }
00402
00403 return (const char *)fg->sources[src].name;
00404 }
00405
00409 const char * fg2_get_device_name( FRAMEGRABBER2* fg )
00410 {
00411 return (const char *)(fg->caps.card);
00412 }
00413
00419 int fg2_set_source( FRAMEGRABBER2* fg, int srcNo, const char *strSrc )
00420 {
00421 if (srcNo<0) {
00422 PLAYER_MSG1(1,"\t\tSetting SourceS: %s", strSrc);
00423 if (strSrc==NULL)
00424 srcNo=0;
00425 else {
00426 for(srcNo=0; (unsigned int)srcNo < fg->numOfIn; srcNo++)
00427 if (strcasecmp(strSrc,(const char *)fg->sources[srcNo].name)==0)
00428 break;
00429 if ((unsigned int)srcNo >= fg->numOfIn)
00430 srcNo = -1;
00431 }
00432 } else
00433 PLAYER_MSG1(1,"\t\tSetting SourceI: %d", srcNo);
00434
00435 if ( srcNo<0 || (unsigned int)srcNo >= fg->numOfIn )
00436 {
00437 PLAYER_ERROR2("fg2_set_sourced(): Invalid source number (%d > %d)r!", srcNo, fg->numOfIn );
00438 return -1;
00439 }
00440 PLAYER_MSG3(1,"selecting\t%d - %s (%d)", srcNo, fg->sources[srcNo].name, fg->sources[srcNo].type);
00441
00442 fg->source = srcNo;
00443
00444 if ( ioctl( fg->fd, VIDIOC_S_INPUT, &(fg->sources[srcNo]) ) < 0 )
00445 {
00446 PERROR( "fg2_set_source(): set source failed" );
00447 return -1;
00448 }
00449
00450 discover_controls(fg);
00451
00452 return 0;
00453 }
00454
00455
00456
00457
00458
00459
00460
00464 int fg2_countControls( FRAMEGRABBER2* fg)
00465 {
00466 return fg->numOfCtls;
00467 }
00468
00473 int fg2_setControlValueI( FRAMEGRABBER2* fg, int id, double val)
00474 {
00475 struct v4l2_control control;
00476 unsigned int uVal;
00477
00478 if (id<0 || (unsigned int)id>fg->numOfCtls)
00479 return -1;
00480
00481 PLAYER_MSG2(2, "Setting value %f to '%s'", val, fg->controls[id].name);
00482
00483 uVal = fg->controls[id].default_value;
00484
00485 if (val>1.0){
00486 PLAYER_WARN1("value %f out of range for control:", val);
00487 printControl(&(fg->controls[id]));
00488 return -2;
00489 }
00490 if (val>=0.0 && fg->controls[id].minimum != fg->controls[id].maximum) {
00491 uVal = fg->controls[id].minimum +
00492 (unsigned int )( val*(fg->controls[id].maximum
00493 - fg->controls[id].minimum));
00494 PLAYER_MSG2(2, "uint value %u of '%f'", uVal, val);
00495 }
00496
00497 memset (&control, 0, sizeof (control));
00498 control.id = fg->controls[id].id;
00499 control.value = uVal;
00500 if (ioctl (fg->fd, VIDIOC_S_CTRL, &control)!=0){
00501 PERROR("VIDIOC_S_CTRL");
00502 PLAYER_WARN1("Failed to set value %f to control:", val);
00503 printControl(&(fg->controls[id]));
00504 return -3;
00505 }
00506 usleep(50000);
00507 PLAYER_MSG1(2, "Value written %u'", control.value);
00508
00509 return 0;
00510 }
00511
00516 int fg2_setControlValue( FRAMEGRABBER2* fg, const char *id, double val)
00517 {
00518 unsigned int i;
00519 for(i=0; i<fg->numOfCtls; i++){
00520 if (strcasecmp(id, (const char *)fg->controls[i].name) == 0){
00521 return fg2_setControlValueI(fg, i, val);
00522 }
00523 }
00524 return -1;
00525 }
00526
00531 double fg2_getControlValueI( FRAMEGRABBER2* fg, int id)
00532 {
00533 struct v4l2_control control;
00534 double dval;
00535
00536 if (id<0 || (unsigned int)id>fg->numOfCtls)
00537 return -1;
00538
00539 memset (&control, 0, sizeof (control));
00540 control.id = fg->controls[id].id;
00541 if (ioctl (fg->fd, VIDIOC_G_CTRL, &control)!=0){
00542 PERROR("VIDIOC_G_CTRL");
00543 PLAYER_WARN("Failed to get value of control:");
00544 printControl(&(fg->controls[id]));
00545 return -3;
00546 }
00547
00548 if (fg->controls[id].maximum == fg->controls[id].minimum )
00549 return 0.0;
00550 dval = (double)(control.value - fg->controls[id].minimum)
00551 / (fg->controls[id].maximum-fg->controls[id].minimum);
00552 PLAYER_MSG2(2, "uint value %u of '%f'", control.value, dval);
00553 return dval;
00554 }
00555
00560 double fg2_getControlValue( FRAMEGRABBER2* fg, const char *id)
00561 {
00562 unsigned int i;
00563 for(i=0; i<fg->numOfCtls; i++){
00564 if (strcasecmp(id, (const char *)fg->controls[i].name) == 0){
00565 return fg2_getControlValueI(fg, i);
00566 }
00567 }
00568 return -1.0;
00569 }
00570
00571 const char *fg2_getControlName( FRAMEGRABBER2* fg, int id)
00572 {
00573 if (id<0 || (unsigned int)id>=fg->numOfCtls)
00574 return 0;
00575 return (const char *)fg->controls[id].name;
00576 }
00577
00578
00579
00580
00581
00582
00586 int fg2_set_source_norm( FRAMEGRABBER2* fg, v4l2_std_id norm )
00587 {
00588 PLAYER_MSG0(1,"setting new norm");
00589 return 0;
00590 if ( ioctl( fg->fd, VIDIOC_S_STD, &norm ) < 0 )
00591 {
00592 PERROR( "Mfg2_set_source_norm(): set channel/norm failed" );
00593 return -1;
00594 }
00595
00596 return 0;
00597 }
00598
00599
00603 int fg2_setPixelSettings( FRAMEGRABBER2* fg, int width, int height,
00604 unsigned int fmt, enum v4l2_field fld, int dpth )
00605 {
00606 PLAYER_MSG0(2,"fg2_set_capture_window()");
00607
00608 fg->width = width;
00609 fg->height = height;
00610 fg->pix_fmt = fmt;
00611 fg->field = fld;
00612 fg->depth = dpth;
00613 ;
00614 return usePixelFormat(fg);
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00632 static int discover_inputs(FRAMEGRABBER2* fg)
00633 {
00634 struct v4l2_input input2;
00635 unsigned int i;
00636 fg->numOfIn=0;
00637 PLAYER_MSG0(2,"discover_inputs()");
00638
00639
00640 for (fg->numOfIn = 0;; fg->numOfIn++) {
00641 memset(&input2,0,sizeof(input2));
00642 input2.index = fg->numOfIn;
00643 if (0 != ioctl( fg->fd, VIDIOC_ENUMINPUT, &input2 ) )
00644 break;
00645 }
00646 fg->source = 0;
00647 fg->sources = (struct v4l2_input *)malloc( sizeof( struct v4l2_input )*fg->numOfIn );
00648 PLAYER_MSG1(1,"Found sources: %d", fg->numOfIn);
00649 for ( i = 0; i < fg->numOfIn; i++ ) {
00650 fg->sources[i].index = i;
00651 ioctl( fg->fd, VIDIOC_ENUMINPUT, &(fg->sources[i]) );
00652 PLAYER_MSG3(1,"\t%d - %s (%d)", i, fg->sources[i].name, fg->sources[i].type);
00653 }
00654
00655 return 0;
00656 }
00657
00658
00659
00660
00661 const char *ctlTypeToString[] = {
00662 "Unknown",
00663 "Integer",
00664 "Boolean",
00665 "Menu",
00666 "Button",
00667 };
00668
00669
00670 static void printControl(struct v4l2_queryctrl *queryctrl){
00671 double procent = (queryctrl->default_value-queryctrl->minimum)*1.0
00672 / (queryctrl->maximum-queryctrl->minimum);
00673 PLAYER_MSG6(1,"\t\"%s\" = %0.4f (def: %d, min: %d, max: %d) of %s",
00674 queryctrl->name,
00675 procent,
00676 queryctrl->default_value,
00677 queryctrl->minimum,
00678 queryctrl->maximum,
00679 ctlTypeToString[queryctrl->type]);
00680 }
00681
00682
00683 static int discover_controls(FRAMEGRABBER2* fg)
00684 {
00685 struct v4l2_queryctrl queryctrl;
00686 unsigned int counter;
00687 int i=0;
00688 PLAYER_MSG0(1,"Discovering controls:");
00689
00690 fg->numOfCtls = 0;
00691 FREE_ME(fg->controls);
00692
00693 memset (&queryctrl, 0, sizeof (queryctrl));
00694
00695 for (queryctrl.id = V4L2_CID_BASE;
00696 queryctrl.id < V4L2_CID_LASTP1 && i<10000;
00697 queryctrl.id++, i++) {
00698 if (0 == ioctl (fg->fd, VIDIOC_QUERYCTRL, &queryctrl)) {
00699 if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
00700 continue;
00701
00702 fg->numOfCtls++;
00703
00704
00705
00706 } else {
00707 if (errno == EINVAL)
00708 continue;
00709
00710 PERROR ("VIDIOC_QUERYCTRL");
00711 break;
00712 }
00713 }
00714
00715 for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;queryctrl.id++) {
00716 if (0 == ioctl (fg->fd, VIDIOC_QUERYCTRL, &queryctrl)) {
00717 if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
00718 continue;
00719
00720 fg->numOfCtls++;
00721
00722
00723
00724 } else {
00725 if (errno == EINVAL) {
00726 if (queryctrl.id - V4L2_CID_PRIVATE_BASE < 100)
00727 continue;
00728 break;
00729 }
00730
00731 PERROR ("VIDIOC_QUERYCTRL");
00732 break;
00733 }
00734 }
00735
00736 if (fg->numOfCtls<=0) {
00737 PLAYER_WARN("\tNo controls");
00738 return 0;
00739 }
00740 fg->controls = (struct v4l2_queryctrl *)malloc( sizeof( struct v4l2_queryctrl )*fg->numOfCtls );
00741 counter = 0;
00742
00743
00744
00745 memset (&queryctrl, 0, sizeof (queryctrl));
00746
00747
00748 i=0;
00749 for (queryctrl.id = V4L2_CID_BASE;
00750 queryctrl.id < V4L2_CID_LASTP1 && i<10000;
00751 queryctrl.id++, i++) {
00752 if (counter >= fg->numOfCtls)
00753 break;
00754 memset (&(fg->controls[counter]), 0, sizeof (fg->controls[counter]));
00755 fg->controls[counter].id = queryctrl.id;
00756 if (0 == ioctl (fg->fd, VIDIOC_QUERYCTRL, &(fg->controls[counter]))) {
00757 if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
00758 continue;
00759
00760 printControl(&(fg->controls[counter]));
00761 counter++;
00762
00763
00764
00765 } else {
00766 if (errno == EINVAL)
00767 continue;
00768
00769 PERROR ("VIDIOC_QUERYCTRL");
00770 break;
00771 }
00772 }
00773
00774 for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;queryctrl.id++) {
00775 if (counter >= fg->numOfCtls)
00776 break;
00777 memset (&(fg->controls[counter]), 0, sizeof (fg->controls[counter]));
00778 fg->controls[counter].id = queryctrl.id;
00779 if (0 == ioctl (fg->fd, VIDIOC_QUERYCTRL, &(fg->controls[counter]))) {
00780 if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
00781 continue;
00782
00783 printControl(&(fg->controls[counter]));
00784 counter++;
00785
00786
00787
00788 } else {
00789 if (errno == EINVAL) {
00790 if (queryctrl.id - V4L2_CID_PRIVATE_BASE < 100)
00791 continue;
00792 break;
00793 }
00794
00795 PERROR ("VIDIOC_QUERYCTRL");
00796 break;
00797 }
00798 }
00799
00800 if (counter<fg->numOfCtls)
00801 fg->numOfCtls = counter;
00802
00803
00804
00805 return 0;
00806 }
00807
00808 static void getPixelFormat(FRAMEGRABBER2 *fg){
00809 char tmpp[5];
00810 tmpp[0] = tmpp[4] = 0;
00811 CLEAR (fg->frmt);
00812 fg->frmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00813 if (-1 == ioctl (fg->fd, VIDIOC_G_FMT, &(fg->frmt)))
00814 {
00815 PLAYER_ERROR1("VIDIOC_G_FMT: %s", strerror(errno));
00816 memcpy(tmpp, &(fg->frmt.fmt.pix.pixelformat), 4);
00817 PLAYER_ERROR3("got (%d, %d) %s", fg->frmt.fmt.pix.width, fg->frmt.fmt.pix.height, tmpp);
00818 } else {
00819 fg->width = fg->frmt.fmt.pix.width;
00820 fg->height = fg->frmt.fmt.pix.height;
00821 fg->pix_fmt = fg->frmt.fmt.pix.pixelformat;
00822 fg->field = fg->frmt.fmt.pix.field;
00823 }
00824
00825 }
00826
00831 static int usePixelFormat(FRAMEGRABBER2 *fg)
00832 {
00833 char tmpp[5];
00834 tmpp[0] = tmpp[4] = 0;
00835 memcpy(tmpp, &(fg->pix_fmt), 4);
00836 PLAYER_MSG3(1,"Changing pixel and frame format (%dx%d, %s)", fg->width, fg->height, tmpp);
00837
00838 CLEAR (fg->frmt);
00839 fg->frmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00840 fg->frmt.fmt.pix.width = fg->width;
00841 fg->frmt.fmt.pix.height = fg->height;
00842
00843 fg->frmt.fmt.pix.pixelformat = fg->pix_fmt;
00844 fg->frmt.fmt.pix.field = fg->field;
00845
00846 if (-1 == ioctl (fg->fd, VIDIOC_S_FMT, &(fg->frmt)))
00847 {
00848 PLAYER_ERROR1("VIDIOC_S_FMT: %s", strerror(errno));
00849 memcpy(tmpp, &(fg->frmt.fmt.pix.pixelformat), 4);
00850 PLAYER_ERROR3("got (%d, %d) %s", fg->frmt.fmt.pix.width, fg->frmt.fmt.pix.height, tmpp);
00851
00852 getPixelFormat(fg);
00853 return -1;
00854 }
00855 if (fg->frmt.fmt.pix.bytesperline*8 != fg->depth*fg->width) {
00856 PLAYER_ERROR("Padding unsuported");
00857 getPixelFormat(fg);
00858 printf("Test");
00859
00860 }
00861
00862 if ( fg->frmt.fmt.pix.width != fg->width ||
00863 fg->frmt.fmt.pix.height != fg->height )
00864 {
00865 PLAYER_ERROR("Failed to apply required frame size settings");
00866 getPixelFormat(fg);
00867 return -1;
00868 }
00869
00870 return 0;
00871 }
00872
00873
00874
00879 static int assignMBufs(FRAMEGRABBER2 *fg){
00880 struct v4l2_requestbuffers req;
00881 PLAYER_MSG0(2,"assignMBufs()");
00882
00883 CLEAR (req);
00884
00885 req.count = 2;
00886 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00887 req.memory = V4L2_MEMORY_MMAP;
00888
00889 if (-1 == ioctl (fg->fd, VIDIOC_REQBUFS, &req)) {
00890 if (EINVAL == errno) {
00891 PLAYER_ERROR ("device does not support " "memory mapping");
00892 PLAYER_ERROR1("device does not support " "memory mapping: %s", strerror(errno));
00893 } else {
00894 PLAYER_ERROR1("VIDIOC_REQBUFS: %s", strerror(errno));
00895 }
00896 return -1;
00897 }
00898
00899 if (req.count < 2)
00900 {
00901 PLAYER_ERROR ("Insufficient buffer memory on device");
00902 return -1;
00903 }
00904
00905
00906 fg->buffers = (struct my_buffer*)calloc (req.count, sizeof (*fg->buffers));
00907
00908 if (!fg->buffers)
00909 {
00910 PLAYER_ERROR ( "Out of memory");
00911 return -1;
00912 }
00913
00914
00915 for (fg->n_buffers = 0; fg->n_buffers < req.count; ++fg->n_buffers)
00916 {
00917 struct v4l2_buffer buf;
00918
00919 CLEAR (buf);
00920
00921 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00922 buf.memory = V4L2_MEMORY_MMAP;
00923 buf.index = fg->n_buffers;
00924
00925 if (-1 == ioctl (fg->fd, VIDIOC_QUERYBUF, &buf)){
00926 PLAYER_ERROR1("VIDIOC_QUERYBUF: %s", strerror(errno));
00927 return -1;
00928 }
00929
00930 fg->buffers[fg->n_buffers].id = fg->n_buffers;
00931 fg->buffers[fg->n_buffers].length = buf.length;
00932 fg->buffers[fg->n_buffers].start = mmap(
00933 NULL ,
00934 buf.length,
00935 PROT_READ | PROT_WRITE ,
00936 MAP_SHARED ,
00937 fg->fd, buf.m.offset
00938 );
00939
00940 if (MAP_FAILED == fg->buffers[fg->n_buffers].start) {
00941 PLAYER_ERROR1("MMAP: %s", strerror(errno));
00942 return -1;
00943 }
00944 }
00945
00946 return 0;
00947 }
00948
00949 static void releaseMBufs(FRAMEGRABBER2* fg){
00950 unsigned int i;
00951 for (i = 0; i < fg->n_buffers; ++i) {
00952 if (-1 == munmap (fg->buffers[i].start, fg->buffers[i].length))
00953 PLAYER_ERROR1("munmap: %s", strerror(errno));
00954 }
00955 FREE_ME(fg->buffers);
00956 fg->n_buffers = 0;
00957
00958 }
00959
00960
00961
00962
00963
00967 static void wyczyscStan(FRAMEGRABBER2* fg)
00968 {
00969 unsigned int i;
00970 if (fg->isCapturing)
00971 fg2_stopCapture(fg);
00972
00973 for (i = 0; i < fg->n_buffers; ++i)
00974 if (-1 == munmap (fg->buffers[i].start, fg->buffers[i].length))
00975 PERROR("munmap");
00976 fg->n_buffers=0;
00977
00978
00979
00980
00981
00982
00983 FREE_ME( fg->buffers );
00984 FREE_ME( fg->device );
00985 FREE_ME( fg->sources );
00986
00987 }
00988
00989
00994 static void fg2_close(FRAMEGRABBER2* fg)
00995 {
00996 wyczyscStan(fg);
00997 if (fg->fd>0)
00998 close( fg->fd );
00999 fg->fd = 0;
01000 }
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018