当前位置: 首页 > news >正文

ffmpeg硬件解码一般流程

流程

  1. 根据硬件名称,查询是否是支持的类型
const char *device_name = "qsv"; //cuda
enum AVHWDeviceType type = av_hwdevice_find_type_by_name(device_name);
if(type == AV_HWDEVICE_TYPE_NONE)
{//如果一个硬件类型是不支持的,打印所有支持的硬件名称printf("Device type %s is not supported.\n", device_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");
}
  1. 通用过程
avformat_open_input
avformat_find_stream_info
av_find_best_stream
  1. 获取硬件编码器
 AVCodec *pCodec;for (i = 0;; i++) {const AVCodecHWConfig *config = avcodec_get_hw_config(pCodec, i);if (!config) {fprintf(stderr, "Decoder %s does not support device type %s.\n",pCodec->name, av_hwdevice_get_type_name(type));return;}if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&config->device_type == type) {hw_pix_fmt = config->pix_fmt;break;}}
  1. 查找解码器
 if (!(pCodecCtx = avcodec_alloc_context3(pCodec)))return;
  1. 复制参数
 video = pFormatCtx->streams[videoStream];if (avcodec_parameters_to_context(pCodecCtx, video->codecpar) < 0)return;pCodecCtx->get_format = get_hw_format;
  1. 初始化硬件解码器与打开解码器
    if (hw_decoder_init(pCodecCtx, type) < 0)return;
//打开解码器if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {printf("Could not open codec.\n");return;}
  1. 读取视频包,发送视频包到解码器,解码
  2. 将显存中的内容复制内存中
ret = av_hwframe_transfer_data(swFrame, pFrame, 0);if(ret < 0){qDebug() << "Error transferring the data to system memory";break;}

完整的代码

    AVFormatContext *pFormatCtx;AVCodecContext *pCodecCtx;AVCodec *pCodec;AVFrame *pFrame, *pFrameRGB, *swFrame, *tempFrame;uint8_t *out_buffer;AVPacket packet;AVStream *video = NULL;static struct SwsContext *img_convert_ctx;int videoStream, i, numBytes;int ret, got_picture;avformat_network_init();//Allocate an AVFormatContext.pFormatCtx = avformat_alloc_context();const char *device_name = "cuda"; //cudaenum AVHWDeviceType type = av_hwdevice_find_type_by_name(device_name);if(type == AV_HWDEVICE_TYPE_NONE){printf("Device type %s is not supported.\n", device_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");}AVDictionary *opt = nullptr;
//    av_dict_set(&opt,"buffer_size","1024000",0);
//    av_dict_set(&opt,"max_delay","0",0);av_dict_set(&opt,"rtsp_transport","tcp",0);av_dict_set(&opt,"stimeout","5000000",0);if (avformat_open_input(&pFormatCtx, mFileName.toUtf8().data(), NULL, NULL) != 0) {printf("can't open the file. \n");return;}if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {printf("Could't find stream infomation.\n");return;}ret = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &pCodec, 0);if (ret < 0) {fprintf(stderr, "Cannot find a video stream in the input file\n");return;}videoStream = ret;for (i = 0;; i++) {const AVCodecHWConfig *config = avcodec_get_hw_config(pCodec, i);if (!config) {fprintf(stderr, "Decoder %s does not support device type %s.\n",pCodec->name, av_hwdevice_get_type_name(type));return;}if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&config->device_type == type) {hw_pix_fmt = config->pix_fmt;break;}}///查找解码器if (!(pCodecCtx = avcodec_alloc_context3(pCodec)))return;video = pFormatCtx->streams[videoStream];if (avcodec_parameters_to_context(pCodecCtx, video->codecpar) < 0)return;pCodecCtx->get_format = get_hw_format;if (hw_decoder_init(pCodecCtx, type) < 0)return;///打开解码器if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {printf("Could not open codec.\n");return;}pFrame = av_frame_alloc();pFrameRGB = av_frame_alloc();tempFrame = av_frame_alloc();swFrame = av_frame_alloc();///这里我们改成了 将解码后的YUV数据转换成RGB32img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,AV_PIX_FMT_NV12, pCodecCtx->width, pCodecCtx->height,AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);numBytes = avpicture_get_size(AV_PIX_FMT_RGB32, pCodecCtx->width,pCodecCtx->height);out_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));avpicture_fill((AVPicture *) pFrameRGB, out_buffer, AV_PIX_FMT_RGB32,pCodecCtx->width, pCodecCtx->height);av_dump_format(pFormatCtx, 0, mFileName.toUtf8().data(), 0); //输出视频信息while (1){if (av_read_frame(pFormatCtx, &packet) < 0){break; //这里认为视频读取完了}if (packet.stream_index == videoStream) {ret = avcodec_send_packet(pCodecCtx, &packet);if (ret < 0) {printf("decode error.\n");return;}while (1) {ret = avcodec_receive_frame(pCodecCtx, pFrame);if(ret == AVERROR(EAGAIN) || ret == AVERROR_EOF){break;}else if(ret < 0){qDebug() << "Error while decoding";break;}ret = av_hwframe_transfer_data(swFrame, pFrame, 0);if(ret < 0){qDebug() << "Error transferring the data to system memory";break;}sws_scale(img_convert_ctx,(uint8_t const * const *) swFrame->data,swFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data,pFrameRGB->linesize);static int index = 0;qDebug() << "frame" << index++;}}av_packet_unref(&packet);msleep(30); //停一停  不然放的太快了}av_free(out_buffer);av_free(pFrameRGB);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);
  • hw_decoder_init
