include/Capture.h File Reference

#include <linux/videodev2.h>
#include <pthread.h>
#include "CaptureTypes.h"

Go to the source code of this file.

Data Structures

struct  _sBuffer
struct  _sCapture

Defines

#define NUM_STREAMING_BUFFERS   4

Typedefs

typedef int BOOL
typedef _sBuffer sBuffer
typedef _sBufferpsBuffer
typedef _sCapture sCapture
typedef _sCapturepsCapture

Functions

int OpenCaptureDevice (char *device, psCapture pCapture, BOOL bBlock)
int OpenCaptureDeviceControl (psCapture pCapture)
void CloseCaptureDevice (int fd, psCapture pCapture)
void CloseCaptureDeviceControl (int fd)
int InitialiseReadCapture (psCapture pCapture, unsigned int buffer_size)
int UninitialiseReadCapture (psCapture pCapture)
int InitialiseMmapCapture (psCapture pCapture, unsigned int buffer_size)
int InitialiseUserPtrCapture (psCapture pCapture, unsigned int buffer_size)
int UninitialiseMmapCapture (psCapture pCapture)
int UninitialiseUserptrCapture (psCapture pCapture)
int InitialiseCapture (psCapture pCapture)
int StartCapture (psCapture pCapture)


Define Documentation

#define NUM_STREAMING_BUFFERS   4


Typedef Documentation

typedef int BOOL

typedef struct _sBuffer * psBuffer

typedef struct _sCapture * psCapture

Parent capture structure.

typedef struct _sBuffer sBuffer

typedef struct _sCapture sCapture

Parent capture structure.


Function Documentation

void CloseCaptureDevice ( int  fd,
psCapture  pCapture 
)

Implementation of CloseCaptureDevice.

00785 {
00786    CapDebug("Closing capture device fd: %d\n", fd);
00787 
00788    /* Check for allocated memory */
00789    if(pCapture->pInputs)
00790    {
00791       free(pCapture->pInputs);
00792       pCapture->pInputs = 0;
00793    }
00794    if(pCapture->pStandards)
00795    {
00796       free(pCapture->pStandards);
00797       pCapture->pStandards = 0;
00798    }
00799    if(pCapture->pFormats)
00800    {
00801       free(pCapture->pFormats);
00802       pCapture->pFormats = 0;
00803    }
00804 
00805    /* close the handle */
00806    close(fd);
00807 }

void CloseCaptureDeviceControl ( int  fd  ) 

Implementation of CloseCaptureDeviceControl.

00813 {
00814    CapDebug("Closing capture device control fd: %d\n", fd);
00815 
00816    /* close the handle */
00817    close(fd);
00818 }

int InitialiseCapture ( psCapture  pCapture  ) 

Implementation of InitialiseCapture.

