21#include <Availability.h>
22#include <CoreMedia/CoreMedia.h>
23#include <CoreVideo/CoreVideo.h>
26#include <TargetConditionals.h>
27#include <VideoToolbox/VideoToolbox.h>
45#if !HAVE_KCMVIDEOCODECTYPE_HEVC
49#if !HAVE_KCMVIDEOCODECTYPE_HEVCWITHALPHA
53#if !HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
58#if !HAVE_KVTQPMODULATIONLEVEL_DEFAULT
63#ifndef TARGET_CPU_ARM64
64# define TARGET_CPU_ARM64 0
82#define REORDER_DELAY 2
85 size_t parameterSetIndex,
86 const uint8_t **parameterSetPointerOut,
87 size_t *parameterSetSizeOut,
88 size_t *parameterSetCountOut,
89 int *NALUnitHeaderLengthOut);
162#define GET_SYM(symbol, defaultVal) \
164 CFStringRef* handle = (CFStringRef*)dlsym(RTLD_DEFAULT, #symbol); \
166 compat_keys.symbol = CFSTR(defaultVal); \
168 compat_keys.symbol = *handle; \
174 compat_keys.CMVideoFormatDescriptionGetHEVCParameterSetAtIndex =
177 "CMVideoFormatDescriptionGetHEVCParameterSetAtIndex"
218 "TargetQualityForAlpha");
220 "PrioritizeEncodingSpeedOverQuality");
225 "EnableHardwareAcceleratedVideoEncoder");
227 "RequireHardwareAcceleratedVideoEncoder");
229 "EnableLowLatencyRateControl");
232 "MaximizePowerEfficiency");
234 "ReferenceBufferCount");
240#define H264_PROFILE_CONSTRAINED_HIGH (AV_PROFILE_H264_HIGH | AV_PROFILE_H264_CONSTRAINED)
327 CFStringRef encoder_id =
NULL;
329 CFIndex length, max_size;
332 status = VTSessionCopyProperty(vtctx->
session,
340 length = CFStringGetLength(encoder_id);
341 max_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8);
344 CFRelease(encoder_id);
348 CFStringGetCString(encoder_id,
351 kCFStringEncodingUTF8);
354 CFRelease(encoder_id);
361 CFStringRef profile_level,
362 CFNumberRef gamma_level,
363 CFDictionaryRef enc_info,
364 CFDictionaryRef pixel_buffer_info);
490 CMSampleBufferRef sample_buffer,
497 size_t src_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
498 CMBlockBufferRef
block = CMSampleBufferGetDataBuffer(sample_buffer);
500 if (length_code_size > 4)
503 while (
offset < src_size) {
508 status = CMBlockBufferCopyDataBytes(
block,
513 if (status != kCMBlockBufferNoErr) {
517 for (
i = 0;
i < length_code_size;
i++) {
519 box_len |= size_buf[
i];
522 curr_src_len = box_len + length_code_size;
534 double alpha_quality)
549 return MKBETAG(
'a',
'p',
'c',
'o');
551 return MKBETAG(
'a',
'p',
'c',
's');
553 return MKBETAG(
'a',
'p',
'c',
'n');
555 return MKBETAG(
'a',
'p',
'c',
'h');
557 return MKBETAG(
'a',
'p',
'4',
'h');
559 return MKBETAG(
'a',
'p',
'4',
'x');
567 desc->log2_chroma_w == 0))
568 return MKBETAG(
'a',
'p',
'4',
'h');
570 return MKBETAG(
'a',
'p',
'c',
'n');
586 CMVideoFormatDescriptionRef vid_fmt,
590 size_t total_size = 0;
592 int is_count_bad = 0;
607 for (
i = 0;
i < ps_count || is_count_bad;
i++) {
621 if (
i > 0 && is_count_bad) status = 0;
640 CMVideoFormatDescriptionRef vid_fmt,
646 int is_count_bad = 0;
664 for (
i = 0;
i < ps_count || is_count_bad;
i++) {
676 if (
i > 0 && is_count_bad) status = 0;
682 if (dst_size < next_offset) {
705 CMVideoFormatDescriptionRef vid_fmt;
709 vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
735 CFDataRef
data = CMFormatDescriptionGetExtension(vid_fmt, kCMFormatDescriptionExtension_VerbatimSampleDescription);
736 if (
data && CFGetTypeID(
data) == CFDataGetTypeID()) {
737 CFIndex
size = CFDataGetLength(
data);
753 void *sourceFrameCtx,
755 VTEncodeInfoFlags
flags,
756 CMSampleBufferRef sample_buffer)
760 BufNode *info = sourceFrameCtx;
775 if (!sample_buffer) {
780 CFRetain(sample_buffer);
797 CMSampleBufferRef sample_buffer,
801 CMVideoFormatDescriptionRef vid_fmt;
805 vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
833 CFStringRef *profile_level_val)
843 *profile_level_val =
NULL;
850 switch (vtctx->
level) {
851 case 0: *profile_level_val =
852 compat_keys.kVTProfileLevel_H264_Baseline_AutoLevel;
break;
853 case 13: *profile_level_val = kVTProfileLevel_H264_Baseline_1_3;
break;
854 case 30: *profile_level_val = kVTProfileLevel_H264_Baseline_3_0;
break;
855 case 31: *profile_level_val = kVTProfileLevel_H264_Baseline_3_1;
break;
856 case 32: *profile_level_val = kVTProfileLevel_H264_Baseline_3_2;
break;
857 case 40: *profile_level_val =
858 compat_keys.kVTProfileLevel_H264_Baseline_4_0;
break;
859 case 41: *profile_level_val = kVTProfileLevel_H264_Baseline_4_1;
break;
860 case 42: *profile_level_val =
861 compat_keys.kVTProfileLevel_H264_Baseline_4_2;
break;
862 case 50: *profile_level_val =
863 compat_keys.kVTProfileLevel_H264_Baseline_5_0;
break;
864 case 51: *profile_level_val =
865 compat_keys.kVTProfileLevel_H264_Baseline_5_1;
break;
866 case 52: *profile_level_val =
867 compat_keys.kVTProfileLevel_H264_Baseline_5_2;
break;
872 *profile_level_val =
compat_keys.kVTProfileLevel_H264_ConstrainedBaseline_AutoLevel;
874 if (vtctx->
level != 0) {
877 "Level is auto-selected when constrained-baseline "
878 "profile is used. The output may be encoded with a "
879 "different level.\n");
884 switch (vtctx->
level) {
885 case 0: *profile_level_val =
886 compat_keys.kVTProfileLevel_H264_Main_AutoLevel;
break;
887 case 30: *profile_level_val = kVTProfileLevel_H264_Main_3_0;
break;
888 case 31: *profile_level_val = kVTProfileLevel_H264_Main_3_1;
break;
889 case 32: *profile_level_val = kVTProfileLevel_H264_Main_3_2;
break;
890 case 40: *profile_level_val = kVTProfileLevel_H264_Main_4_0;
break;
891 case 41: *profile_level_val = kVTProfileLevel_H264_Main_4_1;
break;
892 case 42: *profile_level_val =
894 case 50: *profile_level_val = kVTProfileLevel_H264_Main_5_0;
break;
895 case 51: *profile_level_val =
897 case 52: *profile_level_val =
903 *profile_level_val =
compat_keys.kVTProfileLevel_H264_ConstrainedHigh_AutoLevel;
905 if (vtctx->
level != 0) {
908 "Level is auto-selected when constrained-high profile "
909 "is used. The output may be encoded with a different "
915 switch (vtctx->
level) {
916 case 0: *profile_level_val =
917 compat_keys.kVTProfileLevel_H264_High_AutoLevel;
break;
918 case 30: *profile_level_val =
920 case 31: *profile_level_val =
922 case 32: *profile_level_val =
924 case 40: *profile_level_val =
926 case 41: *profile_level_val =
928 case 42: *profile_level_val =
930 case 50: *profile_level_val = kVTProfileLevel_H264_High_5_0;
break;
931 case 51: *profile_level_val =
933 case 52: *profile_level_val =
938 switch (vtctx->
level) {
939 case 0: *profile_level_val =
940 compat_keys.kVTProfileLevel_H264_Extended_AutoLevel;
break;
941 case 50: *profile_level_val =
942 compat_keys.kVTProfileLevel_H264_Extended_5_0;
break;
947 if (!*profile_level_val) {
962 CFStringRef *profile_level_val)
971 *profile_level_val =
NULL;
985 "main profile with %d bit input\n",
bit_depth);
992 "Invalid main10 profile with %d bit input\n",
bit_depth);
1000 *profile_level_val =
1001 compat_keys.kVTProfileLevel_HEVC_Main42210_AutoLevel;
1005 if (!*profile_level_val) {
1016 int* av_pixel_format,
1019 const char *range_name;
1025 if (*av_pixel_format)
1030 "Could not get pixel format for color format '%s' range '%s'.\n",
1032 range_name ? range_name :
"Unknown");
1041 CFDictionarySetValue(dict,
1042 kCVImageBufferColorPrimariesKey,
1047 CFDictionarySetValue(dict,
1048 kCVImageBufferTransferFunctionKey,
1053 CFDictionarySetValue(dict,
1054 kCVImageBufferYCbCrMatrixKey,
1060 CFMutableDictionaryRef* dict)
1062 CFNumberRef cv_color_format_num =
NULL;
1063 CFNumberRef width_num =
NULL;
1064 CFNumberRef height_num =
NULL;
1065 CFMutableDictionaryRef pixel_buffer_info =
NULL;
1066 int cv_color_format;
1072 if (status)
return status;
1074 pixel_buffer_info = CFDictionaryCreateMutable(
1075 kCFAllocatorDefault,
1077 &kCFCopyStringDictionaryKeyCallBacks,
1078 &kCFTypeDictionaryValueCallBacks);
1080 if (!pixel_buffer_info)
goto pbinfo_nomem;
1082 cv_color_format_num = CFNumberCreate(kCFAllocatorDefault,
1083 kCFNumberSInt32Type,
1085 if (!cv_color_format_num)
goto pbinfo_nomem;
1087 CFDictionarySetValue(pixel_buffer_info,
1088 kCVPixelBufferPixelFormatTypeKey,
1089 cv_color_format_num);
1092 width_num = CFNumberCreate(kCFAllocatorDefault,
1093 kCFNumberSInt32Type,
1095 if (!width_num)
goto pbinfo_nomem;
1097 CFDictionarySetValue(pixel_buffer_info,
1098 kCVPixelBufferWidthKey,
1102 height_num = CFNumberCreate(kCFAllocatorDefault,
1103 kCFNumberSInt32Type,
1105 if (!height_num)
goto pbinfo_nomem;
1107 CFDictionarySetValue(pixel_buffer_info,
1108 kCVPixelBufferHeightKey,
1114 *dict = pixel_buffer_info;
1121 if (pixel_buffer_info) CFRelease(pixel_buffer_info);
1127 CFNumberRef *gamma_level)
1131 *gamma_level =
NULL;
1139 *gamma_level = CFNumberCreate(
NULL, kCFNumberFloat32Type, &gamma);
1151 const char *print_option_name,
1157 if (status == kVTPropertyNotSupportedErr) {
1160 "This device does not support the %s option. Value ignored.\n",
1162 }
else if (status != 0) {
1165 "Error setting %s: Error %d\n",
1173 const char* print_option_name,
1175 CFNumberRef value_cfnum = CFNumberCreate(kCFAllocatorDefault,
1179 if (value_cfnum ==
NULL) {
1185 CFRelease(value_cfnum);
1192 CFStringRef profile_level,
1193 CFNumberRef gamma_level,
1194 CFDictionaryRef enc_info,
1195 CFDictionaryRef pixel_buffer_info,
1196 bool constant_bit_rate,
1197 VTCompressionSessionRef *session)
1202 CFNumberRef bit_rate_num;
1203 CFNumberRef bytes_per_second;
1204 CFNumberRef one_second;
1205 CFArrayRef data_rate_limits;
1206 int64_t bytes_per_second_value = 0;
1210 int status = VTCompressionSessionCreate(kCFAllocatorDefault,
1216 kCFAllocatorDefault,
1221 if (status || !vtctx->
session) {
1224#if !TARGET_OS_IPHONE
1226 av_log(avctx,
AV_LOG_ERROR,
"Try -allow_sw 1. The hardware encoder may be busy, or not supported.\n");
1233#if defined (MAC_OS_X_VERSION_10_13) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_13)
1234 if (__builtin_available(macOS 10.13, iOS 11.0, *)) {
1239 status = VTCopySupportedPropertyDictionaryForEncoder(avctx->
width,
1246 if (status != noErr) {
1258 av_log(avctx,
AV_LOG_ERROR,
"-q:v qscale not available for encoder. Use -b:v bitrate instead.\n");
1266 CFNumberRef quality_num = CFNumberCreate(kCFAllocatorDefault,
1267 kCFNumberFloat32Type,
1269 if (!quality_num)
return AVERROR(ENOMEM);
1271 status = VTSessionSetProperty(vtctx->
session,
1272 kVTCompressionPropertyKey_Quality,
1274 CFRelease(quality_num);
1276 bit_rate_num = CFNumberCreate(kCFAllocatorDefault,
1277 kCFNumberSInt32Type,
1279 if (!bit_rate_num)
return AVERROR(ENOMEM);
1281 if (constant_bit_rate) {
1282 status = VTSessionSetProperty(vtctx->
session,
1283 compat_keys.kVTCompressionPropertyKey_ConstantBitRate,
1285 if (status == kVTPropertyNotSupportedErr) {
1286 av_log(avctx,
AV_LOG_ERROR,
"-constant_bit_rate true is not supported by the encoder.\n");
1287 CFRelease(bit_rate_num);
1291 status = VTSessionSetProperty(vtctx->
session,
1292 kVTCompressionPropertyKey_AverageBitRate,
1296 CFRelease(bit_rate_num);
1305 status = VTSessionSetProperty(vtctx->
session,
1306 compat_keys.kVTCompressionPropertyKey_PrioritizeEncodingSpeedOverQuality,
1307 vtctx->
prio_speed ? kCFBooleanTrue : kCFBooleanFalse);
1309 av_log(avctx,
AV_LOG_WARNING,
"PrioritizeEncodingSpeedOverQuality property is not supported on this device. Ignoring.\n");
1315 bytes_per_second_value = max_rate >> 3;
1316 bytes_per_second = CFNumberCreate(kCFAllocatorDefault,
1317 kCFNumberSInt64Type,
1318 &bytes_per_second_value);
1319 if (!bytes_per_second) {
1322 one_second_value = 1;
1323 one_second = CFNumberCreate(kCFAllocatorDefault,
1324 kCFNumberSInt64Type,
1327 CFRelease(bytes_per_second);
1330 nums[0] = (
void *)bytes_per_second;
1331 nums[1] = (
void *)one_second;
1332 data_rate_limits = CFArrayCreate(kCFAllocatorDefault,
1333 (
const void **)nums,
1335 &kCFTypeArrayCallBacks);
1337 if (!data_rate_limits) {
1338 CFRelease(bytes_per_second);
1339 CFRelease(one_second);
1342 status = VTSessionSetProperty(vtctx->
session,
1343 kVTCompressionPropertyKey_DataRateLimits,
1346 CFRelease(bytes_per_second);
1347 CFRelease(one_second);
1348 CFRelease(data_rate_limits);
1364 CFNumberRef alpha_quality_num = CFNumberCreate(kCFAllocatorDefault,
1365 kCFNumberDoubleType,
1367 if (!alpha_quality_num)
return AVERROR(ENOMEM);
1369 status = VTSessionSetProperty(vtctx->
session,
1370 compat_keys.kVTCompressionPropertyKey_TargetQualityForAlpha,
1372 CFRelease(alpha_quality_num);
1377 "Error setting alpha quality: %d\n",
1383 if (profile_level) {
1384 status = VTSessionSetProperty(vtctx->
session,
1385 kVTCompressionPropertyKey_ProfileLevel,
1388 av_log(avctx,
AV_LOG_ERROR,
"Error setting profile/level property: %d. Output will be encoded using a supported profile/level combination.\n", status);
1393 CFNumberRef interval = CFNumberCreate(kCFAllocatorDefault,
1400 status = VTSessionSetProperty(vtctx->
session,
1401 kVTCompressionPropertyKey_MaxKeyFrameInterval,
1403 CFRelease(interval);
1406 av_log(avctx,
AV_LOG_ERROR,
"Error setting 'max key-frame interval' property: %d\n", status);
1412 status = VTSessionSetProperty(vtctx->
session,
1413 kVTCompressionPropertyKey_MoreFramesBeforeStart,
1416 if (status == kVTPropertyNotSupportedErr) {
1417 av_log(avctx,
AV_LOG_WARNING,
"frames_before property is not supported on this device. Ignoring.\n");
1418 }
else if (status) {
1424 status = VTSessionSetProperty(vtctx->
session,
1425 kVTCompressionPropertyKey_MoreFramesAfterEnd,
1428 if (status == kVTPropertyNotSupportedErr) {
1429 av_log(avctx,
AV_LOG_WARNING,
"frames_after property is not supported on this device. Ignoring.\n");
1430 }
else if (status) {
1438 CFMutableDictionaryRef par;
1445 num = CFNumberCreate(kCFAllocatorDefault,
1449 den = CFNumberCreate(kCFAllocatorDefault,
1455 par = CFDictionaryCreateMutable(kCFAllocatorDefault,
1457 &kCFCopyStringDictionaryKeyCallBacks,
1458 &kCFTypeDictionaryValueCallBacks);
1460 if (!par || !
num || !den) {
1461 if (par) CFRelease(par);
1463 if (den) CFRelease(den);
1468 CFDictionarySetValue(
1470 kCMFormatDescriptionKey_PixelAspectRatioHorizontalSpacing,
1473 CFDictionarySetValue(
1475 kCMFormatDescriptionKey_PixelAspectRatioVerticalSpacing,
1478 status = VTSessionSetProperty(vtctx->
session,
1479 kVTCompressionPropertyKey_PixelAspectRatio,
1489 "Error setting pixel aspect ratio to %d:%d: %d.\n",
1500 status = VTSessionSetProperty(vtctx->
session,
1501 kVTCompressionPropertyKey_TransferFunction,
1511 status = VTSessionSetProperty(vtctx->
session,
1512 kVTCompressionPropertyKey_YCbCrMatrix,
1522 status = VTSessionSetProperty(vtctx->
session,
1523 kVTCompressionPropertyKey_ColorPrimaries,
1532 status = VTSessionSetProperty(vtctx->
session,
1533 kCVImageBufferGammaLevelKey,
1542 status = VTSessionSetProperty(vtctx->
session,
1543 kVTCompressionPropertyKey_AllowFrameReordering,
1547 av_log(avctx,
AV_LOG_ERROR,
"Error setting 'allow frame reordering' property: %d\n", status);
1557 status = VTSessionSetProperty(vtctx->
session,
1558 compat_keys.kVTCompressionPropertyKey_H264EntropyMode,
1567 status = VTSessionSetProperty(vtctx->
session,
1569 vtctx->
realtime ? kCFBooleanTrue : kCFBooleanFalse);
1578 compat_keys.kVTCompressionPropertyKey_AllowOpenGOP,
1583 if (avctx->
qmin >= 0) {
1585 compat_keys.kVTCompressionPropertyKey_MinAllowedFrameQP,
1594 if (avctx->
qmax >= 0) {
1596 compat_keys.kVTCompressionPropertyKey_MaxAllowedFrameQP,
1607 kVTCompressionPropertyKey_MaxH264SliceBytes,
1618 compat_keys.kVTCompressionPropertyKey_MaximizePowerEfficiency,
1625 compat_keys.kVTCompressionPropertyKey_ReferenceBufferCount,
1636 compat_keys.kVTCompressionPropertyKey_SpatialAdaptiveQPLevel,
1641 status = VTCompressionSessionPrepareToEncodeFrames(vtctx->
session);
1652 CFMutableDictionaryRef enc_info;
1653 CFMutableDictionaryRef pixel_buffer_info =
NULL;
1656 CFStringRef profile_level =
NULL;
1657 CFNumberRef gamma_level =
NULL;
1666#if defined(MAC_OS_X_VERSION_10_9) && !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9)
1668 if (__builtin_available(macOS 10.10, *)) {
1669 VTRegisterProfessionalVideoWorkflowVideoEncoders();
1681 av_log(avctx,
AV_LOG_WARNING,
"Cannot use B-frames with baseline profile. Output will not contain B-frames.\n");
1686 av_log(avctx,
AV_LOG_WARNING,
"CABAC entropy requires 'main' or 'high' profile, but baseline was requested. Encode will not use CABAC entropy.\n");
1700 enc_info = CFDictionaryCreateMutable(
1701 kCFAllocatorDefault,
1703 &kCFCopyStringDictionaryKeyCallBacks,
1704 &kCFTypeDictionaryValueCallBacks
1707 if (!enc_info)
return AVERROR(ENOMEM);
1709#if !TARGET_OS_IPHONE
1711 CFDictionarySetValue(enc_info,
1712 compat_keys.kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
1715 CFDictionarySetValue(enc_info,
1716 compat_keys.kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder,
1719 CFDictionarySetValue(enc_info,
1720 compat_keys.kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
1730 "please specify bitrate explicitly\n");
1734 CFDictionarySetValue(enc_info,
1735 compat_keys.kVTVideoEncoderSpecification_EnableLowLatencyRateControl,
1775 CFRelease(gamma_level);
1777 if (pixel_buffer_info)
1778 CFRelease(pixel_buffer_info);
1780 CFRelease(enc_info);
1788 CFBooleanRef has_b_frames_cfbool;
1800 if (status)
return status;
1802 status = VTSessionCopyProperty(vtctx->
session,
1803 kVTCompressionPropertyKey_AllowFrameReordering,
1804 kCFAllocatorDefault,
1805 &has_b_frames_cfbool);
1807 if (!status && has_b_frames_cfbool) {
1809 if (CFBooleanGetValue(has_b_frames_cfbool))
1813 CFRelease(has_b_frames_cfbool);
1822 CFArrayRef attachments;
1823 CFDictionaryRef attachment;
1824 CFBooleanRef not_sync;
1827 attachments = CMSampleBufferGetSampleAttachmentsArray(
buffer,
false);
1828 len = !attachments ? 0 : CFArrayGetCount(attachments);
1831 *is_key_frame =
true;
1835 attachment = CFArrayGetValueAtIndex(attachments, 0);
1837 if (CFDictionaryGetValueIfPresent(attachment,
1838 kCMSampleAttachmentKey_NotSync,
1839 (
const void **)¬_sync))
1841 *is_key_frame = !CFBooleanGetValue(not_sync);
1843 *is_key_frame =
true;
1864 size_t sei_payload_size = 0;
1865 uint8_t *nal_start = nal_data;
1871 nal_type = *nal_data & 0x1F;
1878 if (nal_data[nal_size - 1] == 0x80)
1881 while (nal_size > 0 && *nal_data > 0) {
1885 }
while (nal_size > 0 && *nal_data == 0xFF);
1893 sei_payload_size += *nal_data;
1896 }
while (nal_size > 0 && *nal_data == 0xFF);
1898 if (nal_size < sei_payload_size) {
1903 nal_data += sei_payload_size;
1904 nal_size -= sei_payload_size;
1907 *sei_end = nal_data;
1909 return nal_data - nal_start + 1;
1929 uint8_t* dst_end =
dst + dst_size;
1930 const uint8_t* src_end =
src + src_size;
1931 int start_at = dst_offset > 2 ? dst_offset - 2 : 0;
1933 for (
i = start_at;
i < dst_offset &&
i < dst_size;
i++) {
1944 int insert_ep3_byte = *
src <= 3;
1945 if (insert_ep3_byte) {
1963 wrote_bytes =
dst - dst_start;
1966 return -wrote_bytes;
1976 uint8_t *sei_start =
dst;
1977 size_t remaining_sei_size =
sei->size;
1978 size_t remaining_dst_size = dst_size;
1983 if (!remaining_dst_size)
1986 while (sei_type && remaining_dst_size != 0) {
1987 int sei_byte = sei_type > 255 ? 255 : sei_type;
1990 sei_type -= sei_byte;
1992 remaining_dst_size--;
1998 while (remaining_sei_size && remaining_dst_size != 0) {
1999 int size_byte = remaining_sei_size > 255 ? 255 : remaining_sei_size;
2002 remaining_sei_size -= size_byte;
2004 remaining_dst_size--;
2007 if (remaining_dst_size < sei->
size)
2010 header_bytes =
dst - sei_start;
2018 if (bytes_written < 0)
2021 bytes_written += header_bytes;
2022 return bytes_written;
2046 size_t length_code_size,
2047 CMSampleBufferRef sample_buffer,
2052 size_t src_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
2053 size_t remaining_src_size = src_size;
2054 size_t remaining_dst_size = dst_size;
2055 size_t src_offset = 0;
2058 uint8_t size_buf[4];
2060 CMBlockBufferRef
block = CMSampleBufferGetDataBuffer(sample_buffer);
2062 if (length_code_size > 4) {
2066 while (remaining_src_size > 0) {
2067 size_t curr_src_len;
2068 size_t curr_dst_len;
2074 status = CMBlockBufferCopyDataBytes(
block,
2083 status = CMBlockBufferCopyDataBytes(
block,
2084 src_offset + length_code_size,
2095 for (
i = 0;
i < length_code_size;
i++) {
2097 box_len |= size_buf[
i];
2110 remaining_dst_size--;
2115 remaining_dst_size);
2117 if (wrote_bytes < 0)
2120 remaining_dst_size -= wrote_bytes;
2121 dst_data += wrote_bytes;
2123 if (remaining_dst_size <= 0)
2129 remaining_dst_size--;
2134 curr_src_len = box_len + length_code_size;
2137 if (remaining_src_size < curr_src_len) {
2141 if (remaining_dst_size < curr_dst_len) {
2148 status = CMBlockBufferCopyDataBytes(
block,
2149 src_offset + length_code_size,
2164 old_sei_length =
find_sei_end(avctx, dst_box, box_len, &new_sei);
2165 if (old_sei_length < 0)
2166 return old_sei_length;
2171 remaining_dst_size - old_sei_length);
2172 if (wrote_bytes < 0)
2175 if (new_sei + wrote_bytes >= dst_data + remaining_dst_size)
2178 new_sei[wrote_bytes++] = 0x80;
2179 extra_bytes = wrote_bytes - (dst_box + box_len - new_sei);
2181 dst_data += extra_bytes;
2182 remaining_dst_size -= extra_bytes;
2187 src_offset += curr_src_len;
2188 dst_data += curr_dst_len;
2190 remaining_src_size -= curr_src_len;
2191 remaining_dst_size -= curr_dst_len;
2212 if ((
sei->size % 255) == 0)
2215 return copied_size +
sei->size / 255 + 1 +
type / 255 + 1;
2220 CMSampleBufferRef sample_buffer,
2229 size_t length_code_size;
2230 size_t header_size = 0;
2232 size_t out_buf_size;
2233 size_t sei_nalu_size = 0;
2238 CMVideoFormatDescriptionRef vid_fmt;
2244 if (status)
return status;
2249 vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
2256 if (status)
return status;
2259 status =
count_nalus(length_code_size, sample_buffer, &nalu_count);
2267 sei_nalu_size =
sizeof(
start_code) + 1 + msg_size + 1;
2270 in_buf_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
2271 out_buf_size = header_size +
2274 nalu_count * ((int)
sizeof(
start_code) - (int)length_code_size);
2282 if(status)
return status;
2290 pkt->data + header_size,
2291 pkt->size - header_size
2300 CMBlockBufferRef buf = CMSampleBufferGetDataBuffer(sample_buffer);
2306 len = CMBlockBufferGetDataLength(buf);
2312 status = CMBlockBufferCopyDataBytes(buf, 0,
len,
pkt->data);
2323 pts = CMSampleBufferGetPresentationTimeStamp(sample_buffer);
2324 dts = CMSampleBufferGetDecodeTimeStamp (sample_buffer);
2326 if (CMTIME_IS_INVALID(
pts)) {
2331 if (CMTIME_IS_INVALID(dts)) {
2350 CVPixelBufferRef cv_img)
2355 size_t num_cv_plane = CVPixelBufferIsPlanar(cv_img) ?
2356 CVPixelBufferGetPlaneCount(cv_img) : 1;
2357 if (num_planes != num_cv_plane) {
2359 "Different number of planes in AVFrame and CVPixelBuffer.\n");
2363 status = CVPixelBufferLockBaseAddress(cv_img, 0);
2365 av_log(avctx,
AV_LOG_ERROR,
"Could not lock base address of CVPixelBuffer: %d.\n", status);
2369 int dst_stride[4] = {0};
2370 uint8_t *dst_addr[4] = {0};
2371 for (
int i = 0;
i < num_planes;
i++) {
2372 dst_addr[
i] = (uint8_t*)CVPixelBufferGetBaseAddressOfPlane(cv_img,
i);
2373 dst_stride[
i] = CVPixelBufferGetBytesPerRowOfPlane(cv_img,
i);
2378 status = CVPixelBufferUnlockBaseAddress(cv_img, 0);
2380 av_log(avctx,
AV_LOG_ERROR,
"Could not unlock CVPixelBuffer base address: %d.\n", status);
2389 CVPixelBufferRef *cv_img,
2393 CVPixelBufferPoolRef pix_buf_pool;
2399 *cv_img = (CVPixelBufferRef)
frame->data[3];
2403 if (
frame->buf[0]) {
2414 &(
int) {0}, &range_guessed);
2420 if (range_guessed) {
2428 pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->
session);
2429 if (!pix_buf_pool) {
2436 vtstatus = VTCompressionSessionPrepareToEncodeFrames(vtctx->
session);
2437 if (vtstatus == kVTInvalidSessionErr) {
2442 pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->
session);
2444 if (!pix_buf_pool) {
2450 "kVTInvalidSessionErr error.\n");
2453 status = CVPixelBufferPoolCreatePixelBuffer(
NULL,
2459 av_log(avctx,
AV_LOG_ERROR,
"Could not create pixel buffer from pool: %d.\n", status);
2474 CFDictionaryRef* dict_out)
2476 CFDictionaryRef dict =
NULL;
2478 const void *keys[] = { kVTEncodeFrameOptionKey_ForceKeyFrame };
2479 const void *vals[] = { kCFBooleanTrue };
2481 dict = CFDictionaryCreate(
NULL, keys, vals, 1,
NULL,
NULL);
2482 if(!dict)
return AVERROR(ENOMEM);
2494 CFDictionaryRef frame_dict =
NULL;
2495 CVPixelBufferRef cv_img =
NULL;
2513 if (vtctx->
a53_cc && side_data && side_data->
size) {
2522 status = VTCompressionSessionEncodeFrame(
2541 CFRelease(frame_dict);
2559 CMSampleBufferRef buf =
NULL;
2580 status = VTCompressionSessionCompleteFrames(vtctx->
session,
2598 if (status)
goto end_nopkt;
2599 if (!buf)
goto end_nopkt;
2604 if (status)
goto end_nopkt;
2616 CFStringRef profile_level,
2617 CFNumberRef gamma_level,
2618 CFDictionaryRef enc_info,
2619 CFDictionaryRef pixel_buffer_info)
2623 CVPixelBufferPoolRef pool =
NULL;
2624 CVPixelBufferRef pix_buf =
NULL;
2626 CMSampleBufferRef buf =
NULL;
2643 pool = VTCompressionSessionGetPixelBufferPool(vtctx->
session);
2650 status = CVPixelBufferPoolCreatePixelBuffer(
NULL,
2654 if(status != kCVReturnSuccess){
2661 status = VTCompressionSessionEncodeFrame(vtctx->
session,
2672 "Error sending frame for extradata: %d\n",
2680 status = VTCompressionSessionCompleteFrames(vtctx->
session,
2704 CVPixelBufferRelease(pix_buf);
2732 VTCompressionSessionCompleteFrames(vtctx->
session,
2764#ifdef kCFCoreFoundationVersionNumber10_7
2769#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
2772#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR8BIPLANARVIDEORANGE
2775#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR10BIPLANARVIDEORANGE
2778#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR16BIPLANARVIDEORANGE
2781#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR8BIPLANARVIDEORANGE
2784#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR10BIPLANARVIDEORANGE
2787#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE
2794#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
2795#define COMMON_OPTIONS \
2796 { "allow_sw", "Allow software encoding", OFFSET(allow_sw), AV_OPT_TYPE_BOOL, \
2797 { .i64 = 0 }, 0, 1, VE }, \
2798 { "require_sw", "Require software encoding", OFFSET(require_sw), AV_OPT_TYPE_BOOL, \
2799 { .i64 = 0 }, 0, 1, VE }, \
2800 { "realtime", "Hint that encoding should happen in real-time if not faster (e.g. capturing from camera).", \
2801 OFFSET(realtime), AV_OPT_TYPE_BOOL, { .i64 = 0 }, -1, 1, VE }, \
2802 { "frames_before", "Other frames will come before the frames in this session. This helps smooth concatenation issues.", \
2803 OFFSET(frames_before), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \
2804 { "frames_after", "Other frames will come after the frames in this session. This helps smooth concatenation issues.", \
2805 OFFSET(frames_after), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \
2806 { "prio_speed", "prioritize encoding speed", OFFSET(prio_speed), AV_OPT_TYPE_BOOL, \
2807 { .i64 = -1 }, -1, 1, VE }, \
2808 { "power_efficient", "Set to 1 to enable more power-efficient encoding if supported.", \
2809 OFFSET(power_efficient), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
2810 { "spatial_aq", "Set to 1 to enable spatial AQ if supported.", \
2811 OFFSET(spatialaq), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, \
2812 { "max_ref_frames", \
2813 "Sets the maximum number of reference frames. This only has an effect when the value is less than the maximum allowed by the profile/level.", \
2814 OFFSET(max_ref_frames), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
2821#define OFFSET(x) offsetof(VTEncContext, x)
2832 {
"1.3",
"Level 1.3, only available with Baseline Profile", 0,
AV_OPT_TYPE_CONST, { .i64 = 13 }, INT_MIN, INT_MAX,
VE, .unit =
"level" },
2833 {
"3.0",
"Level 3.0", 0,
AV_OPT_TYPE_CONST, { .i64 = 30 }, INT_MIN, INT_MAX,
VE, .unit =
"level" },
2834 {
"3.1",
"Level 3.1", 0,
AV_OPT_TYPE_CONST, { .i64 = 31 }, INT_MIN, INT_MAX,
VE, .unit =
"level" },
2835 {
"3.2",
"Level 3.2", 0,
AV_OPT_TYPE_CONST, { .i64 = 32 }, INT_MIN, INT_MAX,
VE, .unit =
"level" },
2836 {
"4.0",
"Level 4.0", 0,
AV_OPT_TYPE_CONST, { .i64 = 40 }, INT_MIN, INT_MAX,
VE, .unit =
"level" },
2837 {
"4.1",
"Level 4.1", 0,
AV_OPT_TYPE_CONST, { .i64 = 41 }, INT_MIN, INT_MAX,
VE, .unit =
"level" },
2838 {
"4.2",
"Level 4.2", 0,
AV_OPT_TYPE_CONST, { .i64 = 42 }, INT_MIN, INT_MAX,
VE, .unit =
"level" },
2839 {
"5.0",
"Level 5.0", 0,
AV_OPT_TYPE_CONST, { .i64 = 50 }, INT_MIN, INT_MAX,
VE, .unit =
"level" },
2840 {
"5.1",
"Level 5.1", 0,
AV_OPT_TYPE_CONST, { .i64 = 51 }, INT_MIN, INT_MAX,
VE, .unit =
"level" },
2841 {
"5.2",
"Level 5.2", 0,
AV_OPT_TYPE_CONST, { .i64 = 52 }, INT_MIN, INT_MAX,
VE, .unit =
"level" },
2851 {
"constant_bit_rate",
"Require constant bit rate (macOS 13 or newer)",
OFFSET(constant_bit_rate),
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
VE },
2852 {
"max_slice_bytes",
"Set the maximum number of bytes in an H.264 slice.",
OFFSET(max_slice_bytes),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX,
VE },
2865 .class_name =
"h264_videotoolbox",
2872 .p.name =
"h264_videotoolbox",
2886 .p.wrapper_name =
"videotoolbox",
2897 {
"alpha_quality",
"Compression quality for the alpha channel",
OFFSET(alpha_quality),
AV_OPT_TYPE_DOUBLE, { .dbl = 0.0 }, 0.0, 1.0,
VE },
2899 {
"constant_bit_rate",
"Require constant bit rate (macOS 13 or newer)",
OFFSET(constant_bit_rate),
AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1,
VE },
2906 .class_name =
"hevc_videotoolbox",
2913 .p.name =
"hevc_videotoolbox",
2928 .p.wrapper_name =
"videotoolbox",
2947 .class_name =
"prores_videotoolbox",
2954 .p.name =
"prores_videotoolbox",
2969 .p.wrapper_name =
"videotoolbox",
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static void bit_depth(AudioStatsContext *s, const uint64_t *const mask, uint8_t *depth)
const FFCodec ff_h264_videotoolbox_encoder
const FFCodec ff_hevc_videotoolbox_encoder
const FFCodec ff_prores_videotoolbox_encoder
static AVFormatContext * ctx
int ff_alloc_a53_sei(const AVFrame *frame, size_t prefix_len, void **data, size_t *sei_size)
Check AVFrame for A53 side data and allocate and fill SEI message with A53 info.
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
static int FUNC sei(CodedBitstreamContext *ctx, RWContext *rw, H264RawSEI *current)
#define CODEC_PIXFMTS_ARRAY(array)
#define FF_CODEC_ENCODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define AV_PROFILE_PRORES_STANDARD
#define AV_PROFILE_PRORES_4444
#define AV_PROFILE_H264_MAIN
#define AV_PROFILE_PRORES_LT
#define AV_PROFILE_H264_EXTENDED
#define AV_PROFILE_UNKNOWN
#define AV_PROFILE_PRORES_PROXY
#define AV_PROFILE_HEVC_REXT
#define AV_PROFILE_HEVC_MAIN
#define AV_PROFILE_HEVC_MAIN_10
#define AV_PROFILE_H264_HIGH
#define AV_PROFILE_H264_CONSTRAINED_BASELINE
#define AV_PROFILE_PRORES_XQ
#define AV_PROFILE_PRORES_HQ
#define AV_PROFILE_H264_BASELINE
float fminf(float, float)
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
#define AV_CODEC_FLAG_CLOSED_GOP
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
#define AV_CODEC_FLAG_LOW_DELAY
Force low delay.
AVCodecID
Identify the syntax and semantics of the bitstream.
#define AV_CODEC_CAP_HYBRID
Codec is potentially backed by a hardware implementation, but not necessarily.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
#define AVERROR_EXTERNAL
Generic error in an external library.
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
@ AV_FRAME_DATA_A53_CC
ATSC A53 Part 4 Closed Captions.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const char * av_default_item_name(void *ptr)
Return the context name.
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
static void av_image_copy2(uint8_t *const dst_data[4], const int dst_linesizes[4], uint8_t *const src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height)
Wrapper around av_image_copy() to workaround the limitation that the conversion from uint8_t * const ...
@ AV_PICTURE_TYPE_I
Intra.
#define LIBAVUTIL_VERSION_INT
H.264 common definitions.
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
CFStringRef av_map_videotoolbox_color_matrix_from_av(enum AVColorSpace space)
Convert an AVColorSpace to a VideoToolbox/CoreVideo color matrix string.
CFStringRef av_map_videotoolbox_color_primaries_from_av(enum AVColorPrimaries pri)
Convert an AVColorPrimaries to a VideoToolbox/CoreVideo color primaries string.
uint32_t av_map_videotoolbox_format_from_pixfmt2(enum AVPixelFormat pix_fmt, bool full_range)
Same as av_map_videotoolbox_format_from_pixfmt function, but can map and return full range pixel form...
CFStringRef av_map_videotoolbox_color_trc_from_av(enum AVColorTransferCharacteristic trc)
Convert an AVColorTransferCharacteristic to a VideoToolbox/CoreVideo color transfer function string.
An API-specific header for AV_HWDEVICE_TYPE_VIDEOTOOLBOX.
static const AVOption h264_options[]
common internal api header.
static const int factor[16]
Macro definitions for various function/variable attributes.
#define MKBETAG(a, b, c, d)
Memory handling functions.
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
#define PTHREAD_ONCE_INIT
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
static av_always_inline int pthread_once(pthread_once_t *once_control, void(*init_routine)(void))
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
const char * av_color_range_name(enum AVColorRange range)
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
#define AV_PIX_FMT_FLAG_ALPHA
The pixel format has an alpha channel.
AVColorRange
Visual content value range.
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
@ AVCOL_RANGE_JPEG
Full range content.
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
@ AV_PIX_FMT_P010LE
like NV12, with 10bpp per component, data in the high bits, zeros in the low bits,...
@ AV_PIX_FMT_VIDEOTOOLBOX
hardware decoding through Videotoolbox
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
@ AV_PIX_FMT_BGRA
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
@ AV_PIX_FMT_NV24
planar YUV 4:4:4, 24bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
@ AV_PIX_FMT_NV16
interleaved chroma YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
@ AV_PIX_FMT_AYUV
packed AYUV 4:4:4:4, 32bpp (1 Cr & Cb sample per 1x1 Y & A samples), AYUVAYUV...
AVColorTransferCharacteristic
Color Transfer Characteristic.
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
#define AV_PIX_FMT_AYUV64
enum AVMediaType codec_type
@ SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
A reference to a data buffer.
Describe the class of an AVClass context structure.
main external API structure.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
int width
picture width / height.
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
int global_quality
Global quality for codecs which cannot change it per frame.
enum AVColorRange color_range
MPEG vs JPEG YUV range.
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
int qmin
minimum quantizer
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
int has_b_frames
Size of the frame reordering buffer in the decoder.
int64_t bit_rate
the average bitrate
enum AVColorSpace colorspace
YUV colorspace type.
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
int64_t rc_max_rate
maximum bitrate
int qmax
maximum quantizer
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
int flags
AV_CODEC_FLAG_*.
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Structure to hold side data for an AVFrame.
This structure describes decoded (raw) audio or video data.
This structure stores compressed data.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
uint64_t flags
Combination of AV_PIX_FMT_FLAG_... flags.
Rational number (pair of numerator and denominator).
CMSampleBufferRef cm_buffer
pthread_cond_t cv_sample_sent
CFStringRef transfer_function
getParameterSetAtIndex get_param_set_func
CFDictionaryRef supported_props
VTCompressionSessionRef session
CFStringRef color_primaries
static int get_frame(AVFilterContext *ctx, int is_second)
static const uint8_t quality[]