如何调试 Mac OS 未使用硬件 H264 编码器的原因
How to debug why Mac OS is not using Hardware H264 encoder
我正在尝试使用 H264 对一些仅视频流进行编码,并且我愿意使用硬件编码器来比较硬件和 CPU 编码之间的质量和资源消耗。问题是我无法强制 OS 使用硬件编码器。
这是我用来创建 VTCompressionSession 的代码:
var status: OSStatus
let encoderSpecifications: CFDictionary? = [
kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder as String: true,
kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder as String: true,
kVTVideoEncoderSpecification_EncoderID as String: "com.apple.videotoolbox.videoencoder.24rgb" // Tried without this paramenter so the system can decide what encoder ID should be using but doesn't work anyway.
]
let pixelBufferOptions: CFDictionary? = [
kCVPixelBufferWidthKey as String: Int(width),
kCVPixelBufferHeightKey as String: Int(height),
kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_24RGB) // Tried commenting this in case that there was a pixelformat constraint but didn't change anything
];
status = VTCompressionSessionCreate(kCFAllocatorDefault, width, height, CMVideoCodecType(kCMVideoCodecType_H264), encoderSpecifications, pixelBufferOptions, nil, { (outputCallbackRefCon: UnsafeMutablePointer<Void>, sourceFrameRefCon: UnsafeMutablePointer<Void>, status: OSStatus, infoFlags: VTEncodeInfoFlags, sampleBuffer: CMSampleBuffer?) -> Void in
...
}, unsafeBitCast(self, UnsafeMutablePointer<Void>.self), &compressionSession)
我打开了控制台,这是我在尝试创建会话时收到的唯一相关消息:
10/28/15 22:06:27.711 Dupla-Mac[87762]: <<<< VTVideoEncoderSelection >>>> VTSelectAndCreateVideoEncoderInstanceInternal: no video encoder found for 'avc1'
这是我使用 EncoderID 时得到的状态码:
2015-10-28 22:17:13.480 Dupla-Mac[87895:5578917] Couldn't create compression session :( -12908
这是我不使用 EncoderID 时得到的:
2015-10-28 22:18:16.695 Dupla-Mac[87996:5581914] Couldn't create compression session :( -12915
两者都与资源可用性不足有关,但找不到任何区别。我已经检查过可能使用硬件编码器的最知名功能是否已关闭,但我不知道如何确定地检查它。 AirPlay 已关闭,QuickTime 已关闭,没有任何应用访问相机,等等。
TL;DR: 有什么方法可以强制 或 知道 OS 用来启用硬件编码器的策略是什么,并最终知道 为什么它在任何时候都不可用?
提前致谢!
我猜你已经解决了这个问题,但对于其他人来说 - macOS 上唯一可用的硬件加速编码器(10.8-10.12 适用于所有 mac 2012+)/ iOS(8-10) 是 com.apple.videotoolbox.videoencoder.h264.gva
这是完整列表:https://gist.github.com/vade/06ace2e33561a79cc240
获取编解码器列表
CFArrayRef encoder_list;
VTCopyVideoEncoderList(NULL, &encoder_list);
CFIndex size = CFArrayGetCount(encoder_list);
for(CFIndex i = 0; i < size; i++) {
CFDictionaryRef encoder_dict = CFArrayGetValueAtIndex(encoder_list, i);
CFStringRef type = CFDictionaryGetValue(encoder_dict, kVTVideoEncoderList_CodecType);
CFStringRef encoderID = CFDictionaryGetValue(encoder_dict, kVTVideoEncoderList_EncoderID);
CFStringRef codecName = CFDictionaryGetValue(encoder_dict, kVTVideoEncoderList_CodecName);
CFStringRef encoderName = CFDictionaryGetValue(encoder_dict, kVTVideoEncoderList_EncoderName);
CFStringRef display_name = CFDictionaryGetValue(encoder_dict, kVTVideoEncoderList_DisplayName);
NSLog(@" %@ %@ %@ %@ %@", type, encoderID, codecName, encoderName, display_name);
}
我正在尝试使用 H264 对一些仅视频流进行编码,并且我愿意使用硬件编码器来比较硬件和 CPU 编码之间的质量和资源消耗。问题是我无法强制 OS 使用硬件编码器。
这是我用来创建 VTCompressionSession 的代码:
var status: OSStatus
let encoderSpecifications: CFDictionary? = [
kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder as String: true,
kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder as String: true,
kVTVideoEncoderSpecification_EncoderID as String: "com.apple.videotoolbox.videoencoder.24rgb" // Tried without this paramenter so the system can decide what encoder ID should be using but doesn't work anyway.
]
let pixelBufferOptions: CFDictionary? = [
kCVPixelBufferWidthKey as String: Int(width),
kCVPixelBufferHeightKey as String: Int(height),
kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_24RGB) // Tried commenting this in case that there was a pixelformat constraint but didn't change anything
];
status = VTCompressionSessionCreate(kCFAllocatorDefault, width, height, CMVideoCodecType(kCMVideoCodecType_H264), encoderSpecifications, pixelBufferOptions, nil, { (outputCallbackRefCon: UnsafeMutablePointer<Void>, sourceFrameRefCon: UnsafeMutablePointer<Void>, status: OSStatus, infoFlags: VTEncodeInfoFlags, sampleBuffer: CMSampleBuffer?) -> Void in
...
}, unsafeBitCast(self, UnsafeMutablePointer<Void>.self), &compressionSession)
我打开了控制台,这是我在尝试创建会话时收到的唯一相关消息:
10/28/15 22:06:27.711 Dupla-Mac[87762]: <<<< VTVideoEncoderSelection >>>> VTSelectAndCreateVideoEncoderInstanceInternal: no video encoder found for 'avc1'
这是我使用 EncoderID 时得到的状态码:
2015-10-28 22:17:13.480 Dupla-Mac[87895:5578917] Couldn't create compression session :( -12908
这是我不使用 EncoderID 时得到的:
2015-10-28 22:18:16.695 Dupla-Mac[87996:5581914] Couldn't create compression session :( -12915
两者都与资源可用性不足有关,但找不到任何区别。我已经检查过可能使用硬件编码器的最知名功能是否已关闭,但我不知道如何确定地检查它。 AirPlay 已关闭,QuickTime 已关闭,没有任何应用访问相机,等等。
TL;DR: 有什么方法可以强制 或 知道 OS 用来启用硬件编码器的策略是什么,并最终知道 为什么它在任何时候都不可用?
提前致谢!
我猜你已经解决了这个问题,但对于其他人来说 - macOS 上唯一可用的硬件加速编码器(10.8-10.12 适用于所有 mac 2012+)/ iOS(8-10) 是 com.apple.videotoolbox.videoencoder.h264.gva
这是完整列表:https://gist.github.com/vade/06ace2e33561a79cc240
获取编解码器列表
CFArrayRef encoder_list;
VTCopyVideoEncoderList(NULL, &encoder_list);
CFIndex size = CFArrayGetCount(encoder_list);
for(CFIndex i = 0; i < size; i++) {
CFDictionaryRef encoder_dict = CFArrayGetValueAtIndex(encoder_list, i);
CFStringRef type = CFDictionaryGetValue(encoder_dict, kVTVideoEncoderList_CodecType);
CFStringRef encoderID = CFDictionaryGetValue(encoder_dict, kVTVideoEncoderList_EncoderID);
CFStringRef codecName = CFDictionaryGetValue(encoder_dict, kVTVideoEncoderList_CodecName);
CFStringRef encoderName = CFDictionaryGetValue(encoder_dict, kVTVideoEncoderList_EncoderName);
CFStringRef display_name = CFDictionaryGetValue(encoder_dict, kVTVideoEncoderList_DisplayName);
NSLog(@" %@ %@ %@ %@ %@", type, encoderID, codecName, encoderName, display_name);
}