00648 {
00649    unsigned int d1 = 0;
00650    unsigned int d2 = 0;
00651 
00652    int rc = 0;
00653 
00654    /* Initialise internals */
00655    pCapture->inputs = 0;
00656    pCapture->standards = 0;
00657 
00658    /* Setup the capture rate, if rate is 0.0
00659     * don't set, just use the default which is the input rate
00660     */
00661    if(pCapture->fFrameRate > 0.0)
00662    {
00663       /* Convert the fp frame rate into a numerator and denominator for
00664        * use in the v4l struct
00665        *  - Assume numerator is 1001 (??)
00666        *
00667        *  - Calculate denominator
00668        *
00669        *     n                       d
00670        *     - =   FrameTime   and   - = fps
00671        *     d                       n
00672        *
00673        *     d = (n * fps)
00674        */
00675       pCapture->StrmParm.parm.capture.timeperframe.numerator = NUMERATOR;
00676 
00677       /* Multiply by 10 to increase precision, then add half lowest value and
00678        * divide by 10 to obtain the 'real' denominator.
00679        */
00680       pCapture->StrmParm.parm.capture.timeperframe.denominator = ((NUMERATOR * DIVISOR * pCapture->fFrameRate) + (DIVISOR / 2)) / DIVISOR;
00681 
00682       pCapture->StrmParm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00683       if((rc = ioctl(pCapture->fd, VIDIOC_S_PARM, &pCapture->StrmParm)) < 0)
00684       {
00685          CapError("Failed to set capture rate to %.2f: %d\n",
00686                pCapture->fFrameRate, rc);
00687          return rc;
00688       }
00689    }
00690 
00691    if(pCapture->CroppingActive)
00692    {
00693       struct v4l2_crop cropping;
00694       cropping.type     = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00695       cropping.c.top    = pCapture->CroppingTop;
00696       cropping.c.left   = pCapture->CroppingLeft;
00697       cropping.c.width  = pCapture->CroppingWidth;
00698       cropping.c.height = pCapture->CroppingHeight;
00699 
00700       if((rc = ioctl(pCapture->fd, VIDIOC_S_CROP, &cropping)) < 0)
00701       {
00702          CapError("Failed to set cropping(%d,%d,%d,%d): %d\n",
00703                cropping.c.top, cropping.c.left,
00704                cropping.c.width, cropping.c.height,
00705                rc);
00706          return rc;
00707       }
00708    }
00709 
00710    if(pCapture->livestream)
00711    {
00712       struct v4l2_queryctrl queryctrl;
00713       struct v4l2_control control;
00714 
00715       memset(&queryctrl, 0, sizeof(queryctrl));
00716       queryctrl.id = RGB133_V4L2_CID_LIVESTREAM;
00717 
00718       if ((rc = ioctl(pCapture->fd, VIDIOC_QUERYCTRL, &queryctrl)) == -1)
00719       {
00720          if (errno != EINVAL)
00721          {
00722             CapError("VIDIOC_QUERYCTRL failed for RGB133_V4L2_CID_LIVESTREAM, error(0x%x)\n", rc);
00723             return rc;
00724          }
00725          else
00726          {
00727             CapError("RGB133_V4L2_CID_LIVESTREAM is not supported\n");
00728          }
00729       }
00730       else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED)
00731       {
00732          CapError("RGB133_V4L2_CID_LIVESTREAM is not supported\n");
00733       }
00734       else
00735       {
00736          memset(&control, 0, sizeof (control));
00737          control.id = RGB133_V4L2_CID_LIVESTREAM;
00738          control.value = pCapture->livestream;
00739 
00740          if ((rc = ioctl(pCapture->fd, VIDIOC_S_CTRL, &control)) == -1)
00741          {
00742             perror("VIDIOC_S_CTRL failed for RGB133_V4L2_CID_LIVESTREAM: ");
00743             return rc;
00744          }
00745       }
00746 
00747       memset(&control, 0, sizeof (control));
00748       control.id = RGB133_V4L2_CID_LIVESTREAM;
00749 
00750       if ((rc = ioctl(pCapture->fd, VIDIOC_G_CTRL, &control)) == -1)
00751       {
00752          perror("VIDIOC_G_CTRL failed for RGB133_V4L2_CID_LIVESTREAM: ");
00753          return rc;
00754       }
00755 
00756       CapError("RGB133_V4L2_CID_LIVESTREAM current value: %d\n", control.value);
00757    }
00758 
00759    return rc;
00760 }

int InitialiseMmapCapture ( psCapture  pCapture,
unsigned int  buffer_size 
)

Implementation of InitialiseMmapCapture.

00484 {
00485    int ret = 0;
00486 
00487    memset( &pCapture->req, 0, sizeof(pCapture->req) );
00488    pCapture->req.count = NUM_STREAMING_BUFFERS;
00489    pCapture->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00490    pCapture->req.memory = V4L2_MEMORY_MMAP;
00491 
00492    if((ret = ioctl(pCapture->fd, VIDIOC_REQBUFS, &pCapture->req)) < 0)
00493    {
00494        CapError("Device does not support mmap IO: %d\n", ret);
00495        return -1;
00496    }
00497 
00498    if( pCapture->req.count < NUM_STREAMING_BUFFERS )
00499    {
00500       CapError("Insufficient buffers (%d, expected %d) for mmap IO\n", pCapture->req.count, NUM_STREAMING_BUFFERS);
00501       return -1;
00502    }
00503 
00504    if(buffer_size == 0)
00505    {
00506       CapError("Invalid buffer initialisation size: %u bytes\n", buffer_size);
00507       return -1;
00508    }
00509 
00510    for(pCapture->buffers = 0; pCapture->buffers < pCapture->req.count; ++pCapture->buffers )
00511    {
00512       struct v4l2_buffer buf;
00513       memset(&buf, 0, sizeof(buf));
00514       buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00515       buf.memory = V4L2_MEMORY_MMAP;
00516       buf.index = pCapture->buffers;
00517 
00518       if((ret = ioctl(pCapture->fd, VIDIOC_QUERYBUF, &buf)) < 0)
00519       {
00520          CapError("VIDIOC_QUERYBUF failed: %d\n", ret);
00521          return -1;
00522       }
00523 
00524       pCapture->pBuffers[pCapture->buffers].DataLength = buf.length;
00525       pCapture->pBuffers[pCapture->buffers].pData =
00526             mmap( NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, pCapture->fd, buf.m.offset );
00527 
00528       CapMessage("Mmap buffer[%d](%p) of %u bytes mmap'd.\n", pCapture->buffers,
00529             pCapture->pBuffers[pCapture->buffers].pData,
00530             pCapture->pBuffers[pCapture->buffers].DataLength);
00531 
00532       if( pCapture->pBuffers[pCapture->buffers].pData == MAP_FAILED )
00533       {
00534          CapError("Failed to mmap buffer[%d]\n", pCapture->buffers);
00535          return -1;
00536       }
00537    }
00538 
00539    return 0;
00540 }

int InitialiseReadCapture ( psCapture  pCapture,
unsigned int  buffer_size 
)

Implementation of InitialiseReadCapture.

00449 {
00450    if(buffer_size == 0)
00451    {
00452       CapError("Invalid buffer initialisation size: %u bytes\n", buffer_size);
00453       return -1;
00454    }
00455 
00456    pCapture->pBuffers[0].DataLength = buffer_size;
00457    pCapture->pBuffers[0].pData = malloc(buffer_size);
00458    if(pCapture->pBuffers[0].pData == 0)
00459       return -1;
00460 
00461    CapMessage("Read buffer(%p) of %u bytes initialised.\n",
00462          pCapture->pBuffers[0].pData, pCapture->pBuffers[0].DataLength);
00463    return 0;
00464 }

int InitialiseUserPtrCapture ( psCapture  pCapture,
unsigned int  buffer_size 
)

Implementation of InitialiseUserPtrCapture.

00546 {
00547    int ret = 0;
00548 
00549    memset( &pCapture->req, 0, sizeof(pCapture->req) );
00550    pCapture->req.count = NUM_STREAMING_BUFFERS;
00551    pCapture->req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00552    pCapture->req.memory = V4L2_MEMORY_USERPTR;
00553 
00554    if(buffer_size == 0)
00555    {
00556       CapError("Invalid buffer initialisation size: %u bytes\n", buffer_size);
00557       return -1;
00558    }
00559 
00560    if((ret = ioctl(pCapture->fd, VIDIOC_REQBUFS, &pCapture->req)) < 0)
00561    {
00562        CapError("Device does not support userptr IO: %d\n", ret);
00563        return -1;
00564    }
00565 
00566    for(pCapture->buffers = 0; pCapture->buffers < pCapture->req.count; ++pCapture->buffers)
00567    {
00568       pCapture->pBuffers[pCapture->buffers].pData = malloc(buffer_size);
00569       if(!pCapture->pBuffers[pCapture->buffers].pData)
00570       {
00571          int i;
00572          // If allocation fails, free buffers we managed to allocate, then return
00573          for(i = (pCapture->buffers - 1); i >= 0; --i)
00574          {
00575             free(pCapture->pBuffers[i].pData);
00576             pCapture->pBuffers[i].pData = 0;
00577             pCapture->pBuffers[i].DataLength = 0;
00578          }
00579          CapError("Failed to allocate buffer %d for userptr io\n", pCapture->buffers);
00580          return -1;
00581       }
00582 
00583       pCapture->pBuffers[pCapture->buffers].DataLength = buffer_size;
00584 
00585       CapMessage("Userptr buffer[%d](%p) of %u bytes allocated.\n",
00586             pCapture->buffers,
00587             pCapture->pBuffers[pCapture->buffers].pData,
00588             pCapture->pBuffers[pCapture->buffers].DataLength);
00589    }
00590 
00591    return 0;
00592 }

