how to capture bayer image

Hi everyone,

I want to get the raw data of imx219. But “nvgstcapture-1.0 -A -C 5 --capture-auto” just get color image. I guess nvarguscamerasrc have process the bayer raw data to yuv data.

Another way I know v4l2src don’t support raw10, I follow the guide https://developer.ridgerun.com/wiki/index.php?title=Compile_gstreamer_on_Jetson_TX1_and_TX2#Steps_to_patch_gstreamer_to_support_RAW10. but still get negotiated error

$ gst-launch-1.0 -vvv v4l2src ! 'video/x-bayer, width=(int)3280, height=(int)2464, format=(string)rggb, framerate=(fraction)20/1' ! fakesink  silent=false 
Setting pipeline to PAUSED ...
Opening in BLOCKING MODE 
Pipeline is live and does not need PREROLL ...
/GstPipeline:pipeline0/GstFakeSink:fakesink0: last-message = event   ******* (fakesink0:sink) E (type: stream-start (10254), GstEventStreamStart, stream-id=(string)2b7f5679e9f0cee0776e7c9d96ffc3b4682b26f7b8931798b4254fc99bdbde9b, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;) 0x558585b1f0
Setting pipeline to PLAYING ...
New clock: GstSystemClock
ERROR: from element /GstPipeline:pipeline0/GstV4l2Src:v4l2src0: Internal data flow error.
Additional debug info:
gstbasesrc.c(2948): gst_base_src_loop (): /GstPipeline:pipeline0/GstV4l2Src:v4l2src0:
streaming task paused, reason not-negotiated (-4)
Execution ended after 0:00:00.000648909
Setting pipeline to PAUSED ...
Setting pipeline to READY ...
Setting pipeline to NULL ...
Freeing pipeline ...

The third way, I try v4l2 API with follow code just get select timeout

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <getopt.h> 
#include <fcntl.h> 
#include <unistd.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <asm/types.h>
#include <linux/videodev2.h>
#include <linux/fb.h>
#define CLEAR(x) memset (&(x), 0, sizeof (x))
 
struct buffer {
    void * start;
    size_t length;
};
 
static char * dev_name = NULL;
static int fd = -1;
struct buffer * buffers = NULL;
static unsigned int n_buffers = 0;
static int time_in_sec_capture=5;
static int fbfd = -1;
static struct fb_var_screeninfo vinfo;
static struct fb_fix_screeninfo finfo;
static char *fbp=NULL;
static long screensize=0;
 
static void errno_exit (const char * s)
{
    fprintf (stderr, "%s error %d, %s\n",s, errno, strerror (errno));
    exit (EXIT_FAILURE);
}
 
static int xioctl (int fd,int request,void * arg)
{
    int r;
    do r = ioctl (fd, request, arg);
    while (-1 == r && EINTR == errno);
    return r;
}
 
static int read_frame (void)
{
    struct v4l2_buffer buf;
    unsigned int i;
 
    CLEAR (buf);
    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    buf.memory = V4L2_MEMORY_MMAP;
 
    if (-1 == xioctl (fd, VIDIOC_DQBUF, &buf)) {
        switch (errno) {
        case EAGAIN:
        return 0;
        case EIO:   
 
       
 
        default:
            errno_exit ("VIDIOC_DQBUF");
        }
    }
 
    assert (buf.index < n_buffers);
 printf("v4l2_pix_format->field(%d)\n", buf.field);
    //assert (buf.field ==V4L2_FIELD_NONE);
    //process_image (buffers[buf.index].start);
    if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))
        errno_exit ("VIDIOC_QBUF");
 
    return 1;
}
 
static void run (void)
{
    unsigned int count;
    int frames;
    frames = 30 * time_in_sec_capture;
 
    while (frames-- > 0) {
        for (;;) {
            fd_set fds;
            struct timeval tv;
            int r;
            FD_ZERO (&fds);
            FD_SET (fd, &fds);
 
           
            tv.tv_sec = 2;
            tv.tv_usec = 0;
 
            r = select (fd + 1, &fds, NULL, NULL, &tv);
 
            if (-1 == r) {
                if (EINTR == errno)
                    continue;
                errno_exit ("select");
            }
 
            if (0 == r) {
                fprintf (stderr, "frame%d select timeout\n", frames);
                exit (EXIT_FAILURE);
            }
 
            if (read_frame ())
                break;
           
            }
    }
}
 
static void stop_capturing (void)
{
    enum v4l2_buf_type type;
 
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    if (-1 == xioctl (fd, VIDIOC_STREAMOFF, &type))
        errno_exit ("VIDIOC_STREAMOFF");
}
 
