FFmpeg 命令:从入门到精通 | FFmpeg 解码流程

news2024/11/20 10:37:25

FFmpeg 命令:从入门到精通 | FFmpeg 解码流程

  • FFmpeg 命令:从入门到精通 | FFmpeg 解码流程
    • 流程图
    • FFmpeg 解码的函数
    • FFmpeg 解码的数据结构
    • 补充小知识

FFmpeg 命令:从入门到精通 | FFmpeg 解码流程

本内容参考雷霄骅博士的 FFmpeg 教程。

流程图

FFmpeg 解码的流程图如下所示:

在这里插入图片描述

FFmpeg 解码的流程:

  1. 注册:
    使用ffmpeg对应的库,都需要进行注册,可以注册子项也可以注册全部。
  2. 打开文件:
    打开文件,根据文件名信息获取对应的ffmpeg全局上下文。
  3. 探测流信息:
    一定要探测流信息,拿到流编码的编码格式,不探测流信息则其流编码器拿到的编码类型可能为空,后续进行数据转换的时候就无法知晓原始格式,导致错误。
  4. 查找对应的解码器:
    依据流的格式查找解码器,软解码还是硬解码是在此处决定的,但是特别注意是否支持硬件,需要自己查找本地的硬件解码器对应的标识,并查询其是否支持。普遍操作是,枚举支持文件后缀解码的所有解码器进行查找,查找到了就是可以硬解了(此处,不做过多的讨论,对应硬解码后续会有文章进行进一步研究)。(注意:解码时查找解码器,编码时查找编码器,两者函数不同,不要弄错了,否则后续能打开但是数据是错的)
  5. 打开解码器:
    打开获取到的解码器。
  6. 申请缩放数据格式转换结构体:
    此处特别注意,基本上解码的数据都是yuv系列格式,但是我们显示的数据是rgb等相关颜色空间的数据,所以此处转换结构体就是进行转换前到转换后的描述,给后续转换函数提供转码依据,是很关键并且非常常用的结构体。
  7. 申请缓存区:
    申请一个缓存区outBuffer,fill到我们目标帧数据的data上,比如rgb数据,QAVFrame的data上存是有指定格式的数据,且存储有规则,而fill到outBuffer(自己申请的目标格式一帧缓存区),则是我们需要的数据格式存储顺序。
    举个例子,解码转换后的数据为rgb888,实际直接用data数据是错误的,但是用outBuffer就是对的,所以此处应该是ffmpeg的fill函数做了一些转换。
    进入循环解码:
  8. 获取一帧packet:
    拿取封装的一个packet,判断packet数据的类型进行解码拿到存储的编码数据
  9. 数据转换:
    使用转换函数结合转换结构体对编码的数据进行转换,那拿到需要的目标宽度、高度和指定存储格式的原始数据。
  10. 自行处理:
    拿到了原始数据自行处理。不断循环,直到拿取pakcet函数成功,但是无法得到一帧数据,则代表文件解码已经完成。帧率需要自己控制循环,此处只是循环拿取,可加延迟等。
  11. 释放QAVPacket:
    此处要单独列出是因为,其实很多网上和开发者的代码在进入循环解码前进行了av_new_packet,循环中未av_free_packet,造成内存溢出;或者,在进入循环解码前进行了av_new_packet,循环中进行av_free_pakcet,那么一次new对应无数次free,在编码器上是不符合前后一一对应规范的。查看源代码,其实可以发现av_read_frame时,自动进行了av_new_packet(),那么其实对于packet,只需要进行一次av_packet_alloc()即可,解码完后av_free_packet。
    执行完后,返回执行“步骤8:获取一帧packet”,一次循环结束。
  12. 释放转换结构体:
    全部解码完成后,安装申请顺序,进行对应资源的释放。
  13. 关闭解码/编码器:
    关闭之前打开的解码/编码器。
  14. 关闭上下文:
    关闭文件上下文后,要对之前申请的变量按照申请的顺序,依次释放。

FFmpeg 解码的函数

  • av_register_all():注册所有组件。
  • avformat_open_input():打开输入视频文件。
  • avformat_find_stream_info():获取视频文件信息。
  • avcodec_find_decoder():查找解码器。
  • avcodec_open2():打开解码器。
  • av_read_frame():从输入文件读取一帧压缩数据。
  • avcodec_decode_video2():解码一帧压缩数据。
  • avcodec_close():关闭解码器。
  • avformat_close_input():关闭输入视频文件。

FFmpeg 解码的数据结构

FFmpeg 解码的数据结构如下所示:

在这里插入图片描述

