2014-01-06 85 views
1

我即将编写堆栈软件。因此,我想将一个或多个视频文件的帧提取到opencl缓冲区,然后使用opencl kernel进行处理。OpenCL视频处理

但我不知道如何加载视频帧,因为我从来没有使用过视频。 正如我使用opencl我的主要重点显然是高性能

我知道有像ffmpegopencv等图书馆,但因为我没有进入它,我不知道哪一个最适合我的需求。

所以,你可以给我建议哪个库/函数使用最好(最快)与opencl结合使用?

我还没有找到有用的东西。我可以从哪里开始? (类似短的ducumentation或教程将是种)

在此先感谢!

我正在Linux下(不需要跨平台)使用nvidia卡,我的(首选)编程语言是c++。我更喜欢h264作为视频格式,但avi,mov,mp4,...也是可能的。

回答

0

我的一位朋友一直快乐与OpenGL的图像处理框架使用的ffmpeg,所以不该OpenCL也没有任何问题。我会选择通过供应商特定的库。如果您使用OpenCV,请记住您的应用程序可能必须随附OpenCV共享库,即使它不需要所有额外的东西,即在用户计算机上浪费硬盘空间。大约2年前我发现ffmpeg很容易使用。

使用OpenCV读取帧的唯一原因是如果您还需要某些图像处理功能。如果没有,那么我会使用ffmpeg。

1

如果您在Windows上使用AMD GPU并尝试使用AMD Media SDK。

从SemiAcurate网站http://semiaccurate.com/2012/06/18/amd-media-sdk-announced-at-afds/

“AMD的媒体SDK。该SDK的目标是通过API和代码示例展示AMD的固定功能硬件模块和GPU加速功能。在竞争激烈的市场背景下,AMD需要开发人员利用其APU中的基于GPU的功能,以便APU为一般计算工作负载提供切实的好处。为此,AMD正在准备示例应用程序,为开发人员在他们的应用程序中使用API​​创建API,并且使用指南和教程记录所有内容,这是他们创建该媒体SDK的努力的一部分。

http://developer.amd.com/tools-and-sdks/heterogeneous-computing/media-sdk/

我认为它仍处于测试阶段,但有一组例子

http://amd.wpengine.com/app-sdk/codelisting.php?q=Media

+0

谢谢,但我正在用** nvidia卡**在Linux上工作。 (但这可能仍然与其他人有关) – Scindix

+0

那么为什么要使用OpenCL? CUDA通常功能更丰富,并且对视频流处理有更多的支持。 Nvidia对OpenCL的支持仅在1.1规范级别。没有迹象表明这将很快改变。但是,您可以期待英特尔ARM和AMD实施OpenCL 1.2和新的2.0规范。 –

+0

原因是我在OpenCL有一些经验,但在CUDA中没有。我不知道这会有什么不同。不过我想我会试试看。 – Scindix

1

FFmpeg可以是正确的选择,它有很多低级优化&运行速度非常快。

最简单的解码应用程序可以ffmpeg的样品中找到: http://www.ffmpeg.org/doxygen/trunk/doc_2examples_2decoding_encoding_8c-example.html

看一看函数decode_write_frame()。解码图像被存储在结构AVFrame:(我加1个参数 - 为了OpenCL上下文分配对象MEM

static int decode_write_frame(
    const char  *outfilename, 
    AVCodecContext *avctx, 
    AVFrame  *frame, 
    int   *frame_count, 
    AVPacket  *pkt, 
    int   last, 
    cl_context  context) 
{ 
    int len, got_frame; 
    len = avcodec_decode_video2(avctx, frame, &got_frame, pkt); 

    if (len < 0) { 
     fprintf(stderr, "Error while decoding frame %d\n", *frame_count); 
     return len; 
    } 

    cl_int ret_code; 

    //frame->data[0] is Y plane 
    cl_mem y_plane = clCreateBuffer(context, CL_MEM_COPY_HOST_PTR, 
     frame->width * frame->height, frame->data[0], &ret_code); 

    if(ret_code != CL_SUCCESS){ 
     fprintf(stderr, "Error %d occured.\n", ret_code); 
    } 

    //frame->data[1] is Cb plane 
    //frame->data[2] is Cr plane  
    //Remember, that video is usually encoded in YCbCr420, which means that 
    //Cb & Cr planes are smaller than Y plane 2 times in each dimension 

    if (pkt->data) { 
     pkt->size -= len; 
     pkt->data += len; 
    } 
    return 0; 
} 

P. S. 不要混淆的编解码器&容器。 Avi或Mov容器可以存储比特流,该比特流由MPEG4,MPEG2 &其他编码器编码。