mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-11-21 10:55:51 +02:00
lavc/videotoolboxenc: check for dictionary key symbols
Fixes #6081. Some dictionary keys are not present on OS X 10.8. This loads the symbols and uses a default value if not present. Signed-off-by: Rick Kern <kernrj@gmail.com>
This commit is contained in:
parent
9568b2e425
commit
dcd3418a35
@ -34,12 +34,91 @@
|
||||
#include <pthread.h>
|
||||
#include "h264.h"
|
||||
#include "h264_sei.h"
|
||||
#include <dlfcn.h>
|
||||
|
||||
#if !CONFIG_VT_BT2020
|
||||
# define kCVImageBufferColorPrimaries_ITU_R_2020 CFSTR("ITU_R_2020")
|
||||
# define kCVImageBufferTransferFunction_ITU_R_2020 CFSTR("ITU_R_2020")
|
||||
# define kCVImageBufferYCbCrMatrix_ITU_R_2020 CFSTR("ITU_R_2020")
|
||||
#endif
|
||||
//These symbols may not be present
|
||||
static struct{
|
||||
CFStringRef kCVImageBufferColorPrimaries_ITU_R_2020;
|
||||
CFStringRef kCVImageBufferTransferFunction_ITU_R_2020;
|
||||
CFStringRef kCVImageBufferYCbCrMatrix_ITU_R_2020;
|
||||
|
||||
CFStringRef kVTCompressionPropertyKey_H264EntropyMode;
|
||||
CFStringRef kVTH264EntropyMode_CAVLC;
|
||||
CFStringRef kVTH264EntropyMode_CABAC;
|
||||
|
||||
CFStringRef kVTProfileLevel_H264_Baseline_4_0;
|
||||
CFStringRef kVTProfileLevel_H264_Baseline_4_2;
|
||||
CFStringRef kVTProfileLevel_H264_Baseline_5_0;
|
||||
CFStringRef kVTProfileLevel_H264_Baseline_5_1;
|
||||
CFStringRef kVTProfileLevel_H264_Baseline_5_2;
|
||||
CFStringRef kVTProfileLevel_H264_Baseline_AutoLevel;
|
||||
CFStringRef kVTProfileLevel_H264_Main_4_2;
|
||||
CFStringRef kVTProfileLevel_H264_Main_5_1;
|
||||
CFStringRef kVTProfileLevel_H264_Main_5_2;
|
||||
CFStringRef kVTProfileLevel_H264_Main_AutoLevel;
|
||||
CFStringRef kVTProfileLevel_H264_High_3_0;
|
||||
CFStringRef kVTProfileLevel_H264_High_3_1;
|
||||
CFStringRef kVTProfileLevel_H264_High_3_2;
|
||||
CFStringRef kVTProfileLevel_H264_High_4_0;
|
||||
CFStringRef kVTProfileLevel_H264_High_4_1;
|
||||
CFStringRef kVTProfileLevel_H264_High_4_2;
|
||||
CFStringRef kVTProfileLevel_H264_High_5_1;
|
||||
CFStringRef kVTProfileLevel_H264_High_5_2;
|
||||
CFStringRef kVTProfileLevel_H264_High_AutoLevel;
|
||||
|
||||
CFStringRef kVTCompressionPropertyKey_RealTime;
|
||||
|
||||
CFStringRef kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder;
|
||||
CFStringRef kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder;
|
||||
} compat_keys;
|
||||
|
||||
#define GET_SYM(symbol, defaultVal) \
|
||||
do{ \
|
||||
CFStringRef cfstr = dlsym(RTLD_DEFAULT, #symbol); \
|
||||
if(!cfstr) \
|
||||
compat_keys.symbol = CFSTR(defaultVal); \
|
||||
else \
|
||||
compat_keys.symbol = symbol; \
|
||||
}while(0)
|
||||
|
||||
static pthread_once_t once_ctrl = PTHREAD_ONCE_INIT;
|
||||
|
||||
static void loadVTEncSymbols(){
|
||||
GET_SYM(kCVImageBufferColorPrimaries_ITU_R_2020, "ITU_R_2020");
|
||||
GET_SYM(kCVImageBufferTransferFunction_ITU_R_2020, "ITU_R_2020");
|
||||
GET_SYM(kCVImageBufferYCbCrMatrix_ITU_R_2020, "ITU_R_2020");
|
||||
|
||||
GET_SYM(kVTCompressionPropertyKey_H264EntropyMode, "H264EntropyMode");
|
||||
GET_SYM(kVTH264EntropyMode_CAVLC, "CAVLC");
|
||||
GET_SYM(kVTH264EntropyMode_CABAC, "CABAC");
|
||||
|
||||
GET_SYM(kVTProfileLevel_H264_Baseline_4_0, "H264_Baseline_4_0");
|
||||
GET_SYM(kVTProfileLevel_H264_Baseline_4_2, "H264_Baseline_4_2");
|
||||
GET_SYM(kVTProfileLevel_H264_Baseline_5_0, "H264_Baseline_5_0");
|
||||
GET_SYM(kVTProfileLevel_H264_Baseline_5_1, "H264_Baseline_5_1");
|
||||
GET_SYM(kVTProfileLevel_H264_Baseline_5_2, "H264_Baseline_5_2");
|
||||
GET_SYM(kVTProfileLevel_H264_Baseline_AutoLevel, "H264_Baseline_AutoLevel");
|
||||
GET_SYM(kVTProfileLevel_H264_Main_4_2, "H264_Main_4_2");
|
||||
GET_SYM(kVTProfileLevel_H264_Main_5_1, "H264_Main_5_1");
|
||||
GET_SYM(kVTProfileLevel_H264_Main_5_2, "H264_Main_5_2");
|
||||
GET_SYM(kVTProfileLevel_H264_Main_AutoLevel, "H264_Main_AutoLevel");
|
||||
GET_SYM(kVTProfileLevel_H264_High_3_0, "H264_High_3_0");
|
||||
GET_SYM(kVTProfileLevel_H264_High_3_1, "H264_High_3_1");
|
||||
GET_SYM(kVTProfileLevel_H264_High_3_2, "H264_High_3_2");
|
||||
GET_SYM(kVTProfileLevel_H264_High_4_0, "H264_High_4_0");
|
||||
GET_SYM(kVTProfileLevel_H264_High_4_1, "H264_High_4_1");
|
||||
GET_SYM(kVTProfileLevel_H264_High_4_2, "H264_High_4_2");
|
||||
GET_SYM(kVTProfileLevel_H264_High_5_1, "H264_High_5_1");
|
||||
GET_SYM(kVTProfileLevel_H264_High_5_2, "H264_High_5_2");
|
||||
GET_SYM(kVTProfileLevel_H264_High_AutoLevel, "H264_High_AutoLevel");
|
||||
|
||||
GET_SYM(kVTCompressionPropertyKey_RealTime, "RealTime");
|
||||
|
||||
GET_SYM(kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
|
||||
"EnableHardwareAcceleratedVideoEncoder");
|
||||
GET_SYM(kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder,
|
||||
"RequireHardwareAcceleratedVideoEncoder");
|
||||
}
|
||||
|
||||
typedef enum VT_H264Profile {
|
||||
H264_PROF_AUTO,
|
||||
@ -520,47 +599,66 @@ static bool get_vt_profile_level(AVCodecContext *avctx,
|
||||
|
||||
case H264_PROF_BASELINE:
|
||||
switch (vtctx->level) {
|
||||
case 0: *profile_level_val = kVTProfileLevel_H264_Baseline_AutoLevel; break;
|
||||
case 0: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_Baseline_AutoLevel; break;
|
||||
case 13: *profile_level_val = kVTProfileLevel_H264_Baseline_1_3; break;
|
||||
case 30: *profile_level_val = kVTProfileLevel_H264_Baseline_3_0; break;
|
||||
case 31: *profile_level_val = kVTProfileLevel_H264_Baseline_3_1; break;
|
||||
case 32: *profile_level_val = kVTProfileLevel_H264_Baseline_3_2; break;
|
||||
case 40: *profile_level_val = kVTProfileLevel_H264_Baseline_4_0; break;
|
||||
case 40: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_Baseline_4_0; break;
|
||||
case 41: *profile_level_val = kVTProfileLevel_H264_Baseline_4_1; break;
|
||||
case 42: *profile_level_val = kVTProfileLevel_H264_Baseline_4_2; break;
|
||||
case 50: *profile_level_val = kVTProfileLevel_H264_Baseline_5_0; break;
|
||||
case 51: *profile_level_val = kVTProfileLevel_H264_Baseline_5_1; break;
|
||||
case 52: *profile_level_val = kVTProfileLevel_H264_Baseline_5_2; break;
|
||||
case 42: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_Baseline_4_2; break;
|
||||
case 50: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_Baseline_5_0; break;
|
||||
case 51: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_Baseline_5_1; break;
|
||||
case 52: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_Baseline_5_2; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case H264_PROF_MAIN:
|
||||
switch (vtctx->level) {
|
||||
case 0: *profile_level_val = kVTProfileLevel_H264_Main_AutoLevel; break;
|
||||
case 0: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_Main_AutoLevel; break;
|
||||
case 30: *profile_level_val = kVTProfileLevel_H264_Main_3_0; break;
|
||||
case 31: *profile_level_val = kVTProfileLevel_H264_Main_3_1; break;
|
||||
case 32: *profile_level_val = kVTProfileLevel_H264_Main_3_2; break;
|
||||
case 40: *profile_level_val = kVTProfileLevel_H264_Main_4_0; break;
|
||||
case 41: *profile_level_val = kVTProfileLevel_H264_Main_4_1; break;
|
||||
case 42: *profile_level_val = kVTProfileLevel_H264_Main_4_2; break;
|
||||
case 42: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_Main_4_2; break;
|
||||
case 50: *profile_level_val = kVTProfileLevel_H264_Main_5_0; break;
|
||||
case 51: *profile_level_val = kVTProfileLevel_H264_Main_5_1; break;
|
||||
case 52: *profile_level_val = kVTProfileLevel_H264_Main_5_2; break;
|
||||
case 51: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_Main_5_1; break;
|
||||
case 52: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_Main_5_2; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case H264_PROF_HIGH:
|
||||
switch (vtctx->level) {
|
||||
case 0: *profile_level_val = kVTProfileLevel_H264_High_AutoLevel; break;
|
||||
case 30: *profile_level_val = kVTProfileLevel_H264_High_3_0; break;
|
||||
case 31: *profile_level_val = kVTProfileLevel_H264_High_3_1; break;
|
||||
case 32: *profile_level_val = kVTProfileLevel_H264_High_3_2; break;
|
||||
case 40: *profile_level_val = kVTProfileLevel_H264_High_4_0; break;
|
||||
case 41: *profile_level_val = kVTProfileLevel_H264_High_4_1; break;
|
||||
case 42: *profile_level_val = kVTProfileLevel_H264_High_4_2; break;
|
||||
case 0: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_High_AutoLevel; break;
|
||||
case 30: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_High_3_0; break;
|
||||
case 31: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_High_3_1; break;
|
||||
case 32: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_High_3_2; break;
|
||||
case 40: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_High_4_0; break;
|
||||
case 41: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_High_4_1; break;
|
||||
case 42: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_High_4_2; break;
|
||||
case 50: *profile_level_val = kVTProfileLevel_H264_High_5_0; break;
|
||||
case 51: *profile_level_val = kVTProfileLevel_H264_High_5_1; break;
|
||||
case 52: *profile_level_val = kVTProfileLevel_H264_High_5_2; break;
|
||||
case 51: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_High_5_1; break;
|
||||
case 52: *profile_level_val =
|
||||
compat_keys.kVTProfileLevel_H264_High_5_2; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -701,7 +799,7 @@ static int get_cv_color_primaries(AVCodecContext *avctx,
|
||||
break;
|
||||
|
||||
case AVCOL_PRI_BT2020:
|
||||
*primaries = kCVImageBufferColorPrimaries_ITU_R_2020;
|
||||
*primaries = compat_keys.kCVImageBufferColorPrimaries_ITU_R_2020;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -748,7 +846,7 @@ static int get_cv_transfer_function(AVCodecContext *avctx,
|
||||
|
||||
case AVCOL_TRC_BT2020_10:
|
||||
case AVCOL_TRC_BT2020_12:
|
||||
*transfer_fnc = kCVImageBufferTransferFunction_ITU_R_2020;
|
||||
*transfer_fnc = compat_keys.kCVImageBufferTransferFunction_ITU_R_2020;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -779,7 +877,7 @@ static int get_cv_ycbcr_matrix(AVCodecContext *avctx, CFStringRef *matrix) {
|
||||
break;
|
||||
|
||||
case AVCOL_SPC_BT2020_NCL:
|
||||
*matrix = kCVImageBufferYCbCrMatrix_ITU_R_2020;
|
||||
*matrix = compat_keys.kCVImageBufferYCbCrMatrix_ITU_R_2020;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -846,7 +944,6 @@ static int vtenc_create_encoder(AVCodecContext *avctx,
|
||||
profile_level);
|
||||
if (status) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error setting profile/level property: %d\n", status);
|
||||
return AVERROR_EXTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1012,22 +1109,21 @@ static int vtenc_create_encoder(AVCodecContext *avctx,
|
||||
|
||||
if (vtctx->entropy != VT_ENTROPY_NOT_SET) {
|
||||
CFStringRef entropy = vtctx->entropy == VT_CABAC ?
|
||||
kVTH264EntropyMode_CABAC:
|
||||
kVTH264EntropyMode_CAVLC;
|
||||
compat_keys.kVTH264EntropyMode_CABAC:
|
||||
compat_keys.kVTH264EntropyMode_CAVLC;
|
||||
|
||||
status = VTSessionSetProperty(vtctx->session,
|
||||
kVTCompressionPropertyKey_H264EntropyMode,
|
||||
compat_keys.kVTCompressionPropertyKey_H264EntropyMode,
|
||||
entropy);
|
||||
|
||||
if (status) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error setting entropy property: %d\n", status);
|
||||
return AVERROR_EXTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (vtctx->realtime) {
|
||||
status = VTSessionSetProperty(vtctx->session,
|
||||
kVTCompressionPropertyKey_RealTime,
|
||||
compat_keys.kVTCompressionPropertyKey_RealTime,
|
||||
kCFBooleanTrue);
|
||||
|
||||
if (status) {
|
||||
@ -1055,6 +1151,8 @@ static av_cold int vtenc_init(AVCodecContext *avctx)
|
||||
CFNumberRef gamma_level = NULL;
|
||||
int status;
|
||||
|
||||
pthread_once(&once_ctrl, loadVTEncSymbols);
|
||||
|
||||
codec_type = get_cm_codec_type(avctx->codec_id);
|
||||
if (!codec_type) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error: no mapping for AVCodecID %d\n", avctx->codec_id);
|
||||
@ -1087,9 +1185,13 @@ static av_cold int vtenc_init(AVCodecContext *avctx)
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
if (!vtctx->allow_sw) {
|
||||
CFDictionarySetValue(enc_info, kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder, kCFBooleanTrue);
|
||||
CFDictionarySetValue(enc_info,
|
||||
compat_keys.kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder,
|
||||
kCFBooleanTrue);
|
||||
} else {
|
||||
CFDictionarySetValue(enc_info, kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder, kCFBooleanTrue);
|
||||
CFDictionarySetValue(enc_info,
|
||||
compat_keys.kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
|
||||
kCFBooleanTrue);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user