ffmpeg解码器使用
目录
- 1、确定解码器类型
- 2、获取解码器
- 3、打开解码器
- 4、进行解码
1、确定解码器类型
单解封装后得到视频流信息,我们可以从第一帧视频(音频)流信息中获取编码格式,从而确定解码器类型。
(1)定位第一帧音视频流信息
使用循环的方式查找,找到后break退出,代码如下:
int videoStream = -1;int audioStream = -1;for (int i = 0; i < pFormatCtx->nb_streams; i++) //循环查找视频中包含的流信息,{if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) //视频流{videoStream = i;break;}if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audioStream < 0) //音频流{audioStream = i;break;}}
pFormatCtx
:描述一个媒体文件或媒体流的构成和基本信息结构,代码中解封装得到的变量。
(2)得到音视频流编码信息
if (videoStream >= 0)pCodecCtx = pFormatCtx->streams[videoStream]->codec; //查找视频解码器类型if (audioStream >= 0)aCodecCtx = pFormatCtx->streams[audioStream]->codec; ///查找音频解码器类型
2、获取解码器
使用AVCodecID枚举(代码中使用codec_id变量) 获取码流对应的标准,进而选择对应的解码器。
(1)软件解码器 ,使用函数:avcodec_find_decoder
,代码如下:
codec_id = pCodecCtx->codec_id;
pCodec = avcodec_find_decoder(codec_id);
(2)硬件解码器(英伟达、英特尔),使用函数:avcodec_find_decoder_by_name
,代码如下:
-------- 英伟达 --------:
codec_id = pCodecCtx->codec_id;char hardWareDecoderName[32] = {0};if (AV_CODEC_ID_H264 == codec_id)sprintf(hardWareDecoderName, "h264_cuvid");else if (AV_CODEC_ID_HEVC == codec_id)sprintf(hardWareDecoderName, "hevc_cuvid");else if (AV_CODEC_ID_MPEG1VIDEO == codec_id)sprintf(hardWareDecoderName, "mpeg1_cuvid");else if (AV_CODEC_ID_MPEG2VIDEO == codec_id)sprintf(hardWareDecoderName, "mpeg2_cuvid");else if (AV_CODEC_ID_MPEG4 == codec_id)sprintf(hardWareDecoderName, "mpeg4_cuvid");
-------- 英特尔 --------:
codec_id = pCodecCtx->codec_id;char hardWareDecoderName[32] = {0};if (AV_CODEC_ID_H264 == codec_id)sprintf(hardWareDecoderName, "h264_qsv");else if (AV_CODEC_ID_HEVC == codec_id)sprintf(hardWareDecoderName, "hevc_qsv");else if (AV_CODEC_ID_MPEG1VIDEO == codec_id)sprintf(hardWareDecoderName, "mpeg1_qsv");else if (AV_CODEC_ID_MPEG2VIDEO == codec_id)sprintf(hardWareDecoderName, "mpeg2_qsv");else if (AV_CODEC_ID_MPEG4 == codec_id)sprintf(hardWareDecoderName, "mpeg4_qsv");if (strlen(hardWareDecoderName) > 0)pCodec = avcodec_find_decoder_by_name(hardWareDecoderName);
3、打开解码器
使用avcodec_alloc_context3
函数创建编码器,avcodec_open2
函数打开编码器,代码如下:
// 配置解码器pCodecCtx = avcodec_alloc_context3(pCodec); //得到的解码器pCodecCtx->thread_count = 8; //只有软件解码需要配置,解码线程数pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P; //指明像素格式//打开解码器if (avcodec_open2(pCodecCtx, pCodec, nullptr) < 0){//返回参数小于0表示编码器打开失败avcodec_close(pCodecCtx);avcodec_free_context(&pCodecCtx);pCodecCtx = nullptr;}
4、进行解码
解码函数如下,参数输入解码前的码流数据,输出为解码后视频帧pFrame(格式为yuv420p,之前解码器配置的类型),以及放回解码结果。
bool decode(uint8_t *inputbuf, int frame_size)
{AVPacket pkt;av_init_packet(&pkt);pkt.data = inputbuf;pkt.size = frame_size;if (avcodec_send_packet(pCodecCtx, &pkt) != 0){av_packet_unref(&pkt);return false;}while (0 == avcodec_receive_frame(pCodecCtx, pFrame));av_packet_unref(&pkt);return true;
}
补充:
前面初始化配置解码器的时候,并没有设置视频的宽高信息。因为h264的每一帧数据都带有编码的信息,当然也包括这些宽高信息了,因此解码完之后,使用pCodecCtx->width, pCodecCtx->height
便可以知道视频的宽高是多少。
ffmpeg解码器使用相关推荐
- 基于Ffmpeg解码器的简单播放器(a simple audio player based on Ffmpeg)
这是一个基于Ffmpeg解码器的简单播放器,怎么在Windows上编译Ffmpeg可以在网上找到很多,开发环境是Windows XP SP3+VS2008,其中DirectSound控制单元来自jdk ...
- ffmpeg解码器优化
在以前的视频项目中,用到了几种商业版的H.264解码器.虽然性能稳定,支持DXVA或CUDA,在高清视频播放效果上不错,但是存在一个共同的缺陷-存在帧间延迟.经过我的测算,大概有3帧的缓冲延迟.当帧率 ...
- 简单的ffmpeg解码器
ffmpeg解码过程 相关函数的介绍 该代码将解码前的h264码流和解码后的yuv数据都保存为文件 直接贴代码 /*** 最简单的基于FFmpeg的解码器* Simplest FFmpeg Decod ...
- XBMC源代码分析 4:视频播放器(dvdplayer)-解码器(以ffmpeg为例)
XBMC分析系列文章: XBMC源代码分析 1:整体结构以及编译方法 XBMC源代码分析 2:Addons(皮肤Skin) XBMC源代码分析 3:核心部分(core)-综述 本文我们分析XBMC中视 ...
- FFMPEG学习【libavcodec】:编解码器:硬件加速器桥:VDPAU解码器和渲染器
VDPAU硬件加速有两个模块. 1.VDPAU解码. 2.VDPAU演示. VDPAU解码模块使用FFmpeg解析机制解析所有头,并使用VDPAU进行实际解码. 根据当前的实现,实际的解码和渲染(AP ...
- Android NDK开发之旅29 云服务器Ubuntu下搭建NDK环境,并编译FFmpeg
###前言 因为在Linux环境下编译FFmpeg生成库和头文件下比较方便,所以接下来主要操作在Linux环境下进行.但是对于Android NDK 开发新手来说,自己电脑配置Ubuntu Linux ...
- 【Android FFMPEG 开发】FFMPEG 解码 AVPacket 数据到 AVFrame ( AVPacket-解码器 | 初始化 AVFrame | 解码为 AVFrame 数据 )
文章目录 I . FFMPEG 解码 AVPacket 数据到 AVFrame 前置操作 II . FFMPEG 解码 AVPacket 数据到 AVFrame 流程 III . FFMPEG 发送 ...
- FFmpeg再学习 -- FFmpeg+SDL+MFC实现图形界面视频播放器
继续看雷霄骅的 课程资料 - 基于FFmpeg+SDL的视频播放器的制作 最后一篇,主要是想学一下 MFC 创建和配置. 一.创建 MFC 工程 文件->新建->项目->Visual ...
- ffmpeg的内部Video Buffer管理和传送机制
本文主要介绍ffmpeg解码器内部管理Video Buffer的原理和过程,ffmpeg的Videobuffer为内部管理,其流程大致为:注册处理函数->帧级释放->帧级申请->清空 ...
- GitHub 超 20000 Star,最火开源视频库 FFmpeg 这 20 年!
[编者按]不知不觉,FFmpeg 已有 20 个年头了.这 20 年总体看来,FFmpeg 如今已非常成功,但期间也有一些波折. 项目发起人 Fabrice Bellard 曾带领部分开发团队脱离 F ...
最新文章
- 推荐一个工作流自动化工具
- codeforces数学1600day4[贪心数学公式推导CodeForces - 1151D ,思维CodeForces - 1085C,数论同余+组合计数 CodeForces - 1056B]
- Struts2的Action和Servlet有什么联系,区别?
- eclipse git插件配置
- CTFshow php特性 web112
- LESSON 9.4 集成算法的参数空间与网格优化
- Android开发之Java和Calendar日期上一年,上一个月,前一天,前一周的方法
- 树的常见概念,二叉树的性质
- SpringBoot和SpringCloud面试题
- [转]浅谈php web安全
- CSS 动画指南: 原理和实战 (一)
- 数据分析之数据预处理、分析建模、可视化
- 数字信号处理:时域采样定理与频域采样定理
- 理解算法中的时间复杂度,O(1),O(n),O(log2n),O(n^2)
- 肇事逃逸人会受到什么处罚
- MaskNet 这个CTR模型,有点意思
- .[转] 家里有娃娃的请注意,终于把儿歌凑齐了!! 儿歌大全
- SAS初学者笔记---001
- 中南大学电子信息 单片机_沙漠老师讲专业系列三:电子信息类相关专业解读(1)...
- 采购堡垒机时候,选择开源堡垒机还是云堡垒机?
热门文章
- 【C语言】游戏管理系统简单设计
- spyder python下载_Spyder Python软件-Spyder Python下载-最火软件站
- Win制作苹果IOS证书
- gaussian 和gaussview_谈谈Gaussian软件中的guess=mix
- Android 性能优化 (十一) 电量优化全解析 秒变大神
- 图书信息管理系统需求分析
- H3C AP当无线路由器静态IP上网配置
- 用Aria2加速下载数据集等
- dev分支clone时git报错:'origin/dev' is not a commit and a branch 'dev' cannot be created from it
- Orcad Capture CIS 绘制原理图库