Skip to content

Instantly share code, notes, and snippets.

@vade
Last active September 7, 2022 11:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vade/f72362c60434e5af2801d01f09bdbf34 to your computer and use it in GitHub Desktop.
Save vade/f72362c60434e5af2801d01f09bdbf34 to your computer and use it in GitHub Desktop.
synopsis-video-decode-benchmark - AVFoundation Performance on Apple Silicon
//
// main.m
// synopsis-video-decode-benchmark
//
// Created by Anton Marini on 11/20/21.
//
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import <Metal/Metal.h>
#import <VideoToolbox/VideoToolbox.h>
#import <CoreMedia/CoreMedia.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
NSLog(@"Choosing device: %@", device);
NSURL* movieURL = [NSURL fileURLWithPath:@"/Users/vade/Downloads/Blur Pool Test 1_analyzed.mov"];
AVURLAsset* movieAsset = [AVURLAsset URLAssetWithURL:movieURL options:@{AVURLAssetPreferPreciseDurationAndTimingKey: @YES}];
NSError* error = nil;
AVAssetReader* reader = [AVAssetReader assetReaderWithAsset:movieAsset error:&error];
AVAssetTrack* videoTrack = nil;
videoTrack = [[movieAsset tracksWithMediaType:AVMediaTypeVideo] firstObject];
if ( !videoTrack )
{
NSLog(@"Unable to determine video track to decode");
exit(0);
}
NSDictionary* outputSettings = @{
// (NSString *)kCVPixelBufferPixelFormatTypeKey: @( kCVPixelFormatType_32BGRA ), // BGRA/RGBA stops working sometime at or before 8k resolution!
(NSString *)kCVPixelBufferPixelFormatTypeKey: @( kCVPixelFormatType_32ARGB ),
// (NSString *)kCVPixelBufferPixelFormatTypeKey: @( kCVPixelFormatType_422YpCbCr8FullRange ),
(NSString *)kCVPixelBufferMetalCompatibilityKey: @YES,
// (NSString *)kCVPixelBufferOpenGLCompatibilityKey: @YES,
(NSString *)kCVPixelBufferIOSurfacePropertiesKey: @{},
AVVideoDecompressionPropertiesKey: @{
(NSString *)kVTVideoDecoderSpecification_PreferredDecoderGPURegistryID: @(device.registryID),
},
};
AVAssetReaderTrackOutput* videoOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:videoTrack outputSettings:outputSettings];
videoOutput.alwaysCopiesSampleData = NO;
if ([reader canAddOutput: videoOutput])
{
[reader addOutput:videoOutput];
}
[reader startReading];
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
NSTimeInterval absoluteStartTime = startTime;
NSMutableArray<NSNumber*>* frameTimes = [NSMutableArray new];
while (reader.status == AVAssetReaderStatusReading)
{
CMSampleBufferRef videoSampleBuffer = [videoOutput copyNextSampleBuffer];
if (videoSampleBuffer != NULL)
{
CVPixelBufferRef decodedFrame = CMSampleBufferGetImageBuffer(videoSampleBuffer);
NSTimeInterval endTime = [NSDate timeIntervalSinceReferenceDate];
NSTimeInterval delta = endTime - startTime;
startTime = endTime;
[frameTimes addObject:@(delta)];
CFRelease(videoSampleBuffer);
}
else
{
if (reader.status != AVAssetReaderStatusCompleted)
{
NSLog(@"Got Error: %@", reader.error);
}
else
{
NSLog(@"Completed Decoding");
}
break;
}
}
NSTimeInterval absoluteEndTime = [NSDate timeIntervalSinceReferenceDate];
NSTimeInterval absoluteTime = absoluteEndTime - absoluteStartTime;
NSLog(@"Total Decode took: %f", absoluteTime);
__block float avgFrameTime = 0;
__block float minFrameTime = FLT_MAX;
__block float maxFrameTime = FLT_MIN;
[frameTimes enumerateObjectsUsingBlock:^(NSNumber * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
float frameTime = obj.floatValue;
minFrameTime = MIN(minFrameTime, frameTime);
maxFrameTime = MAX(maxFrameTime, frameTime);
avgFrameTime = (frameTime + avgFrameTime) * 0.5;
}];
NSLog(@"Avg Frame Time: %f fps", 1.0 / avgFrameTime);
NSLog(@"Min Frame Time: %f fps", 1.0 / minFrameTime);
NSLog(@"Max Frame Time: %f fps", 1.0 / maxFrameTime);
}
return 0;
}
@vade
Copy link
Author

vade commented Nov 20, 2021

For BGRA:

Completed Decoding
Total Decode took: 21.887636
Avg Frame Time: 366.290767 fps
Min Frame Time: 76959.706422 fps
Max Frame Time: 29.273989 fps

For ARGB:

Completed Decoding
Total Decode took: 4.174427
Avg Frame Time: 2406.638785 fps
Min Frame Time: 83886.080000 fps
Max Frame Time: 90.228222 fps

For YUV
Total Decode took: 3.921696
Avg Frame Time: 2735.936801 fps
Min Frame Time: 110376.421053 fps
Max Frame Time: 91.149808 fps

@vade
Copy link
Author

vade commented Nov 20, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment