FFmepg视频解码
1 前言
上一篇文章<FFmpeg下载安装及Windows开发环境设置>介绍了FFmpeg的下载安装及环境配置,本文介绍最简单的FFmpeg视频解码示例。
2 视频解码过程
本文只讨论视频解码。
FFmpeg视频解码的过程比较简单,实际就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 1for (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
相关文章:
FFmepg视频解码
1 前言 上一篇文章<FFmpeg下载安装及Windows开发环境设置>介绍了FFmpeg的下载安装及环境配置,本文介绍最简单的FFmpeg视频解码示例。 2 视频解码过程 本文只讨论视频解码。 FFmpeg视频解码的过程比较简单,实际就4步: 打开媒体流获取…...
SpringCloud深入理解 | 生产者、消费者
💗wei_shuo的个人主页 💫wei_shuo的学习社区 🌐Hello World ! SpringCloud Spring Cloud是一组用于构建分布式系统和微服务架构的开源框架和工具集合。它是在Spring生态系统的基础上构建的,旨在简化开发人员构建分布式…...
web题型
0X01 命令执行 漏洞原理 没有对用户输入的内容进行一定过滤直接传给shell_exec、system一类函数执行 看一个具体例子 cmd1|cmd2:无论cmd1是否执行成功,cmd2将被执行 cmd1;cmd2:无论cmd1是否执行成功,cmd2将被执行 cmd1&cmd2:无论cmd1是否执行成…...
使用curl和postman调用Azure OpenAI Restful API
使用curl在cmd中调用时,注意:json大括号内的每一个双引号前需要加上\ curl https://xxxopenai.openai.azure.com/openai/deployments/Your_deployid/chat/completions?api-version2023-05-15 -H "Content-Type: application/json" -H "…...
草莓叶病害数据集
1.草莓数据集有两个文件夹 训练集 健康文件夹(2819张) 草莓叶焦病害(3327张) 数据集可以关注最后一行 import numpy as np import os import matplotlib.pyplot as plt import cv2import warnings warnings.filterwarnings(igno…...
安卓音视频多对多级联转发渲染
最近利用自己以前学习和用到的音视频知识和工程技能做了一个android的sdk,实现了本地流媒体ipc rtsp 拉流以及自带mip usb等camera audio节点产生的流媒体通过webrtc sfu的方式进行多对多级联发布共享,网状结构,p2p组网,支持实时渲染以及转推rtmp&#x…...
2023年电赛---运动目标控制与自动追踪系统(E题)OpenART mini的代码移植到OpenMV
前言 (1)已经有不少同学根据我上一篇博客完成了前三问,恭喜恭喜。有很多同学卡在了第四问。 (2)我说了OpenART mini的代码是可行的。但是他们不会移植到OpenMV上,再次我讲移植之后的代码贴出来。 ÿ…...
SAP CAP篇十二:AppRouter 深入研究
本文目录 本系列文章理解现有程序app文件夹中的package.json理解approuter.js 修改现有程序修改package.json新建index.js在Approuter中显示额外的逻辑 添加一些额外的Logger对应代码及branch 本系列文章 SAP CAP篇一: 快速创建一个Service,基于Java的实现 SAP CAP…...
HDFS中数据迁移的使用场景和考量因素
HDFS中数据迁移的使用场景和考量因素 数据迁移使用场景数据迁移要素考量HDFS分布式拷贝工具-DistCpdistcp的优势性能命令 数据迁移使用场景 冷热集群数据同步、分类存储集群数据整体搬迁 当公司业务迅速的发展,导致的当前的服务器数量资源出现临时紧张的时候&#…...
科普 | 以太坊坎昆升级是什么
坎昆升级是什么 坎昆,是墨西哥一个著名的旅游城市,也是 Devcon 3 大会的举办地,按照以太坊升级命名的规律,以地名命名的升级,是针对以太坊执行层的升级。 之前同样命名的还有柏林升级、伦敦升级和这次的上海升级等。…...
C# 一些知识整理
C#反射和特性 反射Reflection Type 类型 Name NameSpace Assembly GetFields() GetProperties() GetMethods() 特性Attribute Obsolete弃用 Condit…...
SpringBoot复习:(15)Spring容器的核心方法refresh是在哪里被调用的?
在SpringApplication的run方法: refreshContext代码如下: 其中调用的refresh方法代码如下: 其中调用的refresh方法代码如下: 其中调用的fresh方法代码如下: 其中调用了super.refresh();而这个super.refresh()就是…...
Android安卓实战项目(5)---完整的健身APP基于安卓(源码在文末)可用于比赛项目或者作业参考中
Android安卓实战项目(5)—完整的健身APP(源码在文末🐕🐕🐕)可用于比赛项目 一.项目运行介绍 1.大致浏览 【bilibili视频】 https://www.bilibili.com/video/BV1uX4y177iR/? (1&…...
AutoSAR系列讲解(实践篇)11.2-存储处理与Block
目录 一、NVRAM Block NVRAM Block的类型 二、Fee Block 三、Ea Block 四、总结 同通信的PDU一样,存储功能也需要一些特殊的数据结构来存放和管理我们的NV数据(NV data) 一、NVRAM Block NVRAM Block的作用类似于IPDU,但它们两仅仅只是作用上相似,其功能实现是完全…...
K8s总结
K8s 是什么 Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的机制…...
3.playbook剧本二
文章目录 playbook二Roles模块roles模式安装LNMP创建nginxfiles目录handlers目录tasks目录templates目录vars目录 创建mysqltasks目录 创建phpfiles目录handlers目录tasks目录templates目录vars目录 创建LNMP剧本文件 playbook二 Roles模块 角色的作用:把playbook…...
【MySQL】视图与用户管理
【MySQL】视图 视图视图概念使用基表与视图的相互影响 用户管理新增用户删除修改密码 用户权限授予权限回收权限 视图 视图概念 视图就是一张虚拟表,其内容由查询定义。与真实的表一样,视图包含一系列带有名称的列和行数据。视图的数据变化影响到基表&…...
LINUX系统监控工具ATOP的使用
最近在排查嵌入式系统的问题,需要监控各种系统资源的消耗。 ATOP不错,可以实时看,也可以保存成日志,分析历史情况。 直接使用: atop 想写入文件就是: sudo atop -a -w /home/guo/atoplog2.log 2 2的意…...
[回馈]ASP.NET Core MVC开发实战之商城系统(五)
经过一段时间的准备,新的一期【ASP.NET Core MVC开发实战之商城系统】已经开始,在之前的文章中,讲解了商城系统的整体功能设计,页面布局设计,环境搭建,系统配置,及首页【商品类型,ba…...
iPhone 8透明屏的透明度高吗?
iPhone 8是苹果公司于2017年推出的一款智能手机,它采用了全新的设计和技术,其中一个亮点就是透明屏。 透明屏是指屏幕具有透明度,可以透过屏幕看到背后的物体。 iPhone 8的透明屏采用了最新的OLED技术,这种技术可以实现更高的对比…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
渗透实战PortSwigger靶场:lab13存储型DOM XSS详解
进来是需要留言的,先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码,输入的<>当成字符串处理回显到页面中,看来只是把用户输…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...
