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/

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

相关文章
|
2月前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
ijkplayer是由Bilibili基于FFmpeg3.4研发并开源的播放器,适用于Android和iOS,支持本地视频及网络流媒体播放。本文详细介绍如何在新版Android Studio中导入并使用ijkplayer库,包括Gradle版本及配置更新、导入编译好的so文件以及添加直播链接播放代码等步骤,帮助开发者顺利进行App调试与开发。更多FFmpeg开发知识可参考《FFmpeg开发实战:从零基础到短视频上线》。
212 2
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
|
2月前
|
并行计算 PyTorch TensorFlow
Ubuntu安装笔记(一):安装显卡驱动、cuda/cudnn、Anaconda、Pytorch、Tensorflow、Opencv、Visdom、FFMPEG、卸载一些不必要的预装软件
这篇文章是关于如何在Ubuntu操作系统上安装显卡驱动、CUDA、CUDNN、Anaconda、PyTorch、TensorFlow、OpenCV、FFMPEG以及卸载不必要的预装软件的详细指南。
5049 3
|
2月前
|
编解码 语音技术 内存技术
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
《FFmpeg开发实战:从零基础到短视频上线》一书中的“5.1.2 把音频流保存为PCM文件”章节介绍了将媒体文件中的音频流转换为原始PCM音频的方法。示例代码直接保存解码后的PCM数据,保留了原始音频的采样频率、声道数量和采样位数。但在实际应用中,有时需要特定规格的PCM音频。例如,某些语音识别引擎仅接受16位PCM数据,而标准MP3音频通常采用32位采样,因此需将32位MP3音频转换为16位PCM音频。
85 0
FFmpeg开发笔记(五十八)把32位采样的MP3转换为16位的PCM音频
|
2月前
|
Ubuntu 应用服务中间件 nginx
Ubuntu安装笔记(三):ffmpeg(3.2.16)源码编译opencv(3.4.0)
本文是关于Ubuntu系统中使用ffmpeg 3.2.16源码编译OpenCV 3.4.0的安装笔记,包括安装ffmpeg、编译OpenCV、卸载OpenCV以及常见报错处理。
213 2
Ubuntu安装笔记(三):ffmpeg(3.2.16)源码编译opencv(3.4.0)
|
2月前
|
XML 开发工具 Android开发
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
ExoPlayer最初是为了解决Android早期MediaPlayer控件对网络视频兼容性差的问题而推出的。现在,Android官方已将其升级并纳入Jetpack的Media3库,使其成为音视频操作的统一引擎。新版ExoPlayer支持多种协议,解决了设备和系统碎片化问题,可在整个Android生态中一致运行。通过修改`build.gradle`文件、布局文件及Activity代码,并添加必要的权限,即可集成并使用ExoPlayer进行网络视频播放。具体步骤包括引入依赖库、配置播放界面、编写播放逻辑以及添加互联网访问权限。
185 1
FFmpeg开发笔记(五十六)使用Media3的Exoplayer播放网络视频
|
2月前
|
Web App开发 安全 程序员
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
多年的互联网寒冬在今年尤为凛冽,坚守安卓开发愈发不易。面对是否转行或学习新技术的迷茫,安卓程序员可从三个方向进阶:1)钻研谷歌新技术,如Kotlin、Flutter、Jetpack等;2)拓展新功能应用,掌握Socket、OpenGL、WebRTC等专业领域技能;3)结合其他行业,如汽车、游戏、安全等,拓宽职业道路。这三个方向各有学习难度和保饭碗指数,助你在安卓开发领域持续成长。
85 1
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
|
3月前
|
XML Java Android开发
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
GSYVideoPlayer是一款国产移动端视频播放器,支持弹幕、滤镜、广告等功能,采用IJKPlayer、Media3(EXOPlayer)、MediaPlayer及AliPlayer多种内核。截至2024年8月,其GitHub星标数达2万。集成时需使用新版Android Studio,并按特定步骤配置依赖与权限。提供了NormalGSYVideoPlayer、GSYADVideoPlayer及ListGSYVideoPlayer三种控件,支持HLS、RTMP等多种直播链接。
122 18
FFmpeg开发笔记(五十二)移动端的国产视频播放器GSYVideoPlayer
|
2月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
116 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
2月前
|
缓存 监控 计算机视觉
视频监控笔记(三):opencv结合ffmpeg获取rtsp摄像头相关信息
本文介绍了如何使用OpenCV结合FFmpeg获取RTSP摄像头信息,包括网络架构、视频监控系统组成、以及如何读取和显示网络摄像头视频流。
73 1
|
3月前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher
EasyPusher是一款国产RTSP直播录制推流客户端工具,支持Windows、Linux、Android及iOS等系统。尽管其GitHub仓库(安卓版:https://github.com/EasyDarwin/EasyPusher-Android)已多年未更新,但通过一系列改造,如升级SDK版本、迁移到AndroidX、指定本地NDK版本及更新Gradle版本等,仍可在最新Android Studio上运行。以下是针对Android Studio Dolphin版本的具体改造步骤。
70 3
FFmpeg开发笔记(五十三)移动端的国产直播录制工具EasyPusher