int OpenCaptureDevice ( char *  device,
psCapture  pCapture,
BOOL  blocking 
)

Implementation of OpenCaptureDevice.

00253 {
00254    char* realDevice = 0;
00255    unsigned long flags = O_RDWR;
00256 
00257    if(device[0])
00258    {
00259       CapLog("Opening capture device: %s\n", device);
00260       realDevice = device;
00261    }
00262    else
00263    {
00264       CapLog("Opening default capture device: %s\n", defaultDevice);
00265       realDevice = (char*)defaultDevice;
00266    }
00267 
00268    if(blocking)
00269    {
00270       flags |= O_NONBLOCK;
00271       CapError("Opening device with non-blocking IO (0x%lx)\n", flags);
00272    }
00273 
00274    /* Open the device */
00275    if((pCapture->fd = open(realDevice, flags)) < 0)
00276    {
00277       CapError("Failed to open \"%s\"\n", realDevice);
00278       goto open_failed;
00279    }
00280 
00281    /* Query the capture device capabilites */
00282    CapMessage("Query device capabilities into %p\n", &pCapture->caps);
00283    if(ioctl(pCapture->fd, VIDIOC_QUERYCAP, &pCapture->caps) < 0)
00284    {
00285       CapError("Failed to query device capabilities.\n");
00286       goto open_failed;
00287    }
00288 
00289    /* Enumerate Capture Device Capabilities */
00290    if( pCapture->caps.capabilities & V4L2_CAP_VIDEO_CAPTURE )
00291    {
00292       CapLog("Enumerate Capture Inputs\n");
00293       if(EnumerateCaptureInputs(pCapture))
00294       {
00295          CapError("Failed to enumerate capture inputs: %d\n", pCapture->inputs);
00296          goto open_failed;
00297       }
00298       CapLog("Enumerate Video Standards\n");
00299       if(EnumerateVideoStandards(pCapture))
00300       {
00301          CapError("Failed to enumerate video standards: %d\n", pCapture->standards);
00302          goto open_failed;
00303       }
00304       CapLog("Enumerate Capture Formats\n");
00305       if(EnumerateCaptureFormats(pCapture))
00306       {
00307          CapError("Failed to enumerate capture formats: %d\n", pCapture->formats);
00308          goto open_failed;
00309       }
00310    }
00311    else
00312    {
00313       CapError("Only Video Captures are supported by this application.\n");
00314       goto open_failed;
00315    }
00316 
00317    /* Check the io method */
00318    if( !(pCapture->caps.capabilities & V4L2_CAP_READWRITE) )
00319    {
00320       CapError("Capture device does not supoprt read io\n");
00321       goto open_failed;
00322    }
00323 
00324    /* Try and find default resolution if not specified */
00325    memset( &pCapture->fmt, 0, sizeof(pCapture->fmt) );
00326    pCapture->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
00327 
00328    if( pCapture->output_width == 0 || pCapture->output_height == 0 )
00329    {
00330       /* Use current width and height settings */
00331       CapMessage("Get Current source width and height.\n");
00332       if(ioctl(pCapture->fd, VIDIOC_G_FMT, &pCapture->fmt) < 0)
00333       {
00334          CapError("Failed to get current source width and height\n");
00335          goto open_failed;
00336       }
00337 
00338       pCapture->output_width  = pCapture->fmt.fmt.pix.width;
00339       pCapture->output_height = pCapture->fmt.fmt.pix.height;
00340 
00341       if( pCapture->fmt.fmt.pix.field == V4L2_FIELD_ALTERNATE )
00342       {
00343          pCapture->output_height = pCapture->output_height * 2;
00344       }
00345    }
00346    else if( pCapture->output_width < 0 || pCapture->output_height < 0 )
00347    {
00348       CapMessage("Using Optimal width and height.\n");
00349    }
00350    else
00351    {
00352        /* The width and height have come from the command line (or defaults) */
00353       CapMessage("Using Specified width and height -> %lux%lu\n",
00354             pCapture->output_width, pCapture->output_height);
00355    }
00356 
00357    pCapture->fmt.fmt.pix.width = pCapture->output_width;
00358    pCapture->fmt.fmt.pix.height = pCapture->output_height;
00359    pCapture->fmt.fmt.pix.field = V4L2_FIELD_NONE;
00360 
00361    /* Setup Capture Format */
00362    pCapture->fmt.fmt.pix.pixelformat = pCapture->output_pixfmt;
00363    if(ioctl(pCapture->fd, VIDIOC_S_FMT, &pCapture->fmt) < 0)
00364    {
00365       CapError("Failed to set capture format: %lux%lu for 0x%x (%c%c%c%c)\n",
00366             pCapture->output_width, pCapture->output_height,
00367             pCapture->output_pixfmt,
00368             ((char*)&pCapture->output_pixfmt)[0],
00369             ((char*)&pCapture->output_pixfmt)[1],
00370             ((char*)&pCapture->output_pixfmt)[2],
00371             ((char*)&pCapture->output_pixfmt)[3]);
00372       goto open_failed;
00373    }
00374    CapDebug("Set capture format: %lux%lu for 0x%x (%c%c%c%c)\n",
00375          pCapture->output_width, pCapture->output_height,
00376          pCapture->output_pixfmt,
00377          ((char*)&pCapture->output_pixfmt)[0],
00378          ((char*)&pCapture->output_pixfmt)[1],
00379          ((char*)&pCapture->output_pixfmt)[2],
00380          ((char*)&pCapture->output_pixfmt)[3]);
00381 
00382    /* Read back set width and height settings */
00383    CapMessage("read back set output buffer width and height.\n");
00384    if(ioctl(pCapture->fd, VIDIOC_G_FMT, &pCapture->fmt) < 0)
00385    {
00386       CapError("Failed to get current output buffer width and height\n");
00387       goto open_failed;
00388    }
00389 
00390    /* Get the source width and height settings */
00391    memset( &pCapture->src_fmt, 0, sizeof(pCapture->src_fmt) );
00392    pCapture->src_fmt.type = V4L2_BUF_TYPE_CAPTURE_SOURCE;
00393    CapMessage("read source width and height.\n");
00394    if((ioctl(pCapture->fd, RGB133_VIDIOC_G_SRC_FMT, &pCapture->src_fmt)) < 0)
00395    {
00396       CapError("Failed to get source input format through proprietary ioctl\n");
00397       if(ioctl(pCapture->fd, VIDIOC_G_FMT, &pCapture->src_fmt) < 0)
00398       {
00399          CapError("Failed to get source input format using ioctl\n");
00400          goto open_failed;
00401       }
00402       else
00403       {
00404          CapLog("Source format (ioctl): ");
00405       }
00406    }
00407    else
00408    {
00409       CapLog("Source format (proprietary ioctl): ");
00410    }
00411 
00412    CapLog("%ux%u @ %.2fHz for 0x%x (%c%c%c%c)\n",
00413          pCapture->src_fmt.fmt.pix.width, pCapture->src_fmt.fmt.pix.height,
00414          (float)((float)pCapture->src_fmt.fmt.pix.priv / 1000.0),
00415          pCapture->src_fmt.fmt.pix.pixelformat,
00416          ((char*)&pCapture->src_fmt.fmt.pix.pixelformat)[0],
00417          ((char*)&pCapture->src_fmt.fmt.pix.pixelformat)[1],
00418          ((char*)&pCapture->src_fmt.fmt.pix.pixelformat)[2],
00419          ((char*)&pCapture->src_fmt.fmt.pix.pixelformat)[3]);
00420 
00421    return 0;
00422 
00423 open_failed:
00424    if(pCapture->fd >= 0)
00425       CloseCaptureDevice(pCapture->fd, pCapture);
00426    return -1;
00427 }

