The latest Arm Mac devices have built-in hardware encoders for common video codecs such as HEVC (H.265) and H.264, the popular x265 and x264 libraries provide a software implementation but this can be slow. As an example, the tech specs for an M1 MacBook Pro says it can:
Media engine
- Hardware-accelerated H.264, HEVC, ProRes, and ProRes RAW
- Video decode engine
- Video encode engine
- ProRes encode and decode engine
Apple provide the videtoolbox framework for this. It can be called from Obj-C/C code as well as Swift code. There is a function called VTCopyVideoEncoderList
that returns a pointer to an array of dictionaries that lists the available encoders for you to use, and whether they’re hardware accelerated.
Using clang
you can compile and link with
clang -framework VideoToolbox -framework CoreMedia -framework Foundation enc.c
#include <CoreFoundation/CoreFoundation.h>
#include <CoreMedia/CoreMedia.h>
#include <CoreVideo/CoreVideo.h>
#include <VideoToolbox/VideoToolbox.h>
#include <stdbool.h>
#include <stdio.h>
void printAvailableVideoEncoders();
int main(void) {
bool vp9hardware = VTIsHardwareDecodeSupported(kCMVideoCodecType_VP9);
printf("Is VP9 hardware decode: %d\n", vp9hardware);
printAvailableVideoEncoders();
return 0;
}
void printAvailableVideoEncoders() {
CFArrayRef encoderList = NULL;
CFDictionaryRef encoderDict = NULL;
CFStringRef encoderName = NULL;
CFBooleanRef isHardware = NULL;
OSStatus status = VTCopyVideoEncoderList(NULL, &encoderList);
if (status != 0) {
printf("Failed to fetch encoder list\n");
return;
}
CFIndex encoderCount = CFArrayGetCount(encoderList);
for (CFIndex i = 0; i < encoderCount; i++) {
encoderDict = CFArrayGetValueAtIndex(encoderList, i);
if (encoderDict) {
encoderName =
CFDictionaryGetValue(encoderDict, kVTVideoEncoderList_EncoderName);
isHardware = CFDictionaryGetValue(
encoderDict, kVTVideoEncoderList_IsHardwareAccelerated);
if (encoderName) {
printf("Encoder: %s\n",
CFStringGetCStringPtr(encoderName, kCFStringEncodingUTF8));
}
if (isHardware) {
if (CFBooleanGetValue(isHardware)) {
printf("Hardware Accelerated: Yes\n");
} else {
printf("Hardware Accelerated: No\n");
}
} else {
printf("Hardware Accelerated: No\n");
}
}
}
if (encoderList) {
CFRelease(encoderList);
}
}
The output on an M1 MacBook Pro looks like (Apple have recently added a VP9 constant to VideoToolbox, so hopefully M3 devices support native VP9 playback)
Is VP9 hardware decode: 0
Encoder: Apple 24-bit RGB
Hardware Accelerated: No
Encoder: Apple 32-bit ARGB
Hardware Accelerated: No
Encoder: Apple ProRes 422
Hardware Accelerated: No
Encoder: Apple ProRes 422 HQ
Hardware Accelerated: No
Encoder: Apple ProRes 422 LT
Hardware Accelerated: No
Encoder: Apple ProRes 422 Proxy
Hardware Accelerated: No
Encoder: Apple ProRes 4444
Hardware Accelerated: No
Encoder: Apple ProRes 4444 XQ
Hardware Accelerated: No
Encoder: Apple Depth (HEVC)-Apple HEVC (HW)
Hardware Accelerated: Yes
Encoder: Apple Depth (HEVC)-Apple HEVC (SW)
Hardware Accelerated: No
Encoder: Apple Disparity (HEVC)-Apple HEVC (HW)
Hardware Accelerated: Yes
Encoder: Apple Disparity (HEVC)-Apple HEVC (SW)
Hardware Accelerated: No
Encoder: Apple H.263 (SW)
Hardware Accelerated: No
Encoder: Apple H.264 (HW)
Hardware Accelerated: Yes
Encoder: Apple H.264 (SW)
Hardware Accelerated: No
Encoder: Apple HEVC (HW)
Hardware Accelerated: Yes
Encoder: Apple HEVC (SW)
Hardware Accelerated: No
Encoder: Apple JPEG
Hardware Accelerated: No
Encoder: JPEG (HW)
Hardware Accelerated: Yes
Encoder: Apple Muxed Alpha-Apple HEVC (HW)
Hardware Accelerated: Yes
Encoder: Apple Muxed Alpha-Apple HEVC (SW)
Hardware Accelerated: No