ffmpeg入门小结(一)—— YUV格式示例

简介: ffmpeg入门小结(一)—— YUV格式示例

1.ffmpeg简介

ffmpeg是一个开源免费跨平台的视频和音频流方案,属于自由软件,采用LGPL/GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的。ffmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它包括了目前领先的音/视频编码库libavcodec。 ffmpeg是在Linux下开发出来的,但它可以在包括Windows在内的大多数操作系统中编译。



----------------------


ffmpeg的一些基本概念


----------------------


Container:在音视频中的“容器”,一般指的是一种特定格式的多媒体文件,里面指明了所包含的音视频、字幕等相关信息;

Stream:可以理解为分解开的、单纯的音频数据流或视频数据流或字幕流等;

Frame:指的是Stream中的一个未经压缩的完整数据单元;

Packet:是存储压缩数据的结构,视频流中通常是压缩的一个Frame的,而在音频流中则可能是压缩的多个Frame;

Codec:编解码器;


采样率:每秒钟记录多少个采样点;



----------------------


ffmpeg的组成结构


----------------------


ffmpeg主要由以下几个库组成:


· libavcodec: encoding/decoding library (编解码库)


· libavfilter: graph-based frame editing library(滤波器库,类似DShow的“可组装”的特点,但要求filter的输入/输出接口是匹配的)


· libavformat: I/O and muxing/demuxing library(IO及分解/合并流)


· libavdevice: special devices muxing/demuxing library(例如打开摄像头,屏幕录制等)


· libavutil: common utility library(小型函数库,内存分配、释放)


· libswresample: audio resampling, format conversion and mixing


· libpostproc: post processing library(后期处理?尚不清楚)


· libswscale: color conversion and scaling library(转码及尺度变换)


ffmpeg软件包经编译过后将生成三个可执行文件(可通过命令行运行):


· ffmpeg:ffmpeg用于对媒体文件进行处理;


· ffserver:ffserver是一个http的流媒体服务器;


· ffplay:ffplay是一个基于SDL的简单播放器。


2.视频YUV格式简介


YUV格式,一般用Y,U,V三者的比率来表示不同格式,比如YUV444 表示三者是比值此是 4:4:4,即一个点数据点,Y,U,V的空间都是一样大小。目前主要有如下比例,注意所有格式中Y比值都是4,占一个字节,表示没有减少采样。不同格式中,减小只是UV的采样值.



4:4:4:表示色度值(UV)没有减少采样。即Y,U,V各占一个字节,总共占3字节。


4:2:2:表示UV分量采样减半,比如第一个像素采样Y,U,第二个像素采样Y,V,依次类推,这样每个点占用2个字节。二个像素组成一个宏像素.


4:2:0:这种采样并不意味着只有Y,Cb而没有Cr分量,这里的0说的U,V分量隔行才采样一次。比如第一行采样 4:2:0,第二行采样 4:0:2 ,依次类推……在这种采样方式下,平均每一个像素占用1.5字节.



4:2:2示例


如果原始数据三个像素是 [Y0 U0 V0] ,[Y1 U1 V1],[Y2 U2 V2],[Y3 U3 V3]


经过4:2:2采样后,数据变成了 Y0 U0 ,Y1 V1 ,Y2 U2,Y3 V3


如果还原后,因为某一些数据丢失就补成 [Y0 U0 V1],[Y1 U0 V1],[Y2 U2 V3] ,[Y3 U3 V2]



4:2:0示例


下面八个像素为:[Y0 U0 V0] [Y1 U1 V1] [Y2 U2 V2] [Y3 U3 V3] [Y5 U5 V5] [Y6 U6 V6] [Y7U7 V7] [Y8 U8 V8]


存放的码流为:  Y0 U0, Y1, Y2 U2, Y3,Y5 V5, Y6,Y7 V7, Y8


映射出的像素点为:[Y0 U0 V5] [Y1 U0 V5] [Y2 U2 V7] [Y3 U2 V7] [Y5 U0 V5] [Y6 U0 V5] [Y7 U2 V7] [Y8 U2 V7]



  除了4:4:4采样,其余采样后信号重新还原显示后,会丢失部分UV数据,只能用相临的数据补齐,但人眼对UV不敏感,因此总体感觉损失不大。


image.png

图1 YUV420sp存储格式

image.png

图2 YUV420p存储格式

