【问题标题】:AVFrame: How to get/replace plane data buffer(s) and size?AVFrame:如何获取/替换平面数据缓冲区和大小?
【发布时间】:2018-12-26 08:42:41
【问题描述】:

我正在研究 gstreamer1.0-libav (1.6.3),试图从 gstreamer 0.10 移植基于 FPGA 的自定义 H264 视频加速。

数据平面 (YUV) 过去在 gstreamer 0.10 中由简单的 malloc 分配,因此我们只需将 AVFrame.data[i] 指针替换为指向视频加速核心中的内存的指针。在 gstreamer 1.12 中似乎要复杂得多。

对于初学者,我尝试将 YUV 平面从 AVFrame.data[i] 复制到单独的缓冲区 - 效果很好!由于我还没有看到获得 AVFrame.data[i] 大小的直接方法,并且我认识到 data[0]、data[1]、data[2] 似乎在一个连续的缓冲区中,所以我只是使用了(data[1] - data [0]) 分别表示 Y 平面的大小和 (data[2] - data[1]) 分别表示 U/V 平面的大小。这工作正常,期待一种情况:

  • 输入 H264 流,分辨率为 800x600 或更高
  • 相机被遮住了(夹克、手……)

这会导致使用如上所述确定的大小在 V 平面 (data[2]) 的 memcpy 中出现 SEGFAULT。在覆盖相机之前,流显示完全正常......所以由于某种原因,暗屏改变了平面尺寸?

我的最终目标是用我的自定义内存分配替换 gstreamer 分配的 data[i] 指针(用于进一步处理)......这些缓冲区的确切分配位置,我可以更改它们以及如何获得每个缓冲区的大小平面(数据[0],数据[1],数据[2])?

【问题讨论】:

    标签: ffmpeg h.264 libavcodec libav gstreamer-1.0


    【解决方案1】:

    不要使用 (data[1] - data [0]) 之类的技巧,平面可能有填充。
    您可以像这样获取缓冲区大小:

    Y = data[0]  
    U = data[1]  
    V = data[2]
    
    YUV444/422 Format:
    Size of data[0] is linesize[0] * AVFrame::height
    Size of data[1] is linesize[1] * AVFrame::height
    Size of data[2] is linesize[2] * AVFrame::height
    
    YUV420 Format:
    Size of data[0] is linesize[0] * AVFrame::height
    Size of data[1] is linesize[1] * (AVFrame::height / 2)
    Size of data[2] is linesize[2] * (AVFrame::height / 2)
    

    如果有 alpha 通道,请使用与 Y 相同的公式。
    希望对您有所帮助。

    【讨论】:

    • 我已经使用 (uv)linesize 和 mb_height 修复了 SEGFAULT(基本上如您所述)。 (data[i+1] - data[i]) hack 有大约 10% 的差异,我仍然不明白当屏幕大部分是黑色时平面大小会发生什么变化或如何变化......但它现在可以工作了所以我可以接受。有没有办法获得飞机的确切大小或更好,你知道飞机分配在哪里吗?填充的确切数量也会很有趣......
    • 这在 FFmpeg 中很复杂(对我来说),想研究成为我的客人.. 检查文件:libavutil/imgutils.c 函数av_image_get_linesizeav_image_fill_linesizes。你会看到 FFmpeg 定义了一些常量并通过AVPixFmtDescriptor 引用它,常量是av_pix_fmt_descriptorspixdesc.c 文件中定义的。 PS.: 分配是在get_video_buffer() 函数中完成的,该函数位于libavutil/frame.c
    • get_video_buffer() 似乎没有被 H264 使用。分配似乎发生在 h264_slice.c 中的 alloc_picture 中……我目前正在深入研究如何分配 data[i]……
    • 我说的是通用 AVFrame 编码,好吧,看来你走对了。
    • 我知道了,飞机分配在get_buffer_internallibavcodec/utils.c。谢谢你的提示!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 2014-04-28
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多