FFmpeg 数据结构:

  • AVFormatContext:封装格式上下文结构体,也是统领全局的结构体,保存了视频文件封装格式相关信息。
  • AVInputFormat:每种封装格式(例如FLV, MKV, MP4, AVI)对应一个该结构体。
  • AVStream:视频文件中每个视频(音频)流对应一个该结构体。
  • AVCodecContext:编码器上下文结构体,保存了视频(音频)编解码相关信息。
  • AVCodec:每种视频(音频)编解码器(例如H.264解码器)对应一个该结构体。
  • AVPacket:存储一帧压缩编码数据。
  • AVFrame:存储一帧解码后像素(采样)数据。

FFmpeg 数据结构分析:

AVFormatContext:

  • iformat:输入视频的AVInputFormat
  • nb_streams :输入视频的AVStream 个数
  • streams :输入视频的AVStream []数组
  • duration :输入视频的时长(以微秒为单位)
  • bit_rate :输入视频的码率

AVInputFormat:

  • name:封装格式名称
  • long_name:封装格式的长名称
  • extensions:封装格式的扩展名
  • id:封装格式ID
  • 一些封装格式处理的接口函数

AVStream:

  • id:序号
  • codec:该流对应的AVCodecContext
  • time_base:该流的时基
  • r_frame_rate:该流的帧率

AVCodecContext:

  • codec:编解码器的AVCodec
  • width, height:图像的宽高(只针对视频)
  • pix_fmt:像素格式(只针对视频)
  • sample_rate:采样率(只针对音频)
  • channels:声道数(只针对音频)
  • sample_fmt:采样格式(只针对音频)

AVCodec:

  • name:编解码器名称
  • long_name:编解码器长名称
  • type:编解码器类型
  • id:编解码器ID
  • 一些编解码的接口函数

AVPacket:

  • pts:显示时间戳
  • dts :解码时间戳
  • data :压缩编码数据
  • size :压缩编码数据大小
  • stream_index :所属的AVStream

AVFrame:

  • data:解码后的图像像素数据(音频采样数据)。
  • linesize:对视频来说是图像中一行像素的大小;对音频来说是整个音频帧的大小。
  • width, height:图像的宽高(只针对视频)。
  • key_frame:是否为关键帧(只针对视频) 。
  • pict_type:帧类型(只针对视频) 。例如I,P,B。

补充小知识

解码后的数据为什么要经过sws_scale()函数处理?

解码后YUV格式的视频像素数据保存在AVFrame的data[0]、data[1]、data[2]中。但是这些像素值并不是连续存储的,每行有效像素之后存储了一些无效像素。以亮度Y数据为例,data[0]中一共包含了linesize[0]*height个数据。但是出于优化等方面的考虑,linesize[0]实际上并不等于宽度width,而是一个比宽度大一些的值。因此需要使用sws_scale()进行转换。转换后去除了无效数据,width和linesize[0] 取值相等。

在这里插入图片描述

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

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

相关文章

视频降噪一些原理

视频降噪,除去部分有可能错误的信息,替换为猜测的可能正确的信息。 真实的细节减少。 亮度低是因为光子少。光子多亮度高。 误差存在,放大倍数越大,误差越大,就会显得噪点越多。 减少噪点: 增加进光量&a…

动图gif怎么做?分享一招超简单方法

