FFMPEG 帧到 DirectX 表面硬件加速
FFMPEG Frame to DirectX Surface Hardware Accelerated
我使用 ffmpeg 函数解码 h264 帧并在 windows 平台上的 window 中显示。我使用的方法如下(来自FFMPEG Frame to DirectX Surface):
AVFrame *frame;
avcodec_decode_video(_ffcontext, frame, etc...);
lockYourSurface();
uint8_t *buf = getPointerToYourSurfacePixels();
// Create an AVPicture structure which contains a pointer to the RGB surface.
AVPicture pict;
memset(&pict, 0, sizeof(pict));
avpicture_fill(&pict, buf, PIX_FMT_RGB32,
_ffcontext->width, _ffcontext->height);
// Convert the image into RGB and copy to the surface.
img_convert(&pict, PIX_FMT_RGB32, (AVPicture *)frame,
_context->pix_fmt, _context->width, _context->height);
unlockYourSurface();
在代码中,我使用 sws_scale 而不是 img_convert。
当我将表面数据指针传递给sws_scale时(实际上在avpicture_fill中),似乎数据指针实际上是在RAM上而不是在GPU内存上,当我想显示时表面上,好像是把数据搬到了GPU上,然后显示出来。据我所知,CPU 在 RAM 和 GPU 内存之间复制数据时利用率很高。
我如何调用 ffmpeg 直接渲染到 GPU 内存上的表面(而不是 RAM 上的数据指针)?
我找到了这个问题的答案。为了防止在使用 ffmpeg 显示帧时额外使用 cpu,我们不得将帧解码为 RGB。几乎所有的视频文件都被解码为 YUV(这是视频文件中的原始图像格式)。这里的重点是GPU可以直接显示YUV数据而不需要将其转换为RGB。据我所知,使用 ffmpeg 普通版本,解码数据总是在 RAM 上。对于一帧,与相同帧的 RGB 解码等价物相比,YUV 数据量非常小。所以当我们将 YUV 数据移动到 GPU 而不是转换为 RGB 然后再移动到 GPU 时,我们从两个方面加速了操作:
- 不转换为 RGB
- 在 RAM 和 GPU 之间移动的数据量减少了
所以最终整体 CPU 使用率下降了。
我使用 ffmpeg 函数解码 h264 帧并在 windows 平台上的 window 中显示。我使用的方法如下(来自FFMPEG Frame to DirectX Surface):
AVFrame *frame;
avcodec_decode_video(_ffcontext, frame, etc...);
lockYourSurface();
uint8_t *buf = getPointerToYourSurfacePixels();
// Create an AVPicture structure which contains a pointer to the RGB surface.
AVPicture pict;
memset(&pict, 0, sizeof(pict));
avpicture_fill(&pict, buf, PIX_FMT_RGB32,
_ffcontext->width, _ffcontext->height);
// Convert the image into RGB and copy to the surface.
img_convert(&pict, PIX_FMT_RGB32, (AVPicture *)frame,
_context->pix_fmt, _context->width, _context->height);
unlockYourSurface();
在代码中,我使用 sws_scale 而不是 img_convert。
当我将表面数据指针传递给sws_scale时(实际上在avpicture_fill中),似乎数据指针实际上是在RAM上而不是在GPU内存上,当我想显示时表面上,好像是把数据搬到了GPU上,然后显示出来。据我所知,CPU 在 RAM 和 GPU 内存之间复制数据时利用率很高。
我如何调用 ffmpeg 直接渲染到 GPU 内存上的表面(而不是 RAM 上的数据指针)?
我找到了这个问题的答案。为了防止在使用 ffmpeg 显示帧时额外使用 cpu,我们不得将帧解码为 RGB。几乎所有的视频文件都被解码为 YUV(这是视频文件中的原始图像格式)。这里的重点是GPU可以直接显示YUV数据而不需要将其转换为RGB。据我所知,使用 ffmpeg 普通版本,解码数据总是在 RAM 上。对于一帧,与相同帧的 RGB 解码等价物相比,YUV 数据量非常小。所以当我们将 YUV 数据移动到 GPU 而不是转换为 RGB 然后再移动到 GPU 时,我们从两个方面加速了操作:
- 不转换为 RGB
- 在 RAM 和 GPU 之间移动的数据量减少了
所以最终整体 CPU 使用率下降了。