static void start_capturing (void)
{
    unsigned int i;
    enum v4l2_buf_type type;
 
    for (i = 0; i < n_buffers; ++i) {
        struct v4l2_buffer buf;
        CLEAR (buf);
 
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = i;
 
        if (-1 == xioctl (fd, VIDIOC_QBUF, &buf))
            errno_exit ("VIDIOC_QBUF");
        }
 
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
    if (-1 == xioctl (fd, VIDIOC_STREAMON, &type))
        errno_exit ("VIDIOC_STREAMON");
   
}
 
static void uninit_device (void)
{
    unsigned int i;
 
    for (i = 0; i < n_buffers; ++i)
        if (-1 == munmap (buffers[i].start, buffers[i].length))
            errno_exit ("munmap");
   
    if (-1 == munmap(fbp, screensize)) {
          printf(" Error: framebuffer device munmap() failed.\n");
          exit (EXIT_FAILURE) ;
        }   
    free (buffers);
}
 
 
static void init_mmap (void)
{
    struct v4l2_requestbuffers req;
 
    printf("into init mmap\n");

    //mmap framebuffer
        fbp = (char *)mmap(NULL,screensize,PROT_READ | PROT_WRITE,MAP_SHARED ,fbfd, 0);
        if ((int)fbp == -1) {
            printf("Error: failed to map framebuffer device to memory.\n");
            exit (EXIT_FAILURE) ;
        }
    memset(fbp, 0, screensize);
    CLEAR (req);
 
    req.count = 4;
    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    req.memory = V4L2_MEMORY_MMAP;
 
    if (-1 == xioctl (fd, VIDIOC_REQBUFS, &req)) {
        if (EINVAL == errno) {
            fprintf (stderr, "%s does not support memory mapping\n", dev_name);
            exit (EXIT_FAILURE);
        } else {
            errno_exit ("VIDIOC_REQBUFS");
        }
    }
 
    if (req.count < 4) {    //if (req.count < 2)
        fprintf (stderr, "Insufficient buffer memory on %s\n",dev_name);
        exit (EXIT_FAILURE);
    }
 
    buffers = calloc (req.count, sizeof (*buffers));
 
    if (!buffers) {
        fprintf (stderr, "Out of memory\n");
        exit (EXIT_FAILURE);
    }
 
    for (n_buffers = 0; n_buffers < req.count; ++n_buffers) {
        struct v4l2_buffer buf;
 
        CLEAR (buf);
 
        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        buf.memory = V4L2_MEMORY_MMAP;
        buf.index = n_buffers;
 
        if (-1 == xioctl (fd, VIDIOC_QUERYBUF, &buf))
            errno_exit ("VIDIOC_QUERYBUF");
 
        buffers[n_buffers].length = buf.length;
        buffers[n_buffers].start =mmap (NULL,buf.length,PROT_READ | PROT_WRITE ,MAP_SHARED,fd, buf.m.offset);
 
        if (MAP_FAILED == buffers[n_buffers].start)
            errno_exit ("mmap");
    }
 
}
 
 
 
static void init_device (void)
{
    struct v4l2_capability cap;
    struct v4l2_cropcap cropcap;
    struct v4l2_crop crop;
    struct v4l2_format fmt;
    unsigned int min;
 
 
    // Get fixed screen information
      if (-1==xioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
            printf("Error reading fixed information.\n");
            exit (EXIT_FAILURE);
        }
 
        // Get variable screen information
    if (-1==xioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
            printf("Error reading variable information.\n");
            exit (EXIT_FAILURE);
      }
    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
 
 
    if (-1 == xioctl (fd, VIDIOC_QUERYCAP, &cap)) {
        if (EINVAL == errno) {
            fprintf (stderr, "%s is no V4L2 device\n",dev_name);
            exit (EXIT_FAILURE);
        } else {
            errno_exit ("VIDIOC_QUERYCAP");
          }
    }
 
    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
        fprintf (stderr, "%s is no video capture device\n",dev_name);
        exit (EXIT_FAILURE);
    }
 
    if (!(cap.capabilities & V4L2_CAP_STREAMING)) {
        fprintf (stderr, "%s does not support streaming i/o\n",dev_name);
        exit (EXIT_FAILURE);
    }
 
   
 
    CLEAR (cropcap);
 
    cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 
    if (0 == xioctl (fd, VIDIOC_CROPCAP, &cropcap)) {
        crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        crop.c = cropcap.defrect;
 
        if (-1 == xioctl (fd, VIDIOC_S_CROP, &crop)) {
            switch (errno) {
            case EINVAL:   
            break;
            default:
            break;
            }
        }
    }else {    }
 
    CLEAR (fmt);
 
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = 3280;//1616; 
    fmt.fmt.pix.height = 2464;//1216;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SRGGB10;//V4L2_PIX_FMT_YUYV;
    fmt.fmt.pix.field = V4L2_FIELD_NONE;//V4L2_FIELD_INTERLACED;
 
    if (-1 == xioctl (fd, VIDIOC_S_FMT, &fmt))
        errno_exit ("VIDIOC_S_FMT");
 
    init_mmap ();
 
}
 
