学习笔记/音视频面试

1.DTS/PTS

如果没有B帧,那么DTS一般与PTS相同

  • DTS(Decoding Time Stamp):即解码时间戳,这个时间戳的意义在于告诉播放器该在什么时候解码这一帧的数据。(解码I->P->B)
  • PTS(Presentation Time Stamp):即显示时间戳,这个时间戳用来告诉播放器该在什么时候显示这一帧的数据。

2.GOP

就是将同一组动作的封装为一个组,组内的动作变化不大,可以不用整个图片传输,降低数据量

2.!宏块!

  • 视频压缩操作的基本单元
  • 帧内压缩还是帧间压缩,都是以宏块为单位
  • 细节部分宏块划分小.

3.帧内压缩和帧间压缩(有损压缩)

  1. 帧内压缩:即只利用了单帧图像内的空间相关性,对冗余数据(相同的像素)进行编码,达到压缩效果,而没有利用时间相关性,不使用运动补偿。
    • 用宏块做对比,然后用算法(9种)选择一种,把当前宏块化为一个数字,对面接受后进行反解就可以恢复
    • 亮度和色度分开预测
    • 预测后与原始图求差值,然后一起传输.到那边反解后再加上差值就可以得到相似的原图
    • 只对I帧和IDR帧
  2. 帧间压缩:由于视频的特性,相邻的帧之间其实是很相似的,通常是运动矢量的变化。利用其时间相关性,可以通过参考帧运动矢量的变化来预测图像,并结合预测图像与原始图像的差分,便能解码 出原始图像。所以,帧间编码需要依赖其他帧才能解码出一帧画面。
    • GOP
    • 参考帧
    • 运动估计(宏块匹配 + 运动矢量) : 用宏块匹配的方法找到运动矢量(一个物品变动的方向和位置)
    • 运动补偿(残差值)
    • P帧,B帧

运动矢量

学习笔记/音视频面试_第1张图片

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.视频花屏/卡顿原因

  1. 花屏原因:如果GOP分组有帧丢失,会造成解码端的图像发生错误,就会出现马赛克(花屏)

  2. 卡顿原因: 为了避免花屏问题的发生,如果发现有帧丢失时,就丢弃整个GOP内的所有帧,

    直到下一个IDR帧重新刷新图像(这段时间就卡顿)

5.DCT帧数离散余弦变化 ,CABAC压缩(无损压缩)

  1. DCT 将空间上的相关性变为频域上无关的数据然后进行量化
    • 就是将一个无序的矩阵化成一个更小的,集中在一个角的矩阵
  2. VLC压缩,类似哈夫曼,用于MPEG2
  3. CABAC压缩(H264),

6.H264码流

1.分层

  • NAL层 : 视频数据网络抽象层(头,类似于TCP头),解决纠错能力.(一个字节的head)
  • VCL层: 视频数据编码层(帧信息,数据)

2.VCL结构

一般都是一个图片一个slice;但是可以包含多个slice

  • slice里面存的是一个个宏块, 宏块中存了 : 宏块类型(9种模式),预测值和残差值

学习笔记/音视频面试_第2张图片

3.码流基本概念

  1. SODB(按位计算)
    • 原始数据比特流,长度一定要到8位的倍数.VLC层尝试
  2. RBSP(按字节计算,因为按位可能不是8的整数倍,所有有了这个)
    • SODB + 补充位. 如果SODB最后一个字节如果不对齐,就补1和多个0
  3. NALU
    • NAL Header(1B) + RBSP

4.图.清晰

学习笔记/音视频面试_第3张图片

5.全部码流图

  • startCode : 0x000001,0x00000001;
  • RTP可以直接传输

学习笔记/音视频面试_第4张图片

7.常用同步策略

  1. 将视频同步到音频上:就是以音频的播放速度为基准来同步视频。

  2. 将音频同步到视频上:就是以视频的播放速度为基准来同步音频。

  3. 将视频和音频同步外部的时钟上:选择一个外部时钟为基准,视频和音频的播放速度都以该时钟为标准。

    当播放源比参考时钟慢,则加快其播放速度,或者丢弃;快了,则延迟播放。

1.选取同步策略

考虑到人对声音的敏感度要强于视频,频繁调节音频会带来较差的观感体验,且音频的播放时钟为线性增长,所以一般会以音频时钟为参考时钟,视频同步到音频上。

2.视频I帧问题(必须等到第一个I帧)

对于起播阶段,特别是TS实时流,由于视频解码需要依赖第一个I帧,而音频是可以实时输出,可能出现的情况是视频PTS超前音频PTS较多,这种情况下进行同步,势必造成较为明显的慢同步。处理这种情况的较好方法是将较为多余的音频数据丢弃,尽量减少起播阶段的音视频差距。

3.同步步骤

  1. 获取当前要显示的video PTS,减去上一帧视频PTS,则得出上一帧视频应该显示的时长delay;
  2. 当前video PTS与参考时钟当前audio PTS比较,得出音视频差距diff;
  3. 获取同步阈值sync_threshold,为一帧视频差距,范围为10ms-100ms;
  4. diff小于sync_threshold,则认为不需要同步;否则delay+diff值,则是正确纠正delay;
  5. 如果超过sync_threshold,且视频落后于音频,那么需要减小delay(FFMAX(0, delay + diff)),让当前帧尽快显示。
    如果视频落后超过1秒,且之前10次都快速输出视频帧,那么需要反馈给音频源减慢,同时反馈视频源进行丢帧处理,让视频尽快追上音频。因为这很可能是视频解码跟不上了,再怎么调整delay也没用。
  6. 如果超过sync_threshold,且视频快于音频,那么需要加大delay,让当前帧延迟显示。
    将delay*2慢慢调整差距,这是为了平缓调整差距,因为直接delay+diff,会让画面画面迟滞。
    如果视频前一帧本身显示时间很长,那么直接delay+diff一步调整到位,因为这种情况再慢慢调整也没太大意义。
  7. 考虑到渲染的耗时,还需进行调整。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 ...

学习笔记/音视频面试_第5张图片

10.音频压缩

压缩两个方向: 压缩体积越来越小,或者压缩速度越来越快

1.方法:

  • 有损压缩: 消除冗余信息(人听不到的信息删除)
    • 频域遮蔽(频率不一样,高频率可以遮盖一点范围的低频率声音)
    • 时域遮蔽(越靠近声音时间,遮盖率就越高)
  • 无损压缩: 文件压缩,编码解码
    • 熵编码 : 哈夫曼,算数编码,香农编码

学习笔记/音视频面试_第6张图片

2.编码过程

学习笔记/音视频面试_第7张图片

2.常见的音频编码器

  1. opus(现在经常用,webrtc,直播等,但是收费)
  2. AAC(应用最广)
  3. speex(可以做回音消除)
  4. G.711(固话)

11.H264编码

1.yuv

YUV有不同的压缩格式,比RGB占用更少的空间.约1.5倍

//YUV420
Y = 1   W * D
H = 1/4 W * D
V = 1/4 W * D
总数 = 1.5 * w * d
 
//RGB
RGB = W * D * 3;

你可能感兴趣的:(面试准备,音视频,学习,面试,c++)