我们在知识星球上创建的音视频技术社群关键帧的音视频开发圈已经运营了一段时间了,在这里群友们会一起做一些打卡任务。比如:周期性地整理音视频相关的面试题,汇集一份音视频面试题集锦,你可以看看这个合集:音视频面试题集锦。再比如:循序渐进地归纳总结音视频技术知识,绘制一幅音视频知识图谱,你可以看看这个合集:音视频知识图谱。
这次的面试题是来自星球里一位音视频方向的应届毕业生群友在一次面试中被问到的问题:
1)RTMP 和 RTSP 有什么区别?使用 RTSP 是基于 UDP 传输的话,我们怎样进行乱序重排?
RTMP 和 RTSP 的区别: RTMP 使用 TCP 作为传输层协议,能保证不丢包和接收顺序,传输质量高。 RTSP 使用 RTP 格式协议和 RTCP 控制协议,命令与数据分离。传输层协议一般会选择 UDP,延迟比较低,传输效率高。 RTSP 中的 RTP 格式头中有
SequenceNumber
字段,可以通过这个序号实现排序。
2)假如给你一堆乱序的 RTP 包,应该怎样实现乱序重排?
可以利用接收 RTP 包缓冲队列使用包的序号进行排序。 在丢包情况下为保证传输质量会引入 NACK 和 FEC 机制。 NACK 表示接收端通知发送端一些包丢失,发送 NACK 包请求重传;FEC 前向纠错值的是每个包携带一些冗余信息可以在部分包丢失的时候利用其他包进行重建。 如果重传次数过多,包无法重建,或者丢的包过多,此时可以丢帧直接跳过丢失的部分。
3)对硬件解码有了解吗?
硬件解码指的是使用硬件的专门处理视频的硬件资源(GPU 和特殊芯片)来解码视频,与软解相比,硬解有速度快、能耗低的特点,但硬解依赖设备提供的能力,支持格式较少,解码前需要看设备是否支持当前的格式。 在 iOS 平台使用 Videotoolbox,Android 平台使用 Mediacodec 来使用硬解能力。硬解码可以直接解码出纹理进行渲染,相比于软解要做一层 CPU 数据转换到 GPU,渲染效率也更高。 FFmpeg 也集成了 Android 和 iOS 的硬解能力,如果在自己的项目中需要引入硬解能力,可以用 OpenMAX 来作为统一接口来集成各平台的硬解能力。
4)你在项目中使用过 SDL 进行渲染,能否讲一下 SDL 渲染?
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用 C 语言写成。其主要用于游戏开发中的多媒体处理,如:视频渲染、音频播放、鼠标键盘控制等操作。它对外接供了一套统一的接口,但在内部,它会根据不同平台调用不同的底层 API 库。 SDL 的基本流程如下:
- 1、初始化 SDL
- 2、创建窗口
- 3、创建渲染器
- 4、清空缓冲区
- 5、绘制要显示的内容
- 6、最终将缓冲区内容渲染到 Window 窗口上
- 7、销毁渲染器
- 8、销毁窗口
- 9、退出 SDL
5)对 YUV 格式有了解吗?YUV 数据做转换是怎样实现的,比如说 YUV422 转为 YUV420?
YUV 格式是传输视频常用的格式,因为相对于 RGB 格式它可以节省更多空间。 YUV 的格式有很多,例如:YUV444、YUV422、YUV420,常用的 YUV 格式是 YUV420 格式。Y 表示亮度信息,是人眼最敏感的分量,UV 则表示色度信息。 YUV420 表示采样方式:UV 分量具有 2:1 的水平采样,2:1 的垂直采样,这里并不是指只有 U,没有 V,而是对于每一行,只有一个 U 或者 V 分量,如果第一行是 4:2:0,那么下一行就是 4:0:2。 可以用工具 YUVView 直接打开 YUV 格式的数据。 YUV 数据因为计算量大和数据量大可以都放到 GPU 存储和计算,YUV422 转 YUV420 可以利用 OpenGL 将 YUV422 的 UV 数据转换成 texture 纹理,编写 shader 做格式转换逻辑继而生成 YUV420 的 UV texture,再通过 readPixel 将显存的 UV 数据读取出来。转换逻辑即将纹理 UV 分量隔行采样。
6)你在项目中是怎么降低端到端的延时的?
下面是直播走 RTMP 推流、HTTP-FLV 播放方案降低端到端延迟的思路:
- 推流端的延迟包含编码延迟和发送缓存队列引入的延迟。可以通过调节编码参数(B 帧、码率、帧率)减小编码延迟但会影响画质。另外可以提高上传的传输性能来减小传输时长。
- CDN 链路上的传输延迟。包括推流的链路和播放回源的链路,这部分延迟不是太大,但依旧会引入几百 ms 的延迟。
- CDN 拉流边缘节点的吐流策略会直接影响延迟的大小。直播流编码的 GOP 的长度,CDN 在客户端拉流时吐几秒的数据、按照 GOP 分隔如何丢数据,这些策略都会影响延时。
- 播放端可以通过对当前已下载的 buffer 进行倍速播放和跳帧来降低缓存从而达到降低延迟。注意如果倍速过大,声音是会明显变调的,需要通过算法来调整。跳帧一定要注意视频跳到 I 帧,音频对齐视频进行丢弃。
7)你对视频倍速播放的时候,是否有改变音调?
倍速变大和变小都会带来变调的问题,目前流行的开源项目有 soundtouch 和 sonic 来达到变速不变调的效果,最经典的就是使用时域压扩(TSM)的算法。