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

时间:2015-08-11 17:53:05

标签: objective-c macos h.264 avcapturesession

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

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

有没有人遇到过这样的问题,或者知道可能导致什么问题?

我尝试检查源上的数据以及目的地的数据,看看我是否可以确定图像被切断的位置,但我没有成功。在我看来,高质量的框架可能被拆分成多个NALU并且我没有将它正确地组合在一起 - 这可能吗?这种分裂在基本流级别上是什么样的(如果可能的话)?

谢谢

1 个答案:

答案 0 :(得分:0)

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

为了识别两个连续的NAL单元是否属于同一帧,需要解析图像NAL单元的切片报头。这需要钻研规范,但或多或​​少是这样的:切片头的第一个字段是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中。