static void close_device (void)
{
    if (-1 == close (fd))
    errno_exit ("close");
    fd = -1;
    close(fbfd);
}
 
static void open_device (void)
{
    struct stat st; 
 
    if (-1 == stat (dev_name, &st)) {
    fprintf (stderr, "Cannot identify '%s': %d, %s\n",dev_name, errno, strerror (errno));
    exit (EXIT_FAILURE);
    }
 
    if (!S_ISCHR (st.st_mode)) {
    fprintf (stderr, "%s is no device/n", dev_name);
    exit (EXIT_FAILURE);
    }
 
    //open framebuffer
        fbfd = open("/dev/fb0", O_RDWR);
        if (fbfd==-1) {
            printf("Error: cannot open framebuffer device.\n");
            exit (EXIT_FAILURE);
        }
 
    //open camera
    fd = open (dev_name, O_RDWR| O_NONBLOCK, 0);
 
    if (-1 == fd) {
    fprintf (stderr, "Cannot open '%s': %d, %s\n",dev_name, errno, strerror (errno));
    exit (EXIT_FAILURE);
    }
}
 
static void usage (FILE * fp,int argc,char ** argv)
{
fprintf (fp,
"Usage: %s [options]\n\n"
"Options:\n"
"-d | --device name Video device name [/dev/video]\n"
"-h | --help Print this message/n"
"-t | --how long will display in seconds\n"
"",
argv[0]);
}
 
static const char short_options [] = "d:ht:";
static const struct option long_options [] = {
{ "device", required_argument, NULL, 'd' },
{ "help", no_argument, NULL, 'h' },
{ "time", no_argument, NULL, 't' },
{ 0, 0, 0, 0 }
};
 
int main (int argc,char ** argv)
{
    dev_name = "/dev/video0";
 
    open_device ();
 
    init_device ();
 
    start_capturing ();
 
    run ();
 
    stop_capturing ();
 
    uninit_device ();
 
    close_device ();
 
    exit (EXIT_SUCCESS);
 
return 0;
}

Any help I appreciated.

This command should grab raw frames for you:

v4l2-ctl -d /dev/video0 --stream-mmap --stream-count="$N_FRAMES" --stream-skip="$N_SKIP" --stream-to="$OUT_FILE"

N_FRAMES is the number of frames to capture, N_SKIP is the number of frames to discard prior to saving frames, and OUT_FILE is where the data is saved to.

If your sensor driver implements multiple modes with identical resolutions you may also need to set the sensor mode (MODE_INDEX is the desired sensor mode index):

v4l2-ctl -d /dev/video0 -csensor_mode="$MODE_INDEX" --stream-mmap --stream-count=$N_FRAMES --stream-skip=$N_SKIP --stream-to=$OUT_FILE

Hi D3_growe,

Thanks for your reply.
I have try your command

v4l2-ctl -d /dev/video0 -csensor_mode="0" --stream-mmap --stream-count="1" --stream-skip="0" --stream-to="v4l2_capture.raw"

I tried many times but only success once, mostly after run the command there is no return and not have any message. How can I get more information about what’s problem. maybe I can find the reason why my code with v4l2 api select timeout.

Additional I checked the v4l2-ctl soure code v4l2-ctl-streaming.cpp in function streaming_set_cap() select return 0 too, seems like the result of my v4l2 api code

