设置AVSampleBufferDisplayLayer呈现样本缓冲区的速率 [英] Set rate at which AVSampleBufferDisplayLayer renders sample buffers

查看:1351
本文介绍了设置AVSampleBufferDisplayLayer呈现样本缓冲区的速率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用AVSampleBufferDisplayLayer来显示以h.264格式通过网络连接的CMSampleBuffers。视频播放流畅且工作正常,但我似乎无法控制帧速率。具体来说,如果我在AVSampleBufferDisplayLayer中每秒排队60帧,它会显示这60帧,即使视频以30 FPS记录。

I am using an AVSampleBufferDisplayLayer to display CMSampleBuffers which are coming over a network connection in the h.264 format. Video playback is smooth and working correctly, however I cannot seem to control the frame rate. Specifically, if I enqueue 60 frames per second in the AVSampleBufferDisplayLayer it displays those 60 frames, even though the video is being recorded at 30 FPS.

创建样本缓冲区时,可以通过将定时信息数组传递给CMSampleBufferCreate来设置显示时间戳(h.264流中不存在定时信息)但可以以容器格式计算或传递)。我设置的演示时间戳大约相隔0.033秒,持续时间为0.033,但显示层仍然每秒显示尽可能多的帧数。

When creating sample buffers, it is possible to set the presentation time stamp by passing a timing info array to CMSampleBufferCreate (the timing info is not present in the h.264 stream but can be calculated or passed in a container format). The presentation time stamps I set are about 0.033 seconds apart and the duration is 0.033 but the display layer still displays as many frames per second as it can.

有两种方法可以在AVSampleBufferDisplayLayer上排队缓冲区:通过调用 - [AVSampleBufferDisplayLayer enqueueSampleBuffer:]每当缓冲区准备就绪时约束,或者通过调用 - 无约束 AVSampleBufferDisplayLayer requestMediaDataWhenReadyOnQueue:usingBlock:]并将该块中的缓冲区排入队列。我已经尝试了两种方法,但即便是第二种方法也尽可能快地显示缓冲区 - 例如,如果我在接收端排队了300帧,那么第一次执行上述方法中的块readyForMoreMediaData无论多少都保持为真缓冲区已入队,并且它们都会在很短的时间内显示出来。

There are two ways to enqueue buffers on AVSampleBufferDisplayLayer: "constrained" by calling -[AVSampleBufferDisplayLayer enqueueSampleBuffer:] whenever a buffer is ready, or "unconstrained" by calling -[AVSampleBufferDisplayLayer requestMediaDataWhenReadyOnQueue:usingBlock:] and enqueuing the buffers in that block. I've tried both but even the second method displays buffers as quickly as it can - for instance if I have 300 frames queued up on the receiving side then the first time the block in the method above is executed readyForMoreMediaData remains true no matter how many buffers get enqueued, and they are all displayed in a very short time.

此行为类似于在CMSampleBuffer上设置kCMSampleAttachmentKey_DisplayImmediately附件时所期望的行为,但是当前未设置(默认为false)。

This behavior is similar to what one would expect if the kCMSampleAttachmentKey_DisplayImmediately attachment were set on the CMSampleBuffer, however this is NOT currently set (and the default is false).

我尝试设置图层controlTimeBase,但似乎没有任何效果。我无法尝试其他东西,也无法在网上找到例子。有谁知道如何控制AVSampleBufferDisplayLayer显示帧的帧率?

I tried setting the layers controlTimeBase, but it didn't seem to have any effect. I'm at a loss of other things to try and could not find examples online. Does anyone know how one may control the framerate at which AVSampleBufferDisplayLayer displays frames?

推荐答案

时基需要设置为演示时间标记(pts)您想要解码的第一帧。我通过从所有后续pts中减去初始pts并将Timebase设置为0来将第一帧的pts索引为0.无论出于何种原因,这都不起作用。

The Timebase needs to be set to the presentation time stamp (pts) of the first frame you intend to decode. I was indexing the pts of the first frame to 0 by subtracting the initial pts from all subsequent pts and setting the Timebase to 0. For whatever reason, that didn't work.

你想要这样的东西(在调用解码前称为):

You want something like this (called before a call to decode):

CMTimebaseRef controlTimebase;
CMTimebaseCreateWithMasterClock( CFAllocatorGetDefault(), CMClockGetHostTimeClock(), &controlTimebase );

displayLayer.controlTimebase = controlTimebase;

// Set the timebase to the initial pts here
CMTimebaseSetTime(displayLayer.controlTimebase, CMTimeMake(ptsInitial, 1));
CMTimebaseSetRate(displayLayer.controlTimebase, 1.0);

设置CMSampleBuffer的PTS ......

Set the PTS for the CMSampleBuffer...

CMSampleBufferSetOutputPresentationTimeStamp(sampleBuffer, presentationTimeStamp);

并且可能确保没有立即显示....

And maybe make sure display immediately isn't set....

CFDictionarySetValue(dict, kCMSampleAttachmentKey_DisplayImmediately, kCFBooleanFalse);

WWDC 2014 Session 513会对此进行了简要介绍。

This is covered very briefly in WWDC 2014 Session 513.

这篇关于设置AVSampleBufferDisplayLayer呈现样本缓冲区的速率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