ffmpeg笔记(一)音视频基础

简介: ffmpeg笔记(一)音视频基础

1 图像基础概念

1.1 像素

像素是一个图片的基本单位 pix 是英语单词 picture 的简写 加上英语单词 元素 element” 就得到了 pixel” 简称 px 所以 像素 有 图像元素之意 。2500 × 2000 的照片就是指横向有 2500 个像素点,竖向有 2000 个像素点,总共是 500 万个像素,也俗称 500 万像素照片。

1.2 分辨率

分辨率是指图像的大小或尺寸。 比如 1920 x 1080 的照片就是指横向宽有1920个像素点,竖向高有1080个像素点。

常见的分辨率:360P(640 x 360)、720P(1280x720) 、 1080P(1920x1080) 、 4K(3840x2160) 、 8K(7680x4320)等。

常说的1080 和 720 其实说的是垂直像素。按照宽:高为16:9的比例进行计算,720p 的水平像素数为 720 ÷ 9 × 16 = 1280,总计像素为 921600 像素即大约为 92 万像素。 1080p 的水平像素为1080 ÷ 9 × 16 = 1920,总计像素约为200万像素,是720p的2倍多。像素越多视频就越清晰,所以1080p 比 720p 的视频更加清晰。 图像的分辨率越高,图像就越清晰。

提供一个讲解分辨率比较好的文章:

https://segmentfault.com/a/1190000023769775

1.3位深

Bit 位深亦称作“位分辨率”(Bit resolution),代表一幅图像中包含的二进制位的数量。

1位深只能在幅图中显示单比特信息,所以图形事实上仅能有纯黑和纯白两种颜色。8位深(2的8次方)意味着有256种灰度或彩色组合。16位深(2的16次方)能表现65 536种可能的颜色组合。24位深能够表现约1670万种不同的颜色。

由于普通人的眼睛仅能区分约1200~1400万种不同的颜色浓淡和色调,所以24位颜色也叫作“相片”彩色或真彩色。通常,24位彩色通道都分配了8位数据,也就是说:红,绿,蓝,这三种原色每一种都可以有256种变化。也就是说可以用3个字节表示24位色。(8x3=24)

计算机在分别存储R、G、B时,采用的均是一个8bit的空间存储,因此计算机可以表达 256256256=16,777,216 = 1677 万种颜色。不同的值表示的颜色。

每个通道的位深越大,能够表示的颜色值就越大,比如现在高端电视说的 10bit 色彩,即是每个通道用 10bit 表示,每个通道有 1024 种颜色。 102410241024, 约为10,7374 万色 =10 亿色, 是 8bit 的 64 倍。

1.4 帧率

在 1 秒钟时间里传输的图片的帧数。也可以理解为图形处理器每秒钟能够刷新几次 ,比如 25 fps 表示一秒有 25 张图片。

FPS 帧率越高就代表视频画面越流畅,越低则越卡顿。

由于视觉图像在视网膜的暂时停留,一般图像帧率能达到

24 帧,我们就认为图像是连续。

帧率越高,画面越流畅,需要的设备性能也越高。

1.5 码率

视频文件在单位时间内使用的数据流量。比如 1 Mbps

大多数情况下码率越高 分辨率越高,也就越清晰。但模糊的视频文件大小(码率)也可以很大,分辨率小的视频文件可能也比分辨率大的视频文件清晰。

对于同一个原始图像源的时候,同样的编码算法,则码率越高,图像的失真就会越小,视频画面就会越清晰。

1.6 Stride

指在内存中每行像素所占的空间 。为了实现内存对齐每行像素在内存中所占的空间 并不一定 是图像的宽度 。

Stride 就是这些扩展内容的名称, Stride 也被称作 Pitch ,如果图像的每一行像素末尾拥有扩展内容, Stride 的值一定大于图像的宽度值,就像下图所示:

对齐问题:

比如分辨率 638x480 的 RGB24 图像,我们在内存处理的时候如果要 以 16 字节对齐则 6383/16=119.625 不能整除,因此不能 16 字节对齐,我们需要在每行尾部填充6个字节。就是 (638+2 -->640), 6403/16=120 。此时该图片的 stride 为 1920 字节。

比如分辨率638x480 的 YUV420P 图像,我们在内存处理的时候如果要以 16 字节对齐,则 638 不能被 16 整除,我们需要在每行尾部填充 2 个字节。就是 640 。此时该图片的 Y stride 为 640 字节。

2 YUV知识汇总

2.1 YUV定义

YUV的"Y"分量表示亮度(也就是灰阶值)、"UV"分量表示色度。其中“u”偏蓝色调,“v”偏红色调。

