FFmepg视频解码

1 前言

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

2 视频解码过程

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

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

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

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

1 打开流文件
这个函数avformat_open_input打开一个媒体流并读取其头信息,对于实时流或者不包含头信息的视频流,此函数通过几帧数据分析以获取其信息
此函数支持的媒体流非常广泛,包括本地视频文件、RTSP、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.mfbz.cn/a/58094.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

人工智能发展的五个主要技术方向是什么?

人工智能主要分支介绍 通讯、感知与行动是现代人工智能的三个关键能力&#xff0c;在这里我们将根据这些能力/应用对这三个技术领域进行介绍&#xff1a; 计算机视觉(CV) 自然语言处理(NLP) 在 NLP 领域中&#xff0c;将覆盖文本挖掘/分类、机器翻译和语音识别。 机器人 1、…

人工智能与物理学(软体机器人能量角度)的结合思考

前言 好久没有更新我的CSDN博客了&#xff0c;细细数下来已经有了16个月。在本科时期我主要研究嵌入式&#xff0c;研究生阶段对人工智能感兴趣&#xff0c;看了一些这方面的论文和视频&#xff0c;因此用博客记录了一下&#xff0c;后来因为要搞自己的研究方向&#xff0c;就…

vscode 第一个文件夹在上一层文件夹同行,怎么处理

我的是这样的 打开终端特别麻烦 解决方法就是 打开vscode里边的首选项 进入设置 把Compact Folders下边对勾给勾掉

【工具使用】git基础操作1

目录 一.拉取git代码1.首次拉取命令2.使用图形化拉取代码3.Idea 开发工具拉取代码 二.查看当前状态1.查看在你上次提交之后是否有对文件进行再次修改 三.创建分支3.1.创建分支3.2.创建分支并切换至分支3.3.提交分支至远程仓 远程没有自动创建 四.查看分支4.1.查看本地分支 当前…

如何开启一个java微服务工程

安装idea IDEA常用配置和插件&#xff08;包括导入导出&#xff09; https://blog.csdn.net/qq_38586496/article/details/109382560安装配置maven 导入source创建项目 修改项目编码utf-8 File->Settings->Editor->File Encodings 修改项目的jdk maven import引入…

偶数科技发布实时湖仓数据平台Skylab 5.3版本

近日&#xff0c; 偶数发布了最新的实时湖仓数据平台 Skylab 5.3 版本。Skylab包含七大产品&#xff0c;分别为云原生分布式数据库 OushuDB、数据分析与应用平台 Kepler、数据资产管理平台 Orbit、自动化机器学习平台 LittleBoy、数据工厂 Wasp、数据开发与调度平台 Flow、系统…

2023年人工智能技术与智慧城市发展白皮书

人工智能与智慧城市是当前热门的话题和概念&#xff0c;通过将人工智能技术应用在城市管理和服务中&#xff0c;利用自动化、智能化和数据化的方式提高城市运行效率和人民生活质量&#xff0c;最终实现城市发展的智慧化&#xff0c;提升城市居民的幸福感。 AI技术在城市中的应…

《金融数据保护治理白皮书》发布(137页)

温馨提示&#xff1a;文末附完整PDF下载链接 导读 目前业界已出台数据保护方面的治理模型&#xff0c;但围绕金融数据保护治理的实践指导等尚不成熟&#xff0c;本课题围绕数据保护治理的金融实践、发展现状&#xff0c;探索和标准化相关能力要求&#xff0c;归纳总结相关建…

【JAVA】正则表达式是啥?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️初识JAVA】 文章目录 前言正则表达式正则表达式语法正则表达式的特点捕获组实例 前言 如果我们想要判断给定的字符串是否符合正则表达式的过滤逻辑&#xff08;称作“匹配”&#xff09;&#xff0c…

设计模式之中介者模式

中介者模式 用一个中介对象来封装一系列的对象交互。中介者使得各对象不需要显示地相互引用&#xff0c;从而使其耦合松散&#xff0c;而且可以独立地改变他们之间的交互。 电脑主板的功能就类似于一个中介者 经典中介者模式UML 例子 经典的中介者模式 package com.tao.Ya…

