From de0ceb1178692240cc3a3d7b442697f26e735880 Mon Sep 17 00:00:00 2001 From: David Schleef Date: Sat, 19 Sep 2009 14:10:28 -0700 Subject: [PATCH] celtenc: Add complexity, cbr, and max-bitrate properties --- ext/celt/gstceltenc.c | 65 +++++++++++++++++++++++++++++++++++++------ ext/celt/gstceltenc.h | 3 ++ 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/ext/celt/gstceltenc.c b/ext/celt/gstceltenc.c index 7ce03ecaa9..bad98aeec9 100644 --- a/ext/celt/gstceltenc.c +++ b/ext/celt/gstceltenc.c @@ -79,12 +79,18 @@ GST_ELEMENT_DETAILS ("Celt audio encoder", #define DEFAULT_BITRATE 64 #define DEFAULT_FRAMESIZE 256 +#define DEFAULT_CBR TRUE +#define DEFAULT_COMPLEXITY 9 +#define DEFAULT_MAX_BITRATE 64 enum { PROP_0, PROP_BITRATE, - PROP_FRAMESIZE + PROP_FRAMESIZE, + PROP_CBR, + PROP_COMPLEXITY, + PROP_MAX_BITRATE }; static void gst_celt_enc_finalize (GObject * object); @@ -152,13 +158,26 @@ gst_celt_enc_class_init (GstCeltEncClass * klass) g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BITRATE, g_param_spec_int ("bitrate", "Encoding Bit-rate", - "Specify an encoding bit-rate (in Kbps). (0 = automatic)", + "Specify an encoding bit-rate (in Kbps).", 10, 320, DEFAULT_BITRATE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (gobject_class, PROP_FRAMESIZE, g_param_spec_int ("framesize", "Frame Size", "The number of samples per frame", 64, 512, DEFAULT_FRAMESIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_CBR, + g_param_spec_boolean ("cbr", "Constant bit rate", + "Constant bit rate", DEFAULT_CBR, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (gobject_class, PROP_COMPLEXITY, + g_param_spec_int ("complexity", "Complexity", + "Complexity", 0, 10, DEFAULT_COMPLEXITY, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MAX_BITRATE, + g_param_spec_int ("max-bitrate", "Maximum Encoding Bit-rate", + "Specify a maximum encoding bit rate (in Kbps) for variable bit rate encoding.", + 10, 320, DEFAULT_MAX_BITRATE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_celt_enc_finalize); @@ -511,6 +530,9 @@ gst_celt_enc_init (GstCeltEnc * enc, GstCeltEncClass * klass) enc->bitrate = DEFAULT_BITRATE; enc->frame_size = DEFAULT_FRAMESIZE; + enc->cbr = DEFAULT_CBR; + enc->complexity = DEFAULT_COMPLEXITY; + enc->max_bitrate = DEFAULT_MAX_BITRATE; enc->setup = FALSE; enc->header_sent = FALSE; @@ -551,7 +573,6 @@ static gboolean gst_celt_enc_setup (GstCeltEnc * enc) { gint error = CELT_OK; - gint bytes_per_packet; enc->setup = FALSE; @@ -562,9 +583,6 @@ gst_celt_enc_setup (GstCeltEnc * enc) celt_mode_info (enc->mode, CELT_GET_FRAME_SIZE, &enc->frame_size); - bytes_per_packet = - (enc->bitrate * 1000 * enc->frame_size / enc->rate + 4) / 8; - celt_header_init (&enc->header, enc->mode); enc->header.nb_channels = enc->channels; @@ -572,6 +590,12 @@ gst_celt_enc_setup (GstCeltEnc * enc) if (!enc->state) goto encoder_creation_failed; + if (!enc->cbr) { + GST_ERROR ("setting vbr"); + celt_encoder_ctl (enc->state, CELT_SET_VBR_RATE (enc->bitrate), 0); + } + celt_encoder_ctl (enc->state, CELT_SET_COMPLEXITY (enc->complexity), 0); + GST_LOG_OBJECT (enc, "we have frame size %d", enc->frame_size); enc->setup = TRUE; @@ -700,8 +724,15 @@ gst_celt_enc_encode (GstCeltEnc * enc, gboolean flush) GstFlowReturn ret = GST_FLOW_OK; gint frame_size = enc->frame_size; gint bytes = frame_size * 2 * enc->channels; - gint bytes_per_packet = - (enc->bitrate * 1000 * enc->frame_size / enc->rate + 4) / 8; + gint bytes_per_packet; + + if (enc->cbr) { + bytes_per_packet = + (enc->bitrate * 1000 * enc->frame_size / enc->rate + 4) / 8; + } else { + bytes_per_packet = + (enc->max_bitrate * 1000 * enc->frame_size / enc->rate + 4) / 8; + } if (flush && gst_adapter_available (enc->adapter) % bytes != 0) { guint diff = gst_adapter_available (enc->adapter) % bytes; @@ -943,6 +974,15 @@ gst_celt_enc_get_property (GObject * object, guint prop_id, GValue * value, case PROP_FRAMESIZE: g_value_set_int (value, enc->frame_size); break; + case PROP_CBR: + g_value_set_boolean (value, enc->cbr); + break; + case PROP_COMPLEXITY: + g_value_set_int (value, enc->complexity); + break; + case PROP_MAX_BITRATE: + g_value_set_int (value, enc->max_bitrate); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -964,6 +1004,15 @@ gst_celt_enc_set_property (GObject * object, guint prop_id, case PROP_FRAMESIZE: enc->frame_size = g_value_get_int (value); break; + case PROP_CBR: + enc->cbr = g_value_get_boolean (value); + break; + case PROP_COMPLEXITY: + enc->complexity = g_value_get_int (value); + break; + case PROP_MAX_BITRATE: + enc->max_bitrate = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/ext/celt/gstceltenc.h b/ext/celt/gstceltenc.h index c0c554b862..a6939b102c 100644 --- a/ext/celt/gstceltenc.h +++ b/ext/celt/gstceltenc.h @@ -62,6 +62,9 @@ struct _GstCeltEnc { gint bitrate; gint frame_size; + gboolean cbr; + gint complexity; + gint max_bitrate; gint channels; gint rate;