文章目录

  • 视频常用颜色空间YUV
  • YUV颜色编码格式
  • 色度抽样方式
  • 存储方式
  • YUV与RGB之间的转换
  • NV12数据渲染
  • NV12转I420
  • 视频压缩编码
  • 视频压缩编码的分类
  • 预测编码
  • 变换编码
  • 熵编码
  • H.261编码
  • H.261复合编码器
  • H.263标准
  • MPEG-1标准
  • MPEG-2标准
  • MPEG-4标准


视频常用颜色空间YUV

YUV,分为三个分量,“Y”表示明亮度(Luminance或Luma),也就是灰度值;而“U”和“V” 表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。这种表达方式起初是为了彩色电视与黑白电视之间的信号兼容,黑白电视只使用明度就可以成像。

Y’CbCr也称为YUV,是YUV的压缩版本,不同之处在于Y’CbCr用于数字图像领域,YUV用于模拟信号领域,MPEG、DVD、摄像机中常说的YUV其实是Y’CbCr,二者转换为RGBA的转换矩阵是不同的。Y’为亮度,Cb、Cr分量代表当前颜色对蓝色和红色的偏移程度。
为了方便,以下文中YUV特指Y’CbCr。

YUV颜色编码格式

YUV编码是image/video pipeline的重要组成。比如常用的I420相对于RGB24(RGB三个分量各8个字节)的编码格式,只需要一半的存储容量。在流数据传输时降低了带宽压力。
YUV色彩编码格式由其色度抽样方式和存储方式决定。

色度抽样方式

色度抽样方式用J:A:B表示

J:最小水平抽样的的宽度,一般为4

A:最小水平抽样区域第一行的色度抽样

B:最小水平抽样区域第二行的色度抽样

android 录制视频编码_数据


android 录制视频编码_视频编码_02


android 录制视频编码_视频编码_03


android 录制视频编码_数据_04

可以看出,YUV编码保留了全部的明度信息,而舍弃了部分色度信息,这是利用了人对色彩信息不敏感的特性,从而降低了对内存的占用,降低了带宽压力。

存储方式

YUV存储方式主要分为两种:Packeted 和 Planar。
Packeted方式类似RGB的存储方式,以像素矩阵为存储方式。
Planar方式将YUV分量分别存储到矩阵,每一个分量矩阵称为一个平面。
YUV420即以平面方式存储,色度抽样为4:2:0的色彩编码格式。其中YUV420P为三平面存储,YUV420SP为两平面存储。
常用的I420(YUV420P),NV12(YUV420SP),YV12(YUV420P),NV21(YUV420SP)等都是属于YUV420,NV12是一种两平面存储方式,Y为一个平面,交错的UV为另一个平面。
由此,I420就是存储方式为Planar,抽样方式为4:2:0,数据组成为YYYYYYYYUUVV的一种色彩编码格式。
除此之外,NV12的数据组成:YYYYYYYYUVUV 。YV12的数据组成:YYYYYYYYVVUU。NV21的数据组成:YYYYYYYYVUVU。
通常,用来远程传输的是I420数据,而本地摄像头采集的是NV12数据。(iOS)

YUV与RGB之间的转换

在渲染时,不管是OpenGL还是iOS,都不支持直接渲染YUV数据,底层都是转为RGB。

//RGB --> YUV
Y = 0.299 R + 0.587 G + 0.114 B

U = - 0.1687 R - 0.3313 G + 0.5 B + 128

V = 0.5 R - 0.4187 G - 0.0813 B + 128
//YUV --> RGB
//由于U、V可能出现负数,单存储为了方便就用一个字节表示:0-255,读取时要-128回归原值。
R = Y + 1.402 (Cr-128)

G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)

B = Y + 1.772 (Cb-128)

NV12数据渲染

void convertNv12ToRgb(unsigned char *rgbout, unsigned char *pdata,int DataWidth,int DataHeight)
{
    unsigned long  idx=0;
    unsigned char *ybase,*ubase;
    unsigned char y,u,v;
    ybase = pdata; //获取Y平面地址
    ubase = pdata+DataWidth * DataHeight; //获取U平面地址,由于NV12中U、V是交错存储在一个平民的,v是u+1
    for(int j=0;j<DataHeight;j++)
    {
        idx=(DataHeight-j-1)*DataWidth*3;//该值保证所生成的rgb数据逆序存放在rgbbuf中,位图是底朝上的
        for(int i=0;i<DataWidth;i++)
        {
            unsigned char r,g,b;
            y=ybase[i + j  * DataWidth];//一个像素对应一个y
            u=ubase[j/2 * DataWidth+(i/2)*2];// 每四个y对应一个uv
            v=ubase[j/2 * DataWidth+(i/2)*2+1];  //一定要注意是u+1
            
            b=(unsigned char)(y+1.779*(u- 128));
            g=(unsigned char)(y-0.7169*(v - 128)-0.3455*(u - 128));
            r=(unsigned char)(y+ 1.4075*(v - 128));
            
            rgbout[idx++]=b;
            rgbout[idx++]=g;
            rgbout[idx++]=r;
        }
    }
}

