在树莓派上解码视频而不使用OpenMAX?

17
我希望您能提供一个在树莓派上直接解码视频的例子,而不使用OpenMAX。请注意,以下是多媒体软件的不同层次:

Raspberry Pi Architecture

这里有一个额外的层,没有显示出来,叫做 "MMAL" 层,我相信它是一个 Broadcom 对 OpenMAX 的封装。如果不是的话,它可能是一个替代 OpenMAX 的选择,位于内核驱动程序之上。例如,raspivid 和 raspistill 就是使用 MMAL 编写的。

我想要一个视频解码的例子,其中输入是原始的 H.264 格式,输出可以是内存中的视频或屏幕上的视频。我想要直接使用 VCHIQ 进行操作,而不是使用 OpenMAX(主要是出于性能和灵活性方面)。

这个 GitHub 仓库:https://github.com/raspberrypi/userland/ 包含了上面显示的所有内容的源代码(橙色和绿色框中的源代码;VCHIQ 本身的源代码,基于 VCHIQ 的 OpenMAX IL 实现,以及 OpenGL 和 EGL 实现等)。理论上,这应该足以开始工作。问题是,即使对于非常熟悉 OpenMAX 和多媒体框架的人来说,如何使用它也是非常不明显的。

例如:vchiq_bulk_transmit() 似乎是用于将视频发送到解码器的函数。但是如何初始化类型为VCHIQ_SERVICE_HANDLE_T的第一个参数?结果放在哪里,是在帧缓冲区还是在结果处理器中等等...?
编辑:奖励可以通过提供使用vchiq进行视频解码的工作示例、显示调用序列的 API 概览(即使不是工作示例)或足以编写此代码文档的指针来收集。一个工作的示例将得到额外的丰厚奖励 :)

1
不使用OpenMAX有什么特别的原因吗? - drahnr
1
@drahnr:我想要一个API,可以立即获取我的解码数据。OpenMAX IL有一堆缓冲区,对于实现可能会做什么没有特定的限制,它可能会缓冲多个帧,并且在API中没有控制它的方法。我见过一些实现非常慢地返回数据(吞吐量仍然很高,数据只是延迟了)。...我想如果有人想尝试回答这个问题,展示如何在RPi上使用OpenMAX在不到1/60秒内获取解码帧,那也可以。 :) - Alex I
这可能不是你想听到的,但实现H264解码器非常具有挑战性,我不知道有谁会免费编写它(即使你放置了500个声望奖励)。 - karlphillip
2
@karlphillip:已经有解码器了。这只是调用VCHIQ api中的几个函数来设置它,然后传递数据并获取结果的问题。这比实现一个解码器简单得多。谢谢您的关注! - Alex I
1
理论上,可以避免使用VCHIQ DMA以减少一些延迟,但是除非分辨率非常低,否则我怀疑RPI ARM无法以持续60 fps的速度消耗数据。了解您想要做什么将会很有帮助。大多数多媒体高性能用例都涉及在GPU硬件块之间配置管道,尽可能少地进行复制和格式转换。 - Tim Gover
2个回答

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

0

我认为OpenMAX在多媒体处理方面提供了更高的性能。您可以通过运行各自的GStreamer管道来比较这两个选择的性能。对于这些操作,不需要编程,您可以使用gst-launch来完成。GStreamer的OpenMAX插件以“omx”前缀开头。使用omx进行编码和解码操作时,主CPU不会负载。H264编码或解码的专有实现是一个非常困难的问题,如果不使用库,您可能需要花费很多年时间。


Xuch,谢谢你。我觉得你误解了问题,我确实想要使用VideoCore加速来进行解码,但是不想通过OpenMAX API层,而是直接进入更低层的VCHIQ API。CPU负载不是问题。 - Alex I

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接