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

Posted

技术标签:

【中文标题】如何准确计算 iOS 8 上硬件解码的 FPS?【英文标题】:How to calculate FPS of Hardware Decode on iOS 8 exactly? 【发布时间】:2014-09-15 03:35:56 【问题描述】:

这里有来自 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】:

我们可以设置一个 NSDate 为 sourceRefCon,然后从回调中获取时间戳来获取准确的解码时间。

void * sourceFrameRefCon in VTDecompressionSessionDecodeFrame

VTDecompressionSessionDecodeFrame(
    VTDecompressionSessionRef       session,
    CMSampleBufferRef               sampleBuffer,
    VTDecodeFrameFlags              decodeFlags, // bit 0 is enableAsynchronousDecompression
    void *                          sourceFrameRefCon,
    VTDecodeInfoFlags               *infoFlagsOut /* may be NULL */ )

解码方法

- (void)render:(CMSampleBufferRef)sampleBuffer

    VTDecodeFrameFlags flags = kVTDecodeFrame_EnableAsynchronousDecompression;

    VTDecodeInfoFlags flagOut;

    NSDate* currentTime = [NSDate date];

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

    CFRelease(sampleBuffer);

解码回调方法

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 将其投射到另一端

以上是关于如何准确计算 iOS 8 上硬件解码的 FPS?的主要内容,如果未能解决你的问题,请参考以下文章

iOS硬编解码相关知识

多媒体开发(13):iOS上音频编码成aac

开发那些事儿:如何解决RK芯片视频处理编解码耗时很长的问题?

iOS8系统H264视频硬件编解码说明

FFmpeg硬件解码API介绍

iOS8系统H264视频硬件编解码说明