celtenc: Add complexity, cbr, and max-bitrate properties
authorDavid Schleef <ds@schleef.org>
Sat, 19 Sep 2009 21:10:28 +0000 (14:10 -0700)
committerDavid Schleef <ds@schleef.org>
Sat, 19 Sep 2009 21:13:26 +0000 (14:13 -0700)
ext/celt/gstceltenc.c
ext/celt/gstceltenc.h

index 7ce03ecaa9a214013237edf006410343b013faea..bad98aeec914e6502e6f682464c99c1d9a32acab 100644 (file)
@@ -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;
index c0c554b862a50867d600b932da3c6a8be72816c7..a6939b102ca23079ddf16b250bf1ee5fb6c04322 100644 (file)
@@ -62,6 +62,9 @@ struct _GstCeltEnc {
 
   gint                  bitrate;
   gint                  frame_size;
+  gboolean              cbr;
+  gint                  complexity;
+  gint                  max_bitrate;
 
   gint                  channels;
   gint                  rate;