static enum AVPixelFormat hw_pix_fmt;
static AVBufferRef *hw_device_ctx = 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)) < 0) {fprintf(stderr, "Failed to create specified HW device.\n");return err;}ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);return err;
}
  • get_hw_format
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;
}

相关文章:

ffmpeg硬件解码一般流程

流程 根据硬件名称&#xff0c;查询是否是支持的类型 const char *device_name "qsv"; //cuda enum AVHWDeviceType type av_hwdevice_find_type_by_name(device_name); if(type AV_HWDEVICE_TYPE_NONE) {//如果一个硬件类型是不支持的&#xff0c;打印所有支持…...

微信支付开发-程序开发

一、操作流程图 二、后端代码实现 1、题库实现 a、列表、所有、详情、保存、启禁用、导入答题 b、获取奖品信息、保存奖品信息、 class Question extends Base {// 列表public function getList(){$param $this->request->param();$where [];if(!empty($param[title])…...

【数据结构】排序算法系列——堆排序(附源码+图解)

堆排序 堆排序基于一种常见的**[[二叉树]]结构**&#xff1a;堆 我们前面讲到选择排序&#xff0c;它在待排序的n个记录中选择一个最小的记录需要比较n一1次。本来这也可以理解&#xff0c;查找第一个数据需要比较这么多次是正常的&#xff0c;否则无法知道它是最小的记录。 …...

Linux——应用层自定义协议与序列化

目录 一应用层 1再谈 "协议" 2序列化与反序列化 3理解read,write,recv,send 4Udp vs Tcp 二网络版本计算器 三手写序列和反序列化 四进程间关系与守护进程 1进程组 1.1什么是进程组 1.2组长进程 2会话 2.1什么是会话 2.2会话下的前后台进程 3作业控…...

CGAL 从DSM到DTM-建筑物区域提取

CGAL 从DSM到DTM-建筑物区域提取 生成的DSM被用作DTM计算的基础&#xff0c;即地面表示为过滤掉非地面点后的另一个TIN。主要是去除一些建筑物和植被非地形点。 建筑物立面及连通区域提取 建筑物立面的特征是三角形面片的高度变化剧烈。 通过遍历每一个三角面片&#xff0c;…...

Python--编码解码报错

报错问题 错误信息 UnicodeDecodeError: gbk codec cant decode byte 0xac in position 2: illegal multibyte sequence 通常出现在尝试使用 GBK 编码解码某些二进制数据时&#xff0c;但数据中包含了无法被 GBK 解码的字符。具体错误提示是解码器在处理某个字节时发现该字节无…...

大屏可视化常用图标效果表达

1-echarts-雷达图 2-echarts-仪表盘 3-echarts-水球图&#xff08;利用插件&#xff0c;echarts-liquidfill&#xff09; 4-element UI tree 添加连接线&#xff0c;修改样式或使用插件&#xff08;element-tree-line&#xff09; 5-echarts-漏斗图 6-echarts-饼状图嵌套 optio…...

高通Liunx 系统镜像编译

本文将会介绍如何在编译高通Liunx代码, 具体可以在高通 Linux | 高通下查看相关信息。 编译服务器配置 首先&#xff0c;准备一台Ubuntu 22.04版本主机或者服务器 1&#xff0c;编译Yocto 系统&#xff0c;需要如下一些配置 sudo apt update sudo apt install repo gawk wg…...

105、解析Java中1000个常用类:StringTokenizer类,你学会了吗?

在线工具站 推荐一个程序员在线工具站:程序员常用工具(http://cxytools.com),有时间戳、JSON格式化、文本对比、HASH生成、UUID生成等常用工具,效率加倍嘎嘎好用。程序员资料站 推荐一个程序员编程资料站:程序员的成长之路(http://cxyroad.com),收录了一些列的技术教程…...

虚幻引擎 | 实时语音转口型 Multilingual lipsync

实时语音转口型&#xff1a;EPIC的metahuman sdk&#xff0c;NVIDIA的audio2face&#xff0c;都好。本文使用metahuman sdk 需要工具&#xff1a;Metahuman SDK网页账号&#xff0c;获取两日免费tokens https://space.metahumansdk.io/#/unauthorized ———————————…...

vue国际化

前言 现在的大公司都走国际化路线&#xff0c;我们应用程序也不例外。今天就在 Vue3 项目中整一个比较简单的国际化 背景 之前搞国际化的时候&#xff0c;也搜索了很多帖子&#xff0c;但是没有一个可以完整的实现。今天有空搞了一版&#xff0c;大家有什么问题欢迎留言探讨…...

解决tiktoken库调用get_encoding时SSL超时

文章目录 解决tiktoken库调用get_encoding时SSL超时1. 获取词表文件url2. 手动下载词表文件并保存到本地3. 复制并重命名文件4. 环境变量中设置tiktoken cache5. 使用tiktoken库参考资料 解决tiktoken库调用get_encoding时SSL超时 最近在看Build a Large Language Model (From…...

C++从入门到起飞之——继承上篇 全方位剖析!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C从入门到起飞 &#x1f516;克心守己&#xff0c;律己则安 目录 1、继承的概念 2、继承定义 2.1 定义格式 2.2 继承基类成员访问⽅式的变化 3、继承类模板 4、 基…...

【文件包含】——日志文件注入

改变的确很难&#xff0c;但结果值得冒险 本文主要根据做题内容的总结&#xff0c;如有错误之处&#xff0c;还请各位师傅指正 一.伪协议的失效 当我们做到关于文件包含的题目时&#xff0c;常用思路其实就是使用伪协议&#xff08;php:filter,data,inpput等等&#xff09;执行…...

UE5源码Windows编译、运行

官方文档 Welcome To Unreal Engine 5 Early Access Learn what to expect from the UE5 Early Access program. 链接如下&#xff1a;https://docs.unrealengine.com/5.0/en-US/Welcome/#gettingue5earlyaccessfromgithub Step 0&#xff1a;找到UE5源码 直接先上链接 https…...

AI大模型与产品经理:替代与合作的深度剖析

在创业的征途中&#xff0c;产品经理常常被外界以一种半开玩笑的口吻提及&#xff1a;“就差一个程序员了。”这句话背后&#xff0c;既蕴含着对产品经理创意与策略能力的认可&#xff0c;也揭示了技术实现环节对于产品成功不可或缺的重要性。然而&#xff0c;随着AI技术的飞速…...

资本的运作方式、贷款的评估标准、杠杆率

在资本领域&#xff0c;涉及到多个角色和复杂的运作机制。以下是一些主要的角色及其运作方式&#xff1a; 主要角色 政府&#xff1a; 发行债券&#xff1a;政府通过发行国债和其他债券来筹集资金&#xff0c;用于公共支出和基础设施建设。货币政策&#xff1a;政府通过调节利…...

Python:抓取 Bilibili(B站)评论、弹幕、字幕等

个人学习需求&#xff0c;需要获取一些 UGC&#xff08;user generated content&#xff09;&#xff0c;包括 UP 的内容、弹幕、评论等。于是从 哔哩哔哩 (゜-゜)つロ 干杯~-bilibili 抓取了一些数据&#xff0c;以下内容仅供学习参考。 目录 1. Python 包&#xff1a;bilib…...

Ubuntu系统Docker部署数据库管理工具DbGate并实现远程查询数据

文章目录 前言1. 安装Docker2. 使用Docker拉取DbGate镜像3. 创建并启动DbGate容器4. 本地连接测试5. 公网远程访问本地DbGate容器5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 前言 本文主要介绍如何在Linux Ubuntu系统中使用Docker部署DbGate数…...

18063 圈中的游戏

### 思路 1. 创建一个循环链表表示围成一圈的 n 个人。 2. 从第一个人开始报数&#xff0c;每报到 3 的人退出圈子。 3. 重复上述过程&#xff0c;直到只剩下一个人。 4. 输出最后留下的人的编号。 ### 伪代码 1. 创建一个循环链表&#xff0c;节点表示每个人的编号。 2. 初始…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

前端倒计时误差!

提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

鸿蒙HarmonyOS 5军旗小游戏实现指南

1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发&#xff0c;采用DevEco Studio实现&#xff0c;包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...

C++--string的模拟实现

一,引言 string的模拟实现是只对string对象中给的主要功能经行模拟实现&#xff0c;其目的是加强对string的底层了解&#xff0c;以便于在以后的学习或者工作中更加熟练的使用string。本文中的代码仅供参考并不唯一。 二,默认成员函数 string主要有三个成员变量&#xff0c;…...