21 #include <VideoToolbox/VideoToolbox.h> 22 #include <CoreVideo/CoreVideo.h> 23 #include <CoreMedia/CoreMedia.h> 24 #include <TargetConditionals.h> 25 #include <Availability.h> 39 #if !HAVE_KCMVIDEOCODECTYPE_HEVC 43 #if !HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE 49 size_t parameterSetIndex,
50 const uint8_t **parameterSetPointerOut,
51 size_t *parameterSetSizeOut,
52 size_t *parameterSetCountOut,
53 int *NALUnitHeaderLengthOut);
98 #define GET_SYM(symbol, defaultVal) \ 100 CFStringRef* handle = (CFStringRef*)dlsym(RTLD_DEFAULT, #symbol); \ 102 compat_keys.symbol = CFSTR(defaultVal); \ 104 compat_keys.symbol = *handle; \ 110 compat_keys.CMVideoFormatDescriptionGetHEVCParameterSetAtIndex =
113 "CMVideoFormatDescriptionGetHEVCParameterSetAtIndex" 152 "EnableHardwareAcceleratedVideoEncoder");
154 "RequireHardwareAcceleratedVideoEncoder");
236 CFStringRef profile_level,
237 CFNumberRef gamma_level,
238 CFDictionaryRef enc_info,
239 CFDictionaryRef pixel_buffer_info);
319 }
else if (info->
sei) {
357 CMSampleBufferRef sample_buffer,
364 size_t src_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
365 CMBlockBufferRef
block = CMSampleBufferGetDataBuffer(sample_buffer);
367 if (length_code_size > 4)
370 while (offset < src_size) {
375 status = CMBlockBufferCopyDataBytes(block,
380 for (i = 0; i < length_code_size; i++) {
382 box_len |= size_buf[
i];
385 curr_src_len = box_len + length_code_size;
386 offset += curr_src_len;
414 CMVideoFormatDescriptionRef vid_fmt,
418 size_t total_size = 0;
420 int is_count_bad = 0;
435 for (i = 0; i < ps_count || is_count_bad; i++) {
449 if (i > 0 && is_count_bad) status = 0;
468 CMVideoFormatDescriptionRef vid_fmt,
474 int is_count_bad = 0;
492 for (i = 0; i < ps_count || is_count_bad; i++) {
504 if (i > 0 && is_count_bad) status = 0;
509 next_offset = offset +
sizeof(
start_code) + ps_size;
510 if (dst_size < next_offset) {
518 memcpy(dst + offset, ps, ps_size);
519 offset = next_offset;
532 CMVideoFormatDescriptionRef vid_fmt;
536 vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
566 void *sourceFrameCtx,
568 VTEncodeInfoFlags
flags,
569 CMSampleBufferRef sample_buffer)
585 if (!sample_buffer) {
602 CMSampleBufferRef sample_buffer,
606 CMVideoFormatDescriptionRef vid_fmt;
610 vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
638 CFStringRef *profile_level_val)
648 *profile_level_val =
NULL;
655 switch (vtctx->
level) {
656 case 0: *profile_level_val =
657 compat_keys.kVTProfileLevel_H264_Baseline_AutoLevel;
break;
658 case 13: *profile_level_val = kVTProfileLevel_H264_Baseline_1_3;
break;
659 case 30: *profile_level_val = kVTProfileLevel_H264_Baseline_3_0;
break;
660 case 31: *profile_level_val = kVTProfileLevel_H264_Baseline_3_1;
break;
661 case 32: *profile_level_val = kVTProfileLevel_H264_Baseline_3_2;
break;
662 case 40: *profile_level_val =
663 compat_keys.kVTProfileLevel_H264_Baseline_4_0;
break;
664 case 41: *profile_level_val = kVTProfileLevel_H264_Baseline_4_1;
break;
665 case 42: *profile_level_val =
666 compat_keys.kVTProfileLevel_H264_Baseline_4_2;
break;
667 case 50: *profile_level_val =
668 compat_keys.kVTProfileLevel_H264_Baseline_5_0;
break;
669 case 51: *profile_level_val =
670 compat_keys.kVTProfileLevel_H264_Baseline_5_1;
break;
671 case 52: *profile_level_val =
672 compat_keys.kVTProfileLevel_H264_Baseline_5_2;
break;
677 switch (vtctx->
level) {
678 case 0: *profile_level_val =
679 compat_keys.kVTProfileLevel_H264_Main_AutoLevel;
break;
680 case 30: *profile_level_val = kVTProfileLevel_H264_Main_3_0;
break;
681 case 31: *profile_level_val = kVTProfileLevel_H264_Main_3_1;
break;
682 case 32: *profile_level_val = kVTProfileLevel_H264_Main_3_2;
break;
683 case 40: *profile_level_val = kVTProfileLevel_H264_Main_4_0;
break;
684 case 41: *profile_level_val = kVTProfileLevel_H264_Main_4_1;
break;
685 case 42: *profile_level_val =
687 case 50: *profile_level_val = kVTProfileLevel_H264_Main_5_0;
break;
688 case 51: *profile_level_val =
690 case 52: *profile_level_val =
696 switch (vtctx->
level) {
697 case 0: *profile_level_val =
698 compat_keys.kVTProfileLevel_H264_High_AutoLevel;
break;
699 case 30: *profile_level_val =
701 case 31: *profile_level_val =
703 case 32: *profile_level_val =
705 case 40: *profile_level_val =
707 case 41: *profile_level_val =
709 case 42: *profile_level_val =
711 case 50: *profile_level_val = kVTProfileLevel_H264_High_5_0;
break;
712 case 51: *profile_level_val =
714 case 52: *profile_level_val =
719 switch (vtctx->
level) {
720 case 0: *profile_level_val =
721 compat_keys.kVTProfileLevel_H264_Extended_AutoLevel;
break;
722 case 50: *profile_level_val =
723 compat_keys.kVTProfileLevel_H264_Extended_5_0;
break;
728 if (!*profile_level_val) {
743 CFStringRef *profile_level_val)
748 *profile_level_val =
NULL;
763 if (!*profile_level_val) {
774 int* av_pixel_format,
783 kCVPixelFormatType_420YpCbCr8BiPlanarFullRange :
784 kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
787 kCVPixelFormatType_420YpCbCr8PlanarFullRange :
788 kCVPixelFormatType_420YpCbCr8Planar;
804 CFDictionarySetValue(dict,
805 kCVImageBufferColorPrimariesKey,
810 CFDictionarySetValue(dict,
811 kCVImageBufferTransferFunctionKey,
816 CFDictionarySetValue(dict,
817 kCVImageBufferYCbCrMatrixKey,
823 CFMutableDictionaryRef* dict)
825 CFNumberRef cv_color_format_num =
NULL;
826 CFNumberRef width_num =
NULL;
827 CFNumberRef height_num =
NULL;
828 CFMutableDictionaryRef pixel_buffer_info =
NULL;
835 if (status)
return status;
837 pixel_buffer_info = CFDictionaryCreateMutable(
840 &kCFCopyStringDictionaryKeyCallBacks,
841 &kCFTypeDictionaryValueCallBacks);
843 if (!pixel_buffer_info)
goto pbinfo_nomem;
845 cv_color_format_num = CFNumberCreate(kCFAllocatorDefault,
848 if (!cv_color_format_num)
goto pbinfo_nomem;
850 CFDictionarySetValue(pixel_buffer_info,
851 kCVPixelBufferPixelFormatTypeKey,
852 cv_color_format_num);
855 width_num = CFNumberCreate(kCFAllocatorDefault,
858 if (!width_num)
return AVERROR(ENOMEM);
860 CFDictionarySetValue(pixel_buffer_info,
861 kCVPixelBufferWidthKey,
865 height_num = CFNumberCreate(kCFAllocatorDefault,
868 if (!height_num)
goto pbinfo_nomem;
870 CFDictionarySetValue(pixel_buffer_info,
871 kCVPixelBufferHeightKey,
877 *dict = pixel_buffer_info;
884 if (pixel_buffer_info) CFRelease(pixel_buffer_info);
890 CFStringRef *primaries)
899 *primaries = kCVImageBufferColorPrimaries_EBU_3213;
903 *primaries = kCVImageBufferColorPrimaries_SMPTE_C;
907 *primaries = kCVImageBufferColorPrimaries_ITU_R_709_2;
911 *primaries =
compat_keys.kCVImageBufferColorPrimaries_ITU_R_2020;
924 CFStringRef *transfer_fnc,
925 CFNumberRef *gamma_level)
933 *transfer_fnc =
NULL;
937 *transfer_fnc = kCVImageBufferTransferFunction_ITU_R_709_2;
941 *transfer_fnc = kCVImageBufferTransferFunction_SMPTE_240M_1995;
944 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_SMPTE_ST_2084_PQ 946 *transfer_fnc = kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ;
949 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_LINEAR 951 *transfer_fnc = kCVImageBufferTransferFunction_Linear;
954 #if HAVE_KCVIMAGEBUFFERTRANSFERFUNCTION_ITU_R_2100_HLG 956 *transfer_fnc = kCVImageBufferTransferFunction_ITU_R_2100_HLG;
962 *transfer_fnc = kCVImageBufferTransferFunction_UseGamma;
963 *gamma_level = CFNumberCreate(
NULL, kCFNumberFloat32Type, &gamma);
968 *transfer_fnc = kCVImageBufferTransferFunction_UseGamma;
969 *gamma_level = CFNumberCreate(
NULL, kCFNumberFloat32Type, &gamma);
974 *transfer_fnc =
compat_keys.kCVImageBufferTransferFunction_ITU_R_2020;
978 *transfer_fnc =
NULL;
989 *matrix = kCVImageBufferYCbCrMatrix_ITU_R_709_2;
998 *matrix = kCVImageBufferYCbCrMatrix_ITU_R_601_4;
1002 *matrix = kCVImageBufferYCbCrMatrix_SMPTE_240M_1995;
1006 *matrix =
compat_keys.kCVImageBufferYCbCrMatrix_ITU_R_2020;
1019 CFStringRef profile_level,
1020 CFNumberRef gamma_level,
1021 CFDictionaryRef enc_info,
1022 CFDictionaryRef pixel_buffer_info,
1023 VTCompressionSessionRef *session)
1028 CFNumberRef bit_rate_num;
1029 CFNumberRef bytes_per_second;
1030 CFNumberRef one_second;
1031 CFArrayRef data_rate_limits;
1032 int64_t bytes_per_second_value = 0;
1033 int64_t one_second_value = 0;
1036 int status = VTCompressionSessionCreate(kCFAllocatorDefault,
1042 kCFAllocatorDefault,
1047 if (status || !vtctx->
session) {
1048 av_log(avctx,
AV_LOG_ERROR,
"Error: cannot create compression session: %d\n", status);
1050 #if !TARGET_OS_IPHONE 1052 av_log(avctx,
AV_LOG_ERROR,
"Try -allow_sw 1. The hardware encoder may be busy, or not supported.\n");
1059 bit_rate_num = CFNumberCreate(kCFAllocatorDefault,
1060 kCFNumberSInt32Type,
1062 if (!bit_rate_num)
return AVERROR(ENOMEM);
1064 status = VTSessionSetProperty(vtctx->
session,
1065 kVTCompressionPropertyKey_AverageBitRate,
1067 CFRelease(bit_rate_num);
1076 bytes_per_second_value = max_rate >> 3;
1077 bytes_per_second = CFNumberCreate(kCFAllocatorDefault,
1078 kCFNumberSInt64Type,
1079 &bytes_per_second_value);
1080 if (!bytes_per_second) {
1083 one_second_value = 1;
1084 one_second = CFNumberCreate(kCFAllocatorDefault,
1085 kCFNumberSInt64Type,
1088 CFRelease(bytes_per_second);
1091 nums[0] = (
void *)bytes_per_second;
1092 nums[1] = (
void *)one_second;
1093 data_rate_limits = CFArrayCreate(kCFAllocatorDefault,
1094 (
const void **)nums,
1096 &kCFTypeArrayCallBacks);
1098 if (!data_rate_limits) {
1099 CFRelease(bytes_per_second);
1100 CFRelease(one_second);
1103 status = VTSessionSetProperty(vtctx->
session,
1104 kVTCompressionPropertyKey_DataRateLimits,
1107 CFRelease(bytes_per_second);
1108 CFRelease(one_second);
1109 CFRelease(data_rate_limits);
1117 if (profile_level) {
1118 status = VTSessionSetProperty(vtctx->
session,
1119 kVTCompressionPropertyKey_ProfileLevel,
1122 av_log(avctx,
AV_LOG_ERROR,
"Error setting profile/level property: %d. Output will be encoded using a supported profile/level combination.\n", status);
1127 CFNumberRef interval = CFNumberCreate(kCFAllocatorDefault,
1134 status = VTSessionSetProperty(vtctx->
session,
1135 kVTCompressionPropertyKey_MaxKeyFrameInterval,
1137 CFRelease(interval);
1140 av_log(avctx,
AV_LOG_ERROR,
"Error setting 'max key-frame interval' property: %d\n", status);
1146 status = VTSessionSetProperty(vtctx->
session,
1147 kVTCompressionPropertyKey_MoreFramesBeforeStart,
1150 if (status == kVTPropertyNotSupportedErr) {
1151 av_log(avctx,
AV_LOG_WARNING,
"frames_before property is not supported on this device. Ignoring.\n");
1152 }
else if (status) {
1158 status = VTSessionSetProperty(vtctx->
session,
1159 kVTCompressionPropertyKey_MoreFramesAfterEnd,
1162 if (status == kVTPropertyNotSupportedErr) {
1163 av_log(avctx,
AV_LOG_WARNING,
"frames_after property is not supported on this device. Ignoring.\n");
1164 }
else if (status) {
1172 CFMutableDictionaryRef par;
1179 num = CFNumberCreate(kCFAllocatorDefault,
1183 den = CFNumberCreate(kCFAllocatorDefault,
1189 par = CFDictionaryCreateMutable(kCFAllocatorDefault,
1191 &kCFCopyStringDictionaryKeyCallBacks,
1192 &kCFTypeDictionaryValueCallBacks);
1194 if (!par || !num || !den) {
1195 if (par) CFRelease(par);
1196 if (num) CFRelease(num);
1197 if (den) CFRelease(den);
1202 CFDictionarySetValue(
1204 kCMFormatDescriptionKey_PixelAspectRatioHorizontalSpacing,
1207 CFDictionarySetValue(
1209 kCMFormatDescriptionKey_PixelAspectRatioVerticalSpacing,
1212 status = VTSessionSetProperty(vtctx->
session,
1213 kVTCompressionPropertyKey_PixelAspectRatio,
1223 "Error setting pixel aspect ratio to %d:%d: %d.\n",
1234 status = VTSessionSetProperty(vtctx->
session,
1235 kVTCompressionPropertyKey_TransferFunction,
1245 status = VTSessionSetProperty(vtctx->
session,
1246 kVTCompressionPropertyKey_YCbCrMatrix,
1256 status = VTSessionSetProperty(vtctx->
session,
1257 kVTCompressionPropertyKey_ColorPrimaries,
1266 status = VTSessionSetProperty(vtctx->
session,
1267 kCVImageBufferGammaLevelKey,
1276 status = VTSessionSetProperty(vtctx->
session,
1277 kVTCompressionPropertyKey_AllowFrameReordering,
1281 av_log(avctx,
AV_LOG_ERROR,
"Error setting 'allow frame reordering' property: %d\n", status);
1291 status = VTSessionSetProperty(vtctx->
session,
1292 compat_keys.kVTCompressionPropertyKey_H264EntropyMode,
1301 status = VTSessionSetProperty(vtctx->
session,
1310 status = VTCompressionSessionPrepareToEncodeFrames(vtctx->
session);
1321 CFMutableDictionaryRef enc_info;
1322 CFMutableDictionaryRef pixel_buffer_info;
1325 CFStringRef profile_level;
1326 CFNumberRef gamma_level =
NULL;
1342 av_log(avctx,
AV_LOG_WARNING,
"Cannot use B-frames with baseline profile. Output will not contain B-frames.\n");
1347 av_log(avctx,
AV_LOG_WARNING,
"CABAC entropy requires 'main' or 'high' profile, but baseline was requested. Encode will not use CABAC entropy.\n");
1358 enc_info = CFDictionaryCreateMutable(
1359 kCFAllocatorDefault,
1361 &kCFCopyStringDictionaryKeyCallBacks,
1362 &kCFTypeDictionaryValueCallBacks
1365 if (!enc_info)
return AVERROR(ENOMEM);
1367 #if !TARGET_OS_IPHONE 1369 CFDictionarySetValue(enc_info,
1370 compat_keys.kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
1373 CFDictionarySetValue(enc_info,
1374 compat_keys.kVTVideoEncoderSpecification_RequireHardwareAcceleratedVideoEncoder,
1377 CFDictionarySetValue(enc_info,
1378 compat_keys.kVTVideoEncoderSpecification_EnableHardwareAcceleratedVideoEncoder,
1388 pixel_buffer_info =
NULL;
1419 CFRelease(gamma_level);
1421 if (pixel_buffer_info)
1422 CFRelease(pixel_buffer_info);
1424 CFRelease(enc_info);
1432 CFBooleanRef has_b_frames_cfbool;
1442 if (status)
return status;
1444 status = VTSessionCopyProperty(vtctx->
session,
1445 kVTCompressionPropertyKey_AllowFrameReordering,
1446 kCFAllocatorDefault,
1447 &has_b_frames_cfbool);
1449 if (!status && has_b_frames_cfbool) {
1451 vtctx->
has_b_frames = CFBooleanGetValue(has_b_frames_cfbool);
1452 CFRelease(has_b_frames_cfbool);
1461 CFArrayRef attachments;
1462 CFDictionaryRef attachment;
1463 CFBooleanRef not_sync;
1466 attachments = CMSampleBufferGetSampleAttachmentsArray(buffer,
false);
1467 len = !attachments ? 0 : CFArrayGetCount(attachments);
1470 *is_key_frame =
true;
1474 attachment = CFArrayGetValueAtIndex(attachments, 0);
1476 if (CFDictionaryGetValueIfPresent(attachment,
1477 kCMSampleAttachmentKey_NotSync,
1478 (
const void **)¬_sync))
1480 *is_key_frame = !CFBooleanGetValue(not_sync);
1482 *is_key_frame =
true;
1503 size_t sei_payload_size = 0;
1504 int sei_payload_type = 0;
1506 uint8_t *nal_start = nal_data;
1511 nal_type = *nal_data & 0x1F;
1518 if (nal_data[nal_size - 1] == 0x80)
1521 while (nal_size > 0 && *nal_data > 0) {
1523 sei_payload_type += *nal_data;
1526 }
while (nal_size > 0 && *nal_data == 0xFF);
1534 sei_payload_size += *nal_data;
1537 }
while (nal_size > 0 && *nal_data == 0xFF);
1539 if (nal_size < sei_payload_size) {
1544 nal_data += sei_payload_size;
1545 nal_size -= sei_payload_size;
1548 *sei_end = nal_data;
1550 return nal_data - nal_start + 1;
1570 uint8_t* dst_end = dst + dst_size;
1571 const uint8_t* src_end = src + src_size;
1572 int start_at = dst_offset > 2 ? dst_offset - 2 : 0;
1574 for (i = start_at; i < dst_offset && i < dst_size; i++) {
1583 for (; src < src_end; src++, dst++) {
1585 int insert_ep3_byte = *src <= 3;
1586 if (insert_ep3_byte) {
1604 wrote_bytes = dst - dst_start;
1607 return -wrote_bytes;
1618 size_t remaining_sei_size = sei->
size;
1619 size_t remaining_dst_size = dst_size;
1624 if (!remaining_dst_size)
1627 while (sei_type && remaining_dst_size != 0) {
1628 int sei_byte = sei_type > 255 ? 255 : sei_type;
1631 sei_type -= sei_byte;
1633 remaining_dst_size--;
1639 while (remaining_sei_size && remaining_dst_size != 0) {
1640 int size_byte = remaining_sei_size > 255 ? 255 : remaining_sei_size;
1643 remaining_sei_size -= size_byte;
1645 remaining_dst_size--;
1648 if (remaining_dst_size < sei->
size)
1651 header_bytes = dst - sei_start;
1653 offset = header_bytes;
1659 if (bytes_written < 0)
1662 bytes_written += header_bytes;
1663 return bytes_written;
1687 size_t length_code_size,
1688 CMSampleBufferRef sample_buffer,
1693 size_t src_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
1694 size_t remaining_src_size = src_size;
1695 size_t remaining_dst_size = dst_size;
1696 size_t src_offset = 0;
1701 CMBlockBufferRef
block = CMSampleBufferGetDataBuffer(sample_buffer);
1703 if (length_code_size > 4) {
1707 while (remaining_src_size > 0) {
1708 size_t curr_src_len;
1709 size_t curr_dst_len;
1715 status = CMBlockBufferCopyDataBytes(block,
1724 status = CMBlockBufferCopyDataBytes(block,
1725 src_offset + length_code_size,
1736 for (i = 0; i < length_code_size; i++) {
1738 box_len |= size_buf[
i];
1751 remaining_dst_size--;
1756 remaining_dst_size);
1758 if (wrote_bytes < 0)
1761 remaining_dst_size -= wrote_bytes;
1762 dst_data += wrote_bytes;
1764 if (remaining_dst_size <= 0)
1770 remaining_dst_size--;
1775 curr_src_len = box_len + length_code_size;
1778 if (remaining_src_size < curr_src_len) {
1782 if (remaining_dst_size < curr_dst_len) {
1789 status = CMBlockBufferCopyDataBytes(block,
1790 src_offset + length_code_size,
1805 old_sei_length =
find_sei_end(avctx, dst_box, box_len, &new_sei);
1806 if (old_sei_length < 0)
1812 remaining_dst_size - old_sei_length);
1813 if (wrote_bytes < 0)
1816 if (new_sei + wrote_bytes >= dst_data + remaining_dst_size)
1819 new_sei[wrote_bytes++] = 0x80;
1820 extra_bytes = wrote_bytes - (dst_box + box_len - new_sei);
1822 dst_data += extra_bytes;
1823 remaining_dst_size -= extra_bytes;
1828 src_offset += curr_src_len;
1829 dst_data += curr_dst_len;
1831 remaining_src_size -= curr_src_len;
1832 remaining_dst_size -= curr_dst_len;
1853 if ((sei->
size % 255) == 0)
1856 return copied_size + sei->
size / 255 + 1 + type / 255 + 1;
1861 CMSampleBufferRef sample_buffer,
1870 size_t length_code_size;
1871 size_t header_size = 0;
1873 size_t out_buf_size;
1874 size_t sei_nalu_size = 0;
1876 int64_t time_base_num;
1880 CMVideoFormatDescriptionRef vid_fmt;
1885 if (status)
return status;
1890 vid_fmt = CMSampleBufferGetFormatDescription(sample_buffer);
1897 if (status)
return status;
1900 status =
count_nalus(length_code_size, sample_buffer, &nalu_count);
1908 sei_nalu_size =
sizeof(
start_code) + 1 + msg_size + 1;
1911 in_buf_size = CMSampleBufferGetTotalSampleSize(sample_buffer);
1912 out_buf_size = header_size +
1923 if(status)
return status;
1931 pkt->
data + header_size,
1932 pkt->
size - header_size
1944 pts = CMSampleBufferGetPresentationTimeStamp(sample_buffer);
1945 dts = CMSampleBufferGetDecodeTimeStamp (sample_buffer);
1947 if (CMTIME_IS_INVALID(dts)) {
1958 pkt->
pts = pts.value / time_base_num;
1959 pkt->
dts = dts.value / time_base_num - dts_delta;
1960 pkt->
size = out_buf_size;
1977 size_t *contiguous_buf_size)
1980 int av_format = frame->
format;
1990 "Could not get pixel format for color format '%s' range '%s'.\n",
2000 if (range_guessed) {
2005 "Color range not set for %s. Using MPEG range.\n",
2010 switch (av_format) {
2014 widths [0] = avctx->
width;
2015 heights[0] = avctx->
height;
2018 widths [1] = (avctx->
width + 1) / 2;
2019 heights[1] = (avctx->
height + 1) / 2;
2020 strides[1] = frame ? frame->
linesize[1] : (avctx->
width + 1) & -2;
2026 widths [0] = avctx->
width;
2027 heights[0] = avctx->
height;
2030 widths [1] = (avctx->
width + 1) / 2;
2031 heights[1] = (avctx->
height + 1) / 2;
2032 strides[1] = frame ? frame->
linesize[1] : (avctx->
width + 1) / 2;
2034 widths [2] = (avctx->
width + 1) / 2;
2035 heights[2] = (avctx->
height + 1) / 2;
2036 strides[2] = frame ? frame->
linesize[2] : (avctx->
width + 1) / 2;
2041 widths[0] = avctx->
width;
2042 heights[0] = avctx->
height;
2043 strides[0] = frame ? frame->
linesize[0] : (avctx->
width * 2 + 63) & -64;
2045 widths[1] = (avctx->
width + 1) / 2;
2046 heights[1] = (avctx->
height + 1) / 2;
2047 strides[1] = frame ? frame->
linesize[1] : ((avctx->
width + 1) / 2 + 63) & -64;
2054 "Could not get frame format info for color %d range %d.\n",
2061 *contiguous_buf_size = 0;
2062 for (i = 0; i < *plane_count; i++) {
2063 if (i < *plane_count - 1 &&
2064 frame->
data[i] + strides[i] * heights[i] != frame->
data[i + 1]) {
2065 *contiguous_buf_size = 0;
2069 *contiguous_buf_size += strides[
i] * heights[
i];
2078 CVPixelBufferRef cv_img,
2079 const size_t *plane_strides,
2080 const size_t *plane_rows)
2092 status = CVPixelBufferLockBaseAddress(cv_img, 0);
2097 "Error: Could not lock base address of CVPixelBuffer: %d.\n",
2102 if (CVPixelBufferIsPlanar(cv_img)) {
2103 plane_count = CVPixelBufferGetPlaneCount(cv_img);
2104 for (i = 0; frame->
data[
i]; i++) {
2105 if (i == plane_count) {
2106 CVPixelBufferUnlockBaseAddress(cv_img, 0);
2109 "Error: different number of planes in AVFrame and CVPixelBuffer.\n" 2115 dst_addr = (
uint8_t*)CVPixelBufferGetBaseAddressOfPlane(cv_img, i);
2117 dst_stride = CVPixelBufferGetBytesPerRowOfPlane(cv_img, i);
2118 src_stride = plane_strides[
i];
2119 rows = plane_rows[
i];
2121 if (dst_stride == src_stride) {
2122 memcpy(dst_addr, src_addr, src_stride * rows);
2124 copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
2126 for (j = 0; j < rows; j++) {
2127 memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
2132 if (frame->
data[1]) {
2133 CVPixelBufferUnlockBaseAddress(cv_img, 0);
2136 "Error: different number of planes in AVFrame and non-planar CVPixelBuffer.\n" 2142 dst_addr = (
uint8_t*)CVPixelBufferGetBaseAddress(cv_img);
2144 dst_stride = CVPixelBufferGetBytesPerRow(cv_img);
2145 src_stride = plane_strides[0];
2146 rows = plane_rows[0];
2148 if (dst_stride == src_stride) {
2149 memcpy(dst_addr, src_addr, src_stride * rows);
2151 copy_bytes = dst_stride < src_stride ? dst_stride : src_stride;
2153 for (j = 0; j < rows; j++) {
2154 memcpy(dst_addr + j * dst_stride, src_addr + j * src_stride, copy_bytes);
2159 status = CVPixelBufferUnlockBaseAddress(cv_img, 0);
2161 av_log(avctx,
AV_LOG_ERROR,
"Error: Could not unlock CVPixelBuffer base address: %d.\n", status);
2170 CVPixelBufferRef *cv_img)
2178 size_t contiguous_buf_size;
2179 CVPixelBufferPoolRef pix_buf_pool;
2185 *cv_img = (CVPixelBufferRef)frame->
data[3];
2192 memset(widths, 0,
sizeof(widths));
2193 memset(heights, 0,
sizeof(heights));
2194 memset(strides, 0,
sizeof(strides));
2204 &contiguous_buf_size
2211 "Error: Cannot convert format %d color_range %d: %d\n",
2220 pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->
session);
2221 if (!pix_buf_pool) {
2228 vtstatus = VTCompressionSessionPrepareToEncodeFrames(vtctx->
session);
2229 if (vtstatus == kVTInvalidSessionErr) {
2234 pix_buf_pool = VTCompressionSessionGetPixelBufferPool(vtctx->
session);
2236 if (!pix_buf_pool) {
2242 "kVTInvalidSessionErr error.\n");
2245 status = CVPixelBufferPoolCreatePixelBuffer(
NULL,
2251 av_log(avctx,
AV_LOG_ERROR,
"Could not create pixel buffer from pool: %d.\n", status);
2266 CFDictionaryRef* dict_out)
2268 CFDictionaryRef dict =
NULL;
2270 const void *keys[] = { kVTEncodeFrameOptionKey_ForceKeyFrame };
2271 const void *vals[] = { kCFBooleanTrue };
2273 dict = CFDictionaryCreate(
NULL, keys, vals, 1,
NULL,
NULL);
2274 if(!dict)
return AVERROR(ENOMEM);
2286 CFDictionaryRef frame_dict;
2287 CVPixelBufferRef cv_img =
NULL;
2292 if (status)
return status;
2301 if (vtctx->
a53_cc && side_data && side_data->
size) {
2316 status = VTCompressionSessionEncodeFrame(
2326 if (frame_dict) CFRelease(frame_dict);
2346 CMSampleBufferRef buf =
NULL;
2367 status = VTCompressionSessionCompleteFrames(vtctx->
session,
2385 if (status)
goto end_nopkt;
2386 if (!buf)
goto end_nopkt;
2394 if (status)
goto end_nopkt;
2406 CFStringRef profile_level,
2407 CFNumberRef gamma_level,
2408 CFDictionaryRef enc_info,
2409 CFDictionaryRef pixel_buffer_info)
2413 CVPixelBufferPoolRef pool =
NULL;
2414 CVPixelBufferRef pix_buf =
NULL;
2416 CMSampleBufferRef buf =
NULL;
2428 pool = VTCompressionSessionGetPixelBufferPool(vtctx->
session);
2434 status = CVPixelBufferPoolCreatePixelBuffer(
NULL,
2438 if(status != kCVReturnSuccess){
2444 status = VTCompressionSessionEncodeFrame(vtctx->
session,
2455 "Error sending frame for extradata: %d\n",
2462 status = VTCompressionSessionCompleteFrames(vtctx->
session,
2500 VTCompressionSessionCompleteFrames(vtctx->
session,
2541 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 2542 #define COMMON_OPTIONS \ 2543 { "allow_sw", "Allow software encoding", OFFSET(allow_sw), AV_OPT_TYPE_BOOL, \ 2544 { .i64 = 0 }, 0, 1, VE }, \ 2545 { "require_sw", "Require software encoding", OFFSET(require_sw), AV_OPT_TYPE_BOOL, \ 2546 { .i64 = 0 }, 0, 1, VE }, \ 2547 { "realtime", "Hint that encoding should happen in real-time if not faster (e.g. capturing from camera).", \ 2548 OFFSET(realtime), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \ 2549 { "frames_before", "Other frames will come before the frames in this session. This helps smooth concatenation issues.", \ 2550 OFFSET(frames_before), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, \ 2551 { "frames_after", "Other frames will come after the frames in this session. This helps smooth concatenation issues.", \ 2552 OFFSET(frames_after), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, 2554 #define OFFSET(x) offsetof(VTEncContext, x) 2563 {
"1.3",
"Level 1.3, only available with Baseline Profile", 0,
AV_OPT_TYPE_CONST, { .i64 = 13 }, INT_MIN, INT_MAX,
VE,
"level" },
2564 {
"3.0",
"Level 3.0", 0,
AV_OPT_TYPE_CONST, { .i64 = 30 }, INT_MIN, INT_MAX,
VE,
"level" },
2565 {
"3.1",
"Level 3.1", 0,
AV_OPT_TYPE_CONST, { .i64 = 31 }, INT_MIN, INT_MAX,
VE,
"level" },
2566 {
"3.2",
"Level 3.2", 0,
AV_OPT_TYPE_CONST, { .i64 = 32 }, INT_MIN, INT_MAX,
VE,
"level" },
2567 {
"4.0",
"Level 4.0", 0,
AV_OPT_TYPE_CONST, { .i64 = 40 }, INT_MIN, INT_MAX,
VE,
"level" },
2568 {
"4.1",
"Level 4.1", 0,
AV_OPT_TYPE_CONST, { .i64 = 41 }, INT_MIN, INT_MAX,
VE,
"level" },
2569 {
"4.2",
"Level 4.2", 0,
AV_OPT_TYPE_CONST, { .i64 = 42 }, INT_MIN, INT_MAX,
VE,
"level" },
2570 {
"5.0",
"Level 5.0", 0,
AV_OPT_TYPE_CONST, { .i64 = 50 }, INT_MIN, INT_MAX,
VE,
"level" },
2571 {
"5.1",
"Level 5.1", 0,
AV_OPT_TYPE_CONST, { .i64 = 51 }, INT_MIN, INT_MAX,
VE,
"level" },
2572 {
"5.2",
"Level 5.2", 0,
AV_OPT_TYPE_CONST, { .i64 = 52 }, INT_MIN, INT_MAX,
VE,
"level" },
2594 .
name =
"h264_videotoolbox",
2604 .priv_class = &h264_videotoolbox_class,
2626 .
name =
"hevc_videotoolbox",
2636 .priv_class = &hevc_videotoolbox_class,
2639 .wrapper_name =
"videotoolbox",
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
ITU-R BT2020 for 12-bit system.
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AV_NUM_DATA_POINTERS
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
pthread_cond_t cv_sample_sent
This structure describes decoded (raw) audio or video data.
#define pthread_mutex_lock(a)
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
"Linear transfer characteristics"
#define AV_LOG_WARNING
Something somehow does not look correct.
int64_t bit_rate
the average bitrate
#define LIBAVUTIL_VERSION_INT
hardware decoding through Videotoolbox
static av_cold int init(AVCodecContext *avctx)
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...
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 ...
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
enum AVColorRange color_range
MPEG vs JPEG YUV range.
const char * av_default_item_name(void *ptr)
Return the context name.
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel...
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
enum AVMediaType codec_type
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
AVColorTransferCharacteristic
Color Transfer Characteristic.
functionally identical to above
const char * av_color_space_name(enum AVColorSpace space)
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
#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_assert0(cond)
assert() equivalent, that is always enabled.
int ff_alloc_packet2(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int64_t min_size)
Check AVPacket size and/or allocate data.
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
The exact code depends on how similar the blocks are and how related they are to the block
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
const char * av_color_range_name(enum AVColorRange range)
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Structure to hold side data for an AVFrame.
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
AVColorRange
Visual content value range.
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
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.
AVColorPrimaries
Chromaticity coordinates of the source primaries.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
H.264 common definitions.
AVCodecID
Identify the syntax and semantics of the bitstream.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int has_b_frames
Size of the frame reordering buffer in the decoder.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
enum AVColorRange color_range
MPEG vs JPEG YUV range.
ATSC A53 Part 4 Closed Captions.
int flags
AV_CODEC_FLAG_*.
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B
simple assert() macros that are a bit more flexible than ISO C assert().
const char * name
Name of the codec implementation.
static int get_frame(AVFilterContext *ctx, int is_second)
int flags
A combination of AV_PKT_FLAG values.
const char * av_color_primaries_name(enum AVColorPrimaries primaries)
VTCompressionSessionRef session
CFStringRef color_primaries
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
enum AVPictureType pict_type
Picture type of the frame.
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
CMSampleBufferRef cm_buffer
int width
picture width / height.
ITU-R BT2020 non-constant luminance system.
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
#define pthread_mutex_unlock(a)
like NV12, with 10bpp per component, data in the high bits, zeros in the low bits, little-endian
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
main external API structure.
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Describe the class of an AVClass context structure.
CFStringRef transfer_function
enum AVColorSpace colorspace
YUV colorspace type.
Rational number (pair of numerator and denominator).
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
they must not be accessed directly The fifo field contains the frames that are queued in the input for processing by the filter The status_in and status_out fields contains the queued status(EOF or error) of the link
static enum AVPixelFormat pix_fmts[]
#define flags(name, subs,...)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Narrow or limited range content.
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
getParameterSetAtIndex get_param_set_func
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
common internal api header.
const char * av_color_transfer_name(enum AVColorTransferCharacteristic transfer)
static av_always_inline int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
static int FUNC() sei(CodedBitstreamContext *ctx, RWContext *rw, H264RawSEI *current)
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
ARIB STD-B67, known as "Hybrid log-gamma".
#define PTHREAD_ONCE_INIT
ITU-R BT2020 for 10-bit system.
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
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.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
#define AVERROR_EXTERNAL
Generic error in an external library.
AVPixelFormat
Pixel format.
This structure stores compressed data.
static av_always_inline int pthread_once(pthread_once_t *once_control, void(*init_routine)(void))
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
int64_t rc_max_rate
maximum bitrate