History

lavc/videotoolboxenc: add ProRes support

rcombs committed 4 years ago

Commit 18192161 parent 88d804b6 files · +120 −7Browse files

Unified · Split

6 files
  1. Changelog +1 −0
  2. configure +2 −0
  3. libavcodec/Makefile +1 −0
  4. libavcodec/allcodecs.c +1 −0
  5. libavcodec/version.h +1 −1
  6. libavcodec/videotoolboxenc.c +114 −6
Changelog+1−0
@@ -42,6 +42,7 @@ version <next>: · 41 unmodified lines
42- vflip_vulkan, hflip_vulkan and flip_vulkan filters42- vflip_vulkan, hflip_vulkan and flip_vulkan filters
43- adynamicequalizer audio filter43- adynamicequalizer audio filter
44- yadif_videotoolbox filter44- yadif_videotoolbox filter
45- VideoToolbox ProRes encoder
45 46
46 47
47version 4.4:48version 4.4:
configure+2−0
@@ -3306,6 +3306,8 @@ h264_videotoolbox_encoder_deps="pthreads" · 3305 unmodified lines
3306h264_videotoolbox_encoder_select="atsc_a53 videotoolbox_encoder"3306h264_videotoolbox_encoder_select="atsc_a53 videotoolbox_encoder"
3307hevc_videotoolbox_encoder_deps="pthreads"3307hevc_videotoolbox_encoder_deps="pthreads"
3308hevc_videotoolbox_encoder_select="atsc_a53 videotoolbox_encoder"3308hevc_videotoolbox_encoder_select="atsc_a53 videotoolbox_encoder"
3309prores_videotoolbox_encoder_deps="pthreads"
3310prores_videotoolbox_encoder_select="videotoolbox_encoder"
3309libaom_av1_decoder_deps="libaom"3311libaom_av1_decoder_deps="libaom"
3310libaom_av1_encoder_deps="libaom"3312libaom_av1_encoder_deps="libaom"
3311libaom_av1_encoder_select="extract_extradata_bsf"3313libaom_av1_encoder_select="extract_extradata_bsf"
libavcodec/Makefile+1−0
@@ -565,6 +565,7 @@ OBJS-$(CONFIG_PRORES_DECODER) += proresdec2.o proresdsp.o proresdata.o · 564 unmodified lines
565OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o proresdata.o565OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o proresdata.o
566OBJS-$(CONFIG_PRORES_AW_ENCODER) += proresenc_anatoliy.o proresdata.o566OBJS-$(CONFIG_PRORES_AW_ENCODER) += proresenc_anatoliy.o proresdata.o
567OBJS-$(CONFIG_PRORES_KS_ENCODER) += proresenc_kostya.o proresdata.o567OBJS-$(CONFIG_PRORES_KS_ENCODER) += proresenc_kostya.o proresdata.o
568OBJS-$(CONFIG_PRORES_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
568OBJS-$(CONFIG_PROSUMER_DECODER) += prosumer.o569OBJS-$(CONFIG_PROSUMER_DECODER) += prosumer.o
569OBJS-$(CONFIG_PSD_DECODER) += psd.o570OBJS-$(CONFIG_PSD_DECODER) += psd.o
570OBJS-$(CONFIG_PTX_DECODER) += ptx.o571OBJS-$(CONFIG_PTX_DECODER) += ptx.o
libavcodec/allcodecs.c+1−0
@@ -837,6 +837,7 @@ extern const AVCodec ff_mpeg4_cuvid_decoder; · 836 unmodified lines
837extern const AVCodec ff_mpeg4_mediacodec_decoder;837extern const AVCodec ff_mpeg4_mediacodec_decoder;
838extern const AVCodec ff_mpeg4_omx_encoder;838extern const AVCodec ff_mpeg4_omx_encoder;
839extern const AVCodec ff_mpeg4_v4l2m2m_encoder;839extern const AVCodec ff_mpeg4_v4l2m2m_encoder;
840extern const AVCodec ff_prores_videotoolbox_encoder;
840extern const AVCodec ff_vc1_cuvid_decoder;841extern const AVCodec ff_vc1_cuvid_decoder;
841extern const AVCodec ff_vp8_cuvid_decoder;842extern const AVCodec ff_vp8_cuvid_decoder;
842extern const AVCodec ff_vp8_mediacodec_decoder;843extern const AVCodec ff_vp8_mediacodec_decoder;
libavcodec/version.h+1−1
@@ -28,7 +28,7 @@ · 27 unmodified lines
28#include "libavutil/version.h"28#include "libavutil/version.h"
29 29
30#define LIBAVCODEC_VERSION_MAJOR 5930#define LIBAVCODEC_VERSION_MAJOR 59
31#define LIBAVCODEC_VERSION_MINOR 1431#define LIBAVCODEC_VERSION_MINOR 15
32#define LIBAVCODEC_VERSION_MICRO 10032#define LIBAVCODEC_VERSION_MICRO 100
33 33
34#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \34#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
libavcodec/videotoolboxenc.c+114−6
@@ -407,6 +407,7 @@ static int count_nalus(size_t length_code_size, · 406 unmodified lines
407}407}
408 408
409static CMVideoCodecType get_cm_codec_type(AVCodecContext *avctx,409static CMVideoCodecType get_cm_codec_type(AVCodecContext *avctx,
410 int64_t profile,
410 double alpha_quality)411 double alpha_quality)
411{412{
412 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt == AV_PIX_FMT_VIDEOTOOLBOX ? avctx->sw_pix_fmt : avctx->pix_fmt);413 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt == AV_PIX_FMT_VIDEOTOOLBOX ? avctx->sw_pix_fmt : avctx->pix_fmt);
@@ -417,6 +418,31 @@ static CMVideoCodecType get_cm_codec_type(AVCodecContext *avctx, · 4 unmodified lines
417 return kCMVideoCodecType_HEVCWithAlpha;418 return kCMVideoCodecType_HEVCWithAlpha;
418 }419 }
419 return kCMVideoCodecType_HEVC;420 return kCMVideoCodecType_HEVC;
421 case AV_CODEC_ID_PRORES:
422 switch (profile) {
423 case FF_PROFILE_PRORES_PROXY:
424 return MKBETAG('a','p','c','o'); // kCMVideoCodecType_AppleProRes422Proxy
425 case FF_PROFILE_PRORES_LT:
426 return MKBETAG('a','p','c','s'); // kCMVideoCodecType_AppleProRes422LT
427 case FF_PROFILE_PRORES_STANDARD:
428 return MKBETAG('a','p','c','n'); // kCMVideoCodecType_AppleProRes422
429 case FF_PROFILE_PRORES_HQ:
430 return MKBETAG('a','p','c','h'); // kCMVideoCodecType_AppleProRes422HQ
431 case FF_PROFILE_PRORES_4444:
432 return MKBETAG('a','p','4','h'); // kCMVideoCodecType_AppleProRes4444
433 case FF_PROFILE_PRORES_XQ:
434 return MKBETAG('a','p','4','x'); // kCMVideoCodecType_AppleProRes4444XQ
435
436 default:
437 av_log(avctx, AV_LOG_ERROR, "Unknown profile ID: %"PRId64", using auto\n", profile);
438 case FF_PROFILE_UNKNOWN:
439 if (desc &&
440 ((desc->flags & AV_PIX_FMT_FLAG_ALPHA) ||
441 desc->log2_chroma_w == 0))
442 return MKBETAG('a','p','4','h'); // kCMVideoCodecType_AppleProRes4444
443 else
444 return MKBETAG('a','p','c','n'); // kCMVideoCodecType_AppleProRes422
445 }
420 default: return 0;446 default: return 0;
421 }447 }
422}448}
@@ -1102,7 +1128,7 @@ static int vtenc_create_encoder(AVCodecContext *avctx, · 679 unmodified lines
1102 kVTCompressionPropertyKey_Quality,1128 kVTCompressionPropertyKey_Quality,
1103 quality_num);1129 quality_num);
1104 CFRelease(quality_num);1130 CFRelease(quality_num);
1105 } else {1131 } else if (avctx->codec_id != AV_CODEC_ID_PRORES) {
1106 bit_rate_num = CFNumberCreate(kCFAllocatorDefault,1132 bit_rate_num = CFNumberCreate(kCFAllocatorDefault,
1107 kCFNumberSInt32Type,1133 kCFNumberSInt32Type,
1108 &bit_rate);1134 &bit_rate);
@@ -1189,7 +1215,7 @@ static int vtenc_create_encoder(AVCodecContext *avctx, · 80 unmodified lines
1189 }1215 }
1190 }1216 }
1191 1217
1192 if (avctx->gop_size > 0) {1218 if (avctx->gop_size > 0 && avctx->codec_id != AV_CODEC_ID_PRORES) {
1193 CFNumberRef interval = CFNumberCreate(kCFAllocatorDefault,1219 CFNumberRef interval = CFNumberCreate(kCFAllocatorDefault,
1194 kCFNumberIntType,1220 kCFNumberIntType,
1195 &avctx->gop_size);1221 &avctx->gop_size);
@@ -1338,7 +1364,7 @@ static int vtenc_create_encoder(AVCodecContext *avctx, · 142 unmodified lines
1338 }1364 }
1339 }1365 }
1340 1366
1341 if (!vtctx->has_b_frames) {1367 if (!vtctx->has_b_frames && avctx->codec_id != AV_CODEC_ID_PRORES) {
1342 status = VTSessionSetProperty(vtctx->session,1368 status = VTSessionSetProperty(vtctx->session,
1343 kVTCompressionPropertyKey_AllowFrameReordering,1369 kVTCompressionPropertyKey_AllowFrameReordering,
1344 kCFBooleanFalse);1370 kCFBooleanFalse);
@@ -1388,16 +1414,24 @@ static int vtenc_configure_encoder(AVCodecContext *avctx) · 43 unmodified lines
1388 CFMutableDictionaryRef pixel_buffer_info;1414 CFMutableDictionaryRef pixel_buffer_info;
1389 CMVideoCodecType codec_type;1415 CMVideoCodecType codec_type;
1390 VTEncContext *vtctx = avctx->priv_data;1416 VTEncContext *vtctx = avctx->priv_data;
1391 CFStringRef profile_level;1417 CFStringRef profile_level = NULL;
1392 CFNumberRef gamma_level = NULL;1418 CFNumberRef gamma_level = NULL;
1393 int status;1419 int status;
1394 1420
1395 codec_type = get_cm_codec_type(avctx, vtctx->alpha_quality);1421 codec_type = get_cm_codec_type(avctx, vtctx->profile, vtctx->alpha_quality);
1396 if (!codec_type) {1422 if (!codec_type) {
1397 av_log(avctx, AV_LOG_ERROR, "Error: no mapping for AVCodecID %d\n", avctx->codec_id);1423 av_log(avctx, AV_LOG_ERROR, "Error: no mapping for AVCodecID %d\n", avctx->codec_id);
1398 return AVERROR(EINVAL);1424 return AVERROR(EINVAL);
1399 }1425 }
1400 1426
1427#if defined(MAC_OS_X_VERSION_10_9) && !TARGET_OS_IPHONE && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_9)
1428 if (avctx->codec_id == AV_CODEC_ID_PRORES) {
1429 if (__builtin_available(macOS 10.10, *)) {
1430 VTRegisterProfessionalVideoWorkflowVideoEncoders();
1431 }
1432 }
1433#endif
1434
1401 vtctx->codec_id = avctx->codec_id;1435 vtctx->codec_id = avctx->codec_id;
1402 1436
1403 if (vtctx->codec_id == AV_CODEC_ID_H264) {1437 if (vtctx->codec_id == AV_CODEC_ID_H264) {
@@ -1415,12 +1449,14 @@ static int vtenc_configure_encoder(AVCodecContext *avctx) · 11 unmodified lines
1415 }1449 }
1416 1450
1417 if (!get_vt_h264_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);1451 if (!get_vt_h264_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);
1418 } else {1452 } else if (vtctx->codec_id == AV_CODEC_ID_HEVC) {
1419 vtctx->get_param_set_func = compat_keys.CMVideoFormatDescriptionGetHEVCParameterSetAtIndex;1453 vtctx->get_param_set_func = compat_keys.CMVideoFormatDescriptionGetHEVCParameterSetAtIndex;
1420 if (!vtctx->get_param_set_func) return AVERROR(EINVAL);1454 if (!vtctx->get_param_set_func) return AVERROR(EINVAL);
1421 if (!get_vt_hevc_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);1455 if (!get_vt_hevc_profile_level(avctx, &profile_level)) return AVERROR(EINVAL);
1422 // HEVC has b-byramid1456 // HEVC has b-byramid
1423 vtctx->has_b_frames = avctx->max_b_frames > 0 ? 2 : 0;1457 vtctx->has_b_frames = avctx->max_b_frames > 0 ? 2 : 0;
1458 } else if (vtctx->codec_id == AV_CODEC_ID_PRORES) {
1459 avctx->codec_tag = av_bswap32(codec_type);
1424 }1460 }
1425 1461
1426 enc_info = CFDictionaryCreateMutable(1462 enc_info = CFDictionaryCreateMutable(
@@ -2601,6 +2637,39 @@ static const enum AVPixelFormat hevc_pix_fmts[] = { · 1174 unmodified lines
2601 AV_PIX_FMT_NONE2637 AV_PIX_FMT_NONE
2602};2638};
2603 2639
2640static const enum AVPixelFormat prores_pix_fmts[] = {
2641 AV_PIX_FMT_VIDEOTOOLBOX,
2642 AV_PIX_FMT_YUV420P,
2643#ifdef kCFCoreFoundationVersionNumber10_7
2644 AV_PIX_FMT_NV12,
2645 AV_PIX_FMT_AYUV64,
2646#endif
2647 AV_PIX_FMT_UYVY422,
2648#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
2649 AV_PIX_FMT_P010,
2650#endif
2651#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR8BIPLANARVIDEORANGE
2652 AV_PIX_FMT_NV16,
2653#endif
2654#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR10BIPLANARVIDEORANGE
2655 AV_PIX_FMT_P210,
2656#endif
2657#if HAVE_KCVPIXELFORMATTYPE_422YPCBCR16BIPLANARVIDEORANGE
2658 AV_PIX_FMT_P216,
2659#endif
2660#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR8BIPLANARVIDEORANGE
2661 AV_PIX_FMT_NV24,
2662#endif
2663#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR10BIPLANARVIDEORANGE
2664 AV_PIX_FMT_P410,
2665#endif
2666#if HAVE_KCVPIXELFORMATTYPE_444YPCBCR16BIPLANARVIDEORANGE
2667 AV_PIX_FMT_P416,
2668#endif
2669 AV_PIX_FMT_BGRA,
2670 AV_PIX_FMT_NONE
2671};
2672
2604#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM2673#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
2605#define COMMON_OPTIONS \2674#define COMMON_OPTIONS \
2606 { "allow_sw", "Allow software encoding", OFFSET(allow_sw), AV_OPT_TYPE_BOOL, \2675 { "allow_sw", "Allow software encoding", OFFSET(allow_sw), AV_OPT_TYPE_BOOL, \
@@ -2704,3 +2773,42 @@ const AVCodec ff_hevc_videotoolbox_encoder = { · 97 unmodified lines
2704 FF_CODEC_CAP_INIT_CLEANUP,2773 FF_CODEC_CAP_INIT_CLEANUP,
2705 .wrapper_name = "videotoolbox",2774 .wrapper_name = "videotoolbox",
2706};2775};
2776
2777static const AVOption prores_options[] = {
2778 { "profile", "Profile", OFFSET(profile), AV_OPT_TYPE_INT64, { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, FF_PROFILE_PRORES_XQ, VE, "profile" },
2779 { "auto", "Automatically determine based on input format", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_UNKNOWN }, INT_MIN, INT_MAX, VE, "profile" },
2780 { "proxy", "ProRes 422 Proxy", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_PROXY }, INT_MIN, INT_MAX, VE, "profile" },
2781 { "lt", "ProRes 422 LT", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_LT }, INT_MIN, INT_MAX, VE, "profile" },
2782 { "standard", "ProRes 422", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_STANDARD }, INT_MIN, INT_MAX, VE, "profile" },
2783 { "hq", "ProRes 422 HQ", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_HQ }, INT_MIN, INT_MAX, VE, "profile" },
2784 { "4444", "ProRes 4444", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_4444 }, INT_MIN, INT_MAX, VE, "profile" },
2785 { "xq", "ProRes 4444 XQ", 0, AV_OPT_TYPE_CONST, { .i64 = FF_PROFILE_PRORES_XQ }, INT_MIN, INT_MAX, VE, "profile" },
2786
2787 COMMON_OPTIONS
2788 { NULL },
2789};
2790
2791static const AVClass prores_videotoolbox_class = {
2792 .class_name = "prores_videotoolbox",
2793 .item_name = av_default_item_name,
2794 .option = prores_options,
2795 .version = LIBAVUTIL_VERSION_INT,
2796};
2797
2798const AVCodec ff_prores_videotoolbox_encoder = {
2799 .name = "prores_videotoolbox",
2800 .long_name = NULL_IF_CONFIG_SMALL("VideoToolbox ProRes Encoder"),
2801 .type = AVMEDIA_TYPE_VIDEO,
2802 .id = AV_CODEC_ID_PRORES,
2803 .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
2804 AV_CODEC_CAP_HARDWARE,
2805 .priv_data_size = sizeof(VTEncContext),
2806 .pix_fmts = prores_pix_fmts,
2807 .init = vtenc_init,
2808 .encode2 = vtenc_frame,
2809 .close = vtenc_close,
2810 .priv_class = &prores_videotoolbox_class,
2811 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
2812 FF_CODEC_CAP_INIT_CLEANUP,
2813 .wrapper_name = "videotoolbox",
2814};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t