V4L2 Cam capture example to PB

Linux specific forum
kevv321
New User
New User
Posts: 1
Joined: Sat Oct 20, 2018 11:03 pm

V4L2 Cam capture example to PB

Post by kevv321 »

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

what is wrong?
can someone help?

c++ exampel:

Code: Select all


/*
 *  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: Select all

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()

vwidmer
Enthusiast
Enthusiast
Posts: 256
Joined: Mon Jan 20, 2014 6:32 pm

Re: V4L2 Cam capture example to PB

Post by vwidmer »

You ever sort this out?
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
Post Reply