int OpenCaptureDeviceControl ( psCapture  pCapture  ) 

Implementation of OpenCaptureDeviceControl.

00433 {
00434    CapDebug("Opening capture device control: %s\n", ctrlDevice);
00435    /* Open the device */
00436    if((pCapture->ctrlFd = open(ctrlDevice, O_RDWR)) < 0)
00437    {
00438       CapError("Failed to open \"%s\"\n", ctrlDevice);
00439       return -1;
00440    }
00441 
00442    return 0;
00443 }

int StartCapture ( psCapture  pCapture  ) 

Implementation of InitialiseCapture.

00766 {
00767    psCaptureThreadArgs pCaptureThreadArgs = 0;
00768    CapDebug("Start Capture Thread...\n");
00769    if(CreateCaptureThread(pCapture, pCaptureThreadArgs))
00770       return -1;
00771 
00772    CapDebug("Wait Capture Thread...\n");
00773    JoinCaptureThread(pCapture);
00774 
00775    CapDebug("Joined Capture Thread...\n");
00776    FreeCaptureThreadArgs(&pCaptureThreadArgs);
00777 
00778    return 0;
00779 }

int UninitialiseMmapCapture ( psCapture  pCapture  ) 

Implementation of InitialiseMmapCapture.

00598 {
00599    unsigned int i = 0;
00600    for(i=0; i<pCapture->buffers; i++)
00601    {
00602       if(pCapture->pBuffers[i].pData != 0)
00603       {
00604          CapMessage("Uninitialise mmap buffer[%d](%p) of %u bytes.\n", i,
00605                pCapture->pBuffers[i].pData,
00606                pCapture->pBuffers[i].DataLength);
00607          if(munmap(pCapture->pBuffers[i].pData, pCapture->pBuffers[i].DataLength))
00608          {
00609             CapError("Failed to munmap buffer[%d]", i);
00610          }
00611          pCapture->pBuffers[i].pData = 0;
00612          pCapture->pBuffers[i].DataLength = 0;
00613       }
00614    }
00615    return 0;
00616 }

