如何使用v4l2loopback将图像渲染到/ dev / video0?

问题描述 投票:1回答:1

我一直在尝试将图像渲染到/ dev / video。我可以显示一些东西,但是有些混乱。

[我首先开始尝试渲染普通的RGB24图像(基于此示例https://stackoverflow.com/a/44648382/3818491,但是结果(如下)是加扰的图像。

#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <iostream>
#include <sys/ioctl.h>
#include <linux/videodev2.h>

#include <CImg.h>

#define VIDEO_OUT "/dev/video0" // V4L2 Loopack

#define WIDTH  1280
#define HEIGHT 720

int main() {
    using namespace cimg_library;

    CImg<uint8_t> canvas(WIDTH, HEIGHT, 1, 3);
    const uint8_t red[] = {255, 0, 0};
    const uint8_t purple[] = {255, 0, 255};

    int fd;
    if ((fd = open(VIDEO_OUT, O_RDWR)) == -1) {
      std::cerr << "Unable to open video output!\n";
      return 1;
    }

    struct v4l2_format vid_format;
    vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;

    if (ioctl(fd, VIDIOC_G_FMT, &vid_format) == -1) {
      std::cerr << "Unable to get video format data. Errro: " << errno << '\n';
      return 1;
    }

    size_t framesize = canvas.size();
    int width = canvas.width(), height = canvas.height();

    vid_format.fmt.pix.width       = width;
    vid_format.fmt.pix.height      = height;
    vid_format.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
    vid_format.fmt.pix.sizeimage   = framesize;
    vid_format.fmt.pix.field       = V4L2_FIELD_NONE;

    if (ioctl(fd, VIDIOC_S_FMT, &vid_format) == -1) {
      std::cerr << "Unable to set video format! Errno: " << errno << '\n';
      return 1;
    }

    std::cout << "Stream running!\n";
    while (true) {
      canvas.draw_plasma();
      canvas.draw_rectangle(
        100, 100, 100 + 100, 100 + 100, red, 1);
      canvas.draw_text(5,5, "Hello World!", purple);
      canvas.draw_text(5, 20, "Image freshly rendered with the CImg Library!", red);

      write(fd, canvas.data(), framesize);
    }
}

rgb24 broken

所以,我检查了/ dev / video期望的(似乎是YUV420P。)>

v4l2-ctl --list-formats-ext                                                                                                                                                                              130 ↵

ioctl: VIDIOC_ENUM_FMT
    Type: Video Capture

    [0]: 'YU12' (Planar YUV 4:2:0)
        Size: Discrete 1280x720
            Interval: Discrete 0.033s (30.000 fps)

因此,我尝试转换该格式的帧(使用this代码进行快速测试)。

将规格调整为:

    vid_format.fmt.pix.width       = width;
    vid_format.fmt.pix.height      = height;
    vid_format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
    vid_format.fmt.pix.sizeimage   = width*height*3/2; // size of yuv buffer
    vid_format.fmt.pix.field       = V4L2_FIELD_NONE;

这会导致这种情况(这似乎是由于我收集了yuv420图像的结构,但是仍然渲染不正确)。

yuv420p broken

/ dev / video0有什么期望?

我一直在尝试将图像渲染到/ dev / video。我可以显示一些东西,但是有些混乱。我首先开始尝试渲染普通的RGB24图像(基于此示例...

c++ linux v4l2 v4l2loopback
1个回答
0
投票

[经过大量的破解之后,我设法生成了一个有效的YUYV视频/图像,并发送到/ dev / video0。

© www.soinside.com 2019 - 2024. All rights reserved.