Декодировать видео в Raspberry Pi без использования OpenMAX?
Я ищу пример декодирования видео на Raspberry Pi напрямую, без использования OpenMAX.
Это объясняет различные уровни мультимедийного программного обеспечения:
Существует дополнительный слой, который здесь не показан, слой " MMAL", который является (я считаю) оберткой Broadcom для OpenMAX. (Если нет, то это будет альтернатива OpenMAX, расположенная поверх драйвера ядра), например, raspivid и raspistill написаны с использованием MMAL.
Я хочу пример видео декодирования, где входной сигнал является сырым H.264, а выходным является либо видео в памяти или видео на экране. Я хочу сделать это, используя VCHIQ напрямую, а не OpenMAX. (В основном из соображений производительности и гибкости)
Этот репозиторий github: https://github.com/raspberrypi/userland/ содержит исходные тексты для всего, что показано выше (оранжевые и зеленые прямоугольники; исходный код самого VCHIQ, реализацию OpenMAX IL поверх VCHIQ, а также реализации OpenGL и EGL,...). Так что в теории этого должно быть достаточно, чтобы начать. Проблема в том, что совершенно неочевидно, как его использовать, даже если вы очень хорошо знакомы с OpenMAX и мультимедийными платформами в целом.
Например: vchiq_bulk_transmit() кажется функцией, которую можно использовать для отправки видео в декодер. Но как инициализировать первый аргумент типа VCHIQ_SERVICE_HANDLE_T
? Куда идут результаты: в фреймбуфере, в дескрипторе результата или...?
РЕДАКТИРОВАТЬ За вознаграждение можно получить либо предоставив рабочий пример декодирования видео с использованием vchiq, пошаговое руководство по API, которое показывает вызывающую последовательность (хотя и не рабочий пример), либо указатель на достаточное количество документации, чтобы написать это. Рабочий пример получит изрядную дополнительную награду:)
2 ответа
У меня нет рабочего примера, но у меня есть пошаговое руководство по API. Вроде, как бы, что-то вроде..
Я нашел следующую функцию, которая демонстрирует, как вы можете вызвать vchiq_bulk_transmit
int32_t vchi_bulk_queue_transmit(VCHI_SERVICE_HANDLE_T handle,
void *data_src,
uint32_t data_size,
VCHI_FLAGS_T flags,
void *bulk_handle)
{
SHIM_SERVICE_T *service = (SHIM_SERVICE_T *)handle;
..
status = vchiq_bulk_transmit(service->handle, data_src,
data_size, bulk_handle, mode);
..
return vchiq_status_to_vchi(status);
}
EXPORT_SYMBOL(vchi_bulk_queue_transmit);
Есть функция для создания VCHI_SERVICE_HANDLE_T
int32_t vchi_service_create(VCHI_INSTANCE_T instance_handle,
SERVICE_CREATION_T *setup,
VCHI_SERVICE_HANDLE_T *handle)
{
VCHIQ_INSTANCE_T instance = (VCHIQ_INSTANCE_T)instance_handle;
SHIM_SERVICE_T *service = service_alloc(instance, setup);
*handle = (VCHI_SERVICE_HANDLE_T)service;
..
return (service != NULL) ? 0 : -1;
}
EXPORT_SYMBOL(vchi_service_create);
Но тебе нужен VCHI_INSTANCE_T
который можно инициализировать здесь
int32_t vchi_initialise(VCHI_INSTANCE_T *instance_handle)
{
VCHIQ_INSTANCE_T instance;
VCHIQ_STATUS_T status;
status = vchiq_initialise(&instance);
*instance_handle = (VCHI_INSTANCE_T)instance;
return vchiq_status_to_vchi(status);
}
EXPORT_SYMBOL(vchi_initialise);
Я думаю, что openmax дает больше производительности при обработке мультимедиа. Вы можете сравнить производительность для этих двух альтернатив, просто запустив соответствующие конвейеры для gstreamer. Для этих действий не требуется программирования, и вы можете использовать gst-launch для этих целей. Плагины Openmax для gstreamer начинаются с префикса 'omx'. Операции кодирования и декодирования прекрасно выполняются с помощью omx, а основной процессор не загружается. Запатентованная реализация для кодирования или декодирования h264 является очень сложной проблемой, и без использования библиотек вы можете потратить на это много лет.