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 to share