PureBasic Forum
https://www.purebasic.fr/english/

V4L2 Cam capture example to PB
https://www.purebasic.fr/english/viewtopic.php?f=15&t=71595
Page 1 of 1

Author:  kevv321 [ Sat Oct 20, 2018 11:26 pm ]
Post subject:  V4L2 Cam capture example to PB

c ++ exampel works
pb error #EAGAIN = 11; / * Try again * /

what is wrong?
can someone help?

c++ exampel:
Code:

/*
 *  V4L2 video capture example
 * see https://linuxtv.org/docs.php for more information
 */
//https://gist.github.com/mike168m/6dd4eb42b2ec906e064d

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <linux/ioctl.h>
#include <linux/types.h>
#include <linux/v4l2-common.h>
#include <linux/v4l2-controls.h>
#include <linux/videodev2.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <string.h>
#include <fstream>
#include <string>
#include <errno.h>
using namespace std;

int main() {


    // 1.  Open the device
    int fd; // A file descriptor to the video device
    fd = open("/dev/video0",O_RDWR);
    if(fd < 0){
        perror("Failed to open device, OPEN");
        return 1;
    }


    // 2. Ask the device if it can capture frames
    v4l2_capability capability;
    if(ioctl(fd, VIDIOC_QUERYCAP, &capability) < 0){
        // something went wrong... exit
        perror("Failed to get device capabilities, VIDIOC_QUERYCAP");
        return 1;
    }


    // 3. Set Image format
    v4l2_format imageFormat;
    imageFormat.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    imageFormat.fmt.pix.width = 1024;
    imageFormat.fmt.pix.height = 1024;
    imageFormat.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
    imageFormat.fmt.pix.field = V4L2_FIELD_NONE;
    // tell the device you are using this format
    if(ioctl(fd, VIDIOC_S_FMT, &imageFormat) < 0){
        perror("Device could not set format, VIDIOC_S_FMT");
        return 1;
    }

    char fourcc[5] = {0};
            strncpy(fourcc, (char *)&imageFormat.fmt.pix.pixelformat, 4);
        printf( "Selected Camera Mode:\n"
                "  Width: %d\n"
                "  Height: %d\n"
                "  PixFmt: %s\n"
                "  Field: %d\n",
                imageFormat.fmt.pix.width,
                imageFormat.fmt.pix.height,
                fourcc,
                imageFormat.fmt.pix.field);




    // 4. Request Buffers from the device
    v4l2_requestbuffers requestBuffer = {0};
    requestBuffer.count = 1; // one request buffer
    requestBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; // request a buffer wich we an use for capturing frames
    requestBuffer.memory = V4L2_MEMORY_MMAP;

    if(ioctl(fd, VIDIOC_REQBUFS, &requestBuffer) < 0){
        perror("Could not request buffer from device, VIDIOC_REQBUFS");
        return 1;
    }


    // 5. Quety the buffer to get raw data ie. ask for the you requested buffer
    // and allocate memory for it
    v4l2_buffer queryBuffer = {0};
    queryBuffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    queryBuffer.memory = V4L2_MEMORY_MMAP;
    queryBuffer.index = 0;
    if(ioctl(fd, VIDIOC_QUERYBUF, &queryBuffer) < 0){
        perror("Device did not return the buffer information, VIDIOC_QUERYBUF");
        return 1;
    }
    // use a pointer to point to the newly created buffer
    // mmap() will map the memory address of the device to
    // an address in memory
    char* buffer = (char*)mmap(NULL, queryBuffer.length, PROT_READ | PROT_WRITE, MAP_SHARED,
                        fd, queryBuffer.m.offset);
    memset(buffer, 0, queryBuffer.length);


    // 6. Get a frame
    // Create a new buffer type so the device knows whichbuffer we are talking about
    v4l2_buffer bufferinfo;
    memset(&bufferinfo, 0, sizeof(bufferinfo));
    bufferinfo.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    bufferinfo.memory = V4L2_MEMORY_MMAP;
    bufferinfo.index = 0;

    // Activate streaming
    if(ioctl(fd, VIDIOC_STREAMON, &bufferinfo.type) < 0){
        perror("Could not start streaming, VIDIOC_STREAMON");
        return 1;
    }

/***************************** Begin looping here *********************/
    // Queue the buffer
    if(ioctl(fd, VIDIOC_QBUF, &bufferinfo) < 0){
        perror("Could not queue buffer, VIDIOC_QBUF");
        return 1;
    }

    // Dequeue the buffer
    if(ioctl(fd, VIDIOC_DQBUF, &bufferinfo) < 0){
        perror("Could not dequeue the buffer, VIDIOC_DQBUF");
        return 1;
    }
    // Frames get written after dequeuing the buffer

    cout << "Buffer has: " << (double)bufferinfo.bytesused / 1024
            << " KBytes of data" << endl;



    // Write the data out to file
    ofstream outFile;
    outFile.open("webcam_output.jpeg", ios::binary| ios::app);
    outFile.write(buffer, (double)bufferinfo.bytesused);
    outFile.close();


/*
    int bufPos = 0, outFileMemBlockSize = 0;  // the position in the buffer and the amoun to copy from
                                        // the buffer
    int remainingBufferSize = bufferinfo.bytesused; // the remaining buffer size, is decremented by
                                                    // memBlockSize amount on each loop so we do not overwrite the buffer
    char* outFileMemBlock = NULL;  // a pointer to a new memory block
    int itr = 0; // counts thenumber of iterations
    while(remainingBufferSize > 0) {

        bufPos += outFileMemBlockSize;  // increment the buffer pointer on each loop
                                        // initialise bufPos before outFileMemBlockSize so we can start
                                        // at the begining of the buffer

        outFileMemBlockSize = 1024;    // set the output block size to a preferable size. 1024 :)
        outFileMemBlock = new char[sizeof(char) * outFileMemBlockSize];

        // copy 1024 bytes of data starting from buffer+bufPos
        memcpy(outFileMemBlock, buffer+bufPos, outFileMemBlockSize);
        outFile.write(outFileMemBlock,outFileMemBlockSize);
        //outFile.write(buffer+bufPos,outFileMemBlockSize);


        // calculate the amount of memory left to read
        // if the memory block size is greater than the remaining
        // amount of data we have to copy
        if(outFileMemBlockSize > remainingBufferSize)
            outFileMemBlockSize = remainingBufferSize;

        // subtract the amount of data we have to copy
        // from the remaining buffer size
        remainingBufferSize -= outFileMemBlockSize;

        // display the remaining buffer size
        cout << itr++ << " Remaining bytes: "<< remainingBufferSize << endl;
    }

    // Close the file
    outFile.close();
*/

/******************************** end looping here **********************/

    // end streaming
    if(ioctl(fd, VIDIOC_STREAMOFF, &bufferinfo.type) < 0){
        perror("Could not end streaming, VIDIOC_STREAMOFF");
        return 1;
    }

    close(fd);
    return 0;
}




