FFmepg视频解码

news2024/12/30 2:51:05

1 前言

上一篇文章<FFmpeg下载安装及Windows开发环境设置>介绍了FFmpeg的下载安装及环境配置,本文介绍最简单的FFmpeg视频解码示例。

2 视频解码过程

本文只讨论视频解码。
FFmpeg视频解码的过程比较简单,实际就4步:

  1. 打开媒体流获取编码格式;
  2. 循环获取解码帧
  3. 显示图像
  4. 关闭流

实际上前两步即已实现视频解码。

2.1 打开媒体流获取编码格式

1 打开流文件
这个函数avformat_open_input打开一个媒体流并读取其头信息,对于实时流或者不包含头信息的视频流,此函数通过几帧数据分析以获取其信息
此函数支持的媒体流非常广泛,包括本地视频文件、远程视频流、TCP码流、UDP码流等等都支持。

m_pFmtCtx = nullptr;
ret = avformat_open_input(&m_pFmtCtx, sVideoUrl.c_str(), nullptr, nullptr);

2 在媒体流中寻找视频流
一个媒体流中可能包含了视频、音频、字幕、文本等多个流,到底哪个是我们要的视频流,需要首先确定,这个实际有两种方法,方法1是遍历媒体中所有的流,检查流类型判断哪个是视频流,找到视频流后获取其解码器

	m_nIndexVideo = -1;
	AVCodec* pAVCodec;
	//method 1
	for (i = 0; i < m_pFmtCtx->nb_streams; i++)
	{
		if (m_pFmtCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
		{
			m_nIndexVideo = i;
			break;
		}
	}
	if (m_nIndexVideo < 0)
		return false;
	pAVCodec = (AVCodec*)avcodec_find_decoder(m_pFmtCtx->streams[m_nIndexVideo]->codecpar->codec_id);

方法2就更简单,直接av_find_best_stream按视频格式查找最符合的流,并直接返回视频流序号及相应的解码器

	m_nIndexVideo = av_find_best_stream(m_pFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, (const AVCodec**)&pAVCodec, 0);

此两种方法结果是同样的,选择其中一种方法使用即可。
3 分配解码器
根据视频流解码格式分配及设置解码器,此处得到的解码器m_pAVCodecCtx即可用于后续的连续帧的解码了

	m_pAVCodecCtx = avcodec_alloc_context3(pAVCodec);
	if (m_pAVCodecCtx == nullptr)return false;
	ret = avcodec_parameters_to_context(m_pAVCodecCtx, m_pFmtCtx->streams[m_nIndexVideo]->codecpar);

4 准备解码
调用函数avcodec_open2后,即可开始解码

	ret = avcodec_open2(m_pAVCodecCtx, pAVCodec, nullptr);

至此,一个媒体流的视频流解码工作就准备好了,可以进行获取和解码视频帧了。

2.2 获取解码帧

获取解码帧的过程是:得到一个流原始包(AVPacket),用以上的解码器从这个包里解出视频帧(AVFrame),具体过程如下:
1 用函数av_read_frame从流中取出一个帧包,此包为流中的原始数据,未解码的。
前面说过,一个媒体流中可能包含了多个流,所以av_read_frame获取的数据包不一定是我们想要的视频流包,需要根据这个包所在流的序号来判断是不是属于前面确定视频流的包。

while (1)
{
	ret = av_read_frame(m_pFmtCtx, m_pPkt);
	if (ret < 0)return nullptr;
	if (m_pPkt->stream_index == m_nIndexVideo)
		break;
}

2 解码这个包,获取一帧解码图像
用前面获得的解码器m_pAVCodecCtx对这个包进行解码,获得AVFrame。

	avcodec_send_packet(m_pAVCodecCtx, m_pPkt);
	avcodec_receive_frame(m_pAVCodecCtx, m_pFrame);

此时获得的m_pFrame即为已解码出的一幅视频帧,为一个AVFrame结构,此结构中包含了图像数据、宽高、格式等等信息,可以用于显示、存储等后续工作。

2.3 显示图像帧

有很多软件架构支持直接对AVFrame结构进行显示,如SDL、D3DX等等。
我们这里用最基本的RGB图像方式来显示这个AVFrame,但AVFrame的图像数据大多数是YUV格式,需要做YUV->RGB转换,当然可以自己找公式转换,实际上FFmpeg对此也提供了方便的转换方法sws_scale:

	int ret;
	int wid, hei;
	wid = pFrame->width;
	hei = pFrame->height;
	if (m_pSwsCtx == nullptr)
	{
		m_pSwsCtx = sws_getContext(wid, hei, (AVPixelFormat)pFrame->format, 
			wid, hei, AV_PIX_FMT_RGB24, SWS_POINT, nullptr, nullptr, nullptr);
	}
	uint8_t* data[1];
	data[0] = pDib;
	int lines[1] = { wid * 3 };
	ret = sws_scale(m_pSwsCtx, pFrame->data, pFrame->linesize, 0, hei, data, lines);

这样转出的pDib就是24位RGB的图像了,之后的显示此处就不再赘述了。

2.4 关闭流

以上打开的流,以及分配的各种资源,最后不用时记得要释放,如

	if (m_pFmtCtx != nullptr)
	{
		avformat_close_input(&m_pFmtCtx);
		m_pFmtCtx = nullptr;
	}
	if (m_pAVCodecCtx != nullptr)
	{
		avcodec_close(m_pAVCodecCtx);
		avcodec_free_context(&m_pAVCodecCtx);
		m_pAVCodecCtx = nullptr;
	}

3 示例

下图为程序运行视频解码结果。
在这里插入图片描述
以上代码的完整工程,已上传,供参考。地址:https://download.csdn.net/download/hangl_ciom/88152736

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/827198.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Meta-Transformer:基于Transformer的多模态感知,融合Token化与共享编码

论文标题&#xff1a;Meta-Transformer: A Unified Framework for Multimodal Learning 论文地址&#xff1a;https://arxiv.org/pdf/2307.10802.pdf 这里写目录标题 引言基于Transformer的多模态发展Meta-Transformer框架预备知识数据到序列如何分词&#xff08;Data-to-Seq…

Clion一个项目内多个main

创建单个main文件时 这样的文件不属于任何项目&#xff0c;每个文件都有自己的exe

全网最强,Jmeter接口测试-SHA256加密接口测试(详细实战)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口文档如下&…

【福建事业单位-语言理解】04 逻辑填空-病句-歧义

【福建事业单位-语言理解】04 逻辑填空-病句-歧义 一、逻辑填空1.1 词的辨析1.1.1词义侧重1.1.2固定搭配1.1.3程度轻重1.1.4 感情色彩总结 1.2语境分析&#xff08;关联关系&#xff09;1.2.1 转折1.2.2递进1.2.3并列1.2.4因果关系 1.3语境分析&#xff08;对应关系&#xff09…

中国工商银行长春分行 聚焦融合互促 让机关党建更有活力

党的十八大以来&#xff0c;中国工商银行长春分行党委认真落实中央部署&#xff0c;立足金融工作政治性、人民性的基本原则&#xff0c;深刻把握机关党建的要点、着力破解难点、大力打造亮点&#xff0c;围绕“党建”模式&#xff0c;将党建融入经营管理各个方面&#xff0c;使…

SSD 之乱七八糟的概念

1. 性能指标有哪些&#xff1f;分别是什么意思&#xff1f; 硬盘性能指标一般包括 IOPS&#xff08;反映的是随机读写性能&#xff09;、吞吐量&#xff08;也称为带宽&#xff0c;反映的是顺序读写性能&#xff09;、Response Time / Latency&#xff08;响应时间 / 时延&…

dev控件gridControl,gridview中添加合计

需求&#xff1a;在合并结账查询中&#xff0c;双击每一条结账出现这次结账对应的结算明细&#xff1a; 弹出的页面包括&#xff1a;结算日期&#xff0c;ID&#xff0c;姓名&#xff0c;费别&#xff0c;预交金收入&#xff0c;结算金额&#xff0c;收据号&#xff0c;合计&a…

什么是线程?为什么需要线程?和进程的区别?

目录 前言 一.线程是什么&#xff1f; 1.1.为什么需要线程 1.2线程的概念 1.3线程和进程的区别 二.线程的生命周期 三.认识多线程 总结 &#x1f381;个人主页&#xff1a;tq02的博客_CSDN博客-C语言,Java,Java数据结构领域博主 &#x1f3a5; 本文由 tq02 原创&#xf…

振动试验台使用过程中经常用到的计算公式,推荐收藏!

以下为正文&#xff1a; 1、求推力(F)的公式 式中&#xff1a; F — 推力(激振力)(N) m0 — 振动台运动部分有效质量(kg) m1 — 辅助台面质量(kg) m2 — 试件(包括夹具、安装螺钉)质量(kg) A — 试验加速度(m/s) 2、加速度(A)、速度(V)、位移(D)三个振动参数的互换运算…

Java反射全面详解

1. 什么是反射&#xff1f; 首先听这个名字就有些疑惑&#xff0c;什么是反射&#xff0c;它能用来干什么呢&#xff1f; Java官方对反射的解释是 "反射允许对封装类的字段&#xff0c;方法和构造函数进行编程式访问"。这里的字段指的就是成员变量&#xff0c;方法…

prometheus监控k8s kube-proxy target down

prometheus target down 修改配置 kubectl edit cm/kube-proxy -n kube-systemmetricsBindAddress: "0.0.0.0:10249"删除 kube-proxy pod 使之重启应用配置 kubectl delete pod --force kubectl get pod -n kube-system |grep kube-proxy|awk {print $1} -n kube-…

网工内推 | 网络安全工程师,最高15K,有高温补贴

01 超圣信华 招聘岗位&#xff1a;网络安全工程师 职责描述&#xff1a; 1. 负责网络安全产品的售前沟通交流、现状调研、方案设计、产品测试、产品选型和招投标等工作。 2. 负责网络安全集成项目的实施管理、项目交付文档编制以及项目验收等工作。 3. 负责网络安全产品的售后…

十八、Spring6集成MyBatis3.5

目录 十八、Spring6集成MyBatis3.5 18.1 实现步骤 18.2 具体实现 第一步&#xff1a;准备数据库表 第二步&#xff1a;IDEA中创建一个模块&#xff0c;并引入依赖 第三步&#xff1a;基于三层架构实现&#xff0c;所以提前创建好所有的包 第四步&#xff1a;编写pojo 第…

算法入门篇——用位运算解决一些问题

目录 1.判断一个数是2的次方数 2.统计一个数&#xff0c;它的二进制数中&#xff0c;1的个数 3.在2*&#xff08;n-1&#xff09;个数中&#xff0c;找到只出现一次的那个数 1.判断一个数是2的次方数 这个问题有好几种做法&#xff0c;但是最优雅的解法是用’位运算‘来做。…

【Spring Cloud 三】Eureka服务注册与服务发现

系列文章目录 【Spring Cloud一】微服务基本知识 Eureka服务注册与服务发现 系列文章目录前言一、什么是Eureka&#xff1f;二、为什么要有服务注册发现中心&#xff1f;三、Eureka的特性四、搭建Eureka单机版4.1Eureka服务端项目代码pom文件配置文件启动类启动项目查看效果 E…

深入学习Mysql引擎InnoDB、MylSAM

目录 一、什么是MySQL 二、什么是InnoDB 三、什么是MyISAM 四、MySQL不同引擎有什么区别 一、什么是MySQL MySQL是一种广泛使用的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它是由瑞典MySQL AB公司开发并推广&#xff0c;后来被Sun Microsystems收…

FPGA项目设计:数字时钟

项目要求&#xff1a; 设计一个数字时钟&#xff0c;数码管前两位显示小时&#xff0c;数码管中间两位显示分钟&#xff0c;数码管后面两位显示秒。 项目设计&#xff1a; 系统框架图&#xff1a; 计数模块时序图&#xff1a; 代码实现&#xff1a; 计数模块&#xff1a; /…

走进人工智能|自动驾驶 开启智能出行新时代

前言 自动驾驶&#xff0c;也被称为无人驾驶或自动驾驶汽车&#xff0c;是指能够在没有人类干预的情况下自主地感知环境、决策和控制车辆行驶的技术和系统。 文章目录 前言主题发展趋势自动驾驶等级L0级自动驾驶L1级别自动驾驶L2级别自动驾驶L3级别自动驾驶L4级别自动驾驶L5级…

C# Microsoft消息队列服务器的使用 MSMQ

先安装消息队列服务器 private static readonly string path ".\\Private$\\myQueue";private void Create(){if (!MessageQueue.Exists(path)){MessageQueue.Create(path);}}private void Send(){Stopwatch stopwatch new Stopwatch();stopwatch.Start();Message…

em3288 linux_4.19 lvds+tp调试

一、显示配置\rk3288_linux4.19\kernel\arch\arm\boot\dts\rk3288-evb-act8846.dtspanel {compatible "simple-panel";backlight <&backlight>;bus-format <MEDIA_BUS_FMT_RGB666_1X18>;enable-gpios <&gpio1 24 GPIO_ACTIVE_HIGH>;ena…