//v4l2-ctl-streaming.cpp
static void streaming_set_cap(cv4l_fd &fd, cv4l_fd &exp_fd)
    .................
	while (!eos && !source_change) {
		fd_set read_fds;
		fd_set exception_fds;
		struct timeval tv = { use_poll ? 2 : 0, 0 };
		int r;

		FD_ZERO(&exception_fds);
		FD_SET(fd.g_fd(), &exception_fds);
		FD_ZERO(&read_fds);
		FD_SET(fd.g_fd(), &read_fds);
		r = select(fd.g_fd() + 1, use_poll ? &read_fds : NULL, NULL, &exception_fds, &tv);

		if (r == -1) {
			if (EINTR == errno)
				continue;
			fprintf(stderr, "select error: %s\n",
					strerror(errno));
			goto done;
		}

Normally I would suggest that you enable trace output but, unfortunately, I have read on this forum that is not possible on the Nano.

Are there errors from the kernel? You can view kernel output by running dmesg.

You should not have errors when running v4l2-ctl. You should always get frames (denoted by ‘>’ in the output).

Hi Guys,
Was this issue closed finally?
I meet the same problem on Jetson Nano now. After the command:
v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1 --stream-skip=3 --stream-to=test.raw
is typed, it is hung, no message output.

Also, I add the -T option:
v4l2-ctl -T -d /dev/video0 --stream-mmap --stream-count=1 --stream-skip=3 --stream-to=test.raw
it is the same.

The size of test.raw is zero.

Following is the kernal message I get, could you please help to take a look?
[ 2612.270706] ------------[ cut here ]------------
[ 2612.275418] WARNING: CPU: 0 PID: 11333 at /dvs/git/dirty/git-master_linux/kernel/kernel-4.9/drivers/media/v4l2-core/videobuf2-core.c:1667 __vb2_queue_cancel+0x11c/0x188
[ 2612.290466] Modules linked in: bnep fuse zram overlay spidev nvgpu bluedroid_pm ip_tables x_tables

[ 2612.290619] CPU: 0 PID: 11333 Comm: v4l2-ctl Tainted: G W 4.9.140-tegra #1
[ 2612.290635] Hardware name: NVIDIA Jetson Nano Developer Kit (DT)
[ 2612.290652] task: ffffffc0543fd400 task.stack: ffffffc0f964c000
[ 2612.290677] PC is at __vb2_queue_cancel+0x11c/0x188
[ 2612.290700] LR is at __vb2_queue_cancel+0x34/0x188
[ 2612.290720] pc : [] lr : [] pstate: 60400045
[ 2612.290733] sp : ffffffc0f964fae0
[ 2612.290748] x29: ffffffc0f964fae0 x28: 0000000000000008
[ 2612.290788] x27: ffffff8008f62000 x26: ffffffc0f964fde8
[ 2612.290823] x25: ffffffc0bd7534e8 x24: ffffffc0f4cfd018
[ 2612.290857] x23: 0000000000000001 x22: ffffffc0f503a018
[ 2612.290890] x21: ffffffc0f4c1b800 x20: ffffffc0f503a5d0
[ 2612.290924] x19: ffffffc0f503a5d0 x18: 0000000000000001
[ 2612.290956] x17: 0000000000000001 x16: 0000000000000000
[ 2612.290989] x15: ffffffffffffffff x14: ffffffc0f964fa00
[ 2612.291022] x13: ffffffc0f964f905 x12: 0000000000000400
[ 2612.291055] x11: ffffffc0f964f8c0 x10: ffffffc0f964f8c0
[ 2612.291088] x9 : ffffffc0f964f9c0 x8 : 0000000000000000
[ 2612.291121] x7 : ffffffc0ae1c2780 x6 : ffffffc0dde85881
[ 2612.291153] x5 : ffffff8008530f84 x4 : ffffffbf0377a150
[ 2612.291186] x3 : 0000000180400033 x2 : ffffffc0dde85880
[ 2612.291218] x1 : ffffffc0f90ed8c0 x0 : 0000000000000004

[ 2612.291263] —[ end trace aaa9ca1a2a5c962f ]—
[ 2612.295911] Call trace:
[ 2612.295940] [] __vb2_queue_cancel+0x11c/0x188
[ 2612.295969] [] vb2_core_queue_release+0x2c/0x58
[ 2612.295994] [] _vb2_fop_release+0x84/0xa0
[ 2612.296018] [] tegra_channel_close+0x64/0x140
[ 2612.296039] [] v4l2_release+0x48/0xa0
[ 2612.296068] [] __fput+0x90/0x1d0
[ 2612.296093] [] ____fput+0x20/0x30
[ 2612.296121] [] task_work_run+0xbc/0xd8
[ 2612.296148] [] do_exit+0x2c4/0xa08
[ 2612.296172] [] do_group_exit+0x40/0xa8
[ 2612.296199] [] get_signal+0x26c/0x578
[ 2612.296225] [] do_signal+0x130/0x500
[ 2612.296249] [] do_notify_resume+0x90/0xb0
[ 2612.296270] [] work_pending+0x8/0x10

Hi river,

Please open a new topic for your issue. Thanks