常见的图片格式有jpg、png以及gif格式,其中gif格式的图片因为其画面内容丰富生动所以深受大家的喜爱。那么,如何将jpg、png格式的图片转换成gif格式动图呢?通过使用GIF中文网的gif制作(https://www.gif.cn/)功能&#…

[管理与领导-113]:IT人看清职场中的隐性规则 - 10 - 看清人的行动、行为、手段、方法背后的动机与背景条件

目录 前言: 一、冰山模型 1.1 冰山模型,系统思考的工具 1.2 冰山模型:发现人行为背后的动机 二、动机、行为模型 "说一套": "做一套": "演一套": "学一套&quo…

C++笔记之不同buffer数量下的生产者-消费者机制

C笔记之不同buffer数量下的生产者-消费者机制 文章目录 C笔记之不同buffer数量下的生产者-消费者机制0.在不同的缓冲区数量下,生产者-消费者机制的实现方式和行为的区别1.最简单的生产者-消费者实现:抄自 https://mp.weixin.qq.com/s/G1lHNcbYU1lUlfugXn…

手机或者电脑连接局域网内的虚拟机(网桥)

手机或者电脑连接局域网内的虚拟机(网桥) 手机软件:ConnectBot,Termius,JuiceSSH … 1.虚拟机vmware中添加桥接网卡 这里桥接网卡选择的是自动,是自动生成动态IP,如果不需要动态生成&#xff…

通达信和同花顺能否实现程序化自动交易股票,量化交易如何实现?

以下写给正在寻找自动交易接口的朋友,首先,不是那种设置个简单条件的条件单,或者某些客户端上形同鸡肋的策略交易,那些策略根本称不上策略,还有各种限制,不支持这个不支持那个,可设置的参数也不…

通过融合UGV的地图信息和IMU的惯性测量数据,实现对车辆精确位置和运动状态的估计和跟踪研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【MySQL】表的基础增删改查

前面我们已经知道怎么来创建表了,接下来就来对创建的表进行一些基本操作。 这里先将上次创建的表删除掉: mysql> use test; Database changedmysql> show tables; ---------------- | Tables_in_test | ---------------- | student | -----…

redis持久化与调优

一 、Redis 高可用: 在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。但是在Redis语境中,高可用的含义似乎要宽泛一些&#x…

联想M7216NWA一体机连接WiFi及手机添加打印机方法

联想M7216NWA一体机连接WiFi方法: 1、首先按打印机操作面板上的“功能键”;【用“”(上翻页)“-”(下翻页)来选择菜单的内容】 2、下翻页键找到并选择“网络”,然后“确认键”; 3…

javaee ssm框架整合例子 ssm例子,需要哪些依赖,配置文件如何配置

项目结构 步骤一&#xff0c;创建springmybatis项目 参考上一篇博客 步骤二&#xff0c;融入SpringMVC 添加依赖 <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http:…

ArcGIS Engine:视图菜单的创建和鹰眼图的实现

目录 01 创建项目 1.1 通过ArcGIS-ExtendingArcObjects创建窗体应用 1.2 通过C#-Windows窗体应用创建窗体应用 1.2.1 创建基础项目 1.2.2 搭建界面 02 创建视图菜单 03 鹰眼图的实现 3.1 OnMapReplaced事件的触发 3.2 OnExtentUpdated事件的触发 04 稍作演示 01 创建项目…

Centos7 安装mysql 8.0.34并设置不区分大小写

索引 Centos7 安装mysql 8.0.34准备工作安装教程安装并配置配置MySQL配置远程访问重新启动MySQL服务 为已安装的MySQL8设置不区分大小写背景操作步骤 Centos7 安装mysql 8.0.34 准备工作 centos7 服务器 xshell 安装教程 安装并配置 在安装MySQL之前&#xff0c;我们应该…

CSS 实现:常见布局

1 设备与视口 设备屏幕尺寸是指屏幕的对角线长度。像素是计算机屏幕能显示一种特定颜色的最小区域&#xff0c;分为设备像素和逻辑像素。 在 Apple 的视网膜屏&#xff08;Retina&#xff09;中&#xff0c;默认每 4 个设备像素为一组&#xff0c;渲染出普通屏幕中一个像素显示…

Eyeshot Fem 2023.3 Crack Eyeshot Ultimate

添加新的 PrintSimulationMesh 和 MultiFastMesh 实体并改进 NURBS 曲面三角测量。 2023 年 10 月 4 日 - 11:09新版本 特征 PrintSimulationMesh 实体预览。MultiFastMesh 实体预览。FEM 模态分析预览。有限元分析结果的动画。assemblySelectionType.Leaf 模式下的几何选择。编…

python修改unittestreport中的用例条数

背景: 自动化框架中使用yaml文件作为数据配置&#xff0c;使用ddt作为数据驱动来运行测试用例&#xff0c;由于测试用例都是基于场景去编写&#xff0c;目前都是一个测试类算是一条测试用例&#xff0c;但基于测试报告里面一个类运行的测试方法有多个&#xff0c;因此统计的测试…

华为云云耀云服务器L实例评测|部署项目管理工具 Focalboard

华为云云耀云服务器L实例评测&#xff5c;部署项目管理工具 Focalboard 一、云耀云服务器L实例介绍1.1 云服务器介绍1.2 产品优势1.3 产品规格1.4 应用场景 二、云耀云服务器L实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 Focalboard3.1 Focalboard 介绍3.2 Doc…

websocket学习笔记1

1. 知识模块一 1.1. websocket与http对比 1.1.1. http协议 主要关注&#xff1a;客户端->服务器&#xff08;获取资源&#xff09; 特点&#xff1a; 无状态协议&#xff0c;每个请求都是独立的&#xff0c;请求应答模式&#xff0c;服务端无法主动给客户端推送消息&am…

linux下的永久保存行号

linux下的永久保存行号 1.首先 这里是引用 输入命令&#xff1a;vi ~/.vimrc 其次 这里是引用 输入命令 set number

一款超实用的AI漫画生成器,支持9种漫画风格,无限免费使用

HI&#xff0c;同学们&#xff0c;我是赤辰&#xff0c;本期是赤辰第12篇AI工具类教程&#xff0c;文章底部准备了粉丝福利&#xff0c;看完可以领取&#xff01;今天给大家介绍一款AI漫画生成器——AI Comic Factory&#xff0c;只需输入提示词&#xff0c;即可瞬间创造出一幅…