~ubuntu-branches/ubuntu/trusty/libavg/trusty-proposed

« back to all changes in this revision

Viewing changes to src/imaging/V4LCamera.cpp

  • Committer: Package Import Robot
  • Author(s): OXullo Intersecans
  • Date: 2011-12-06 22:44:56 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20111206224456-qc7250z3ya1vi8s9
Tags: 1.7.0-0ubuntu1
* New upstream release (LP: #899183)
* Remove patches 0002-libav-0.7.patch, 0003-fglrx-segfault-on-startup.patch
  now merged to upstream
* Remove unnecessary .la files
* Update debian/watch file
* Fix debian/copyright dep-5 compliancy
* Update standards to version 3.9.2
* Add man pages for avg_checktouch, avg_checkvsync, avg_showsvg
* Minor debian/rules enhancement
* Add librsvg2-dev, libgdk-pixbuf2.0-dev to Build-Depends
* Proper transition to dh_python2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
//
2
2
//  libavg - Media Playback Engine. 
3
 
//  Copyright (C) 2003-2008 Ulrich von Zadow
 
3
//  Copyright (C) 2003-2011 Ulrich von Zadow
4
4
//
5
5
//  This library is free software; you can redistribute it and/or
6
6
//  modify it under the terms of the GNU Lesser General Public
62
62
    }
63
63
}
64
64
 
 
65
 
65
66
V4LCamera::V4LCamera(std::string sDevice, int channel, IntPoint size, PixelFormat camPF,
66
67
        PixelFormat destPF, double frameRate)
67
68
    : Camera(camPF, destPF),
103
104
    }
104
105
    
105
106
    initDevice();
106
 
    startCapture();
107
107
    AVG_TRACE(Logger::CONFIG, "V4L2 Camera opened");
108
108
}
109
109
 
112
112
    close();
113
113
}
114
114
 
