【问题标题】:What is the best way to fill AVFrame.data填充 AVFrame.data 的最佳方法是什么
【发布时间】:2015-12-18 12:34:54
【问题描述】:

我想尽快将 opengl 帧缓冲数据传输到 AVCodec。

我已经使用着色器将 RGB 转换为 YUV 并使用 glReadPixels 读取它

我仍然需要手动填充 AVFrame 数据。有没有更好的办法?

AVFrame *frame;
// Y
frame->data[0][y*frame->linesize[0]+x] = data[i*3];
// U
frame->data[1][y*frame->linesize[1]+x] = data[i*3+1];
// V
frame->data[2][y*frame->linesize[2]+x] = data[i*3+2];

【问题讨论】:

  • 我认为应该可以将数据读回 PBO 并将其映射到客户端地址空间,并在 AVFrame 结构中直接引用该内存。
  • 但是数据格式是YUV数组。我需要单独的数组
  • 您已经可以在着色器中根据需要组织数据。乍一看可能有点不直观,但绝对有可能。

标签: opengl ffmpeg libavcodec avcodec


【解决方案1】:

您可以使用sws_scale。

事实上,你不需要着色器来转换 RGB->YUV。相信我,它不会有非常不同的表现。

swsContext = sws_getContext(WIDTH, HEIGHT, AV_PIX_FMT_RGBA, WIDTH, HEIGHT, AV_PIX_FMT_YUV, SWS_BICUBIC, 0, 0, 0 );
sws_scale(swsContext, (const uint8_t * const *)sourcePictureRGB.data, sourcePictureRGB.linesize, 0, codecContext->height, destinyPictureYUV.data, destinyPictureYUV.linesize);

destinyPictureYUV 中的数据将准备好进入编解码器。

在这个示例中,destinationPictureYUV 是您要填充的AVFrame。尝试这样设置:

AVFrame * frame;
AVPicture destinyPictureYUV;

avpicture_alloc(&destinyPictureYUV, codecContext->pix_fmt, newCodecContext->width, newCodecContext->height);

// THIS is what you want probably
*reinterpret_cast<AVPicture *>(frame) = destinyPictureYUV;

通过此设置,您还可以根据需要在 GPU 中填充已转换为 YUV 的数据...您可以选择所需的方式。

【讨论】:

  • 实际上并不是...sws_scale 是高度优化的。检查我写的最后一次更新...设置命运PictureYUV/frame [带有演员,它们是同一件事],然后尝试直接填充YUV。比较两种方法的性能。我认为不会有太大的不同。
  • 我相信根据您图像的大小会注意到差异。请记住,在 GPU 上完成时您有很多 GPU 内核,而 CPU 上的内核较少。但是,1 个 CPU 内核比 GPU 内核快。这就是为什么有时sws_scale 可以比 GPU 更快的原因。对于非常大的图像,也许 GPU 会有所作为并且速度更快.. 但这只是打赌,我从未对此进行过精确的基准测试。
  • @WagnerPatriota:好吧,sws_scale 的性能可能非常高,但任何适当的基于 GPU 的实现都会以数量级击败它。此外,甚至可以直接在 GPU 上应用一些色度二次采样,从而减少必须读回客户端内存的内存量。
  • @WagnerPatriota:核心数量与此转换完全无关。您将受到 CPU 和 GPU 操作的带宽限制。但 GPU 对于此类操作具有架构优势。内存带宽要高得多,并且图像数据是针对 2D 缓存局部性组织的。现代 GPU 可以轻松地以 200 到 300GB/s 的速度处理这个,而在一个不错的台式机 CPU 上你可以得到十分之一——如果你幸运的话。
  • @derhass,我同意......你是对的。正如我在回答中所说的“它不会有非常不同的表现”,但它当然会,而且我从未对此进行基准测试。但是,我在 GPU 与 CPU 上的某些算法的计时方面有很好的经验,我确信 sws_scale 真的很快。 sws_scale FOR SURE 对于小图像更快。我的赌注是,对于大图像,GPU 会更快。但这只是我的赌注,我建议进行测试!比赌注更好:-)
猜你喜欢
  • 2012-08-30
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
  • 2020-10-14
相关资源
最近更新 更多