Last active
July 3, 2024 07:34
-
-
Save vade/f72362c60434e5af2801d01f09bdbf34 to your computer and use it in GitHub Desktop.
synopsis-video-decode-benchmark - AVFoundation Performance on Apple Silicon
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://www.dropbox.com/s/swcdgak5cbrzat6/synopsis-video-decode-benchmark.trace.zip?dl=0
Trace file for the bug