音视频 iOS 面试题 | 音视频面试题集锦 56 期

本文分享来自“关键帧Keyframe”的音视频面试题集锦第 56 期——音视频 iOS 面试题相关内容。

1、CMSampleBuffer 内存安全与生命周期管理

  1. 非 ARC 管理:CMSampleBufferRef 属于 Core Foundation 对象,必须使用 CFRetain / CFRelease。在异步队列传递时,必须在发送端 Retain,接收端处理完后 Release。
  2. Autoreleasepool 的局限:@autoreleasepool 只能管理 Objective-C 对象。虽然某些系统 API 返回的 CF 对象可能被包装在 NSData 中,但对于原生的 CMSampleBuffer,它不会自动调用 CFRelease。如果不在循环中手动释放,会造成显存和内存迅速耗尽。
  3. CVPixelBufferPool 的意义:
  • 减少分配开销: 频繁申请/销毁显存(特别是 4K 帧)非常耗时且易产生内存碎片。
  • 硬件复用: 视频硬解和编码器通常需要一组循环使用的缓冲区,Pool 可以实现“零拷贝”级别的内存复用,保证处理链路的平滑。

2、视频硬解码中的“对齐”与“步长” (Stride/BytesPerRow)

  1. 对齐原因: 为了利用 CPU 的 SIMD 指令集(如 ARM NEON)进行并行加速,硬件要求每一行内存的起始地址必须是对齐的(如 16 或 32 字节)。因此,对于宽度为 350 的图片,系统会补齐 8 字节(350×4=1400,补到 1408)作为 Stride。
  2. 手动处理: 在 CGBitmapContextCreate 中,bytesPerRow 必须传入真实的步长(如 1408)。如果传入 1400,渲染引擎会按 1408 步进,导致每一行丢失 8 字节,产生逐行错位(斜向花屏)。
  3. 透明区域变黑:
  • kCGImageAlphaNoneSkipLast 会强制忽略 Alpha 位并将其视为不透明,如果原始数据 Alpha 是 0(透明),忽略后通常表现为黑色。
  • Premultiplied(预乘)是指 RGB 分量已经乘以了 Alpha 值。如果显示时使用了预乘逻辑但数据是未预乘的,透明边缘会出现黑边。

3、音画同步(AVSync)的底层实现与漂移处理

  1. 音频为准: 通常以音频时钟为 Master。因为人类耳朵对声音的断续(Jitter)极其敏感,而眼睛对视频跳帧(Drop Frame)的忍受度较高。
  2. 漂移修正策略:
  • 视频追赶/放慢: 若视频落后,减小下一帧渲染的等待时间;若视频领先,增加等待时间。
  • 动态重采样(音频抗漂移): 若必须以视频为准,则需要对音频进行微小的采样率重采样(Resampling)以对齐视频 PTS。
  • 平滑处理: 设置阈值(如 30ms),在阈值内不调整,超过阈值则通过修改 CMTimebase 的 Rate 或直接丢弃非 IDR 帧来强制追赶。
  1. 倍速实现: 使用 CMTimebaseSetRate 统一调整时钟基准频率,音轨需进行速度改变而不改变音调的处理(Pitch Shifting)。

4、H.264/H.265 编码中的 GOP 结构与重排延迟

  1. B 帧延迟: B 帧(双向预测帧)依赖于前后的 I/P 帧。编码器必须缓存后续的 P 帧才能编码当前的 B 帧;解码器同理。这种双向依赖导致了必然的帧重排(Reordering Delay)。
  2. 动态切换与 SPS/PPS:
  • **SPS (Sequence Parameter Set)**:包含分辨率、帧率等。
  • **PPS (Picture Parameter Set)**:包含熵编码模式等。
  • 切换逻辑: 必须在切换分辨率后,立即发送新的 IDR 帧,并在该帧之前附带新的 SPS/PPS,否则解码器会按旧参数解析新像素导致崩溃或花屏。
  1. 马赛克原因: 如果丢失了 I 帧或 IDR 帧,后续 P 帧只能在错误的参考帧基础上进行增量更新,导致图像错误不断累积,直到下一个 I 帧到来才能消除。

5、Metal 与 OpenGL ES 的纹理转换及零拷贝优化

  1. 零拷贝: 通过 CVMetalTextureCacheCreateTextureFromImage 直接基于 CVPixelBuffer 的内存创建纹理,避免了从 CPU 内存到 GPU 显存的显式 memcpy 拷贝。
  2. YUV 处理:
  • 纹理数量:YUV420P 通常创建两个纹理:Luma(Y 通道,单通道纹理)和 Chroma(UV 通道,双通道纹理)。
  • 转换逻辑: 在 Shader 中读取两个纹理的值,利用颜色空间转换矩阵(如 BT.709 或 BT.601)执行矩阵乘法:。
  1. 处理建议: 尽量在 YUV 空间处理(如亮度调节),因为 YUV 数据量通常只有 RGBA 的一半(4:2:0 采样),能节省大量内存带宽和 GPU 功耗。

学习和提升音视频开发技术,欢迎你加入我们的知识星球

音视频 iOS 面试题 | 音视频面试题集锦 56 期

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