c++ PB:
Code:
EnableExplicit

#VIDEO_MAX_FRAME   = 32
#VIDEO_MAX_PLANES  = 8
#VIDIOC_QUERYCAP   = $80685600


#V4L2_FIELD_ANY           = 0 ;/* driver can choose from none,
                              ;top, bottom, interlaced
                              ;depending on whatever it thinks
                              ;is approximate ... */
#V4L2_FIELD_NONE          = 1 ;/* this device has no fields ... */
#V4L2_FIELD_TOP           = 2 ;/* top field only */
#V4L2_FIELD_BOTTOM        = 3 ;/* bottom field only */
#V4L2_FIELD_INTERLACED    = 4 ;/* both fields interlaced */
#V4L2_FIELD_SEQ_TB        = 5 ;/* both fields sequential into one
                              ;buffer, top-bottom order */
#V4L2_FIELD_SEQ_BT        = 6 ;/* same As above + bottom-top order */
#V4L2_FIELD_ALTERNATE     = 7 ;/* both fields alternating into
                              ;separate buffers */
#V4L2_FIELD_INTERLACED_TB = 8 ;/* both fields interlaced, top field
                              ;first And the top field is
                              ;transmitted first */
#V4L2_FIELD_INTERLACED_BT = 9 ;/* both fields interlaced, top field
                              ;first And the bottom field is
                              ;transmitted first */




