From 4207b4e2814ca0d21f75b9b18855ec0b3881b7c4 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Thu, 25 Jul 2024 04:36:09 +0530 Subject: [PATCH] vtenc: Add support for constant bitrate encoding Only supported on macOS 13.0+ and iOS 16.0+ on Apple Silicon. Part-of: --- .../gst-plugins-bad/sys/applemedia/vtenc.c | 53 ++++++++++++++++++- .../gst-plugins-bad/sys/applemedia/vtenc.h | 14 +++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/applemedia/vtenc.c b/subprojects/gst-plugins-bad/sys/applemedia/vtenc.c index 3cdc4c1419..02fd97261e 100644 --- a/subprojects/gst-plugins-bad/sys/applemedia/vtenc.c +++ b/subprojects/gst-plugins-bad/sys/applemedia/vtenc.c @@ -192,6 +192,7 @@ enum PROP_MAX_KEYFRAME_INTERVAL, PROP_MAX_KEYFRAME_INTERVAL_DURATION, PROP_PRESERVE_ALPHA, + PROP_RATE_CONTROL, }; typedef struct _GstVTEncFrame GstVTEncFrame; @@ -263,6 +264,24 @@ static void gst_pixel_buffer_release_cb (void *releaseRefCon, const void *planeAddresses[]); #endif +#define GST_TYPE_VTENC_RATE_CONTROL (gst_vtenc_rate_control_get_type()) +static GType +gst_vtenc_rate_control_get_type (void) +{ + static GType rc_type = 0; + + static const GEnumValue rc_types[] = { + {GST_VTENC_RATE_CONTROL_ABR, "Average Bitrate", "abr"}, + {GST_VTENC_RATE_CONTROL_CBR, "Constant Bitrate", "cbr"}, + {0, NULL, NULL}, + }; + + if (!rc_type) { + rc_type = g_enum_register_static ("GstVtencRateControl", rc_types); + } + return rc_type; +} + static GstStaticCaps sink_caps = GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE ("{ AYUV64, UYVY, NV12, I420 }")); @@ -461,6 +480,15 @@ gst_vtenc_class_init (GstVTEncClass * klass) G_MAXUINT64, VTENC_DEFAULT_MAX_KEYFRAME_INTERVAL_DURATION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + /** + * Since: 1.26 + */ + g_object_class_install_property (gobject_class, PROP_RATE_CONTROL, + g_param_spec_enum ("rate-control", "Rate Control", + "Desired rate control for the encoder", GST_TYPE_VTENC_RATE_CONTROL, + GST_VTENC_RATE_CONTROL_ABR, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + /* * H264 doesn't support alpha components, and H265 uses a separate element for encoding * with alpha, so only add the property for prores @@ -625,6 +653,9 @@ gst_vtenc_get_property (GObject * obj, guint prop_id, GValue * value, case PROP_MAX_KEYFRAME_INTERVAL_DURATION: g_value_set_uint64 (value, self->max_keyframe_interval_duration); break; + case PROP_RATE_CONTROL: + g_value_set_enum (value, self->rate_control); + break; case PROP_PRESERVE_ALPHA: g_value_set_boolean (value, self->preserve_alpha); break; @@ -660,6 +691,9 @@ gst_vtenc_set_property (GObject * obj, guint prop_id, const GValue * value, gst_vtenc_set_max_keyframe_interval_duration (self, g_value_get_uint64 (value)); break; + case PROP_RATE_CONTROL: + self->rate_control = g_value_get_enum (value); + break; case PROP_PRESERVE_ALPHA: self->preserve_alpha = g_value_get_boolean (value); break; @@ -1640,8 +1674,23 @@ static void gst_vtenc_session_configure_bitrate (GstVTEnc * self, VTCompressionSessionRef session, guint bitrate) { - gst_vtenc_session_configure_property_int (self, session, - kVTCompressionPropertyKey_AverageBitRate, bitrate); + CFStringRef key = kVTCompressionPropertyKey_AverageBitRate; + + if (self->rate_control == GST_VTENC_RATE_CONTROL_CBR) { +#ifdef __aarch64__ + /* + * In addition to the OS requirements, CBR also requires Apple Silicon + */ + if (__builtin_available (macOS 13.0, iOS 16.0, *)) { + key = kVTCompressionPropertyKey_ConstantBitRate; + } else +#endif + { + GST_WARNING_OBJECT (self, "CBR is unsupported on your system, using ABR"); + } + } + + gst_vtenc_session_configure_property_int (self, session, key, bitrate); } static void diff --git a/subprojects/gst-plugins-bad/sys/applemedia/vtenc.h b/subprojects/gst-plugins-bad/sys/applemedia/vtenc.h index ef0d966f6d..5dbc476dab 100644 --- a/subprojects/gst-plugins-bad/sys/applemedia/vtenc.h +++ b/subprojects/gst-plugins-bad/sys/applemedia/vtenc.h @@ -34,6 +34,19 @@ G_BEGIN_DECLS ((const GstVTEncoderDetails *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass), \ GST_VTENC_CODEC_DETAILS_QDATA)) +/** + * GstVtencRateControl: + * @GST_VTENC_RATE_CONTROL_ABR: average (variable) bitrate + * @GST_VTENC_RATE_CONTROL_CBR: constant bitrate + * + * Since: 1.26 + */ +typedef enum +{ + GST_VTENC_RATE_CONTROL_ABR, + GST_VTENC_RATE_CONTROL_CBR, +} GstVtencRateControl; + typedef struct _GstVTEncoderDetails GstVTEncoderDetails; typedef struct _GstVTEncClassParams GstVTEncClassParams; @@ -71,6 +84,7 @@ struct _GstVTEnc GstClockTime max_keyframe_interval_duration; gint latency_frames; gboolean preserve_alpha; + GstVtencRateControl rate_control; gboolean dump_properties; gboolean dump_attributes;