如何准确计算iOS 8上硬件解码的FPS?

3
iOS8中新增了新的硬件解码方法,我们可以使用“VTDecompressionSessionDecodeFrame”解码iOS8中的h264格式。我尝试编写一个程序来打印硬件解码的fps,但是这里有一个问题,回调是异步的,所以我该如何精确计算fps呢?我发现了一个方法,“VTDecompressionSessionWaitForAsynchronousFrames”,这是我想要的吗?
解码函数:
- (void)render:(CMSampleBufferRef)sampleBuffer
{
    if (_isDecoding == NO) {

        _isDecoding = YES;

        _lastTime = [NSDate date];

    }

    VTDecodeFrameFlags flags = kVTDecodeFrame_EnableAsynchronousDecompression;

    VTDecodeInfoFlags flagOut;

    VTDecompressionSessionDecodeFrame(_decompression, sampleBuffer, flags, NULL, &flagOut);

    VTDecompressionSessionWaitForAsynchronousFrames(_decompression);

    if (_gotFrame == YES) {

        _gotFrame = NO;

        _isDecoding = NO;

    }

    CFRelease(sampleBuffer);
}

解码回调函数
void didDecompress( void *decompressionOutputRefCon, void *sourceFrameRefCon, OSStatus status, VTDecodeInfoFlags infoFlags, CVImageBufferRef imageBuffer, CMTime presentationTimeStamp, CMTime presentationDuration ){

    VideoView* THIS = (__bridge VideoView*)decompressionOutputRefCon;

    THIS->_gotFrame = YES;

    NSDate* currentTime = [NSDate date];

    NSTimeInterval runTime = currentTime.timeIntervalSince1970 - THIS->_lastTime.timeIntervalSince1970;

    THIS->_totalTime += runTime;

    THIS->_counts++;

    THIS->_lastTime = currentTime;

}
1个回答

1
我们可以将NSDate设置为sourceRefCon,然后在回调中访问时间戳以获取精确的解码时间。
VTDecompressionSessionDecodeFrame中的sourceFrameRefCon是一个无类型指针。
VTDecompressionSessionDecodeFrame(
    VTDecompressionSessionRef       session,
    CMSampleBufferRef               sampleBuffer,
    VTDecodeFrameFlags              decodeFlags, // bit 0 is enableAsynchronousDecompression
    void *                          sourceFrameRefCon,
    VTDecodeInfoFlags               *infoFlagsOut /* may be NULL */ )

Decode Method

- (void)render:(CMSampleBufferRef)sampleBuffer
{
    VTDecodeFrameFlags flags = kVTDecodeFrame_EnableAsynchronousDecompression;

    VTDecodeInfoFlags flagOut;

    NSDate* currentTime = [NSDate date];

    VTDecompressionSessionDecodeFrame(_decompression, sampleBuffer, flags, (void*)CFBridgingRetain(currentTime), &flagOut);

    CFRelease(sampleBuffer);
}

Decode Callback Method

void didDecompress( void *decompressionOutputRefCon, void *sourceFrameRefCon, OSStatus status, VTDecodeInfoFlags infoFlags, CVImageBufferRef imageBuffer, CMTime presentationTimeStamp, CMTime presentationDuration ){

    NSDate* currentTime = (__bridge NSDate *)sourceFrameRefCon;

    if (currentTime != nil) {

        //Do something

    }
}

你有一个 Swift 的等价物吗?我正在尝试使用 sourceFrameRefCon 传递数据,然后在另一侧使用 Swift 的 UnsafeMutableRawPointer 进行转换。 - LLooggaann

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接