#V4L2_BUF_TYPE_VIDEO_CAPTURE        = 1
#V4L2_BUF_TYPE_VIDEO_OUTPUT         = 2
#V4L2_BUF_TYPE_VIDEO_OVERLAY        = 3
#V4L2_BUF_TYPE_VBI_CAPTURE          = 4
#V4L2_BUF_TYPE_VBI_OUTPUT           = 5
#V4L2_BUF_TYPE_SLICED_VBI_CAPTURE   = 6
#V4L2_BUF_TYPE_SLICED_VBI_OUTPUT    = 7
;#if 1
;/* Experimental */
#V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8
;#endif
#V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9
#V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE  = 10
#V4L2_BUF_TYPE_SDR_CAPTURE          = 11
#V4L2_BUF_TYPE_SDR_OUTPUT           = 12
;/* Deprecated, do Not use */
#V4L2_BUF_TYPE_PRIVATE              = $80


#V4L2_MEMORY_MMAP             = 1
#V4L2_MEMORY_USERPTR          = 2
#V4L2_MEMORY_OVERLAY          = 3
#V4L2_MEMORY_DMABUF           = 4


#V4L2_CAP_VIDEO_CAPTURE           =   $00000001  ;/* Is a video capture device */
#V4L2_CAP_VIDEO_OUTPUT           =   $00000002  ;/* Is a video output device */
#V4L2_CAP_VIDEO_OVERLAY           =   $00000004  ;/* Can do video overlay */
#V4L2_CAP_VBI_CAPTURE             =   $00000010  ;/* Is a raw VBI capture device */
#V4L2_CAP_VBI_OUTPUT             =   $00000020  ;/* Is a raw VBI output device */
#V4L2_CAP_SLICED_VBI_CAPTURE    = $00000040  ;/* Is a sliced VBI capture device */
#V4L2_CAP_SLICED_VBI_OUTPUT       = $00000080  ;/* Is a sliced VBI output device */
#V4L2_CAP_RDS_CAPTURE             =   $00000100  ;/* RDS Data capture */
#dV4L2_CAP_VIDEO_OUTPUT_OVERLAY =   $00000200  ;/* Can do video output overlay */
#V4L2_CAP_HW_FREQ_SEEK          = $00000400  ;/* Can do hardware frequency seek  */
#V4L2_CAP_RDS_OUTPUT            = $00000800  ;/* Is an RDS encoder */



; //errno-base.h
#EPERM    = 1     ;/* Operation Not permitted */
#ENOENT   = 2     ;/* No such file Or directory */
#ESRCH    = 3     ;/* No such process */
#EINTR    = 4     ;/* Interrupted system call */
#EIO      = 5     ;/* I/O error */
#ENXIO    = 6     ;/* No such device Or address */
#E2BIG    = 7     ;/* Argument List too long */
#ENOEXEC  = 8     ;/* Exec format error */
#EBADF    = 9     ;/* Bad file number */
#ECHILD   = 10   ;/* No child processes */
#EAGAIN   = 11   ;/* Try again */
#ENOMEM   = 12   ;/* Out of memory */
#EACCES   = 13   ;/* Permission denied */
#EFAULT   = 14   ;/* Bad address */
#ENOTBLK  = 15   ;/* Block device required */
#EBUSY    = 16   ;/* Device Or resource busy */
#EEXIST   = 17   ;/* File exists */
#EXDEV    = 18   ;/* Cross-device link */
#ENODEV   = 19   ;/* No such device */
#ENOTDIR  = 20   ;/* Not a directory */
#EISDIR   = 21   ;/* Is a directory */
#EINVAL   = 22   ;/* Invalid argument */
#ENFILE   = 23   ;/* File table overflow */
#EMFILE   = 24   ;/* Too many open files */
#ENOTTY   = 25   ;/* Not a typewriter */
#ETXTBSY  = 26   ;/* Text file busy */
#EFBIG    = 27   ;/* File too large */
#ENOSPC   = 28   ;/* No space left on device */
#ESPIPE   = 29   ;/* Illegal seek */
#EROFS    = 30   ;/* Read-only file system */
#EMLINK   = 31   ;/* Too many links */
#EPIPE    = 32   ;/* Broken pipe */
#EDOM     = 33   ;/* Math argument out of domain of func */
#ERANGE   = 34   ;/* Math result Not representable */









; struct v4l2_capabilityX {
;    __u8   driver[16];
;    __u8   card[32];
;    __u8   bus_info[32];
;    __u32   version;
;    __u32   capabilities;
;    __u32   device_caps;
;    __u32   reserved[3];
; };
Structure v4l2_capability
  driver.b[16]
  card.b[32];
  bus_info.b[32];
  version.l
  capabilities.l;
  device_caps.l;
  reserved.l[3];
