vtenc: Support emulating CBR mode with data rate limits

CBR is only supported on Apple Silicon, and this "emulation" works
surprisingly well. We set the window size to a single frame, and don't
set ABR at all.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7232>
This commit is contained in:
Nirbheek Chauhan 2024-07-27 05:47:34 +05:30 committed by GStreamer Marge Bot
parent d327105228
commit 30d2b8895a

View file

@ -1705,6 +1705,9 @@ static void
gst_vtenc_session_configure_bitrate (GstVTEnc * self, gst_vtenc_session_configure_bitrate (GstVTEnc * self,
VTCompressionSessionRef session, guint bitrate) VTCompressionSessionRef session, guint bitrate)
{ {
gboolean emulate_cbr = FALSE;
double bitrate_window = self->bitrate_window;
guint max_bitrate = self->max_bitrate;
CFStringRef key = kVTCompressionPropertyKey_AverageBitRate; CFStringRef key = kVTCompressionPropertyKey_AverageBitRate;
if (self->rate_control == GST_VTENC_RATE_CONTROL_CBR) { if (self->rate_control == GST_VTENC_RATE_CONTROL_CBR) {
@ -1717,22 +1720,28 @@ gst_vtenc_session_configure_bitrate (GstVTEnc * self,
} else } else
#endif #endif
{ {
GST_WARNING_OBJECT (self, "CBR is unsupported on your system, using ABR"); GST_INFO_OBJECT (self, "CBR is unsupported on your system, emulating "
"with custom data rate limits");
emulate_cbr = TRUE;
max_bitrate = bitrate;
gst_util_fraction_to_double (self->video_info.fps_d,
self->video_info.fps_n, &bitrate_window);
} }
} }
if (self->max_bitrate > 0 && self->bitrate_window > 0) { if (max_bitrate > 0 && bitrate_window > 0) {
if (self->rate_control == GST_VTENC_RATE_CONTROL_CBR) if (self->rate_control == GST_VTENC_RATE_CONTROL_CBR &&
self->max_bitrate > 0 && self->bitrate_window > 0)
GST_INFO_OBJECT (self, "Ignoring data-rate-limits property, CBR mode is " GST_INFO_OBJECT (self, "Ignoring data-rate-limits property, CBR mode is "
"enabled"); "enabled");
if (key == kVTCompressionPropertyKey_AverageBitRate) { if (key == kVTCompressionPropertyKey_AverageBitRate) {
/* Convert to bytes */ /* Convert to bytes */
int size = (self->max_bitrate * self->bitrate_window) / 8; int size = (max_bitrate * bitrate_window) / 8;
CFNumberRef cf_size = CFNumberCreate (NULL, kCFNumberIntType, &size); CFNumberRef cf_size = CFNumberCreate (NULL, kCFNumberIntType, &size);
CFNumberRef cf_window = CFNumberCreate (NULL, kCFNumberFloatType, CFNumberRef cf_window = CFNumberCreate (NULL, kCFNumberFloatType,
&self->bitrate_window); &bitrate_window);
CFTypeRef values[2] = { cf_size, cf_window }; CFTypeRef values[2] = { cf_size, cf_window };
CFArrayRef data = CFArrayCreate (NULL, values, 2, &kCFTypeArrayCallBacks); CFArrayRef data = CFArrayCreate (NULL, values, 2, &kCFTypeArrayCallBacks);
@ -1753,6 +1762,7 @@ gst_vtenc_session_configure_bitrate (GstVTEnc * self,
} }
} }
if (!emulate_cbr)
gst_vtenc_session_configure_property_int (self, session, key, bitrate); gst_vtenc_session_configure_property_int (self, session, key, bitrate);
} }