YUV将亮度Y和UV分开进行表示的好处:

1、避免互相干扰,单靠Y也可以完整显示一张黑白图片,解决了黑白电视与彩色电视的兼容问题。

2、降低色度(UV)的采样率 而不会对图像质量影响太大 降低了视屏信号传输时对频宽 带宽 的要求 。可以通过对UV的采样频率修改降低带宽,节省网络流量,间接降低了视频延时问题。

2.2 YUV的格式

YUV 是一个比较笼统地说法 针对它的具体排列方式 可以分为很多种具体的格式:

1、打包 packed 格式:将 每个像素点的 Y 、 U 、 V 分量交叉排列 并以像素点为单元连续的存放在同一数组中 通常几个相邻的像素组成一个宏像素 macro pixel

打包模式,通俗讲就是不同的小分量包在一起作为大的分量。

2、平面 planar 格式: 使用三个数组分开连续的存放 Y 、 U 、 V 三个分量 即 Y 、 U 、 V 分别存放在各自的数组中。

平面模式,通俗理解就是将Y、U、V分量分别进行平铺展现。

2.3 YUV采样

主要的采样方式:

1、YUV 4:4:4采样,表示色度频道没有下采样, 即一个 Y 分量对应着一个 U 分量和一个 V 分量

2、YUV 4:2:2采样,表示 2:1 的水平下采样,没有垂直下采样,即每 两个 Y 分量共用一个 U 分量和一个 V 分量 。

3、YUV 4:2:0采样,表示 2:1 的水平下采样, 2:1 的垂直下采样,即每 四个 Y 分量共用一个 U 分量和一个 V 分量 。

2.4 FFMPEG中YUV数据存储

1、I444(YUV 444 P) 格式:对应 Ffmpeg 像素表示 AV_PIX_FMT_ YUV444P,该类型为平面模式

2、I422 (YUV422P) 格式

对应 Ffmpeg 像素表示 AV_PIX_FMT_YUV422 P,该类型为平面模式

3、4:2:0 格式 YUV420P

对应 Ffmpeg 像素表示 AV_PIX_FMT_ YUV420 P(也就是I420),该类型为平面格式,占用(4+1+1)/4 = 1.5个字节

4、4:2:0 格式 NV12

对应 Ffmpeg 像素表示 AV_PIX_FMT_NV12,该类型为平面格式

5、从内存排布上看区别

YV12与I420的区别:

YYYYYYYY VV UU (YV12)

YYYYYYYY UU VV (I420)

可以看到U分量和V分量的顺序互换了。

NV12和NV21的区别:

YYYYYYYY UV UV (NV12)

YYYYYYYY VU VU(NV21)

可以看到U和V的位置互换了。

2.5 RGB和YUV的转换

通常情况下 RGB 和 YUV 直接的相互转换都是调用接口实现 比如 Ffmpeg 的 swscale 或者libyuv 等库 。

YUV(256级别 ) 可以从 8 位 RGB 直接计算:

Y = 0.299*R + 0.587*G + 0.114*B;
U = 0.169*R 0.331*G + 0.5 *B
V = 0.5 *R 0.419*G 0.081*B;

8bit位深的情况下

TV range 是 16 235(Y) 、 16 240(UV) , 也叫 Limited Range。

PC range 是 0 255 ,也叫 Full Range。

而 RGB 没有 range 之分,全是 0 255。

反过来,RGB 也可以直接从 YUV (256 级别 ) 计算

R = Y + 1.402 (Y-128)

G = Y - 0.34414 (U 128) 0.71414 (U 128)

B = Y + 1.772 (V - 128)

从 YUV 转到 RGB 如果值小于 0 要取 0 ,如果大于 255 要取 255。

问题:RGB和 YUV 的转换 为什么解码出错的时候显示绿屏?

分析:因为解码失败时,YUV 分量都填为 0 值,然后根据公式:

R = 1.402 * (128) = 126.598
G = 0.34414*( 128) 0.71414*( 128) = 44.04992 + 91.40992 = 135.45984
B = 1.772 * (128) = 126.228

RGB的值范围为 [0 255], 所以最终的计算值为:

R = 0,G = 135.45984,B = 0。此时只有G 分量有值所以为绿色。

3 音视频相关

3.1 音视频录制原理

3.2 音视频播放原理:

3.3 I、P、B帧

3.4、常用的视频压缩算法

MPEG2   MPEG阵营
H264    MPEG阵营
H265    MPEG阵营
AVS       中国阵营
VP8       Google阵营
VP9       Google阵营

3.5、封装格式

