Camera application

Hi, my name is mahesh working as embedded softeware engineer @spanidea systems , Currently working on NVIDIA tx2 development board, So i am trying to write my own application for camera driver. I need help to open camera.

hello maheshavula41,

please access L4T Multimedia API via download center, there’re samples to demonstrate the camera functionality.
you may check Multimedia API Sample Applications for reference.
besides, you may also check developer guide, Approaches for Validating and Testing the V4L2 Driver shows some general commands to access camera sensors.

please review Sensor Software Driver Programming Guide if you would like to have camera driver implementation.
please contact with Jetson Preferred Partners for camera solutions.
thanks

Yes i gone through L4T multimedia API but they were calling their own API’s to open a camera. So here iam writing my own application for camera. Please can anyone explain the flow for opening a camera.

thanks

hello maheshavula41,

please refer to Camera Architecture Stack for the NVIDIA camera software architecture.
you should note that there’re two user-space components to access camera sensors, v4l2src and nvarguscamerasrc.

  • v4l2src is a standard Linux V4L2 application that uses direct kernel IOCTL calls to access camera functionality.
  • nvarguscamerasrc has the options to control ISP properties using the Argus APIs.

if you’re implement your own applications, you should refer to the path of v4l2src.
thanks

i am going through v4l2 direct ioctl calls to access the camera functionality.but still i am not able to open camera, See the below my application code.

#include <errno.h>
#include <fcntl.h>
#include <linux/videodev2.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>

static int xioctl(int fd, int request, void *arg)
{
int r;

    do r = ioctl (fd, request, arg);
    while (-1 == r && EINTR == errno);

    return r;

}

int print_caps(int fd)
{
struct v4l2_capability caps = {};
if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &caps))
{
perror(“Querying Capabilities”);
return 1;
}

    printf( "Driver Caps:\n"
            "  Driver: \"%s\"\n"
            "  Card: \"%s\"\n"
            "  Bus: \"%s\"\n"
            "  Version: %d.%d\n"
            "  Capabilities: %08x\n",
            caps.driver,
            caps.card,
            caps.bus_info,
            (caps.version>>16)&&0xff,
            (caps.version>>24)&&0xff,
            caps.capabilities);

int support_grbg10 = 0;

struct v4l2_fmtdesc fmtdesc = {0};

fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
char fourcc[5] = {0};
char c, e;
printf(" FMT : CE Desc\n--------------------\n");
while (0 == xioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc))
{
strncpy(fourcc, (char *)&fmtdesc.pixelformat, 4);
if (fmtdesc.pixelformat == V4L2_PIX_FMT_SGRBG10)
support_grbg10 = 1;
c = fmtdesc.flags & 1? ‘C’ : ’ ';
e = fmtdesc.flags & 2? ‘E’ : ’ ';
printf(“fourcc= %s\n: frame desc= %s\n”, fourcc, fmtdesc.descri
ption);
printf(“c =%c\n, e=%c\n”, c,e);
fmtdesc.index++;
}

   struct v4l2_format fmt = {0};
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = 640;
    fmt.fmt.pix.height = 480;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
    fmt.fmt.pix.field = V4L2_FIELD_NONE;

    if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt))
    {
        perror("Setting Pixel Format");
        return 1;
    }

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

return 0;

}

int init_mmap(int fd)
{
struct v4l2_requestbuffers req = {0};
req.count = 1;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;

if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req))
struct v4l2_requestbuffers req = {0};
req.count = 1;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;

if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req))
{
    perror("Requesting Buffer");
    return 1;
}

struct v4l2_buffer buf = {0};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
 if(-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
{
    perror("Querying Buffer");
    return 1;
}

buffer = mmap (NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf

.m.offset);
printf(“Length: %d\nAddress: %p\n”, buf.length, buffer);
printf(“Image Length: %d\n”, buf.bytesused);

struct v4l2_buffer buf = {0};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if(-1 == xioctl(fd, VIDIOC_QUERYBUF, &buf))
{
    perror("Querying Buffer");
    return 1;
}

 buffer = mmap (NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf

.m.offset);
printf(“Length: %d\nAddress: %p\n”, buf.length, buffer);
printf(“Image Length: %d\n”, buf.bytesused);

return 0;
}

int capture_image(int fd)
{
struct v4l2_buffer buf = {0};
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if(-1 == xioctl(fd, VIDIOC_QBUF, &buf))
{
perror(“Query Buffer”);
return 1;
}

if(-1 == xioctl(fd, VIDIOC_STREAMON, &buf.type))
    return 1;
}

if(-1 == xioctl(fd, VIDIOC_STREAMON, &buf.type))
{
    perror("Start Capture");
    return 1;
}

fd_set fds;
FD_ZERO(&fds);
FD_SET(fd, &fds);
struct timeval tv = {0};
tv.tv_sec = 2;
int r = select(fd+1, &fds, NULL, NULL, &tv);
if(-1 == r)
{
    perror("Waiting for Frame");
    return 1;
}

if(-1 == xioctl(fd, VIDIOC_DQBUF, &buf))
{
    perror("Retrieving Frame");
    return 1;
}

}

int main()
{
int fd,i;

    fd = open("/dev/video0", O_RDWR);
    if (fd == -1)
    {
            perror("Opening video device");
            return 1;
    }
    if(print_caps(fd))
        return 1;
    if(init_mmap(fd))
     return 1;
    if(capture_image(fd))
      return 1;
     close(fd);


    return 0;

}

please can any one help me to open my camera.

Thanks.

hello maheshavula41,

had you confirmed your camera streaming is accessible with the standard controls,
you might have quick confirmation by v4l2-ctl.
for example,

$ v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=RG10 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=100

@JerryChang,

v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=RG10 --set-ctrl bypass_mode=0 --stream-mmap --stream-count=100

if i run above command camera is working…as expected, but here my senario is different because i am writing my own application by using direct v4l2 ioctl calls.

hello maheshavula41,

may I know what’s the sensor types you’re working with, is it a bayer sensor or YUV sensor.

if you’re working with a YUV sensor.
you might check the L4T Multimedia API for the sample applications.
please refer to 12_camera_v4l2_cuda, to demonstrates how to capture images from a V4L2 YUV type of camera.
thanks

@JerryChang,

Nvidia tx2 using bayer 0v5693 sensor.

Thanks

hello maheshavula41,

you should access L4T sources via download center, then please also refer to below kernel sources for processing sensor streaming as vb2 buffers.
thanks

$l4t-r32.3.1/public_sources/kernel_src/kernel/nvidia/drivers/media/platform/tegra/camera/vi/vi4_fops.c
$l4t-r32.3.1/public_sources/kernel_src/kernel/nvidia/drivers/media/platform/tegra/camera/vi/channel.c