int UninitialiseReadCapture ( psCapture  pCapture  ) 

Implementation of UninitialiseReadCapture.

00470 {
00471    if(pCapture->pBuffers[0].pData != 0)
00472    {
00473       free(pCapture->pBuffers[0].pData);
00474       pCapture->pBuffers[0].pData = 0;
00475       pCapture->pBuffers[0].DataLength = 0;
00476    }
00477    return 0;
00478 }

int UninitialiseUserptrCapture ( psCapture  pCapture  ) 

Implementation of UninitialiseUserptrCapture.

00622 {
00623    unsigned int i = 0;
00624    for(i=0; i<pCapture->buffers; i++)
00625    {
00626       if(pCapture->pBuffers[i].pData != 0)
00627       {
00628          CapMessage("Uninitialise userptr buffer[%d](%p) of %u bytes.\n", i,
00629                pCapture->pBuffers[i].pData,
00630                pCapture->pBuffers[i].DataLength);
00631 
00632          free(pCapture->pBuffers[i].pData);
00633          pCapture->pBuffers[i].pData = 0;
00634          pCapture->pBuffers[i].DataLength = 0;
00635       }
00636    }
00637 
00638    return 0;
00639 }


Generated on Fri Jan 20 10:36:57 2017 for Vision Utils by  doxygen 1.4.7