Use Objective-C types in VideoToolbox encoder / decoder

The goal of this CL is to make the CFDictionaryRef not dependent
on a fixed number of properties, which will facilitate future work.

No behavior change intended.

Bug: None
Change-Id: I32261d81eaa9b77380cecbdaefcbaeafde300f9a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/257920
Auto-Submit: Daniel.L (Byoungchan) Lee <daniel.l@hpcnt.com>
Reviewed-by: Kári Helgason <kthelgason@webrtc.org>
Commit-Queue: Daniel.L (Byoungchan) Lee <daniel.l@hpcnt.com>
Cr-Commit-Position: refs/heads/main@{#36449}
This commit is contained in:
Byoungchan Lee
2022-04-05 22:32:01 +09:00
committed by WebRTC LUCI CQ
parent 64380ce385
commit f8750fcf67
2 changed files with 38 additions and 77 deletions

View File

@ -202,48 +202,30 @@ void decompressionOutputCallback(void *decoderRef,
// CVPixelBuffers directly to the renderer.
// TODO(tkchin): Maybe only set OpenGL/IOSurface keys if we know that that
// we can pass CVPixelBuffers as native handles in decoder output.
#if TARGET_OS_SIMULATOR
static size_t const attributesSize = 2;
#else
static size_t const attributesSize = 3;
#endif
CFTypeRef keys[attributesSize] = {
NSDictionary *attributes = @{
#if defined(WEBRTC_IOS) && (TARGET_OS_MACCATALYST || TARGET_OS_SIMULATOR)
kCVPixelBufferMetalCompatibilityKey,
(NSString *)kCVPixelBufferMetalCompatibilityKey : @(YES),
#elif defined(WEBRTC_IOS)
kCVPixelBufferOpenGLESCompatibilityKey,
(NSString *)kCVPixelBufferOpenGLESCompatibilityKey : @(YES),
#elif defined(WEBRTC_MAC)
kCVPixelBufferOpenGLCompatibilityKey,
(NSString *)kCVPixelBufferOpenGLCompatibilityKey : @(YES),
#endif
#if !(TARGET_OS_SIMULATOR)
kCVPixelBufferIOSurfacePropertiesKey,
#endif
kCVPixelBufferPixelFormatTypeKey};
CFDictionaryRef ioSurfaceValue = CreateCFTypeDictionary(nullptr, nullptr, 0);
int64_t nv12type = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange;
CFNumberRef pixelFormat = CFNumberCreate(nullptr, kCFNumberLongType, &nv12type);
#if TARGET_OS_SIMULATOR
CFTypeRef values[attributesSize] = {kCFBooleanTrue, pixelFormat};
#else
CFTypeRef values[attributesSize] = {kCFBooleanTrue, ioSurfaceValue, pixelFormat};
(NSString *)kCVPixelBufferIOSurfacePropertiesKey : @{},
#endif
(NSString *)
kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange),
};
CFDictionaryRef attributes = CreateCFTypeDictionary(keys, values, attributesSize);
if (ioSurfaceValue) {
CFRelease(ioSurfaceValue);
ioSurfaceValue = nullptr;
}
if (pixelFormat) {
CFRelease(pixelFormat);
pixelFormat = nullptr;
}
VTDecompressionOutputCallbackRecord record = {
decompressionOutputCallback, (__bridge void *)self,
};
OSStatus status = VTDecompressionSessionCreate(
nullptr, _videoFormat, nullptr, attributes, &record, &_decompressionSession);
CFRelease(attributes);
OSStatus status = VTDecompressionSessionCreate(nullptr,
_videoFormat,
nullptr,
(__bridge CFDictionaryRef)attributes,
&record,
&_decompressionSession);
if (status != noErr) {
RTC_LOG(LS_ERROR) << "Failed to create decompression session: " << status;
[self destroyDecompressionSession];

View File

@ -605,59 +605,38 @@ NSUInteger GetMaxSampleRate(const webrtc::H264ProfileLevelId &profile_level_id)
// Set source image buffer attributes. These attributes will be present on
// buffers retrieved from the encoder's pixel buffer pool.
const size_t attributesSize = 3;
CFTypeRef keys[attributesSize] = {
NSDictionary *sourceAttributes = @{
#if defined(WEBRTC_IOS) && (TARGET_OS_MACCATALYST || TARGET_OS_SIMULATOR)
kCVPixelBufferMetalCompatibilityKey,
(NSString *)kCVPixelBufferMetalCompatibilityKey : @(YES),
#elif defined(WEBRTC_IOS)
kCVPixelBufferOpenGLESCompatibilityKey,
(NSString *)kCVPixelBufferOpenGLESCompatibilityKey : @(YES),
#elif defined(WEBRTC_MAC)
kCVPixelBufferOpenGLCompatibilityKey,
(NSString *)kCVPixelBufferOpenGLCompatibilityKey : @(YES),
#endif
kCVPixelBufferIOSurfacePropertiesKey,
kCVPixelBufferPixelFormatTypeKey};
CFDictionaryRef ioSurfaceValue = CreateCFTypeDictionary(nullptr, nullptr, 0);
int64_t pixelFormatType = framePixelFormat;
CFNumberRef pixelFormat = CFNumberCreate(nullptr, kCFNumberLongType, &pixelFormatType);
CFTypeRef values[attributesSize] = {kCFBooleanTrue, ioSurfaceValue, pixelFormat};
CFDictionaryRef sourceAttributes = CreateCFTypeDictionary(keys, values, attributesSize);
if (ioSurfaceValue) {
CFRelease(ioSurfaceValue);
ioSurfaceValue = nullptr;
}
if (pixelFormat) {
CFRelease(pixelFormat);
pixelFormat = nullptr;
}
CFMutableDictionaryRef encoder_specs = nullptr;
(NSString *)kCVPixelBufferIOSurfacePropertiesKey : @{},
(NSString *)kCVPixelBufferPixelFormatTypeKey : @(framePixelFormat),
};
NSDictionary *encoder_specs;
#if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS)
// Currently hw accl is supported above 360p on mac, below 360p
// the compression session will be created with hw accl disabled.
encoder_specs = CFDictionaryCreateMutable(
nullptr, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(encoder_specs,
kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
kCFBooleanTrue);
encoder_specs = @{
(NSString *)kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder : @(YES),
};
#endif
OSStatus status =
VTCompressionSessionCreate(nullptr, // use default allocator
_width,
_height,
kCMVideoCodecType_H264,
encoder_specs, // use hardware accelerated encoder if available
sourceAttributes,
nullptr, // use default compressed data allocator
compressionOutputCallback,
nullptr,
&_compressionSession);
if (sourceAttributes) {
CFRelease(sourceAttributes);
sourceAttributes = nullptr;
}
if (encoder_specs) {
CFRelease(encoder_specs);
encoder_specs = nullptr;
}
OSStatus status = VTCompressionSessionCreate(
nullptr, // use default allocator
_width,
_height,
kCMVideoCodecType_H264,
(__bridge CFDictionaryRef)encoder_specs, // use hardware accelerated encoder if available
(__bridge CFDictionaryRef)sourceAttributes,
nullptr, // use default compressed data allocator
compressionOutputCallback,
nullptr,
&_compressionSession);
if (status != noErr) {
RTC_LOG(LS_ERROR) << "Failed to create compression session: " << status;
return WEBRTC_VIDEO_CODEC_ERROR;