FFMPEG硬件编解码器使用

在前文《视频编解码硬件方案漫谈》中,我们探讨了硬件视频编解码的一般方案。本文将进一步探讨如何在ffmpeg中利用显卡硬件加速音视频编解码。

FFMPEG硬件编解码器使用

一、基本概况

ffmpeg通过对显卡厂商的SDK进行封装和集成,实现了部分硬件编解码功能。

NVIDIA AMD INTEL

编码器xxx_nvencxxx_amfxxxx_qsv解码器xxx_cuvid暂未实现xxxx_qsv

其中,xxx代表编码类型,如h264、h265、mpeg2、vp8、vp9等。此外,ffmpeg中的软件编解码器也可以实现相关硬件加速。例如,在h264解码器中可以使用cuda加速、qsv加速、dxva2加速、d3d11va加速和opencl加速等。

cuda qsv dxva2/d3d11va opencl

应用场景适用于NVIDIA显卡平台,但跨操作系统适用于Intel显卡平台,但跨操作系统适用于Windows操作系统,但跨硬件平台仅支持opencl的硬件平台

二、命令行的使用

在ffmpeg中,如果使用

-vcodec xxx

指定硬件编解码器,否则将使用软件编解码。例如:

ffplay -x 800 -y 600 -vcodec h264_qsv h264.mp4ffplay -x 800 -y 600 -vcodec hevc_qsv 4k_hevc.mp4ffmpeg.exe -i test.ts -vcodec hevc_amf -s 1280x720 output.ts

三、代码中使用

1)使用特定的编解码器

编解码器包由AVCodec描述,其中ID代表一类编码器或解码器。例如,

AV_CODEC_ID_H264

代表h264编解码器,而name代表特定编码器或解码器。通常我们使用

avcodec_find_decoder(ID)

avcodec_find_encoder(ID)

来查找解码器和编码器,默认使用软件编解码。如果需要使用硬件编解码,则使用

avcodec_find_encoder_by_name(name)

avcodec_find_decoder_by_name(name)

来指定编码器。其余代码流程与软件编解码一致。

php订单系统可以整合支付宝接口 php订单系统可以整合支付宝接口

一、系统设置:用Dreamweaver等网页设计软件在代码视图下打开【dddingdan/config.php】系统设置文件,按注释说明进行系统设置。 二、系统使用:WFPHP在线订单系统是无台后的,不用数据库,也不用安装,解压源码包后,先进行系统设置,然后把整个【dddingdan】文件夹上传到服务器。在网页中要插入订单系统的位置,插入系统调用代码: 注意:id=01就表示使用样式01,如果要使

php订单系统可以整合支付宝接口 0 查看详情 php订单系统可以整合支付宝接口

例如:

//codec = avcodec_find_decoder(AV_CODEC_ID_H264);codec = avcodec_find_decoder_by_name("h264_cuvid");if (!codec) {    fprintf(stderr, "Codec not foundn");    exit(1);}

2)使用硬件加速

使用特定编解码器的好处是跨操作系统,无论是Windows还是Linux都使用同一套代码,但缺点是不跨硬件,不同显卡厂商使用不同的编解码器。基于软件编码器的硬件加速则跨硬件显卡,如Windows上的d3d11va硬件加速,无论底层是AMD、Intel还是NVIDIA显卡都适用,相当于Windows系统屏蔽了硬件细节,我们只需调用Windows的API即可。以下是一个基于硬件加速的示例代码:

static AVBufferRef* hw_device_ctx = NULL;static enum AVPixelFormat hw_pix_fmt;static FILE* output_file = NULL;

//硬件加速初始化static int hw_decoder_init(AVCodecContext* ctx, const enum AVHWDeviceType type) {int err = 0;//创建一个硬件设备上下文if ((err = av_hwdevice_ctx_create(&hw_device_ctx, type, NULL, NULL, 0)) hw_device_ctx = av_buffer_ref(hw_device_ctx);return err;}

//获取GPU硬件解码帧的格式static enum AVPixelFormat get_hw_format(AVCodecContext ctx, const enum AVPixelFormat pix_fmts) {const enum AVPixelFormat p;for (p = pix_fmts; p != -1; p++) {if (p == hw_pix_fmt)return p;}fprintf(stderr, "Failed to get HW surface format.n");return AV_PIX_FMT_NONE;}

