24 #include "config_components.h"
42 #include <Availability.h>
43 #include <AvailabilityMacros.h>
44 #include <TargetConditionals.h>
46 #ifndef kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder
47 # define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder CFSTR("RequireHardwareAcceleratedVideoDecoder")
49 #ifndef kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder
50 # define kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder CFSTR("EnableHardwareAcceleratedVideoDecoder")
53 #if !HAVE_KCMVIDEOCODECTYPE_HEVC
57 #if !HAVE_KCMVIDEOCODECTYPE_VP9
61 #if !HAVE_KCMVIDEOCODECTYPE_AV1
65 #define VIDEOTOOLBOX_ESDS_EXTRADATA_PADDING 12
76 CVPixelBufferRelease(
ref->pixbuf);
132 frame->crop_right = 0;
133 frame->crop_left = 0;
135 frame->crop_bottom = 0;
140 frame->data[3] = (uint8_t*)
ref->pixbuf;
142 if (
ref->hw_frames_ctx) {
145 if (!
frame->hw_frames_ctx)
172 fdd =
frame->private_ref;
182 #define AV_W8(p, v) *(p) = (v)
190 for (
i = 0;
i < src_size;
i++) {
191 if (
i + 2 < src_size &&
193 src[
i + 1] == 0x00 &&
194 src[
i + 2] <= 0x03) {
221 int vt_extradata_size;
222 uint8_t *vt_extradata;
224 vt_extradata_size = 6 + 2 + sps_size + 3 + pps_size;
225 vt_extradata =
av_malloc(vt_extradata_size);
233 AV_W8(
p + 1,
h->ps.sps->data[1]);
234 AV_W8(
p + 2,
h->ps.sps->data[2]);
235 AV_W8(
p + 3,
h->ps.sps->data[3]);
251 memcpy(vtctx->
sps,
h->ps.sps->data + 1, 3);
253 data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
261 int i, num_vps = 0, num_sps = 0, num_pps = 0;
267 uint8_t parallelismType;
270 int vt_extradata_size = 23 + 3 + 3 + 3;
271 uint8_t *vt_extradata;
273 #define COUNT_SIZE_PS(T, t) \
274 for (i = 0; i < HEVC_MAX_##T##PS_COUNT; i++) { \
275 if (h->ps.t##ps_list[i]) { \
276 const HEVC##T##PS *lps = h->ps.t##ps_list[i]; \
277 vt_extradata_size += 2 + escape_ps(NULL, lps->data, lps->data_size); \
286 vt_extradata =
av_malloc(vt_extradata_size);
304 for (
i = 0;
i < 4;
i++) {
339 else if (
pps->entropy_coding_sync_enabled_flag &&
pps->tiles_enabled_flag)
341 else if (
pps->entropy_coding_sync_enabled_flag)
343 else if (
pps->tiles_enabled_flag)
347 AV_W8(
p + 15, 0xfc | parallelismType);
353 AV_W8(
p + 16,
sps->chroma_format_idc | 0xfc);
359 AV_W8(
p + 17, (
sps->bit_depth - 8) | 0xf8);
365 AV_W8(
p + 18, (
sps->bit_depth_chroma - 8) | 0xf8);
377 sps->max_sub_layers << 3 |
378 sps->temporal_id_nesting << 2 |
386 #define APPEND_PS(T, t) \
393 HEVC_NAL_##T##PS & 0x3f); \
395 AV_WB16(p + 1, num_##t##ps); \
397 for (i = 0; i < HEVC_MAX_##T##PS_COUNT; i++) { \
398 if (h->ps.t##ps_list[i]) { \
399 const HEVC##T##PS *lps = h->ps.t##ps_list[i]; \
400 int size = escape_ps(p + 2, lps->data, lps->data_size); \
414 data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
427 if (
h->is_avc == 1) {
444 memcpy(vtctx->
sps,
h->ps.sps->data + 1, 3);
492 #if CONFIG_VIDEOTOOLBOX
519 VTDecompressionSessionInvalidate(videotoolbox->
session);
520 CFRelease(videotoolbox->
session);
533 CVPixelBufferRelease(vtctx->
frame);
536 videotoolbox_stop(avctx);
547 CVPixelBufferRef pixbuf = (CVPixelBufferRef)vtctx->
frame;
548 OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf);
550 int width = CVPixelBufferGetWidth(pixbuf);
551 int height = CVPixelBufferGetHeight(pixbuf);
565 CVPixelBufferRelease(
ref->pixbuf);
589 hw_ctx = hw_frames->
hwctx;
604 if (!
ref->hw_frames_ctx)
610 static void videotoolbox_write_mp4_descr_length(
PutByteContext *pb,
int length)
615 for (
i = 3;
i >= 0;
i--) {
616 b = (length >> (
i * 7)) & 0x7F;
620 bytestream2_put_byteu(pb,
b);
624 static CFDataRef videotoolbox_esds_extradata_create(
AVCodecContext *avctx)
627 uint8_t *rw_extradata;
638 bytestream2_put_byteu(&pb, 0);
642 bytestream2_put_byteu(&pb, 0x03);
643 videotoolbox_write_mp4_descr_length(&pb, full_size);
645 bytestream2_put_byteu(&pb, 0);
648 bytestream2_put_byteu(&pb, 0x04);
649 videotoolbox_write_mp4_descr_length(&pb, config_size);
650 bytestream2_put_byteu(&pb, 32);
651 bytestream2_put_byteu(&pb, 0x11);
657 bytestream2_put_byteu(&pb, 0x05);
663 bytestream2_put_byteu(&pb, 0x06);
664 bytestream2_put_byteu(&pb, 0x01);
665 bytestream2_put_byteu(&pb, 0x02);
669 data = CFDataCreate(kCFAllocatorDefault, rw_extradata,
s);
675 static CMSampleBufferRef videotoolbox_sample_buffer_create(CMFormatDescriptionRef fmt_desc,
680 CMBlockBufferRef block_buf;
681 CMSampleBufferRef sample_buf;
686 status = CMBlockBufferCreateWithMemoryBlock(kCFAllocatorDefault,
697 status = CMSampleBufferCreate(kCFAllocatorDefault,
712 CFRelease(block_buf);
717 static void videotoolbox_decoder_callback(
void *opaque,
718 void *sourceFrameRefCon,
720 VTDecodeInfoFlags
flags,
721 CVImageBufferRef image_buffer,
728 CVPixelBufferRelease(vtctx->
frame);
738 "vt decoder cb: output image buffer is null: %i, reconfig %d\n",
743 vtctx->
frame = CVPixelBufferRetain(image_buffer);
746 static OSStatus videotoolbox_session_decode_frame(
AVCodecContext *avctx)
749 CMSampleBufferRef sample_buf;
753 sample_buf = videotoolbox_sample_buffer_create(videotoolbox->
cm_fmt_desc,
760 status = VTDecompressionSessionDecodeFrame(videotoolbox->
session,
766 status = VTDecompressionSessionWaitForAsynchronousFrames(videotoolbox->
session);
768 CFRelease(sample_buf);
773 static CMVideoFormatDescriptionRef videotoolbox_format_desc_create(CMVideoCodecType
codec_type,
774 CFDictionaryRef decoder_spec,
778 CMFormatDescriptionRef cm_fmt_desc;
781 status = CMVideoFormatDescriptionCreate(kCFAllocatorDefault,
794 static CFDictionaryRef videotoolbox_buffer_attributes_create(
int width,
798 CFMutableDictionaryRef buffer_attributes;
799 CFMutableDictionaryRef io_surface_properties;
800 CFNumberRef cv_pix_fmt;
804 w = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &
width);
805 h = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &
height);
806 cv_pix_fmt = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &
pix_fmt);
808 buffer_attributes = CFDictionaryCreateMutable(kCFAllocatorDefault,
810 &kCFTypeDictionaryKeyCallBacks,
811 &kCFTypeDictionaryValueCallBacks);
812 io_surface_properties = CFDictionaryCreateMutable(kCFAllocatorDefault,
814 &kCFTypeDictionaryKeyCallBacks,
815 &kCFTypeDictionaryValueCallBacks);
818 CFDictionarySetValue(buffer_attributes, kCVPixelBufferPixelFormatTypeKey, cv_pix_fmt);
819 CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfacePropertiesKey, io_surface_properties);
820 CFDictionarySetValue(buffer_attributes, kCVPixelBufferWidthKey,
w);
821 CFDictionarySetValue(buffer_attributes, kCVPixelBufferHeightKey,
h);
823 CFDictionarySetValue(buffer_attributes, kCVPixelBufferOpenGLESCompatibilityKey, kCFBooleanTrue);
825 CFDictionarySetValue(buffer_attributes, kCVPixelBufferIOSurfaceOpenGLTextureCompatibilityKey, kCFBooleanTrue);
828 CFRelease(io_surface_properties);
829 CFRelease(cv_pix_fmt);
833 return buffer_attributes;
836 static CFDictionaryRef videotoolbox_decoder_config_create(CMVideoCodecType
codec_type,
839 CFMutableDictionaryRef avc_info;
842 CFMutableDictionaryRef config_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
844 &kCFTypeDictionaryKeyCallBacks,
845 &kCFTypeDictionaryValueCallBacks);
847 CFDictionarySetValue(config_info,
856 avc_info = CFDictionaryCreateMutable(kCFAllocatorDefault,
858 &kCFTypeDictionaryKeyCallBacks,
859 &kCFTypeDictionaryValueCallBacks);
862 case kCMVideoCodecType_MPEG4Video :
864 data = videotoolbox_esds_extradata_create(avctx);
866 CFDictionarySetValue(avc_info, CFSTR(
"esds"),
data);
868 case kCMVideoCodecType_H264 :
871 CFDictionarySetValue(avc_info, CFSTR(
"avcC"),
data);
876 CFDictionarySetValue(avc_info, CFSTR(
"hvcC"),
data);
878 #if CONFIG_VP9_VIDEOTOOLBOX_HWACCEL
882 CFDictionarySetValue(avc_info, CFSTR(
"vpcC"),
data);
885 #if CONFIG_AV1_VIDEOTOOLBOX_HWACCEL
889 CFDictionarySetValue(avc_info, CFSTR(
"av1C"),
data);
896 CFDictionarySetValue(config_info,
897 kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms,
911 VTDecompressionOutputCallbackRecord decoder_cb;
912 CFDictionaryRef decoder_spec;
913 CFDictionaryRef buf_attr;
944 case MKTAG(
'a',
'p',
'c',
'o'):
945 case
MKTAG(
'a',
'p',
'c',
's'):
946 case
MKTAG(
'a',
'p',
'c',
'n'):
947 case
MKTAG(
'a',
'p',
'c',
'h'):
948 case
MKTAG(
'a',
'p',
'4',
'h'):
949 case
MKTAG(
'a',
'p',
'4',
'x'):
950 videotoolbox->cm_codec_type =
av_bswap32(avctx->codec_tag);
967 #if defined(MAC_OS_X_VERSION_10_9) && !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9) && AV_HAS_BUILTIN(__builtin_available)
969 if (__builtin_available(macOS 10.9, *)) {
970 VTRegisterProfessionalVideoWorkflowVideoDecoders();
975 #if defined(MAC_OS_VERSION_11_0) && !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0) && AV_HAS_BUILTIN(__builtin_available)
976 if (__builtin_available(macOS 11.0, *)) {
977 VTRegisterSupplementalVideoDecoderIfAvailable(videotoolbox->
cm_codec_type);
981 decoder_spec = videotoolbox_decoder_config_create(videotoolbox->
cm_codec_type, avctx);
994 CFRelease(decoder_spec);
1000 buf_attr = videotoolbox_buffer_attributes_create(avctx->
width,
1004 decoder_cb.decompressionOutputCallback = videotoolbox_decoder_callback;
1015 CFRelease(decoder_spec);
1017 CFRelease(buf_attr);
1020 case kVTVideoDecoderNotAvailableNowErr:
1023 case kVTVideoDecoderUnsupportedDataFormatErr:
1026 case kVTCouldNotFindVideoDecoderErr:
1029 case kVTVideoDecoderMalfunctionErr:
1032 case kVTVideoDecoderBadDataErr:
1043 static const char *videotoolbox_error_string(OSStatus
status)
1046 case kVTVideoDecoderBadDataErr:
1048 case kVTVideoDecoderMalfunctionErr:
1049 return "decoder malfunction";
1050 case kVTInvalidSessionErr:
1051 return "invalid session";
1065 videotoolbox_stop(avctx);
1066 if (videotoolbox_start(avctx) != 0) {
1074 status = videotoolbox_session_decode_frame(avctx);
1076 if (
status == kVTVideoDecoderMalfunctionErr ||
status == kVTInvalidSessionErr)
1085 return videotoolbox_buffer_create(avctx,
frame);
1106 frame->crop_right = 0;
1107 frame->crop_left = 0;
1108 frame->crop_top = 0;
1109 frame->crop_bottom = 0;
1122 static int videotoolbox_hevc_decode_params(
AVCodecContext *avctx,
1167 static int videotoolbox_prores_start_frame(
AVCodecContext *avctx,
1176 if (!
ctx->first_field)
1182 static int videotoolbox_prores_decode_slice(
AVCodecContext *avctx,
1194 if (!
ctx->first_field)
1200 static int videotoolbox_prores_raw_start_frame(
AVCodecContext *avctx,
1210 static int videotoolbox_prores_raw_decode_slice(
AVCodecContext *avctx,
1217 static int videotoolbox_prores_raw_end_frame(
AVCodecContext *avctx)
1239 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE
1244 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR10BIPLANARVIDEORANGE
1246 #if HAVE_KCVPIXELFORMATTYPE_444YPCBCR8BIPLANARVIDEORANGE
1253 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR10BIPLANARVIDEORANGE
1255 #if HAVE_KCVPIXELFORMATTYPE_422YPCBCR8BIPLANARVIDEORANGE
1262 #if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
1278 if (cv_pix_fmt_type == 0) {
1279 cv_pix_fmt_type = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
1281 ret->cv_pix_fmt_type = cv_pix_fmt_type;
1299 return videotoolbox_start(avctx);
1303 "Either hw_frames_ctx or hw_device_ctx must be set.\n");
1324 hw_frames->
sw_format = videotoolbox_best_pixel_format(avctx);
1327 hw_ctx = hw_frames->
hwctx;
1350 "Failed to map underlying FFmpeg pixel format %s (%s range) to "
1351 "a VideoToolbox format!\n",
1352 attempted_format ? attempted_format->
name :
"<unknown>",
1358 err = videotoolbox_start(avctx);
1377 frames_ctx->
sw_format = videotoolbox_best_pixel_format(avctx);
1383 .
p.
name =
"h263_videotoolbox",
1388 .start_frame = videotoolbox_mpeg_start_frame,
1389 .decode_slice = videotoolbox_mpeg_decode_slice,
1390 .end_frame = videotoolbox_mpeg_end_frame,
1398 .
p.
name =
"hevc_videotoolbox",
1403 .start_frame = videotoolbox_hevc_start_frame,
1404 .decode_slice = videotoolbox_hevc_decode_slice,
1405 .decode_params = videotoolbox_hevc_decode_params,
1406 .end_frame = videotoolbox_hevc_end_frame,
1414 .
p.
name =
"h264_videotoolbox",
1422 .end_frame = videotoolbox_h264_end_frame,
1430 .
p.
name =
"mpeg1_videotoolbox",
1435 .start_frame = videotoolbox_mpeg_start_frame,
1436 .decode_slice = videotoolbox_mpeg_decode_slice,
1437 .end_frame = videotoolbox_mpeg_end_frame,
1445 .
p.
name =
"mpeg2_videotoolbox",
1450 .start_frame = videotoolbox_mpeg_start_frame,
1451 .decode_slice = videotoolbox_mpeg_decode_slice,
1452 .end_frame = videotoolbox_mpeg_end_frame,
1460 .
p.
name =
"mpeg4_videotoolbox",
1465 .start_frame = videotoolbox_mpeg_start_frame,
1466 .decode_slice = videotoolbox_mpeg_decode_slice,
1467 .end_frame = videotoolbox_mpeg_end_frame,
1475 .
p.
name =
"prores_videotoolbox",
1480 .start_frame = videotoolbox_prores_start_frame,
1481 .decode_slice = videotoolbox_prores_decode_slice,
1482 .end_frame = videotoolbox_prores_end_frame,
1490 .
p.
name =
"prores_raw_videotoolbox",
1495 .start_frame = videotoolbox_prores_raw_start_frame,
1496 .decode_slice = videotoolbox_prores_raw_decode_slice,
1497 .end_frame = videotoolbox_prores_raw_end_frame,