如何将 MJPEG 解码为原始 RGB(或 YUV)数据

How to decode an MJPEG to raw RGB (or YUV) data

我正在使用 Video4Linux2 打开与连接到我的机器的摄像头的连接。我可以从我的相机设备请求 YUV 或 MJPEG 数据。由于增加相机请求的分辨率,同时还请求 YUV,导致程序减慢超过相机的刷新率(可能是因为在这段时间内发送的数据太多),我需要使用来自的 MJPEG 数据相机。我被困了一段时间,在网上找到了很少的关于如何解码 MJPEG 的资源。

顺便说一句,我有以下所有数据:

unsigned char *data; // pointing to the data for the most current mjpeg frame from v4l2
size_t data_size; // the size (in bytes) of the mjpeg frame received from v4l2

unsigned char *r, *g, *b; // three heap allocated arrays in which to store the resulting data
// Can easily be altered to represent an array of structs holding all 3 components,
// as well as using yuv at different rates.

我只需要能够将我的 mjpeg 帧实时 转换为 原始数据,RGB 或 YUV。 我听说过 libjpeg、mjpegtools、nvjpeg 等库,但是我无法找到太多关于如何使用它们从我所在的地方解码 mjpeg 的信息。任何帮助将不胜感激!

我是通过评论中链接的来源弄明白的。我的工作示例如下:

// variables:
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
unsigned int width, height;
// data points to the mjpeg frame received from v4l2.
unsigned char *data;
size_t data_size;
// a *to be allocated* heap array to put the data for
// all the pixels after conversion to RGB.
unsigned char *pixels;

// ... In the initialization of the program:
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
pixels = new unsigned char[width * height * sizeof(Pixel)];

// ... Every frame:
if (!(data == nullptr) && data_size > 0) {
    jpeg_mem_src(&cinfo, data, data_size);
    int rc = jpeg_read_header(&cinfo, TRUE);
    jpeg_start_decompress(&cinfo);

    while (cinfo.output_scanline < cinfo.output_height) {
        unsigned char *temp_array[] = {pixels + (cinfo.output_scanline) * width * 3};
        jpeg_read_scanlines(&cinfo, temp_array, 1);
    }

    jpeg_finish_decompress(&cinfo);
}

如果这对任何试图解决同样问题的人仍然不起作用,请尝试合并 "Huffman tables",如第二条评论中所述,某些相机需要它。