//解码后数据格式转换,GPU到CPU拷贝,YUV数据dump到文件static int decode_write(AVCodecContext avctx, AVPacket packet) {AVFrame frame = NULL, sw_frame = NULL;AVFrame tmp_frame = NULL;uint8_t buffer = NULL;int size;int ret = 0;

ret = avcodec_send_packet(avctx, packet);if (ret = 0) {    if (!(frame = av_frame_alloc()) || !(sw_frame = av_frame_alloc())) {        fprintf(stderr, "Can not alloc framen");        ret = AVERROR(ENOMEM);        goto fail;    }    ret = avcodec_receive_frame(avctx, frame);    if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {        av_frame_free(&frame);        av_frame_free(&sw_frame);        return 0;    } else if (ret format == hw_pix_fmt) {        /* 将解码后的数据从GPU内存格式转为CPU内存格式,并完成GPU到CPU内存的拷贝*/        if ((ret = av_hwframe_transfer_data(sw_frame, frame, 0)) format, tmp_frame->width, tmp_frame->height, 1);    //分配内存    buffer = (uint8_t *)av_malloc(size);    if (!buffer) {        fprintf(stderr, "Can not alloc buffern");        ret = AVERROR(ENOMEM);        goto fail;    }    //将图片数据拷贝到buffer中(按行拷贝)    ret = av_image_copy_to_buffer(buffer, size, (const uint8_t* const*)tmp_frame->data, (const int*)tmp_frame->linesize, (AVPixelFormat)tmp_frame->format, tmp_frame->width, tmp_frame->height, 1);    if (ret < 0) {        fprintf(stderr, "Can not copy image to buffern");        goto fail;    }    fwrite(buffer, 1, size, output_file);    av_frame_free(&frame);    av_frame_free(&sw_frame);    av_free(buffer);}

fail:av_frame_free(&frame);av_frame_free(&sw_frame);av_free(buffer);return ret;}

int main(int argc, char argv[]) {AVFormatContext input_ctx = NULL;AVCodecContext decoder_ctx = NULL;AVCodec decoder = NULL;AVPacket packet;enum AVHWDeviceType type;int video_stream = -1;AVCodecParameters video = NULL;AVHWDeviceType type = AV_HWDEVICE_TYPE_NONE;const AVCodecHWConfig config = NULL;

if (argc < 4) {    fprintf(stderr, "Usage: %s   n", argv[0]);    return -1;}// 设备类型为:cuda dxva2 qsv d3d11va opencl,通常在windows使用d3d11va或者dxva2type = av_hwdevice_find_type_by_name(argv[1]);if (type == AV_HWDEVICE_TYPE_NONE) {    fprintf(stderr, "Device type %s is not supported.n", argv[1]);    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 -1;}/* open the input file */if (avformat_open_input(&input_ctx, argv[2], NULL, NULL) != 0) {    fprintf(stderr, "Cannot open input file '%s'n", argv[2]);    return -1;}if (avformat_find_stream_info(input_ctx, NULL) < 0) {    fprintf(stderr, "Cannot find stream informationn");    return -1;}for (int i = 0; i nb_streams; i++) {    if (input_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {        video_stream = i;        break;    }}if (video_stream == -1) {    fprintf(stderr, "No video stream foundn");    return -1;}decoder = avcodec_find_decoder(input_ctx->streams[video_stream]->codecpar->codec_id);if (!decoder) {    fprintf(stderr, "Failed to find %s codecn", av_get_media_type_string(AVMEDIA_TYPE_VIDEO));    return -1;}while ((config = avcodec_get_hw_config(decoder, config ? config->config_id + 1 : 0))) {    if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&        config->device_type == type) {        hw_pix_fmt = config->pix_fmt;        break;    }}if (!(decoder_ctx = avcodec_alloc_context3(decoder)))    return AVERROR(ENOMEM);video = input_ctx->streams[video_stream];if (avcodec_parameters_to_context(decoder_ctx, video->codecpar) get_format = get_hw_format;//硬件加速初始化if (hw_decoder_init(decoder_ctx, type) < 0)    return -1;if (avcodec_open2(decoder_ctx, decoder, NULL) = 0) {    if (packet.stream_index == video_stream) {        ret = decode_write(decoder_ctx, &packet);        if (ret < 0)            goto end;    }    av_packet_unref(&packet);}// Flush the decoderpacket.data = NULL;packet.size = 0;ret = decode_write(decoder_ctx, &packet);if (ret < 0)    goto end;

end:fclose(output_file);avcodec_free_context(&decoder_ctx);avformat_close_input(&input_ctx);av_buffer_unref(&hw_device_ctx);

return ret;

}

编译后生成

hw_decoder.exe

,解码生成YUV文件如下:

hw_decoder.exe dxva2 D:videoshevcdemo.ts test.yuv

FFMPEG硬件编解码器使用

由此可见,GPU解码器的利用率高,CPU占用率极低,硬件加速成功。

以上就是FFMPEG硬件编解码器使用的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/848415.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
linux 入门指令
上一篇 2025年11月27日 16:23:02
影像大王!荣耀Magic7 RSR 保时捷设计今天发布
下一篇 2025年11月27日 16:23:05

相关推荐

  • Linux怎么监控特定进程的运行状态

    Linux怎么监控特定进程的运行状态Linux怎么监控特定进程的运行状态Linux怎么监控特定进程的运行状态Linux怎么监控特定进程的运行状态

    监控Linux进程需综合使用ps、top、htop、pgrep和systemctl等工具,结合资源占用、进程状态、日志输出和进程数量判断是否异常,并通过systemd的Restart机制或看门狗脚本实现自动重启,同时利用journalctl、sar、atop及Prometheus+Grafana等方…

    2026年9月21日 用户投稿
    000
  • Laravel中的服务容器(Service Container)是什么?

    laravel中的服务容器是框架的核心组件,充当服务定位器和依赖注入容器。1)它管理类及其依赖,简化依赖管理,提升代码可测试性和可维护性。2)服务容器是应用架构的基石,帮助拆分复杂业务逻辑成独立服务,提高代码灵活性和可扩展性。3)基本用法包括绑定和解析服务,如app()->bind(&#821…

    2026年9月21日
    100
  • 为什么VSCode的语法高亮有时会失效?

    语法高亮失效通常由语言模式识别错误、扩展冲突或配置问题导致。1. 检查右下角语言模式并手动切换为正确类型,确保文件有正确扩展名;2. 禁用近期安装的扩展或以 code –disable-extensions 启动排查冲突;3. 切换至默认主题并检查 settings.json 是否覆盖颜…

    2026年9月21日
    500
  • mysql如何启用binlog日志

    MySQL启用binlog需修改配置文件添加log-bin和server-id,重启服务后执行SHOW VARIABLES LIKE ‘log_bin’验证是否为ON,确认启用。 MySQL启用binlog日志需要修改配置文件并重启服务,同时可进行简单验证确保生效。以下是具体…

    2026年9月21日
    000
  • Linux命令行如何查看登录用户

    Linux命令行如何查看登录用户Linux命令行如何查看登录用户Linux命令行如何查看登录用户Linux命令行如何查看登录用户

    答案是 who、w 和 users 命令用于查看Linux系统登录用户,其中 who 显示登录用户及终端信息,w 还显示用户正在执行的命令和系统负载,users 仅输出用户名列表。 在Linux命令行下,要查看当前系统上有哪些用户登录,最直接、最常用的命令包括 who 、 w 和 users 。它们…

    2026年9月21日 用户投稿
    100
  • 虚拟伴侣AI如何实现智能学习 虚拟伴侣AI自适应训练系统的优化指南

    虚拟伴侣AI如何实现智能学习 虚拟伴侣AI自适应训练系统的优化指南虚拟伴侣AI如何实现智能学习 虚拟伴侣AI自适应训练系统的优化指南虚拟伴侣AI如何实现智能学习 虚拟伴侣AI自适应训练系统的优化指南虚拟伴侣AI如何实现智能学习 虚拟伴侣AI自适应训练系统的优化指南

    通过强化学习、记忆网络、多模态融合、联邦学习与课程学习五大机制,构建虚拟伴侣AI的自适应训练系统:一、利用用户反馈信号驱动PPO算法优化对话策略,结合稀疏奖励补偿提升长期决策质量;二、建立增量式上下文记忆网络,以向量数据库存储并检索用户个性化信息,增强长期依赖建模能力;三、融合文本、语音、打字节奏等…

    2026年9月21日 用户投稿
    100
  • 《忍者龙剑传4》PS版画面对比!Pro有专属模式!

    《忍者龙剑传4》PS版画面对比!Pro有专属模式!《忍者龙剑传4》PS版画面对比!Pro有专属模式!《忍者龙剑传4》PS版画面对比!Pro有专属模式!《忍者龙剑传4》PS版画面对比!Pro有专属模式!

    《忍者龙剑传4》(ninja gaiden 4)作为首款深度适配索尼playstation 5 pro硬件特性的动作大作,已于10月21日正式发售。随着媒体评测全面解禁,游戏凭借极致的战斗体验与技术表现赢得广泛赞誉。 本作在标准版PS5与PS5 Pro上均展现出顶尖水准,但得益于更强的GPU与定制A…

    2026年9月21日 用户投稿
    100
  • 外媒称虚幻5是PS5 Pro的克星:多款大作的优化已“翻车”

    外媒称虚幻5是PS5 Pro的克星:多款大作的优化已“翻车”外媒称虚幻5是PS5 Pro的克星:多款大作的优化已“翻车”外媒称虚幻5是PS5 Pro的克星:多款大作的优化已“翻车”外媒称虚幻5是PS5 Pro的克星:多款大作的优化已“翻车”

    作为PS5的强化版本,PS5 Pro的目标是缩小与当代PC在硬件性能上的差距,借助PSSR技术为玩家带来更流畅的帧率、更强的视觉表现力以及更细腻的图像质量。然而,根据外媒twistedvoxel的最新报道,多款大型游戏的表现问题表明,虚幻五引擎可能正成为PS5 Pro难以攻克的技术瓶颈。 以恐怖大作…

    2026年9月21日 用户投稿
    100
  • mac怎么撤销已发送的信息_Mac撤销已发送信息方法

    答案:Mac上可通过“信息”应用在2分钟内撤回或编辑iMessage消息。操作步骤:1. 悬停消息气泡点击“…”;2. 选择“撤回”或“编辑”;3. 编辑最多5次,超限仅可撤回,对方消息同步删除。 如果您在Mac上使用信息应用发送了消息,但发现内容有误或需要撤回,可以在一定时间内执行撤销操作。此功能…

    2026年9月21日
    000
  • Windows系统下的兼容性问题

    windows兼容性问题严重是因为系统演进快、硬件和软件环境多样。处理此问题需:1.了解目标系统版本和配置;2.使用低版本api或兼容性模式;3.检测操作系统版本并调整程序行为;4.避免依赖特定版本的库,提供多版本安装包;5.考虑硬件依赖性,提供备选方案;6.进行跨版本性能测试和优化。 在Windo…

    2026年9月21日
    000
  • Linux如何限制用户执行特定命令

    Linux如何限制用户执行特定命令Linux如何限制用户执行特定命令Linux如何限制用户执行特定命令Linux如何限制用户执行特定命令

    首选sudo进行命令限制,因其灵活且可审计;通过visudo配置精确的用户权限,结合白名单、命令别名和!语法实现允许或拒绝特定命令;同时防范绕过手段如全路径执行、间接调用、脚本执行等,需多层防御并辅以日志监控。 在Linux环境中,限制用户执行特定命令,最直接有效且灵活的方法通常是利用 sudo 权…

    2026年9月21日 用户投稿
    000
  • 豆包大模型1.6 lite— 字节跳动推出的轻量级AI模型

    豆包大模型1.6 lite— 字节跳动推出的轻量级AI模型豆包大模型1.6 lite— 字节跳动推出的轻量级AI模型豆包大模型1.6 lite— 字节跳动推出的轻量级AI模型豆包大模型1.6 lite— 字节跳动推出的轻量级AI模型

    ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜ 豆包大模型 字节跳动自主研发的一系列大型语言模型 834 查看详情 豆包大模型1.6 lite是什么 豆包大模型1.6 lite(doubao-seed-1.6-lite)是字节跳动推出的轻量级…

    2026年9月21日 用户投稿
    300
  • win11怎么设置默认终端为cmd或powershell_Win11默认终端设置方法

    通过系统设置可更改Windows 11默认终端:1. 进入“设置→隐私与安全性→开发者选项”,在“终端”中选择默认应用;2. 或通过命令提示符属性的“终端”选项卡设定;3. 若使用Windows Terminal,可在其设置中将CMD或PowerShell设为默认配置文件;4. 高级用户可通过修改注…

    2026年9月21日
    100
  • 百度AI开发者大会何时举行_百度AI开发者大会参与指南

    2025百度AI开发者大会于4月25日在武汉体育中心举办,主题为“模型的世界,应用的天下”,发布了两大模型及多款AI应用,参会需通过官网注册报名,审核后获取电子凭证,同时提供线上直播及会后视频回看。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜…

    2026年9月21日
    000
  • 抖音商城是哪个公司在运营

    抖音商城的运营主体揭晓 抖音商城由北京微播视界科技有限公司负责运营。 作为抖音背后的母公司,字节跳动通过其全资子公司——微播视界,全面掌舵抖音平台及其电商板块的日常运作。依托雄厚的技术积累与多元化的业务布局,为用户打造流畅、智能且高效的购物环境。 抖音商城究竟是什么? 抖音商城是抖音App内嵌的一站…

    2026年9月21日
    100
  • Linux如何创建符号链接和硬链接

    Linux如何创建符号链接和硬链接Linux如何创建符号链接和硬链接Linux如何创建符号链接和硬链接Linux如何创建符号链接和硬链接

    符号链接是快捷方式,指向文件或目录路径,原文件删除后链接失效;2. 硬链接共享同一inode,不能跨文件系统或链接目录;3. 使用ln -s创建符号链接,ln创建硬链接;4. 符号链接可跨分区,硬链接删除原文件后仍可访问数据。 在Linux中,创建符号链接(软链接)和硬链接是管理文件和目录的常用操作…

    2026年9月21日 用户投稿
    000
  • mysql如何理解索引选择性

    索引选择性是衡量索引效率的关键指标,定义为索引列不同值数量与总行数的比值,范围在0到1之间。越接近1,数据唯一性越高,索引过滤能力越强,查询性能越好。例如主键列选择性为1,而性别列因重复值多选择性极低。MySQL优化器会优先选择高选择性索引以缩小搜索范围,提高执行效率。可通过SELECT COUNT…

    2026年9月21日
    000
  • 卖不动!iPhone Air暂时停产!库存已经够用了

    据数码博主“定焦数码”透露,苹果iphone air目前已暂停生产。此次调整主要受两方面因素影响:一是该机型在海外市场销量未达预期;二是中国大陆地区的上市时间有所推迟。不过,由于前期已储备了充足的整机库存,当前市场供应不受影响,未来将根据订单积累情况再决定恢复生产的时机。 这一产能变动与此前投资机构…

    2026年9月21日
    000
  • 豆包语音2.0— 字节跳动推出的升级版AI语音模型

    豆包语音2.0是什么 豆包语音2.0是字节跳动推出的升级版ai语音模型,包含两大核心模型:豆包语音合成模型2.0(doubao-seed-tts 2.0)和豆包声音复刻模型2.0(doubao-seed-icl 2.0)。语音合成模型2.0支持对话式合成,可精准理解语义和情感,实现复杂公式朗读,准确…

    2026年9月21日
    100
  • Linux如何查看sudo执行的历史记录

    Linux如何查看sudo执行的历史记录Linux如何查看sudo执行的历史记录Linux如何查看sudo执行的历史记录Linux如何查看sudo执行的历史记录

    要追溯sudo执行的命令,需查看系统日志或配置sudo日志;在Ubuntu/Debian中查/var/log/auth.log,CentOS/RHEL中查/var/log/secure,或使用journalctl _COMM=sudo筛选;通过配置/etc/sudoers中的Defaults log…

    2026年9月21日 用户投稿
    300

发表回复

登录后才能评论
关注微信