EndStructure



; struct v4l2_rect {
;    __s32   left;
;    __s32   top;
;    __u32   width;
;    __u32   height;
; };
Structure v4l2_rect
  left.l
  top.l
  width.l
  height.l
EndStructure



; struct v4l2_fract {
;    __u32   numerator;
;    __u32   denominator;
; };
Structure v4l2_fract
  numerator.l
  denominator.l
EndStructure


; struct v4l2_cropcap {
;    __u32         type;   /* enum v4l2_buf_type */
;    struct v4l2_rect        bounds;
;    struct v4l2_rect        defrect;
;    struct v4l2_fract       pixelaspect;
; };
Structure v4l2_cropcap
  type.l
  bounds.v4l2_rect
  defrect.v4l2_rect
  pixelaspect.v4l2_fract
EndStructure





; struct v4l2_pix_format {
;    __u32               width;
;    __u32         height;
;    __u32         pixelformat;
;    __u32         field;      /* enum v4l2_field */
;    __u32               bytesperline;   /* for padding, zero if unused */
;    __u32                sizeimage;
;    __u32         colorspace;   /* enum v4l2_colorspace */
;    __u32         priv;      /* private data, depends on pixelformat */
;    __u32         flags;      /* format flags (V4L2_PIX_FMT_FLAG_*) */
;    __u32         ycbcr_enc;   /* enum v4l2_ycbcr_encoding */
;    __u32         quantization;   /* enum v4l2_quantization */
;    __u32         xfer_func;   /* enum v4l2_xfer_func */
; };
Structure v4l2_pix_format
  width.l;
  height.l;
  pixelformat.l;
  field.l      ;   /* enum v4l2_field */
  bytesperline.l;   /* for padding, zero if unused */
  sizeimage.l   ;
  colorspace.l  ;   /* enum v4l2_colorspace */
  priv.l        ;   /* private data, depends on pixelformat */
  flags.l       ;   /* format flags (V4L2_PIX_FMT_FLAG_*) */
  ycbcr_enc.l   ;   /* enum v4l2_ycbcr_encoding */
  quantization.l;   /* enum v4l2_quantization */
  xfer_func.l   ;   /* enum v4l2_xfer_func */
EndStructure





; /**
;  * struct v4l2_plane_pix_format - additional, per-plane format definition
;  * @sizeimage:      maximum size in bytes required For Data, For which
;  *         this plane will be used
;  * @bytesperline:   distance in bytes between the leftmost pixels in two
;  *         adjacent lines
;  */
; struct v4l2_plane_pix_format {
;    __u32      sizeimage;
;    __u32      bytesperline;
;    __u16      reserved[6];
; } __attribute__ ((packed));
Structure v4l2_plane_pix_format
  sizeimage.l
  bytesperline.l
  reserved.u[6]
EndStructure





; struct v4l2_sliced_vbi_format {
;    __u16   service_set;
;    /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
;       service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
;              (equals frame lines 313-336 For 625 line video
;               standards, 263-286 For 525 line standards) */
;    __u16   service_lines[2][24];
;    __u32   io_size;
;    __u32   reserved[2];            /* must be zero */
; };

; - TODO service_lines ?
Structure v4l2_sliced_vbi_format
  service_set.u;
               ;    /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
               ;       service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
               ;              (equals frame lines 313-336 For 625 line video
               ;               standards, 263-286 For 525 line standards) */
               ;    __u16   service_lines[2][24];
 
  service_lines.u[48]
  io_size.l;
  reserved.l[2];            /* must be zero */
EndStructure









