You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将FFmpeg AVFrame中的CUdeviceptr平面复制到自定义CUDA内存?

FFmpeg CUDA解码帧复制到自定义CUDA内存失败问题排查

问题现象

将FFmpeg(CUDA)解码得到的帧平面复制到自定义CUDA内存时,cuMemcpyDtoD_v2始终返回ErrorInvalidValue,提示AVFrame.data[0]对应的CUdeviceptr无效;已创建并设置CUDA上下文,但cuCtxPushCurrent_v2或cuCtxSetCurrent均无法解决问题。

排查与解决步骤

1. 强制复用FFmpeg的CUDA上下文

FFmpeg初始化CUDA解码器时会创建独立的CUDA上下文,自定义内存分配必须在同一个上下文下进行,否则设备指针无法跨上下文访问:

  • 从FFmpeg的硬件设备上下文中提取CUDA上下文:
// 假设已初始化好解码器的hw_device_ctx
CUcontext ffmpeg_cuda_ctx;
// 通过AVHWDeviceContext提取底层CUDA上下文
AVHWDeviceContext *hw_ctx = (AVHWDeviceContext*)codec_ctx->hw_device_ctx->data;
CUcontext* ctx_ptr = (CUcontext*)hw_ctx->hwctx;
ffmpeg_cuda_ctx = *ctx_ptr;

// 将FFmpeg的上下文设为当前,再执行内存分配和复制操作
cuCtxSetCurrent(ffmpeg_cuda_ctx);
  • 禁止自行创建新的CUDA上下文,否则会导致上下文不匹配,触发ErrorInvalidValue。

2. 正确提取CUDA帧的设备指针

AV_PIX_FMT_CUDA格式的AVFrame中,data[n]直接对应CUdeviceptr,无需通过av_frame_get_plane_buffer提取:

// 确保avFrame的格式是AV_PIX_FMT_CUDA
if (avFrame->format != AV_PIX_FMT_CUDA) {
    // 处理错误:当前帧不是CUDA硬件帧
}

// 直接从data字段获取源指针
CUdeviceptr srcPtr = (CUdeviceptr)avFrame->data[0];

av_frame_get_plane_buffer仅适用于CPU内存帧,对CUDA硬件帧调用会返回错误的内存信息,导致后续复制失败。

3. 验证内存大小匹配

目标内存的分配大小必须与源帧平面的实际大小一致:

  • 计算CUDA帧平面的正确大小:
// 以Y平面为例,linesize[0]是每行字节数,height是帧高度
size_t plane_size = (size_t)avFrame->linesize[0] * avFrame->height;
// 分配目标内存时使用该大小
cuMemAlloc_v2(ref dstPtr, plane_size);

避免使用plane->size(来自av_frame_get_plane_buffer),该值对CUDA帧无效。

4. 输出详细错误信息

通过cuGetErrorString获取错误的具体描述,辅助定位问题:

CUResult error = cuMemcpyDtoD_v2(dstPtr, srcPtr, plane_size);
if (error != CUDA_SUCCESS) {
    const char* err_msg;
    cuGetErrorString(error, &err_msg);
    fprintf(stderr, "CUDA复制错误: %s\n", err_msg);
}

5. 确认FFmpeg CUDA解码器初始化正确

确保解码器已正确关联硬件加速上下文:

// 创建CUDA硬件设备上下文
AVBufferRef* hw_device_ctx = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_CUDA);
if (!hw_device_ctx) {
    // 处理分配失败
}
// 初始化硬件上下文(需传入CUDA设备ID等参数)
if (av_hwdevice_ctx_init(hw_device_ctx) < 0) {
    // 处理初始化失败
}
// 将硬件上下文关联到解码器
codec_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);

解码后的AVFrame必须满足avFrame->hw_frames_ctx != NULL,否则说明未成功解码为CUDA硬件帧。

内容的提问来源于stack exchange,提问作者SexyBoooom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 06:03:29