Получить кадр из видео с помощью libvlc smem и преобразовать его в opencv Mat. (C ++)
[ОБНОВЛЕНО ЧАСТИЧНЫМ ОТВЕТОМ]
Вот мой код:
void cbVideoPrerender(void *p_video_data, uint8_t **pp_pixel_buffer, int size) {
// Locking
imageMutex.lock();
videoBuffer = (uint8_t *)malloc(size);
*pp_pixel_buffer = videoBuffer;
}
void cbVideoPostrender(void *p_video_data, uint8_t *p_pixel_buffer
, int width, int height, int pixel_pitch, int size, int64_t pts) {
// Unlocking
imageMutex.unlock();
Mat img = Mat(Size(width,height), CV_8UC3, p_pixel_buffer);
//cvtColor(img,img,CV_RGB2BGR);
}
int main(int argc, char ** argv)
{
libvlc_instance_t * inst;
char smem_options[1000];
sprintf(smem_options
, "#transcode{vcodec=RV24}:smem{"
"video-prerender-callback=%lld,"
"video-postrender-callback=%lld,"
"video-data=%lld,"
"no-time-sync},"
, (long long int)(intptr_t)(void*)&cbVideoPrerender
, (long long int)(intptr_t)(void*)&cbVideoPostrender //This would normally be useful data, 100 is just test data
, (long long int)200 //Test data
);
const char * const vlc_args[] = {
"-I", "dummy", // Don't use any interface
"--ignore-config", // Don't use VLC's config
"--extraintf=logger", // Log anything
"--verbose=1", // Be verbose
"--sout", smem_options // Stream to memory
};
// We launch VLC
inst = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
...
return 0;
}
ВОПРОС ОБНОВЛЕНО
Я проверил, что две мои функции обратного вызова кажутся правильно выполненными.
_Какой тип данных выводит RV32? Подходит ли он для CV_8U3C (здесь требуется беззнаковый 8-битный 3-канальный канал? _ Мне нужно добавить шаг в мой класс Mat? (Шаг - количество байтов, занимаемых каждой строкой матрицы)
UPDATED2
Я изменил RV32 на RV24, что имеет больше смысла. Я добавляю cvtColor, потому что матрице Mat требуется пиксель BGR, а не RGB, но изображение по-прежнему отображается неправильно.
_Есть ли vcodec, который выдаст мне формат YUV в качестве выходных данных, чтобы я мог проверить данные пикселей перед тем, как пытаться вывести opencv :: Mat img?
[РЕДАКТИРОВАТЬ ВЫХОД IMG] (Изменяя тип vlc на четырехканальный CV_8UC4 (не знаю почему), мы можем почти видеть кадр, но с очень низким качеством, почему это так?
[РЕШЕНИЕ]
Я обнаружил, что изображения в начале моего видео были низкого качества, поэтому мой Mat imshow () показал мне такую уродливую вещь, что приведенный выше код должен работать сейчас (по-видимому, нет необходимости в cvtColor)