封装格式(也叫容器)就是将已经编码压缩好的视频流、音频流及字幕按照一定的方案放到一个文件中,便于播放软件播放。

一般来说,视频文件的后缀名就是它的封装格式。

封装的格式不一样,后缀名也就不一样。

比如:同样的陷可以做成饺子也可以做成包子。对于视频也是一个道理,同样的音视频流可以用不同容器来承载。

可知流0是视频格式、使用的是h264压缩算法,流1是音频格式、使用的是mp3压缩算法。

常用的视频封装格式:
AVI、MKV、MPE、MPG、MPEG
MP4、WMV、MOV、3GP
M2V、M1V、M4V、OGM
RM、RMS、RMM、RMVB、IFO
SWF、FLV、F4V、
ASF、PMF、XMB、DIVX、PART
DAT、VOB、M2TS、TS、PS

其中H264+AAC封装为FLV或MP4是最为流行的模式。

3.6、音视频同步

音视频同步概念:

DTS(Decoding Time Stamp)解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。

PTS(Presentation Time Stamp)显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。

音视频同步方式:

Audio Master:同步视频到音频

Video Master:同步音频到视频

External Clock Master:同步音频和视频到外部时钟。

一般情况下 Audio Master > External Clock Master > Video Master

结束前,提供一个各种格式的测试视频下载网站

https://sample-videos.com/

该网站提供各类音视频格式的下载文件,方面测试。

