带有VTDecompressionSession的AVSampleBufferDisplayLayer

时间:2016-01-07 20:01:38

标签: ios ffmpeg video-toolbox

我一直在努力与AVSampleBufferDisplayLayer进行大量动作。当我的直播中有动作时,它会变成像素化并且半冻结,同时显示多个帧。但是,一旦我添加了以下代码,一切都解决了:

VTDecodeFrameFlags flags = kVTDecodeFrame_EnableAsynchronousDecompression 
| kVTDecodeFrame_EnableTemporalProcessing;
VTDecodeInfoFlags flagOut;
VTDecompressionSessionDecodeFrame(decompressionSession, sampleBuffer, flags,
(void*)CFBridgingRetain(NULL), &flagOut);

请注意,之前我确实创建过解压缩会话,但实际上我并没有在回调中做任何事情。我仍然在AVSampleBufferDisplayLayer上调用enqueueSampleBuffer:这就是视频在屏幕上的显示方式。

您是否必须为AVSampleBufferDisplayLayer调用VTDecompressionSessionDecodeFrame才能正确显示?我以为AVSampleBufferDisplayLayerr会在内部使用VTDecompressionSessionDecodeFrame。这是因为在iOS模拟器上吗?

2 个答案:

答案 0 :(得分:1)

AVSampleBufferDisplayLayer和VTDecompressionSession是两个不同的东西,虽然AVSampleBufferDisplayLayer可能会使用VTDecompressionSession(我不知道)。你不要一起使用它们,它是VTDecompressionSession低于AVSampleBufferDisplayLayer的一个或另一个。您不应该也不应该调用VTDecompressionSessionDecodeFrame()来使用AVSampleDisplayLayer enqueueSampleBuffer()。

根据您的描述,听起来您的PTS(演示时间戳)存在时间问题。确保正确设置时基。

见这里:Set rate at which AVSampleBufferDisplayLayer renders sample buffers

另外,请确保以编码器顺序(它们从编码器中输出的顺序)输入AVSampleBufferDisplayLayer帧,而不是显示顺序。

最后,确保不要通过网络将数据包丢弃到某个地方,尤其是在使用UDP时。

答案 1 :(得分:0)

当然你可以一起使用它们,在这种情况下,VTDecompressionSessionDecodeFrame仅用于解码,而AVSampleBufferDisplayLayer仅用于显示VTDecompressionSessionDecodeFrame的输出(CVPixelBufferRef,在将其放入AVSampleBufferDisplayLayer之前应该转换为CMSampleBufferRef)。