1.DTS/PTS
如果没有B帧,那么DTS一般与PTS相同
- DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。(解码I->P->B)
- PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。
2.GOP
就是将同一组动作的封装为一个组,组内的动作变化不大,可以不用整个图片传输,降低数据量
2.!宏块!
- 视频压缩操作的基本单元
- 帧内压缩还是帧间压缩,都是以宏块为单位
- 细节部分宏块划分小.
3.帧内压缩和帧间压缩(有损压缩)
- 帧内压缩:即只利用了单帧图像内的空间相关性,对冗余数据(相同的像素)进行编码,达到压缩效果,而没有利用时间相关性,不使用运动补偿。
- 用宏块做对比,然后用算法(9种)选择一种,把当前宏块化为一个数字,对面接受后进行反解就可以恢复
- 亮度和色度分开预测
- 预测后与原始图求差值,然后一起传输.到那边反解后再加上差值就可以得到相似的原图
- 只对I帧和IDR帧
- 帧间压缩:由于视频的特性,相邻的帧之间其实是很相似的,通常是运动矢量的变化。利用其时间相关性,可以通过参考帧运动矢量的变化来预测图像,并结合预测图像与原始图像的差分,便能解码 出原始图像。所以,帧间编码需要依赖其他帧才能解码出一帧画面。
- GOP
- 参考帧
- 运动估计(宏块匹配 + 运动矢量) : 用宏块匹配的方法找到运动矢量(一个物品变动的方向和位置)
- 运动补偿(残差值)
- P帧,B帧
运动矢量
I帧P帧B帧
- I帧 : 内编码方式, IDR帧(每个GOP中的第一帧),也是I帧
- P帧,向前参考.大小为I帧的一半
- B帧,双向参考帧,大小为I帧的1/4
IDR帧与I帧区别
IDR 解码立即刷新.
每当遇到IDR帧,解码器就会清空解码器参考buffer中的内容
每个GOP中的第一帧为IDR帧
SPS/PPS
在每个IDR前面,一定有SPS/PPS
- SPS 序列参数集. 参考帧数量(可以修改一个帧参考多个I帧),帧数,帧场编码模式
- PPS 熵编码模式,组数目
4.视频花屏/卡顿原因
-
花屏原因:如果GOP分组有帧丢失,会造成解码端的图像发生错误,就会出现马赛克(花屏)
-
卡顿原因: 为了避免花屏问题的发生,如果发现有帧丢失时,就丢弃整个GOP内的所有帧,
直到下一个IDR帧重新刷新图像(这段时间就卡顿)
5.DCT帧数离散余弦变化 ,CABAC压缩(无损压缩)
- DCT 将空间上的相关性变为频域上无关的数据然后进行量化
- 就是将一个无序的矩阵化成一个更小的,集中在一个角的矩阵
- VLC压缩,类似哈夫曼,用于MPEG2
- CABAC压缩(H264),
6.H264码流
1.分层
- NAL层 : 视频数据网络抽象层(头,类似于TCP头),解决纠错能力.(一个字节的head)
- VCL层: 视频数据编码层(帧信息,数据)
2.VCL结构
一般都是一个图片一个slice;但是可以包含多个slice
- slice里面存的是一个个宏块, 宏块中存了 : 宏块类型(9种模式),预测值和残差值
3.码流基本概念
-
SODB(按位计算)
- 原始数据比特流,长度一定要到8位的倍数.VLC层尝试
-
RBSP(按字节计算,因为按位可能不是8的整数倍,所有有了这个)
- SODB + 补充位. 如果SODB最后一个字节如果不对齐,就补1和多个0
-
NALU
- NAL Header(1B) + RBSP
4.图.清晰
5.全部码流图
- startCode : 0x000001,0x00000001;
- RTP可以直接传输
7.常用同步策略
-
将视频同步到音频上:就是以音频的播放速度为基准来同步视频。
-
将音频同步到视频上:就是以视频的播放速度为基准来同步音频。
-
将视频和音频同步外部的时钟上:选择一个外部时钟为基准,视频和音频的播放速度都以该时钟为标准。
当播放源比参考时钟慢,则加快其播放速度,或者丢弃;快了,则延迟播放。
1.选取同步策略
考虑到人对声音的敏感度要强于视频,频繁调节音频会带来较差的观感体验,且音频的播放时钟为线性增长,所以一般会以音频时钟为参考时钟,视频同步到音频上。
2.视频I帧问题(必须等到第一个I帧)
对于起播阶段,特别是TS实时流,由于视频解码需要依赖第一个I帧,而音频是可以实时输出,可能出现的情况是视频PTS超前音频PTS较多,这种情况下进行同步,势必造成较为明显的慢同步。处理这种情况的较好方法是将较为多余的音频数据丢弃,尽量减少起播阶段的音视频差距。
3.同步步骤
- 获取当前要显示的video PTS,减去上一帧视频PTS,则得出上一帧视频应该显示的时长delay;
- 当前video PTS与参考时钟当前audio PTS比较,得出音视频差距diff;
- 获取同步阈值sync_threshold,为一帧视频差距,范围为10ms-100ms;
- diff小于sync_threshold,则认为不需要同步;否则delay+diff值,则是正确纠正delay;
- 如果超过sync_threshold,且视频落后于音频,那么需要减小delay(FFMAX(0, delay + diff)),让当前帧尽快显示。
如果视频落后超过1秒,且之前10次都快速输出视频帧,那么需要反馈给音频源减慢,同时反馈视频源进行丢帧处理,让视频尽快追上音频。因为这很可能是视频解码跟不上了,再怎么调整delay也没用。 - 如果超过sync_threshold,且视频快于音频,那么需要加大delay,让当前帧延迟显示。
将delay*2慢慢调整差距,这是为了平缓调整差距,因为直接delay+diff,会让画面画面迟滞。
如果视频前一帧本身显示时间很长,那么直接delay+diff一步调整到位,因为这种情况再慢慢调整也没太大意义。 - 考虑到渲染的耗时,还需进行调整。frame_timer为一帧显示的系统时间,frame_timer+delay- curr_time,则得出正在需要延迟显示当前帧的时间。
8.行对齐问题
//播放内容放置到材质内存空间中,格式为YUV
if (width == frame->linesize[0]) //无需对齐
{
memcpy(datas[0], frame->data[0], width*height);
memcpy(datas[1], frame->data[1], width*height / 4);
memcpy(datas[2], frame->data[2], width*height / 4);
}
else//行对齐问题
{
for(int i = 0; i < height; i++) //Y
memcpy(datas[0] + width*i, frame->data[0] + frame->linesize[0]*i, width);
for (int i = 0; i < height/2; i++) //U
memcpy(datas[1] + width/2*i, frame->data[1] + frame->linesize[1] * i, width);
for (int i = 0; i < height/2; i++) //V
memcpy(datas[2] + width/2*i, frame->data[2] + frame->linesize[2] * i, width);
}
9.YUV类型
//YUV444
Y0 U0 V0 Y1 U1 V1 ....
//YUV420
Y0 Y0 Y1 V0....
//YUV420 真正样子为上下隔开 上面均为Y,下面均为u0v0
Y0 Y1 Y2 Y3 Y4 ...
U0V0 U1V1 ...
Y1 Y1 Y1 Y1 Y1 ...
10.音频压缩
压缩两个方向: 压缩体积越来越小,或者压缩速度越来越快
1.方法:
- 有损压缩: 消除冗余信息(人听不到的信息删除)
- 频域遮蔽(频率不一样,高频率可以遮盖一点范围的低频率声音)
- 时域遮蔽(越靠近声音时间,遮盖率就越高)
- 无损压缩: 文件压缩,编码解码
- 熵编码 : 哈夫曼,算数编码,香农编码
2.编码过程
文章来源:https://www.toymoban.com/news/detail-411234.html
2.常见的音频编码器
- opus(现在经常用,webrtc,直播等,但是收费)
- AAC(应用最广)
- speex(可以做回音消除)
- G.711(固话)
11.H264编码
1.yuv
YUV有不同的压缩格式,比RGB占用更少的空间.约1.5倍文章来源地址https://www.toymoban.com/news/detail-411234.html
//YUV420
Y = 1 W * D
H = 1/4 W * D
V = 1/4 W * D
总数 = 1.5 * w * d
//RGB
RGB = W * D * 3;
到了这里,关于学习笔记/音视频面试的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!