相关文章
|
1天前
|
JavaScript 前端开发 Java
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
IT寒冬使APP开发门槛提升,安卓程序员需转型。选项包括:深化Android开发,跟进Google新技术如Kotlin、Jetpack、Flutter及Compose;研究Android底层框架,掌握AOSP;转型Java后端开发,学习Spring Boot等框架;拓展大前端技能,掌握JavaScript、Node.js、Vue.js及特定框架如微信小程序、HarmonyOS;或转向C/C++底层开发,通过音视频项目如FFmpeg积累经验。每条路径都有相应的书籍和技术栈推荐,助你顺利过渡。
9 3
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
|
2天前
|
Web App开发 Android开发
FFmpeg开发笔记(四十六)利用SRT协议构建手机APP的直播Demo
实时数据传输在互联网中至关重要,不仅支持即时通讯如QQ、微信的文字与图片传输,还包括音视频通信。一对一通信常采用WebRTC技术,如《Android Studio开发实战》中的App集成示例;而一对多的在线直播则需部署独立的流媒体服务器,使用如SRT等协议。SRT因其优越的直播质量正逐渐成为主流。本文档概述了SRT协议的使用,包括通过OBS Studio和SRT Streamer进行SRT直播推流的方法,并展示了推流与拉流的成功实例。更多细节参见《FFmpeg开发实战》一书。
9 1
FFmpeg开发笔记(四十六)利用SRT协议构建手机APP的直播Demo
|
9天前
|
Web App开发 5G Linux
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
一年一度的毕业季来临,计算机专业的毕业设计尤为重要,不仅关乎学业评价还积累实战经验。选择紧跟5G技术趋势的音视频APP作为课题极具吸引力。这里推荐三类应用:一是融合WebRTC技术实现视频通话的即时通信APP;二是具备在线直播功能的短视频分享平台,涉及RTMP/SRT等直播技术;三是具有自定义动画特效及卡拉OK歌词字幕功能的视频剪辑工具。这些项目不仅技术含量高,也符合市场需求,是毕业设计的理想选择。
31 6
FFmpeg开发笔记(四十四)毕业设计可做的几个拉满颜值的音视频APP
|
8天前
|
编解码 Java Android开发
FFmpeg开发笔记(四十五)使用SRT Streamer开启APP直播推流
​SRT Streamer是一个安卓手机端的开源SRT协议直播推流框架,可用于RTMP直播和SRT直播。SRT Streamer支持的视频编码包括H264、H265等等,支持的音频编码包括AAC、OPUS等等,可谓功能强大的APP直播框架。另一款APP直播框架RTMP Streamer支持RTMP直播和RTSP直播,不支持SRT协议的直播。而本文讲述的SRT Streamer支持RTMP直播和SRT直播,不支持RTSP协议的直播。有关RTMP Streamer的说明参见之前的文章《使用RTMP Streamer开启APP直播推流》,下面介绍如何使用SRT Streamer开启手机直播。
27 4
FFmpeg开发笔记(四十五)使用SRT Streamer开启APP直播推流
|
15天前
|
缓存 视频直播 Linux
FFmpeg开发笔记(四十三)使用SRS开启SRT协议的视频直播服务
《FFmpeg开发实战》书中介绍了轻量级流媒体服务器MediaMTX,适合测试但不适用于生产环境。SRS是一款国产开源服务器,支持RTMP、SRT等协议,适合生产使用。要启用SRS的SRT推流,需配置`srt.conf`,开启SRT服务并配置端口。在确保FFmpeg集成libsrt后,拉流则使用类似但带有`m=request`的地址。在Windows上,同样需要集成libsrt的FFmpeg来使用ffplay拉流。SRS的日志确认了推拉流的成功。书中提供更深入的FFmpeg开发知识。
46 2
FFmpeg开发笔记(四十三)使用SRS开启SRT协议的视频直播服务
|
22天前
|
视频直播 Windows
FFmpeg开发笔记(四十一)结合OBS与MediaMTX实现SRT直播推流
《FFmpeg开发实战》书中介绍了直播中的RTSP、RTMP和SRT协议,SRT提供更低延迟和稳定性。FFmpeg从4.0版起支持SRT,OBS Studio和MediaMTX等工具也已支持。在Windows环境下,通过集成libsrt的FFmpeg,可以建立SRT直播系统。MediaMTX日志显示SRT服务监听8890端口,OBS Studio设置SRT推流至"publish:live"。ffplay和VLC通过"read:live"拉流成功,验证了SRT推拉流功能。更多详情见《FFmpeg开发实战:从零基础到短视频上线》。
54 2
FFmpeg开发笔记(四十一)结合OBS与MediaMTX实现SRT直播推流
|
30天前
|
Web App开发 缓存 编解码
FFmpeg开发笔记(三十八)APP如何访问SRS推流的RTMP直播地址
《FFmpeg开发实战》书中介绍了轻量级流媒体服务器MediaMTX,适合测试RTSP/RTMP协议,但不适用于复杂直播场景。SRS是一款强大的开源流媒体服务器,支持多种协议,起初为RTMP,现扩展至HLS、SRT等。在FFmpeg 6.1之前,推送给SRS的HEVC流不受支持。要播放RTMP流,Android应用可使用ExoPlayer,需在`build.gradle`导入ExoPlayer及RTMP扩展,并根据URL类型创建MediaSource。若SRS播放黑屏,需在配置文件中开启`gop_cache`以缓存关键帧。
87 2
FFmpeg开发笔记(三十八)APP如何访问SRS推流的RTMP直播地址
|
1月前
|
Web App开发 缓存 Linux
FFmpeg开发笔记(三十六)Linux环境安装SRS实现视频直播推流
《FFmpeg开发实战》书中第10章提及轻量级流媒体服务器MediaMTX,适合测试RTSP/RTMP协议,但不适合生产环境。推荐使用SRS或ZLMediaKit,其中SRS是国产开源实时视频服务器,支持多种流媒体协议。本文简述在华为欧拉系统上编译安装SRS和FFmpeg的步骤,包括安装依赖、下载源码、配置、编译以及启动SRS服务。此外,还展示了如何通过FFmpeg进行RTMP推流,并使用VLC播放器测试拉流。更多FFmpeg开发内容可参考相关书籍。
49 2
FFmpeg开发笔记(三十六)Linux环境安装SRS实现视频直播推流
|
16天前
|
视频直播 Linux Windows
FFmpeg开发笔记(四十二)使用ZLMediaKit开启SRT视频直播服务
《FFmpeg开发实战》书中介绍了使用MediaMTX测试RTSP/RTMP,但该工具简单,不适合生产环境。ZLMediaKit,一个支持RTSP/RTMP/SRT的国产流媒体服务器,是更好的选择。要通过ZLMediaKit和FFmpeg实现SRT推流,需确保FFmpeg已集成libsrt。ZLMediaKit默认配置文件中,SRT监听9000端口。日志显示推流和拉流成功。ZLMediaKit支持多种音视频编码,如H264、AAC等。要了解更多FFmpeg开发信息,可参考该书。
34 0
FFmpeg开发笔记(四十二)使用ZLMediaKit开启SRT视频直播服务
|
1月前
|
Linux Apache C++
FFmpeg开发笔记(三十五)Windows环境给FFmpeg集成libsrt
该文介绍了如何在Windows环境下为FFmpeg集成SRT协议支持库libsrt。首先,需要安装Perl和Nasm,然后编译OpenSSL。接着,下载libsrt源码并使用CMake配置,生成VS工程并编译生成srt.dll和srt.lib。最后,将编译出的库文件和头文件按照特定目录结构放置,并更新环境变量,重新配置启用libsrt的FFmpeg并进行编译安装。该过程有助于优化直播推流的性能,减少卡顿问题。
62 2
FFmpeg开发笔记(三十五)Windows环境给FFmpeg集成libsrt