AVSampleBufferDisplayLayer 在使用高预设时渲染每帧的一半

AVSampleBufferDisplayLayer renders half of each frame when using high preset

我正在使用 AVSampleBufferDisplayLayer 来显示通过网络流式传输的视频。在发送端,AVCaptureSession 用于捕获 CMSampleBuffers,这些 CMSampleBuffers 被序列化为 NAL 单元并流式传输到接收器,然后接收器将它们转回 CMSampelBuffers 并将它们提供给 AVSampleBufferDisplayLayer(如 here 中所述)。它工作得很好 - 我可以看到视频并且流式传输或多或少很流畅。

如果我将捕获会话的 sessionPreset 设置为 AVCaptureSessionPresetHigh,接收方显示的视频将被切成两半 - 上半部分显示来自发送方的视频,而下半部分是纯深绿色。如果我使用任何其他预设(例如 AVCaptureSessionPresetMedium 或 AVCaptureSessionPreset1280x720),视频会完整显示。

有没有人遇到过这样的问题,或者知道是什么原因造成的?

我尝试检查源数据和目标数据,看看是否可以确定图像被截断的位置,但我没有成功。我突然想到,也许高质量的帧被分割成多个 NALU,而我没有正确地将它们组合在一起——这可能吗?这种拆分在基本流级别上看起来如何(如果可能的话)?

谢谢

阿摩司

原来的问题是,在预设的 AVCaptureSessionPresetHigh 下,一帧会被分成多个类型 5(或类型 1)NALU。在接收端,我将 SPS、PPS 和类型 1(或类型 5)NAL 单元组合到一个 CMSampleBuffer 中,但如果它们被拆分,则会忽略帧的第二部分,这导致了问题。

为了识别两个连续的 NAL 单元是否属于同一帧,需要解析图片 NAL 单元的切片 header。这需要深入研究规范,但或多或​​少是这样的:切片 header 的第一个字段是 first_mb_in_slice,它以 Golomb 编码进行编码。接下来是 slice_type 和 pic_aprameter_set_id,也是 Golomb 编码,最后是 frame_number,作为长度为 (log2_max_frame_num_minus_4 + 4) 位的无符号整数(以获取值log2_max_frame_num_minus_4的需要解析本帧对应的PPS)。如果两个连续的 NAL 单元具有相同的 frame_num 它们是同一帧的一部分,应该放入同一个 CMSampleBuffer。