ps: ffmpeg中,图像原始数据包括两种:planar和packed。planar就是将几个分量分开存,比如YUV420中,data[0]专门存Y,data[1]专门存U,data[2]专门存V。而packed则是打包存,所有数据都存在data[0]中.


3.YUV格式示例【顺时针旋转90°YUV420图像】:

public static void rotateYUV420(byte[] src,byte[] des,int width,int height, String type){
        // 原图按行序存储
    int wh = width * height;
    int k = 0;
    //旋转Y分量(按原图的列序存储)
    for(int i=0;i<width;i++) {
      for(int j=0;j<height;j++) {
                des[k] = src[width*j + i];      
            k++;
      }
    }
if(type.equals(“YUV420SP”)){
        // YUV420SP是UV分量交错依次存储的情况
    // 旋转UV分量(按原图的列序存储)
    for(int i=0;i<width;i+=2) {  // +2
      for(int j=0;j<height/2;j++) { 
                des[k] = src[wh+ width*j + i];  
                des[k+1]=src[wh + width*j + i+1];
            k+=2;
      }
    }
}
else if(type.equals(“YUV420P”)){
        // YUV420P是UV分量分开存储的情况
        // 旋转U分量(按原图的列序存储)
    for(int i=0;i<width;i++) {
      for(int j=0;j<height/4;j++) { 
                  // stride = wh
                des[k] = src[wh + width*j + i]; 
            k++;
      }
    }
        // 旋转V分量(按原图的列序存储)
    for(int i=0;i<width;i++) {
      for(int j=0;j<height/4;j++) { 
                  // stride = wh + wh*1/4
                des[k] = src[(1+1/4.0f)*wh + width*j + i];  
            k++;
      }
      }
}
  }

ps: ffmpeg库的接口都是c函数,在cpp文件里调用ffmpeg函数要注意了,由于C++语言支持函数重载,C语言不支持函数重载,函数被C++编译器编译后在库中的名字与C语言的不同(mangled name),一个用C写成的库如果想被C/C++同时可以使用,那在头文件应该加上以下代码

#ifdef __cplusplus
extern "C" {
#endif 
...
#ifdef __cplusplus
}
#endif
目录
相关文章
|
6月前
|
Web App开发 编解码 安全
视频会议技术 入门探究:WebRTC、Qt与FFmpeg在视频编解码中的应用
视频会议技术 入门探究:WebRTC、Qt与FFmpeg在视频编解码中的应用
648 4
|
6月前
|
存储 编解码 数据处理
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码(三)
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码
205 0
|
6月前
|
存储 编解码 数据处理
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码(二)
【FFmpeg 视频基本格式】深入理解FFmpeg:从YUV到PCM,解码到编码
229 0
|
编解码 API 开发工具
FFmpeg入门及编译 1
FFmpeg入门及编译
176 1
|
C++ Windows
FFmpeg入门及编译 3
FFmpeg入门及编译
109 0
|
6月前
|
存储 编解码 缓存
FFmpeg编程入门
FFmpeg编程入门
86 1
|
1月前
FFmpeg学习笔记(二):多线程rtsp推流和ffplay拉流操作,并储存为多路avi格式的视频
这篇博客主要介绍了如何使用FFmpeg进行多线程RTSP推流和ffplay拉流操作,以及如何将视频流保存为多路AVI格式的视频文件。
194 0
|
2月前
|
内存技术
速通FFmpeg入门
速通FFmpeg入门
37 5
|
5月前
|
编解码 Linux 计算机视觉
python 调用ffmpeg使用usb摄像头录制视频,输出h264格式,自动获取摄像头的最佳帧率和最大画面尺寸
使用 Python 调用 FFmpeg 进行 USB 摄像头视频录制,需先确保安装 FFmpeg 和 Python 的 `subprocess` 模块。代码示例展示了如何自动获取摄像头的最佳帧率和最大分辨率,然后录制视频。首先通过 FFmpeg 列出摄像头格式获取信息,解析出帧率和分辨率,选择最优值。之后调用 FFmpeg 命令录制视频,设置帧率、分辨率等参数。注意 `/dev/video0` 是 Linux 的摄像头设备路径,Windows 系统需相应调整。代码中未直接实现自动获取最佳参数,通常需要借助其他库如 OpenCV。
|
5月前
|
存储 编解码 Linux
rodert教你学FFmpeg实战这一篇就够了 - 音视频处理入门篇
rodert教你学FFmpeg实战这一篇就够了 - 音视频处理入门篇
64 1