setting/getting camera jpeg compression quality in v4l2 with JPEG pixel format via C/C++

Viewed 3697

Can you please show how to get and set the JPEG compression quality (with JPEG pixel format) in V4L2 via C++?

I can detect the various pixel formats supported by the camera and the corresponding resolutions and frame-rates. I can also select them and capture JPEG images accordingly. However I fail in setting and getting the jpeg quality.

I am using Linux Mint and Logitech c910 camera.

The camera seems to expose this parameter since

v4l2-ctl --all

produces

JPEG Compression Controls

        compression_quality (int)    : min=50 max=87 step=1 default=75 value=75
 [...]

However, the code

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <iostream>
using namespace std;

int main()
{
    int fd = open("/dev/video0", O_RDWR);
    if (fd == -1) 
    {   
        perror("open: "); return 1; 
    }

    {   
        // first option
        v4l2_jpegcompression ctrl={0};
        if(ioctl(fd, VIDIOC_G_JPEGCOMP, &ctrl)<0)
        {
            perror("VIDIOC_G_JPEGCOMP:");
        }
        else
        {
            cout<<"QUALITY:"<<ctrl.quality<<endl; 
        }
    }

    {   
        // second option
        v4l2_ext_control extCtrl={0};
        extCtrl.id = V4L2_CID_JPEG_COMPRESSION_QUALITY;
        extCtrl.size = 0;
        extCtrl.value = 100;

        v4l2_ext_controls extCtrls={0};
        extCtrls.controls = &extCtrl;
        extCtrls.count = 1;
        extCtrls.ctrl_class = V4L2_CTRL_CLASS_JPEG;

        if(ioctl(fd, VIDIOC_G_EXT_CTRLS, &extCtrls)<0)
        { 
             perror("VIDIOC_G_EXT_CTRLS:");
        }
    }

    {   
        // third option
        v4l2_ext_control extCtrl={0};
        extCtrl.id = V4L2_CID_JPEG_COMPRESSION_QUALITY;
        extCtrl.size = 0;
        extCtrl.value = 100;

        v4l2_ext_controls extCtrls={0};
        extCtrls.controls = &extCtrl;
        extCtrls.count = 1;
        extCtrls.ctrl_class = V4L2_CID_JPEG_CLASS;

        if(ioctl(fd, VIDIOC_G_EXT_CTRLS, &extCtrls)<0)
        { 
            perror("VIDIOC_G_EXT_CTRLS V4L2_CID_JPEG_CLASS:");
        }
    }

    close(fd);
    return 0;
}

which can be compiled via

g++ query.cpp -o query.out

produces:

VIDIOC_G_JPEGCOMP:: Inappropriate ioctl for device
VIDIOC_G_EXT_CTRLS:: Invalid argument
VIDIOC_G_EXT_CTRLS V4L2_CID_JPEG_CLASS:: Invalid argument
3 Answers
Related