115
 
 
116
115
void V4LCamera::close()
117
116
{
118
117
    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
119
 
    if (-1 == xioctl (m_Fd, VIDIOC_STREAMOFF, &type)) {
 
118
    int rc = xioctl(m_Fd, VIDIOC_STREAMOFF, &type);
 
119
    if (rc == -1) {
120
120
        AVG_TRACE(Logger::ERROR, "VIDIOC_STREAMOFF");
121
121
    }
122
122
    vector<Buffer>::iterator it;
206
206
    
207
207
    unsigned char * pCaptureBuffer = (unsigned char*)m_vBuffers[buf.index].start;
208
208
   
209
 
    IntPoint size = getImgSize();
210
209
    double lineLen;
211
210
    switch (getCamPF()) {
212
211
        case YCbCr411:
213
 
            lineLen = size.x*1.5;
 
212
            lineLen = m_ImgSize.x*1.5;
214
213
            break;
215
214
        case YCbCr420p:
216
 
            lineLen = size.x;
 
215
            lineLen = m_ImgSize.x;
217
216
            break;
218
217
        default:
219
 
            lineLen = size.x*Bitmap::getBytesPerPixel(getCamPF());
 
218
            lineLen = m_ImgSize.x*getBytesPerPixel(getCamPF());
220
219
    }
221
 
    BitmapPtr pCamBmp(new Bitmap(size, getCamPF(), pCaptureBuffer, lineLen,
 
220
    BitmapPtr pCamBmp(new Bitmap(m_ImgSize, getCamPF(), pCaptureBuffer, lineLen,
222
221
            false, "TempCameraBmp"));
223
222
 
224
223
    BitmapPtr pDestBmp = convertCamFrameToDestPF(pCamBmp);
372
371
    setFeature(V4L2_CID_BLUE_BALANCE, v); 
373
372
}
374
373
 
 
374
int dumpCameras_open(int j)
 
375
{
 
376
    stringstream minorDeviceNumber;
 
377
    minorDeviceNumber << j;
 
378
    string address = "/dev/video";
 
379
    string result = address + minorDeviceNumber.str();  
 
380
    int fd = ::open(result.c_str(), O_RDWR /* required */ | O_NONBLOCK, 0);
 
381
    return fd;
 
382
}
 
383
 
 
384
v4l2_capability dumpCameraCapabilities(int fd)
 
385
{
 
386
    v4l2_capability capability;
 
387
    memset(&capability, 0, sizeof(capability));
 
388
    int rc = ioctl(fd, VIDIOC_QUERYCAP, &capability);
 
389
    if (rc != -1) {
 
390
        cout << capability.card << ":" << endl;
 
391
        cout << "    Driver:  " << capability.driver << endl;
 
392
        cout << "  Location:  " << capability.bus_info;
 
393
        cout << endl << endl;
 
394
    }
 
395
    return capability;
 
396
}
 
397
 
 
398
void dumpSupportedImgFormats(int fd)
 
399
{
 
400
    cout << "Suported Image Formats:" << endl;
 
401
    for (int i = 0;; i++) {
 
402
        v4l2_fmtdesc fmtDesc;
 
403
        memset(&fmtDesc, 0, sizeof(fmtDesc));
 
404
        fmtDesc.index = i;
 
405
        fmtDesc.type  = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
406
        int rc = ioctl(fd, VIDIOC_ENUM_FMT, &fmtDesc);
 
407
        if (rc == -1) {
 
408
            break; 
 
409
        }
 
410
        v4l2_frmsizeenum frmSizeEnum;
 
411
        memset(&frmSizeEnum, 0, sizeof (frmSizeEnum));
 
412
        frmSizeEnum.index = 0;
 
413
        frmSizeEnum.pixel_format = fmtDesc.pixelformat;
 
414
        bool bSupported = false;
 
415
        while (ioctl(fd, VIDIOC_ENUM_FRAMESIZES, &frmSizeEnum) == 0) {
 
416
            string sAvgPixelformat;
 
417
            switch (fmtDesc.pixelformat) {
 
418
                case v4l2_fourcc('Y','U','Y','V'):
 
419
                    sAvgPixelformat = "YUYV422";
 
420
                    bSupported = true;
 
421
                    break; 
 
422
                case v4l2_fourcc('U','Y','V','Y'):
 
423
                    sAvgPixelformat = "YUV422";
 
424
                    bSupported = true;
 
425
                    break; 
 
426
                case v4l2_fourcc('G','R','E','Y'):
 
427
                    sAvgPixelformat = "I8"; 
 
428
                    bSupported = true;
 
429
                    break; 
 
430
                case v4l2_fourcc('Y','1','6',' '):
 
431
                    sAvgPixelformat = "I16";
 
432
                    bSupported = true;
 
433
                    break; 
 
434
                case v4l2_fourcc('R','G','B','3'):
 
435
                    sAvgPixelformat = "RGB";
 
436
                    bSupported = true;
 
437
                    break; 
 
438
                case v4l2_fourcc('B','G','R','3'):
 
439
                    sAvgPixelformat = "BGR";
 
440
                    bSupported = true;
 
441
                    break; 
 
442
                default:
 
443
                    break;
 
444
            }
 
445
            
 
446
            if (bSupported) {
 
447
                v4l2_frmivalenum frmIvalEnum;
 
448
                cout << "   " << sAvgPixelformat << " ";
 
449
                cout << "  (" << frmSizeEnum.discrete.width << ", ";
 
450
                cout << frmSizeEnum.discrete.height << ")";
 
451
                cout << "   fps: ";
 
452
                memset (&frmIvalEnum, 0, sizeof (frmIvalEnum));
 
453
                frmIvalEnum.index = 0;      
 
454
                frmIvalEnum.pixel_format = frmSizeEnum.pixel_format;  
 
455
                frmIvalEnum.width = frmSizeEnum.discrete.width;   
 
456
                frmIvalEnum.height = frmSizeEnum.discrete.height;
 
457
                while (ioctl(fd, VIDIOC_ENUM_FRAMEINTERVALS, &frmIvalEnum) == 0) {
 
458
                    cout << frmIvalEnum.discrete.denominator << "/";
 
459
                    frmIvalEnum.index++;                                 
 
460
                }
 
461
                cout << endl;
 
462
            }
 
463
            frmSizeEnum.index++;
 
464
        }
 
465
    }
 
466
}
 
467
 
 
468
void dumpCameraControls(int fd)
 
469
{
 
470
    cout << endl << "Camera Controls:" << endl;
 
471
    v4l2_queryctrl queryCtrl;
 
472
    for (queryCtrl.id = V4L2_CID_BASE; queryCtrl.id < V4L2_CID_LASTP1; queryCtrl.id++) {
 
473
        int rc = ioctl (fd, VIDIOC_QUERYCTRL, &queryCtrl);
 
474
        if (rc != -1) {
 
475
            if (queryCtrl.flags & V4L2_CTRL_FLAG_DISABLED) {
 
476
                continue;
 
477
            }
 
478
            cout << "  " << queryCtrl.name << ":" << endl;
 
479
            cout << "    Min: " << queryCtrl.minimum << " | ";
 
480
            cout << "Max: " << queryCtrl.maximum << " | ";
 
481
            cout << "Default: "<< queryCtrl.default_value << endl;
 
482
        } else {
 
483
            if (errno != EINVAL) {
 
484
                perror("VIDIOC_QUERYCTRL");
 
485
                exit(EXIT_FAILURE);
 
486
            }          
 
487
        }
 
488
    }
 
489
}
 
490
 
375
491
void V4LCamera::dumpCameras()
376
 
{
 
492
 
493
    for(int j = 0; j < 256; j++){
 
494
        int fd = dumpCameras_open(j);
 
495
        if (fd != -1) {
 
496
            cout << "------------------------Video4linux Camera-------------------------";
 
497
            cout << endl;
 
498
            cout << "/dev/video" << j << " ";
 
499
            v4l2_capability capability = dumpCameraCapabilities(fd);
 
500
            if (capability.capabilities & V4L2_CAP_VIDEO_CAPTURE) { 
 
501
                dumpSupportedImgFormats(fd);   
 
502
                dumpCameraControls(fd);
 
503
            } 
 
504
            cout << "-------------------------------------------------------------------";
 
505
            cout << endl;
 
506
        }
 
507
    }
377
508
}
378
509
 
 
510
 
379
511
void V4LCamera::setFeature(CameraFeature feature, int value, bool bIgnoreOldValue)
380
512
{
381
513
    // ignore -1 coming from default unbiased cameranode parameters
452
584
        Crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
453
585
        Crop.c = CropCap.defrect; /* reset to default */
454
586
 
455
 
        if (-1 == xioctl (m_Fd, VIDIOC_S_CROP, &Crop)) {
 
587
        if (-1 == xioctl(m_Fd, VIDIOC_S_CROP, &Crop)) {
456
588
            switch (errno) {
457
589
                case EINVAL:
458
590
                    /* Cropping not supported. */
469
601
    CLEAR(fmt);
470
602
 
471
603
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
472
 
    fmt.fmt.pix.width = getImgSize().x; 
473
 
    fmt.fmt.pix.height = getImgSize().y;
 
604
    fmt.fmt.pix.width = m_ImgSize.x; 
 
605
    fmt.fmt.pix.height = m_ImgSize.y;
474
606
    fmt.fmt.pix.pixelformat = m_v4lPF;
475
607
    fmt.fmt.pix.field = V4L2_FIELD_ANY;
476
 
 
477
 
    if (xioctl(m_Fd, VIDIOC_S_FMT, &fmt) == -1) {
 
608
    int rc = xioctl(m_Fd, VIDIOC_S_FMT, &fmt);
 
609
    if (int(fmt.fmt.pix.width) != m_ImgSize.x || int(fmt.fmt.pix.height) != m_ImgSize.y
 
610
        || rc == -1)
 
611
    {
478
612
        throw(Exception(AVG_ERR_CAMERA_NONFATAL, 
479
613
                string("Unable to set V4L camera image format: '")
480
614
                +strerror(errno)
481
 
                +"'. Try using v4l-info to find out what the device supports."));
 
615
                +"'. Try using avg_showcamera.py --dump to find out what the device supports."));
482
616
    }
483
617
 
484
618
    CLEAR(StreamParam);
486
620
    StreamParam.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
487
621
    StreamParam.parm.capture.timeperframe.numerator = 1;
488
622
    StreamParam.parm.capture.timeperframe.denominator = (int) m_FrameRate;
489
 
    if (xioctl(m_Fd, VIDIOC_S_PARM, &StreamParam) == -1) {
 
623
    rc = xioctl(m_Fd, VIDIOC_S_PARM, &StreamParam);
 
624
    if (m_FrameRate != StreamParam.parm.capture.timeperframe.denominator || rc == -1) {
490
625
        throw(Exception(AVG_ERR_CAMERA_NONFATAL,
491
626
                string("Unable to set V4L camera framerate: '")
492
627
                +strerror(errno)
493
 
                +"'. Try using v4l-info to find out what the device supports."));
 
628
                +"'. Try using avg_showcamera.py --dump to find out what the device supports."));
494
629
    }
495
630
    m_FrameRate = (double)StreamParam.parm.capture.timeperframe.denominator / \
496
631
            (double)StreamParam.parm.capture.timeperframe.numerator;