NV12转I420

unsigned char* convertNV12ToI420(unsigned char *data , int dataWidth, int dataHeight){
    unsigned char *ybase,*ubase;
    ybase = data;
    ubase = data + dataWidth*dataHeight;
    unsigned char* tmpData = (unsigned char*)malloc(dataWidth*dataHeight * 1.5);
    int offsetOfU = dataWidth*dataHeight;
    int offsetOfV = dataWidth*dataHeight* 5/4;
    memcpy(tmpData, ybase, dataWidth*dataHeight);
    for (int i = 0; i < dataWidth*dataHeight/2; i++) {
        if (i % 2 == 0) {
            tmpData[offsetOfU] = ubase[i];
            offsetOfU++;
        }else{
            tmpData[offsetOfV] = ubase[i];
            offsetOfV++;
        }
    }
    free(data);
    return tmpData;
}

YUV颜色编码解析

视频压缩编码

编码:将信息按照一定规则使用某种形式的码流表示与传输。
常需要编码的信息:文字、语音、视频、控制信息等。
长期以来,视频编码标准主要由两个国际组织负责制定:国际电信联盟ITU-T(International Telecommunications Union-Telecommunication Standardization Sector)和国际标准化组织ISO。目前影响力最强的视频编码标准基本均出自这两个组织。
除了上述两个组织之外,其他比较有影响力的标准还有:
Google:VP8/VP9;
Microsoft : VC-1;
国产自主标准:AVS/AVS+/AVS2

其中ITU-T下属有视频编码专家组VCEG(Video Coding Experts Group),指定了H.261/H.263/H.263+/H.263++等
ISO下属有移动图像专家组MPEG(Motion Picture Experts Group),制定了MPEG-1/MPEG-4等

android 录制视频编码_存储方式_05

基于波形的编码:
特点:编码的数据针对每一帧图像包含的像素值,即采样像素的波形
方法:利用像素之间在时间和空间上的相关性,采用预测编码和变换编码结合的和基于块的混合编码方法
代表:MPEG-1,MPEG-2,H.264,H.265等

基于内容的编码:
特点:视频帧分成对应不同物体的区域,分别对其编码
方法:针对不同物体的形状,运动和纹理进行编码
代表:MPEG-4
由于其运算复杂度过高,这种方式的发展不是很好。

视频压缩编码的分类

预测编码

传输预测像素值和实际像素值的差,利用时间或空间相邻像素之间较强的相关性
帧内预测:预测值与实际值位于同一帧内,用于消除图像的空间冗余。帧内预测压缩率较低,但是可以独立解码,不依赖其它外部数据。关键帧一般采用帧内预测。
帧间预测:实际值位于当前帧,预测值位于参考帧,用于消除图像的时间冗余。压缩率比帧内预测更高,但是参考了其它帧的数据,不能独立解码,只能在获取参考帧之后才能重建出当前帧。

I帧一般采用帧内编码,P帧和B帧有可能采用帧间编码,也有可能采用帧内编码。

目前主流的视频编码算法包括MPEG-1,MPEG-2,H264,H265,它们都属于有损编码。这些编码算法通过对视频造成有限的可以容忍的损失,来获取相对更高的编码效率。而造成损失的这部分,就在它的变换量化这部分,在变换量化之前,需要将视频帧从空间域变换为频域。

变换编码

将像素由空间域变换为频域,针对变换系数进行编码
可用于视频编码的正交变换:DCT(离散余弦变换),DST(离散正弦变换),K-L变换等

熵编码

利用信源的统计特性进行压缩编码
常用方法:变长编码,算数编码

H.261编码

第一种采用块结构的混合编码方案的编码标准
目的:视频会议、可视电话等低码率视频图像传输
数据格式:公共中间格式(Common Intermediate Format,CIF)

  • 各国电视制式不统一,无法互通
  • 在使用H.261进行编码之前,首先转换为CIF格式然后再编码
  • 每一帧分辨率:
    CIF:352288
    QCIF:176
    144