485modbus转profinet网关连三菱变频器modbus通讯触摸屏监控

本案例介绍了如何通过485modbus转profinet网关连接威纶通与三菱变频器进行modbus通讯。485modbus转profinet网关提供了可靠的连接方式&#xff0c;使用户能够轻松地将不同类型的设备连接到同一网络中。通过使用这种网关&#xff0c;用户可以有效地管理和监控设备&#xff0c;从…

2023网络安全学习路线 非常详细 推荐学习

首先咱们聊聊&#xff0c;学习网络安全方向通常会有哪些问题 1、打基础时间太长 学基础花费很长时间&#xff0c;光语言都有几门&#xff0c;有些人会倒在学习 linux 系统及命令的路上&#xff0c;更多的人会倒在学习语言上&#xff1b; 2、知识点掌握程度不清楚 对于网络安…

zabbix

ZABBIX 安装 Zabbix z-sever yum list | grep nginx # 查看 nginx 版本 &#xff0c;这里使用 1.20 nginx.x86_64 1:1.20.1-10.el7 epel yum install -y nginx# 安装 php https://webtatic.com/packages/php72/ # 源的官…

爬虫007_python中的输出以及格式化输出_以及输入---python工作笔记025

首先看输出 输出这里,注意不能直接上面这样,18需要转换成字符串 可以看到python中这个字符串和数字一起的时候,数字要转换一下成字符串. 然后这里要注意%s 和%d,这个s指的是字符串,d指的是数字 注意后面的内容前面要放个% ,然后多个参数的话,那么这里用(),里面用,号隔开 然…

面向对象程序三大特性一:多态(超详细)

目录 1.重写 1.1基本语法规则 1.2规则深化 1.3重写与重载的区别 2.向上转型 2.1简单介绍 2.3向上转型的作用 3.向下转型 3.1介绍 3.2instanceof 基本介绍 4.多态 4.1多态实现条件 4.2避免在构造方法中调用重写的方法 1.重写 重写 (override) &#xff1a;也称为覆…

iOS——Block签名

首先来看block结构体对象Block_layout&#xff08;等同于clang编译出来的__Block_byref_a_0&#xff09; #define BLOCK_DESCRIPTOR_1 1 struct Block_descriptor_1 {uintptr_t reserved;uintptr_t size; };#define BLOCK_DESCRIPTOR_2 1 struct Block_descriptor_2 {// requi…

华为数通HCIP-IP组播基础

点到点业务&#xff1a;比如FTP&#xff0c;WEB业务&#xff0c;此类业务主要特点是不同的用户有不同的需求&#xff0c;比如用户A需要下载资料A&#xff0c;用户B需要下载资料B。此类业务一般由单播承载&#xff0c;服务器对于不同用户发送不同的点到点数据流。 ospf、isis…

设计模式行为型——责任链模式

目录 什么是责任链模式 责任链模式的实现 责任链模式角色 责任链模式类图 责任链模式举例 责任链模式代码实现 责任链模式的特点 优点 缺点 使用场景 注意事项 实际应用 什么是责任链模式 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;又叫职…

SpringBoot整合邮件服务

SpringBoot整合邮件服务 发送邮件应该是网站的必备功能之一&#xff0c;什么注册验证&#xff0c;忘记密码或者是给用户发送营销信息。最早期的时候我们会 使用 JavaMail 相关 api 来写发送邮件的相关代码&#xff0c;后来 Spring 推出了 JavaMailSender 更加简化了邮件发送的…

前端下载文化部几种方法(excel,zip,html,markdown、图片等等)和导出 zip 压缩包

文章目录 1、location.href2、location.href3、a标签4、请求后端的方式5、文件下载的方式6、Blob和Base647、下载附件方法(excel,zip,html,markdown)8、封装下载函数9、导出 zip 压缩包相关方法(流方式) 总结 1、location.href //get请求 window.location.href url;2、locati…
最新文章