How to accurately calculate the FPS of hardware decoding on iOS 8?

There are new hardwrare decoding methods from iOS8 here,

we can use " VTDecompressionSessionDecodeFrame " to decode h264 from iOS8,

I am trying to code a program that can print fps of hardware decoding,

but there is a problem here, the callback is asynchronous,

so how can i calculate fps exactly?

I found the method " VTDecompressionSessionWaitForAsynchronousFrames "

Is this what I want?

Decode function

- (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);
}

      

Callback decoding function

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;

}

      

+3


source to share


1 answer


We can set NSDate as sourceRefCon and then access the timestamp from the callback to get the exact decoding time.

void * sourceFrameRefCon in VTDecompressionSessionDecodeFrame

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

      

Decoding 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);
}

      

Callback decoding 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

    }
}

      

+1


source







All Articles