android 录制视频编码_android 录制视频编码_06


帧内/帧间编码判定:根据帧间相关性判定,相关性高使用帧间编码,相关性低使用帧内编码。

帧间编码/运动估计:使用以宏块为基础的运动补偿预测编码;当前宏块从参考帧中查找最佳匹配宏块,并计算其相对偏移量(Vx,Vy)作为运动矢量;编码器使用DCT、量化编码当前宏块和预测宏块的残差信号;

帧内编码:帧内编码直接使用DCT编码8*8像素值

环路滤波器:实际是一个数字低通滤波器,滤除不必要的高频信息,以消除方块效应。

H.261复合编码器

帧层:由帧首和块组数据构成;帧首包括帧起始码(PSC)、帧计数码(TR)、帧类型(PTYPE)等;
块组层:由块组首和宏块数据组成;块组首包括组起始码(GBSC)、块组编号码(GN)、块组量化步长等;
宏块层:由宏块首和块数据构成;宏块首包括宏块地址码、宏块类型、宏块量化步长、运动矢量数据、编码模式等;
块层:包括每个8*8块的DCT系数按之字形扫描后的熵编码码流,以块结束符结尾。

android 录制视频编码_存储方式_07

H.263标准

H.263相对于H.261的改进:
运动矢量:相对于H.261对每一个MB(宏块层)分配一个运动矢量,H.263支持每一个8*8块(块层)各自使用一个运动矢量;
MV精度:相对于H.261只支持整数像素运动搜索,H.263的精度为1/2像素;
双向预测模式:H.263支持B帧,使用前后双向预测模式
熵编码采用算术编码算法,运算复杂度高,可显著降低码率

H.263支持的图像格式

图像格式

Sub-QCIF

QCIF

CIF

4CIF

16CIF

分辨率

128*96

176*144

352*288

704*576

1480*1152

MPEG-1标准

作用:在CD/VCD介质中存储音视频信息

码率:1.2~1.5Mb/s

图像类型:支持I,B,P帧类型

图像显示顺序:

I->B->B->P->B->B->P_B->…

码流结构:

android 录制视频编码_视频编码_08


总体结构上,MPEG-1与H.261类似,采用分层的码流结构

MPEG-1相比于H.261增加了条带层,每个宏块所有的编码操作只能在一个条带内实现

条带层可以有效防止编码错误在一帧内扩散

MPEG-1出现后不久MPEG-2就出现了,而且MPEG-2兼容MPEG-1,所以MPEG-2就将MPEG-1淘汰了

MPEG-2标准

MPEG-2的标准编号是iso-13818。
DVD光盘就是采用MPEG-2进行压缩的,由于MPEG-2兼容MPEG-1,所以DVD能播放VCD光盘。
MPEG-2的码流层次:共分为三层:

  • 基本流:ES,由视频编码的视频基本流和音频编码的音频基本流构成
  • 打包基本流:PES,为音视频ES分别打包
  • 传输流、节目流:TS/PS,若干个PES进行复用后输出,分别用于传输和存储

档(Profile)和级(Level):

  • 按照使用的编码工具共定义了5个Profile(SP简单/MP主要/SNP信噪比可分级/SSP空间可分级/HP高级)
  • 按照视频分辨率定义了4个级别(LL低级/ML主级/H1440高1440级/HL高级)

MPEG-2格式支持逐行或隔行扫描视频,使用基于帧或场的编码

MPEG-2的ES流结构类似于MPEG-1,也分为图像序列层、图像组、图像、片、宏块和块层:
图像序列层:包括若干GOP,序列头包含起始码和序列参数等
图像组(GOP)层:包括若干图像,GOP头包括起始码,GOP标识等
图像层:包括若干个Slice,图像头中包括起始码和图像参数等
片(Slice)层:最小的同步单位,包括若干宏块,Slice头中包括起始码、片地址、量化步长等信息;
宏块(Macroblock)层:由4个亮度块和2个色度块组成,宏块头包括地址、类型、MV等信息

MPEG-4标准

与前任MPEG-1和MPEG-2相比,MPEG-4更注重多媒体系统的交互性、灵活性和扩展性
MPEG-4标准采用了基于对象的编码,其中视频对象主要定义为画面中分割出来的不同物体,每个物体由三类信息描述:运动信息、轮廓信息和纹理信息