IE盒子

搜索
查看: 127|回复: 0

C++使用ffmpeg硬解码

[复制链接]

1

主题

5

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2023-3-21 08:52:32 | 显示全部楼层 |阅读模式
使用ffmpeg解码video模块,支持3种解码:cpu解码、amd64平台的cuda解码和NX平台的Nvmpi解码 封装库只依赖ffmpeg,测试程序中用到了OpenCV,可用于将帧送往opencv检测程序 ref:
https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/hw_decode.c ref: https://github.com/chinahbcq/ffmpeg_hw_decode  
1.概要

该库希望支持能在一份代码中支持CUDA GPU和CPU模式的切换,也可以选择是否只解码关键帧。主要设计思想如下:
2.判断是否支持CUDA GPU解码

bool support_hwdevice()
{
    AVHWDeviceType type;
    type = av_hwdevice_find_type_by_name(s_hwdevice_name);
    if (type == AV_HWDEVICE_TYPE_NONE)
    {
        fprintf(stderr, "Device type %s is not supported.\n", s_hwdevice_name);
        fprintf(stderr, "Available device types:");
        while ((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE)
            fprintf(stderr, " %s", av_hwdevice_get_type_name(type));
        fprintf(stderr, "\n");
        return false;
    }
    return true;
}该方法对有显卡,但不支持硬解加速的机器不适用,比如部分笔记本。
此时该函数也会返回true,但是解码时候会报Hardware is lacking required capabilities这样的错误。
3.初始化

init_ctx初始化函数主要是对输入的input_ctx和用于解码的decoder_ctx初始化。
3.1GPU解码初始化





说明:

  • 深色框为硬件解码与软解解码不一样的地方。
  • av_hwdevice_find_type_by_name()的功能是根据名称查找对应的AVHWDeviceType。
  • AVHWDeviceType表示硬件加速API的类型,比如AV_HWDEVICE_TYPE_CUDA是nvidia提供的加速API.
  • av_hwdevice_find_type_by_name支持的名称如下所示。
static const char *const hw_type_names[] = {     [AV_HWDEVICE_TYPE_CUDA]   = "cuda",     [AV_HWDEVICE_TYPE_DRM]    = "drm",     [AV_HWDEVICE_TYPE_DXVA2]  = "dxva2",     [AV_HWDEVICE_TYPE_D3D11VA] = "d3d11va",     [AV_HWDEVICE_TYPE_OPENCL] = "opencl",     [AV_HWDEVICE_TYPE_QSV]    = "qsv",     [AV_HWDEVICE_TYPE_VAAPI]  = "vaapi",     [AV_HWDEVICE_TYPE_VDPAU]  = "vdpau",     [AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox",     [AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec", };

  • avcodec_get_hw_config:用于获取编解码器支持的硬件配置AVCodecHWConfig。这里用于获取硬件支持的像素格式。
  • av_hwdevice_ctx_create:av_hwdevice_ctx_create创建硬件设备相关的上下文信息AVHWDeviceContext和对硬件设备进行初始化。
  • decoder_ctx->get_format = get_hw_format ,get_hw_format是向AVCodecContext注册的一个函数,用于协商支持的像素格式。.
音视频免费学习地址:【免费】FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发-学习视频教程-腾讯课堂
【文章福利】小编整理了一些个人觉得比较好的学习书籍、视频资料共享在群文件里面,有需要的可以自行添加哦!~点击1150259293加入(需要自取)




3.2CPU解码初始化


  • cpu解码初始化与GPU不一样的是,调用avcodec_find_decoder寻找合适的decoder,并给decoder context设置类型、高和宽。
4.解码






  • GPU解码与CPU解码的一个区别是,GPU需要调用av_hwframe_transfer_data,该函数拷贝GPU到CPU。
  • av_hwframe_transfer_data:拷贝数据到一个硬件的surface,或者从一个硬件surface拷贝数据,也就是GPU和CPU之间数据拷贝。这里用于GPU拷贝到CPU。
  • 格式

    • GPU解码后数据格式默认类型是从硬件读取,CUDA可能是AV_PIX_FMT_NV12;而CPU解码后的数据一般是YUV数据,比如AV_PIX_FMT_YUV420P。

原文:https://blog.csdn.net/yaningli/article/details/128032093?spm=1001.2100.3001.7377&utm_medium=distribute.pc_feed_blog_category.none-task-blog-classify_tag-3-128032093-null-null.nonecase&depth_1-utm_source=distribute.pc_feed_blog_category.none-task-blog-classify_tag-3-128032093-null-null.nonecase
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表