windows下使用FFmpeg生成YUV视频文件并播放(通过命令的方式)

一、YUV的定义

  YUV是一种颜色编码方法。它跟我们常见的RGB格式区分开来,常使用在各个视频处理组件中。其中"Y"代表明亮度,"U"和"V"代表其色度。视频播放器把市面上流行的MP4等格式文件的视频部分解码出来,得到的一般会是YUV格式的数据,然后得进行像素格式转换(比如通过opengl的shader或者ffmpeg),把YUV格式的数据转成RGB格式的数据,然后才能在显示屏播放显示。

  YUV与RGB相比,优点是:

1.亮度参量和色度参量分开表示,不但可以避免相互干扰,还可以降低色度的采样率而不会对图像质量影响太大(也就是说色度频道的采样率可比 Y 频道低,同时不会明显降低视觉质量)。

2.兼容老式黑白电视,使黑白电视机也能接收彩色电视信号。

3.只需要极少的频宽来进行视频信号传输。

4.占用空间小,对于同一幅图像,使用YUV420表示比RGB24表示少占用一半的空间,数据率压缩了一倍,而图像的效果基本没发生变化。

RGB24一帧的大小size=width×heigth×3 Byte 
RGB32一帧的大小size=width×heigth×4 Byte 
YUV420一帧的大小size=width×heigth×1.5 Byte 

二、通过FFmpeg命令转换得到YUV文件

  如下图所示,工程目录下有video1.mp4这个MP4文件,下面我们介绍把它转为YUV文件的方法。

windows下使用FFmpeg生成YUV视频文件并播放(通过命令的方式)_第1张图片

在命令提示符cmd.exe中进入当前工程所在目录(ffmpeg.exe和video1.mp4所在目录),然后输入命令:

ffmpeg -i video1.mp4 -s 640x272 -pix_fmt yuv420p video1.yuv

该命令的作用是把所在路径下的video1.mp4文件转换为帧宽度为640,帧高度为272,像素格式为yuv420p的YUV文件:video1.yuv。

注:
-i 表示设定输入流
-s 设定画面的宽与高
-pix_fmt 设定的像素格式

YUV格式通常有两大类:打包(packed)格式和平面(planar)格式。yuv420p是planar格式的YUV格式,对于这种格式,其先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V(在ffmpeg中是存储在struct AVFrame的data[]数组中,data[0]存放Y分量、data[1]存放U分量、data[2]存放V分量。AVFrame的linesize[]数组中保存的是对应通道的数据宽度,linesize[0]存放Y分量的宽度,linesize[1]存放U分量的宽度,linesize[2]存放V分量的宽度。注意,linesize[0]的值并不一定等于图片的宽度,有时候为了对齐各解码器的CPU,实际尺寸会大于图片的宽度,所以得作行对齐处理)。 对于packed格式的YUV格式,每个像素点的Y,U,V是连续交叉存储的(在ffmpeg中YUV分量都存贮在AVFrame的data[0]数组中)。

执行该命令后,我们发现工程目录下会生成video1.yuv文件,如下图所示:

windows下使用FFmpeg生成YUV视频文件并播放(通过命令的方式)_第2张图片

三、存贮空间分析

windows下使用FFmpeg生成YUV视频文件并播放(通过命令的方式)_第3张图片

由上图可知,4:2:0 水平方向是1/2,垂直方向是1/2,表示一个色度像素对应了四个图形像素。

所以对于一张yuv420p格式的分辨率为640 * 272的图片,

每一个像素都需要一个亮度(luminance)值,即y。那么总共需要 640 * 272 = 174080 字节

每四个像素都需要一个色度(chrominance)u值,那么总共需要 640 * 272 / 4 =  43520 字节

每四个像素都需要一个色度(chrominance)v值,那么总共需要 640 * 272 / 4 =  43520 字节

把 y、u、v 三个 plane 加起来就是:174080 + 43520 + 43520 = 261120 字节

所以对于一张yuv420p格式的分辨率为640 * 272的图片,其需要占用261120字节的存贮空间。

然后由命令:

ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 video1.mp4

可以知道video1.mp4总共有5443帧(5443张图片)。

注:

-v error 这隐藏了“信息”输出(版本信息等),使分析更容易。

-count_frames 计算每个流的帧数并在相应的流部分报告。

-select_streams v:0 只选择视频流。

-show_entries stream=nb_read_frames 仅显示读取帧的数量。

-of default=nokey=1:noprint_wrappers=1设置输出格式(即“作者”)default,不要打印每个字段(nokey=1)的关键字,并且不要打印节标题和页脚

所以可以计算出video1.yuv大小为:5443 * 261120 = 1421276160字节。

查看video1.yuv的属性,可以看到系统显示的大小和我们计算的完全吻合。

windows下使用FFmpeg生成YUV视频文件并播放(通过命令的方式)_第4张图片

四、使用ffplay.exe播放YUV文件

   YUV文件用市面上流行的播放器我们一般无法直接播放。但我们可以通过FFmpeg提供的ffplay.exe播放YUV文件。

  在命令提示符cmd.exe中进入当前工程所在目录(ffplay.exe和video1.yuv所在目录),然后输入命令:

ffplay -video_size 640x272 -i video1.yuv

该命令的作用是使用ffplay播放帧宽度为640,帧高度为272的YUV文件vido1.yuv

注:

-i 表示指定的输入文件
-video_size 播放的视频文件的帧宽度和帧高度

如下图所示,看到如下画面,则表示播放成功。

windows下使用FFmpeg生成YUV视频文件并播放(通过命令的方式)_第5张图片

使用代码用OpenGL播放YUV(yuv420p)文件的方法可以参考:《windows下使用OpenGL实现yuv420p转rgb播放视频(三重纹理实现)》

五、附件资源下载

  本博文附件资源下载地址在https://download.csdn.net/download/u014552102/10700001,资源里面包含博文演示用的ffplay.exe,ffmpeg.exe工具,转换用的video1.mp4视频文件,和转换成功的video1.yuv文件,用户可以结合该资源和博文学习生成和播放yuv文件的方法

你可能感兴趣的:(音视频技术,ffmpeg,音视频,YUV,ffplay)