; /**
;  * struct v4l2_pix_format_mplane - multiplanar format definition
;  * @width:      image width in pixels
;  * @height:      image height in pixels
;  * @pixelformat:   little endian four character code (fourcc)
;  * @field:      enum v4l2_field; field order (for interlaced video)
;  * @colorspace:      enum v4l2_colorspace; supplemental to pixelformat
;  * @plane_fmt:      per-plane information
;  * @num_planes:      number of planes For this format
;  * @flags:      format flags (V4L2_PIX_FMT_FLAG_*)
;  * @ycbcr_enc:      enum v4l2_ycbcr_encoding, Y'CbCr encoding
;  * @quantization:   enum v4l2_quantization, colorspace quantization
;  * @xfer_func:      enum v4l2_xfer_func, colorspace transfer function
;  */
; struct v4l2_pix_format_mplane {
;    __u32            width;
;    __u32            height;
;    __u32            pixelformat;
;    __u32            field;
;    __u32            colorspace;
;
;    struct v4l2_plane_pix_format   plane_fmt[VIDEO_MAX_PLANES];
;    __u8            num_planes;
;    __u8            flags;
;    __u8            ycbcr_enc;
;    __u8            quantization;
;    __u8            xfer_func;
;    __u8            reserved[7];
; } __attribute__ ((packed));
Structure v4l2_pix_format_mplane
  width.l
  height.l
  pixelformat.l
  field.l     
  colorspace.l 
  plane_fmt.v4l2_plane_pix_format[#VIDEO_MAX_PLANES]
  num_planes.b
  flags.b     
  ycbcr_enc.b
  quantization.b
  xfer_func.b   
  reserved.b[7]
EndStructure




; struct v4l2_clip {
;    struct v4l2_rect        c;
;    struct v4l2_clip   *Next;
; };
Structure v4l2_clip
  c.v4l2_rect
  *Next.v4l2_clip
EndStructure



; struct v4l2_window {
;    struct v4l2_rect        w;
;    __u32         field;    /* enum v4l2_field */
;    __u32         chromakey;
;    struct v4l2_clip   *clips;
;    __u32         clipcount;
;    void         *bitmap;
;    __u8                    global_alpha;
; };
Structure v4l2_window
   w.v4l2_rect;
   field.l    ;    /* enum v4l2_field */
   chromakey.l;
    *clips.v4l2_clip;
   clipcount.l     ;
   *bitmap         ;
   global_alpha.b  ;
EndStructure


; struct v4l2_vbi_formatX {
;    __u32   sampling_rate;      /* in 1 Hz */
;    __u32   offset;
;    __u32   samples_per_line;
;    __u32   sample_format;      /* V4L2_PIX_FMT_* */
;    __s32   start[2];
;    __u32   count[2];
;    __u32   flags;         /* V4L2_VBI_* */
;    __u32   reserved[2];      /* must be zero */
; };
Structure v4l2_vbi_format
  sampling_rate.l;      /* in 1 Hz */
  offset.l       ;
  samples_per_line.l;
  sample_format.l   ;      /* V4L2_PIX_FMT_* */
  start.l[2]        ;
  count.l[2]        ;
  flags.l           ;         /* V4L2_VBI_* */
  reserved.l[2]     ;      /* must be zero */
EndStructure


; /**
;  * struct v4l2_sdr_format - SDR format definition
;  * @pixelformat:   little endian four character code (fourcc)
;  * @buffersize:      maximum size in bytes required For Data
;  */
; struct v4l2_sdr_format {
;    __u32            pixelformat;
;    __u32            buffersize;
;    __u8            reserved[24];
; } __attribute__ ((packed));
Structure v4l2_sdr_format
  pixelformat.l
  buffersize.l
  reserved.b[24]
EndStructure


;
; /**
;  * struct v4l2_format - stream Data format
;  * @type:   enum v4l2_buf_type; type of the data stream
;  * @pix:   definition of an image format
;  * @pix_mp:   definition of a multiplanar image format
;  * @win:   definition of an overlaid image
;  * @vbi:   raw VBI capture Or output parameters
;  * @sliced:   sliced VBI capture Or output parameters
;  * @raw_data:   placeholder For future extensions And custom formats
;  */
; struct v4l2_format {
;    __u32    type;
;    union {
;       struct v4l2_pix_format      pix;     /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
;       struct v4l2_pix_format_mplane   pix_mp;  /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
;       struct v4l2_window      win;     /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
;       struct v4l2_vbi_format      vbi;     /* V4L2_BUF_TYPE_VBI_CAPTURE */
;       struct v4l2_sliced_vbi_format   sliced;  /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
;       struct v4l2_sdr_format      sdr;     /* V4L2_BUF_TYPE_SDR_CAPTURE */
;       __u8   raw_data[200];                   /* user-defined */
;    } fmt;
; };
Structure v4l2_format
  type.l
    StructureUnion
      pix.v4l2_pix_format
      pix_mp.v4l2_pix_format_mplane
      win.v4l2_window
      vbi.v4l2_vbi_format
      sliced.v4l2_sliced_vbi_format
      sdr.v4l2_sdr_format
      raw_data.b[200]
    EndStructureUnion
EndStructure



; struct v4l2_crop {
;    __u32         type;   /* enum v4l2_buf_type */
;    struct v4l2_rect        c;
; };
Structure v4l2_crop
   type.l;   /* enum v4l2_buf_type */
   c.v4l2_rect       
EndStructure


; struct v4l2_requestbuffers {
;    __u32         count;
;    __u32         type;      /* enum v4l2_buf_type */
;    __u32         memory;      /* enum v4l2_memory */
;    __u32         reserved[2];
; };
Structure v4l2_requestbuffers
   count.l;
   type.l;          /* enum v4l2_buf_type */
   memory.l;        /* enum v4l2_memory */
   reserved.l[2];
EndStructure


; struct timeval
;   {
;     __time_t tv_sec;      /* Seconds.  */
;     __suseconds_t tv_usec;   /* Microseconds.  */
;   };
; # EndIf   /* struct timeval */
Structure timeval
  tv_sec.l
  tv_usec.l
EndStructure



; struct v4l2_timecode {
;    __u32   type;
;    __u32   flags;
;    __u8   frames;
;    __u8   seconds;
;    __u8   minutes;
;    __u8   hours;
;    __u8   userbits[4];
; };
Structure v4l2_timecode
   type.l;
   flags.l;
   frames.b;
   seconds.b;
   minutes.b;
   hours.b;
   userbits.b[4];
EndStructure


; struct v4l2_plane {
;    __u32         bytesused;
;    __u32         length;
;    union {
;       __u32      mem_offset;
;       unsigned long   userptr;
;       __s32      fd;
;    } m;
;    __u32         data_offset;
;    __u32         reserved[11];
; };
Structure v4l2_plane
   bytesused.l;
   length.l;
   StructureUnion
      mem_offset.l;
      userptr.l;
      fd.l;
   EndStructureUnion
   data_offset.l;
   reserved.l[11];
EndStructure




; struct v4l2_buffer {
;    __u32         index;
;    __u32         type;
;    __u32         bytesused;
;    __u32         flags;
;    __u32         field;
;    struct timeval      timestamp;
;    struct v4l2_timecode   timecode;
;    __u32         sequence;
;
;    /* memory location */
;    __u32         memory;
;    union {
;       __u32           offset;
;       unsigned long   userptr;
;       struct v4l2_plane *planes;
;       __s32      fd;
;    } m;
;    __u32         length;
;    __u32         reserved2;
;    __u32         reserved;
; };
Structure v4l2_buffer
   index.l;
   type.l;
   bytesused.l;
   flags.l;
   field.l;
   timestamp.timeval;
   timecode.v4l2_timecode;
   sequence.l;
   ;/* memory location */
   memory.l;
   StructureUnion
      offset.l;
      userptr.l;
      *planes.v4l2_plane;
      fd.l;
   EndStructureUnion
   length.l;
   reserved2.l;
   reserved.l;
EndStructure







ImportC ""
  open(pathname, flags);
  errno() As "__errno_location"
EndImport

Procedure errexit(msg$)
  perror_(UTF8(msg$))
  Debug "errorcode: "+PeekL(errno())
  Input()
  CloseConsole()
  End
EndProcedure

#EINTR  = 4     ;/* Interrupted system call */
#EINVAL   =   22  ;/* Invalid argument */

#O_RDWR = 2
#O_NONBLOCK  = $800






OpenConsole("")

;// 1.  Open device
Define paht.s = "/dev/video0"
Define fd = open(UTF8(paht), #O_RDWR | #O_NONBLOCK);
If fd = -1
  errexit("ERROR_1 open device")
EndIf


; // 2. Ask the device If it can capture frames
Define capability.v4l2_capability
If ioctl_(fd, #VIDIOC_QUERYCAP, @capability) < 0
  errexit("ERROR_2 VIDIOC_QUERYCAP")
EndIf



; // chek
PrintN("Driver:  " + PeekS(@capability\driver, 16 ,#PB_UTF8))
PrintN("Card:  "   + PeekS(@capability\card, 32 ,#PB_UTF8))
PrintN("Bus:  "    + PeekS(@capability\bus_info, 32 ,#PB_UTF8))
PrintN("Capabilities:  "   + Hex(capability\capabilities, #PB_Long))
PrintN("")
If (Not capability\capabilities & #V4L2_CAP_VIDEO_CAPTURE)
  PrintN("ERROR_3 is no video device")
  End
EndIf



#V4L2_PIX_FMT_YUYV     = 1448695129
#V4L2_PIX_FMT_SGRBG10  = 808534338
#V4L2_PIX_FMT_MJPEG    = 1196444237
#VIDIOC_S_FMT          = 3234616837
; // 3. Set Image format
Define imageFormat.v4l2_format
imageFormat\type = #V4L2_BUF_TYPE_VIDEO_CAPTURE
imageFormat\pix\width = 1024             
imageFormat\pix\height = 1024             
imageFormat\pix\pixelformat = #V4L2_PIX_FMT_MJPEG
imageFormat\pix\field = #V4L2_FIELD_NONE         
; // tell the device you are using this format
If ioctl_(fd, #VIDIOC_S_FMT, @imageFormat) = -1
  errexit("ERROR_4 VIDIOC_S_FMT")
EndIf


; // chek
PrintN("Selected Camera Mode:")
PrintN("Width: "+imageFormat\pix\width)
PrintN("Height: "+imageFormat\pix\height)
PrintN("PixFmt: "+PeekS(@imageFormat\pix\pixelformat, 4, #PB_UTF8))
PrintN("Field: "+imageFormat\pix\field)
PrintN("")




; // 4. Request Buffers from the device
#VIDIOC_REQBUFS = 3222558216
Define requestBuffer.v4l2_requestbuffers
requestBuffer\count = 1                ; // one request buffer
requestBuffer\type = #V4L2_BUF_TYPE_VIDEO_CAPTURE; // request a buffer wich we an use for capturing frames
requestBuffer\memory = #V4L2_MEMORY_MMAP         ;
If ioctl_(fd, #VIDIOC_REQBUFS, @requestBuffer) = -1
  errexit("ERROR_5 VIDIOC_REQBUFS")
EndIf



; // 5. Quety the buffer To get raw Data ie. ask For the you requested buffer
; // And allocate memory For it
#VIDIOC_QUERYBUF = 3225703945
Define queryBuffer.v4l2_buffer
queryBuffer\type = #V4L2_BUF_TYPE_VIDEO_CAPTURE
queryBuffer\memory = #V4L2_MEMORY_MMAP         
queryBuffer\index = 0                         
If ioctl_(fd, #VIDIOC_QUERYBUF, @queryBuffer) = -1
  errexit("ERROR_6 VIDIOC_QUERYBUF")
EndIf



; // use a pointer To point To the newly created buffer
; // mmap() will Map the memory address of the device To
; // an address in memory
#PROT_READ  = $01
#PROT_WRITE = $02
#MAP_SHARED = $01
Define *buffer = mmap_(#Null, queryBuffer\length, #PROT_READ | #PROT_WRITE, #MAP_SHARED, fd, queryBuffer\offset);
memset_(*buffer, 0, queryBuffer\length);



; // 6. Get a frame
; // Create a new buffer type so the device knows whichbuffer we are talking about
; // Activate streaming
#VIDIOC_STREAMON = 1074026002
Define bufferinfo.v4l2_buffer
memset_(@bufferinfo, 0, SizeOf(bufferinfo));
bufferinfo\type = #V4L2_BUF_TYPE_VIDEO_CAPTURE;
bufferinfo\memory = #V4L2_MEMORY_MMAP         ;
bufferinfo\index = 0                         ;
If ioctl_(fd, #VIDIOC_STREAMON, @bufferinfo\type) = -1
  errexit("ERROR_7 VIDIOC_STREAMON")
EndIf


; // Queue the buffer
#VIDIOC_QBUF = 3225703951
If ioctl_(fd, #VIDIOC_QBUF, @bufferinfo) = -1
  errexit("ERROR_7 VIDIOC_QBUF")
EndIf



; // Dequeue the buffer
#VIDIOC_DQBUF = 3225703953
If ioctl_(fd, #VIDIOC_DQBUF, @bufferinfo) = -1     ; <= ERROR = #EAGAIN =========
  errexit("ERROR_8 VIDIOC_DQBUF")
EndIf

; // Frames get written after dequeuing the buffer
PrintN("framesize" + bufferinfo\bytesused)





Input()
CloseConsole()


Author:  vwidmer [ Mon Mar 25, 2019 9:34 pm ]
Post subject:  Re: V4L2 Cam capture example to PB

You ever sort this out?

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/