Как декодировать MJPEG в необработанные RGB (или YUV) данные - PullRequest
0 голосов
/ 07 января 2020

Я использую Video4Linux2, чтобы открыть соединение с камерой, подключенной к моей машине. У меня есть возможность запрашивать данные YUV или MJPEG с моего устройства камеры. Поскольку увеличение запрошенного разрешения с камеры, а также запрос YUV приводит к тому, что программа замедляет скорость, превышающую частоту обновления sh камеры (вероятно, из-за того, что за этот промежуток времени отправляется слишком много данных), мне требуется использовать Данные 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 и др. c, однако мне не удалось найти много информации о том, как использовать их для декодирования mjpeg, откуда я нахожусь. Любая помощь будет принята с благодарностью!

1 Ответ

0 голосов
/ 14 января 2020

Я понял это по источникам, связанным в комментариях. Мой рабочий пример выглядит следующим образом:

// 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);
}

Если это все еще не работает для тех, кто пытается понять то же самое, попробуйте включить «таблицы Хаффмана», которые нужны некоторым камерам, как сказал во втором комментарии.

...