视频传输通话流程:
Android手机摄像头的数据格式是nv21,数据为什么采用yuv而不采用rgb呢?
argb表示像素需要的字节更大。每个像素都需要4字节表示亮度a,4x3字节表示rgb三色值,一共需要4x4=16字节;
YUV方式,同样还是用4个字节表示亮度,剩下一个字节表示u,一个字节表示v,这样就表示出了这个像素,只需要4+1+1=6字节。
因为人眼对亮度是比较敏感的,所以要尽可能的保存更多的亮度的值来精确表达亮度的实际值,人眼对色度不太敏感,所以可以降低色度的存储的数据,不用那么精确的表达色度的实际值,人眼也可以达到差不多相同的感官体验。
编码:把YUV编码成H264的码流。
编码之前需要把nv21的YUV数据转化成nv12格式。nv12又称为YUV420.
把YUV数据传入ByteBuffer,然后传给MediaCodec进行编码。
然后设置pts,也就是每一帧的播放顺序。那么第一帧的pts是0么?肯定不是。因为pts是一个递增的值,解码的时候解码器初始化需要时间,在这个解码的时间轴上,初始化解码器如果耗时10s,这个时候时间轴已经往前走了10s,pts也跟着走到了10了,这回出现个什么问题,0-10s的帧都是过时的帧了,过时虽然被解码出来了,但是不会被播放出来,永远不会被播放出来。举个例子,快进视频的时候,就类似于这种场景了。快进的那一部分视频帧虽然会被解码出来,但是并不会被播放出来。
所以第一帧的pts不可能是0.
设置pts。
之后就是通过dsp芯片编码了。
编码之后就生成了16进制的码流数据了。
编码出来的第一帧不是原始数据,也就是不是画面数据,就是说16进制的第一个NALU不是视频帧数据,而是sps和pps。之后才是I帧,也就是第一帧视频帧。