Reputation: 8741
I am trying to find the accepted formats on an AVFoundation output:
self.theOutput=[[AVCaptureVideoDataOutput alloc]init];
if ([self.theSession canAddOutput:self.theOutput])
[self.theSession addOutput:self.theOutput];
I am then inserting a breakpoint right after and:
po [self.theOutput availableVideoCVPixelFormatTypes]
and I get this:
(NSArray *) $5 = 0x2087ad00 <__NSArrayM 0x2087ad00>(
875704438,
875704422,
1111970369
)
How do I get the string values of these format types?
Thanks
Upvotes: 11
Views: 3946
Reputation: 138
I've written this Swift extension that you can add to your project
extension FourCharCode {
func convertToString() -> String {
let number: UInt32 = self
let ostype = number.bigEndian // Assuming big-endian byte order
let bytes = withUnsafeBytes(of: ostype) {
Array($0)
}
let ostypeString = String(bytes: bytes, encoding: .ascii)
return ostypeString ?? "error converting FourCharCode to String"
}
}
Then call it this way
for pixel in videoOutput.availableVideoPixelFormatTypes {
print("\(pixel) = ", pixel.convertToString())
}
This will print
2016686642 = x422
2016686640 = x420
645428786 = &xv2
762869298 = -xv2
645428784 = &xv0
762869296 = -xv0
Then you can check the apple documentation do get the matching pixelFormat: https://developer.apple.com/documentation/technotes/tn3121-selecting-a-pixel-format-for-an-avcapturevideodataoutput
ps: I'm using an iPhone 13Pro with iOS 16.2, and an active format compatile with ProRes
Upvotes: 1
Reputation: 1523
You can convert values returned by availableVideoCVPixelFormatTypes
like so:
NSArray *supportedPixelFormats = [videoDeviceOutput availableVideoCVPixelFormatTypes];
char buffer[5] = {0};
for (NSNumber *pixelFormat in supportedPixelFormats){
*(int *)&buffer[0] = CFSwapInt32HostToBig([pixelFormat intValue]);
NSLog(@"FORMAT: %s", buffer);
}
and the output will be
FORMAT: 420v
FORMAT: 420f
FORMAT: BGRA
These values correspond to enum values described in CVPixelBuffer.h
of CoreVideo
:
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange = '420v'
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange = '420f',
kCVPixelFormatType_32BGRA = 'BGRA',
Explanation of the code:
The constant value '420v' is stored in memory as 4 bytes. At the same time, int
is also 4 bytes, which allows us to convert '420v' into bytes and back into int.
The following line is writing a value as an int
into buffer of chars to later read it as string.
*(int *)&buffer[0] = CFSwapInt32HostToBig([pixelFormat intValue]);
The only problem is that normally Objective-C would save an int value as little endian and this would produce 'v024' instead of '420v'. Hence, we need to use CFSwapInt32HostToBig
to convert an enum value into big endian
before saving it to the buffer.
Hope this helps.
Upvotes: 1
Reputation: 51
When you call availableVideoCVPixelFormatTypes you get the decimal representation of all of the pixel format type labels. If you convert those to hex you can match some of them to labels listed on Apple's Documentation. For the rest you have to convert the hex value you got into ASCII characters to finally match the label.
For example:
(Decimal) ------> (Hex) ---> (ASCII)
875704438 -> 34323076 -> 420v
875704422 -> 34323066 -> 420f
1111970369 -> 42475241 -> BGRA
I found this site "ASCII to Hex" to be useful.
Upvotes: 5
Reputation: 22245
#import <CoreVideo/CoreVideo.h>
@implementation NSNumber (CVPixelFormatType)
- (NSString *)descriptivePixelFormat
{
return @{
@(kCVPixelFormatType_1Monochrome): @"kCVPixelFormatType_1Monochrome",
@(kCVPixelFormatType_2Indexed): @"kCVPixelFormatType_2Indexed",
@(kCVPixelFormatType_4Indexed): @"kCVPixelFormatType_4Indexed",
@(kCVPixelFormatType_8Indexed): @"kCVPixelFormatType_8Indexed",
@(kCVPixelFormatType_1IndexedGray_WhiteIsZero): @"kCVPixelFormatType_1IndexedGray_WhiteIsZero",
@(kCVPixelFormatType_2IndexedGray_WhiteIsZero): @"kCVPixelFormatType_2IndexedGray_WhiteIsZero",
@(kCVPixelFormatType_4IndexedGray_WhiteIsZero): @"kCVPixelFormatType_4IndexedGray_WhiteIsZero",
@(kCVPixelFormatType_8IndexedGray_WhiteIsZero): @"kCVPixelFormatType_8IndexedGray_WhiteIsZero",
@(kCVPixelFormatType_16BE555): @"kCVPixelFormatType_16BE555",
@(kCVPixelFormatType_16LE555): @"kCVPixelFormatType_16LE555",
@(kCVPixelFormatType_16LE5551): @"kCVPixelFormatType_16LE5551",
@(kCVPixelFormatType_16BE565): @"kCVPixelFormatType_16BE565",
@(kCVPixelFormatType_16LE565): @"kCVPixelFormatType_16LE565",
@(kCVPixelFormatType_24RGB): @"kCVPixelFormatType_24RGB",
@(kCVPixelFormatType_24BGR): @"kCVPixelFormatType_24BGR",
@(kCVPixelFormatType_32ARGB): @"kCVPixelFormatType_32ARGB",
@(kCVPixelFormatType_32BGRA): @"kCVPixelFormatType_32BGRA",
@(kCVPixelFormatType_32ABGR): @"kCVPixelFormatType_32ABGR",
@(kCVPixelFormatType_32RGBA): @"kCVPixelFormatType_32RGBA",
@(kCVPixelFormatType_64ARGB): @"kCVPixelFormatType_64ARGB",
@(kCVPixelFormatType_48RGB): @"kCVPixelFormatType_48RGB",
@(kCVPixelFormatType_32AlphaGray): @"kCVPixelFormatType_32AlphaGray",
@(kCVPixelFormatType_16Gray): @"kCVPixelFormatType_16Gray",
@(kCVPixelFormatType_422YpCbCr8): @"kCVPixelFormatType_422YpCbCr8",
@(kCVPixelFormatType_4444YpCbCrA8): @"kCVPixelFormatType_4444YpCbCrA8",
@(kCVPixelFormatType_4444YpCbCrA8R): @"kCVPixelFormatType_4444YpCbCrA8R",
@(kCVPixelFormatType_444YpCbCr8): @"kCVPixelFormatType_444YpCbCr8",
@(kCVPixelFormatType_422YpCbCr16): @"kCVPixelFormatType_422YpCbCr16",
@(kCVPixelFormatType_422YpCbCr10): @"kCVPixelFormatType_422YpCbCr10",
@(kCVPixelFormatType_444YpCbCr10): @"kCVPixelFormatType_444YpCbCr10",
@(kCVPixelFormatType_420YpCbCr8Planar): @"kCVPixelFormatType_420YpCbCr8Planar",
@(kCVPixelFormatType_420YpCbCr8PlanarFullRange): @"kCVPixelFormatType_420YpCbCr8PlanarFullRange",
@(kCVPixelFormatType_422YpCbCr_4A_8BiPlanar): @"kCVPixelFormatType_422YpCbCr_4A_8BiPlanar",
@(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange): @"kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange",
@(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange): @"kCVPixelFormatType_420YpCbCr8BiPlanarFullRange",
@(kCVPixelFormatType_422YpCbCr8_yuvs): @"kCVPixelFormatType_422YpCbCr8_yuvs",
@(kCVPixelFormatType_422YpCbCr8FullRange): @"kCVPixelFormatType_422YpCbCr8FullRange"
}[self];
}
@end
NSMutableArray *mutablePixelFormatTypes = [NSMutableArray array];
[captureOutput.availableVideoCVPixelFormatTypes enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[mutablePixelFormatTypes addObject:[obj descriptivePixelFormat]];
}];
NSString *pixelFormats = [mutablePixelFormatTypes componentsJoinedByString:@",\n"];
NSLog(@"Available pixel formats:\n%@\n", pixelFormats);
Upvotes: 5
Reputation: 8741
On an iPhone5 running iOS6, here are the AVCaptureVideoDataOuput availableVideoCVPixelFormatTypes:
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
kCVPixelFormatType_32BGRA
Credit where credit is due, I found a way to get the value supported here. https://gist.github.com/2327666
Upvotes: 10