ffmpeg硬件解码一般流程
流程
- 根据硬件名称,查询是否是支持的类型
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");
}
- 通用过程
avformat_open_input
avformat_find_stream_info
av_find_best_stream
- 获取硬件编码器
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;}}
- 查找解码器
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;}
- 读取视频包,发送视频包到解码器,解码
- 将显存中的内容复制内存中
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硬件解码一般流程
流程 根据硬件名称,查询是否是支持的类型 const char *device_name "qsv"; //cuda enum AVHWDeviceType type av_hwdevice_find_type_by_name(device_name); if(type AV_HWDEVICE_TYPE_NONE) {//如果一个硬件类型是不支持的,打印所有支持…...
微信支付开发-程序开发
一、操作流程图 二、后端代码实现 1、题库实现 a、列表、所有、详情、保存、启禁用、导入答题 b、获取奖品信息、保存奖品信息、 class Question extends Base {// 列表public function getList(){$param $this->request->param();$where [];if(!empty($param[title])…...
【数据结构】排序算法系列——堆排序(附源码+图解)
堆排序 堆排序基于一种常见的**[[二叉树]]结构**:堆 我们前面讲到选择排序,它在待排序的n个记录中选择一个最小的记录需要比较n一1次。本来这也可以理解,查找第一个数据需要比较这么多次是正常的,否则无法知道它是最小的记录。 …...
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计算的基础,即地面表示为过滤掉非地面点后的另一个TIN。主要是去除一些建筑物和植被非地形点。 建筑物立面及连通区域提取 建筑物立面的特征是三角形面片的高度变化剧烈。 通过遍历每一个三角面片,…...
Python--编码解码报错
报错问题 错误信息 UnicodeDecodeError: gbk codec cant decode byte 0xac in position 2: illegal multibyte sequence 通常出现在尝试使用 GBK 编码解码某些二进制数据时,但数据中包含了无法被 GBK 解码的字符。具体错误提示是解码器在处理某个字节时发现该字节无…...
大屏可视化常用图标效果表达
1-echarts-雷达图 2-echarts-仪表盘 3-echarts-水球图(利用插件,echarts-liquidfill) 4-element UI tree 添加连接线,修改样式或使用插件(element-tree-line) 5-echarts-漏斗图 6-echarts-饼状图嵌套 optio…...
高通Liunx 系统镜像编译
本文将会介绍如何在编译高通Liunx代码, 具体可以在高通 Linux | 高通下查看相关信息。 编译服务器配置 首先,准备一台Ubuntu 22.04版本主机或者服务器 1,编译Yocto 系统,需要如下一些配置 sudo apt update sudo apt install repo gawk wg…...
105、解析Java中1000个常用类:StringTokenizer类,你学会了吗?
在线工具站 推荐一个程序员在线工具站:程序员常用工具(http://cxytools.com),有时间戳、JSON格式化、文本对比、HASH生成、UUID生成等常用工具,效率加倍嘎嘎好用。程序员资料站 推荐一个程序员编程资料站:程序员的成长之路(http://cxyroad.com),收录了一些列的技术教程…...
虚幻引擎 | 实时语音转口型 Multilingual lipsync
实时语音转口型:EPIC的metahuman sdk,NVIDIA的audio2face,都好。本文使用metahuman sdk 需要工具:Metahuman SDK网页账号,获取两日免费tokens https://space.metahumansdk.io/#/unauthorized ———————————…...
vue国际化
前言 现在的大公司都走国际化路线,我们应用程序也不例外。今天就在 Vue3 项目中整一个比较简单的国际化 背景 之前搞国际化的时候,也搜索了很多帖子,但是没有一个可以完整的实现。今天有空搞了一版,大家有什么问题欢迎留言探讨…...
解决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++从入门到起飞之——继承上篇 全方位剖析!
🌈个人主页:秋风起,再归来~🔥系列专栏:C从入门到起飞 🔖克心守己,律己则安 目录 1、继承的概念 2、继承定义 2.1 定义格式 2.2 继承基类成员访问⽅式的变化 3、继承类模板 4、 基…...
【文件包含】——日志文件注入
改变的确很难,但结果值得冒险 本文主要根据做题内容的总结,如有错误之处,还请各位师傅指正 一.伪协议的失效 当我们做到关于文件包含的题目时,常用思路其实就是使用伪协议(php:filter,data,inpput等等)执行…...
UE5源码Windows编译、运行
官方文档 Welcome To Unreal Engine 5 Early Access Learn what to expect from the UE5 Early Access program. 链接如下:https://docs.unrealengine.com/5.0/en-US/Welcome/#gettingue5earlyaccessfromgithub Step 0:找到UE5源码 直接先上链接 https…...
AI大模型与产品经理:替代与合作的深度剖析
在创业的征途中,产品经理常常被外界以一种半开玩笑的口吻提及:“就差一个程序员了。”这句话背后,既蕴含着对产品经理创意与策略能力的认可,也揭示了技术实现环节对于产品成功不可或缺的重要性。然而,随着AI技术的飞速…...
资本的运作方式、贷款的评估标准、杠杆率
在资本领域,涉及到多个角色和复杂的运作机制。以下是一些主要的角色及其运作方式: 主要角色 政府: 发行债券:政府通过发行国债和其他债券来筹集资金,用于公共支出和基础设施建设。货币政策:政府通过调节利…...
Python:抓取 Bilibili(B站)评论、弹幕、字幕等
个人学习需求,需要获取一些 UGC(user generated content),包括 UP 的内容、弹幕、评论等。于是从 哔哩哔哩 (゜-゜)つロ 干杯~-bilibili 抓取了一些数据,以下内容仅供学习参考。 目录 1. Python 包: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. 从第一个人开始报数,每报到 3 的人退出圈子。 3. 重复上述过程,直到只剩下一个人。 4. 输出最后留下的人的编号。 ### 伪代码 1. 创建一个循环链表,节点表示每个人的编号。 2. 初始…...
多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
R语言AI模型部署方案:精准离线运行详解
R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
Java-41 深入浅出 Spring - 声明式事务的支持 事务配置 XML模式 XML+注解模式
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
