summaryrefslogtreecommitdiffstats
path: root/ext/speex/gstspeexenc.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2008-06-16 10:09:03 +0000
committerWim Taymans <wim.taymans@gmail.com>2008-06-16 10:09:03 +0000
commit4710c0ab85cf8dba4c77b9659af2f38ee8a880cd (patch)
treebe592545083860f0f77de554696453e33feb186e /ext/speex/gstspeexenc.c
parent5e606453c015993d4367003a077ae627d3b9eb65 (diff)
ext/speex/gstspeexenc.c: Add mode property.
Original commit message from CVS: * ext/speex/gstspeexenc.c: (gst_speex_enc_mode_get_type), (gst_speex_enc_class_init), (gst_speex_enc_sink_getcaps), (gst_speex_enc_get_latency), (gst_speex_enc_get_query_types), (gst_speex_enc_src_query), (gst_speex_enc_init), (gst_speex_enc_setup), (gst_speex_enc_push_buffer), (gst_speex_enc_chain), (gst_speex_enc_get_property), (gst_speex_enc_set_property): Add mode property. Some cleanups, add more debug info. Add latency query.
Diffstat (limited to 'ext/speex/gstspeexenc.c')
-rw-r--r--ext/speex/gstspeexenc.c162
1 files changed, 120 insertions, 42 deletions
diff --git a/ext/speex/gstspeexenc.c b/ext/speex/gstspeexenc.c
index 398aac20..910e3c6c 100644
--- a/ext/speex/gstspeexenc.c
+++ b/ext/speex/gstspeexenc.c
@@ -60,6 +60,7 @@ GST_ELEMENT_DETAILS ("Speex audio encoder",
#define DEFAULT_QUALITY 8.0
#define DEFAULT_BITRATE 0
+#define DEFAULT_MODE GST_SPEEX_ENC_MODE_AUTO
#define DEFAULT_VBR FALSE
#define DEFAULT_ABR 0
#define DEFAULT_VAD FALSE
@@ -69,18 +70,38 @@ GST_ELEMENT_DETAILS ("Speex audio encoder",
enum
{
- ARG_0,
- ARG_QUALITY,
- ARG_BITRATE,
- ARG_VBR,
- ARG_ABR,
- ARG_VAD,
- ARG_DTX,
- ARG_COMPLEXITY,
- ARG_NFRAMES,
- ARG_LAST_MESSAGE
+ PROP_0,
+ PROP_QUALITY,
+ PROP_BITRATE,
+ PROP_MODE,
+ PROP_VBR,
+ PROP_ABR,
+ PROP_VAD,
+ PROP_DTX,
+ PROP_COMPLEXITY,
+ PROP_NFRAMES,
+ PROP_LAST_MESSAGE
};
+#define GST_TYPE_SPEEX_ENC_MODE (gst_speex_enc_mode_get_type())
+static GType
+gst_speex_enc_mode_get_type (void)
+{
+ static GType speex_enc_mode_type = 0;
+ static const GEnumValue speex_enc_modes[] = {
+ {GST_SPEEX_ENC_MODE_AUTO, "Auto", "auto"},
+ {GST_SPEEX_ENC_MODE_UWB, "Ultra Wide Band", "uwb"},
+ {GST_SPEEX_ENC_MODE_WB, "Wide Band", "wb"},
+ {GST_SPEEX_ENC_MODE_NB, "Narrow Band", "nb"},
+ {0, NULL, NULL},
+ };
+ if (G_UNLIKELY (speex_enc_mode_type == 0)) {
+ speex_enc_mode_type = g_enum_register_static ("GstSpeexEncMode",
+ speex_enc_modes);
+ }
+ return speex_enc_mode_type;
+}
+
#if 0
static const GstFormat *
gst_speex_enc_get_formats (GstPad * pad)
@@ -152,35 +173,39 @@ gst_speex_enc_class_init (GstSpeexEncClass * klass)
gobject_class->set_property = gst_speex_enc_set_property;
gobject_class->get_property = gst_speex_enc_get_property;
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_QUALITY,
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_QUALITY,
g_param_spec_float ("quality", "Quality", "Encoding quality",
0.0, 10.0, DEFAULT_QUALITY, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BITRATE,
+ 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 bps). (0 = automatic)",
0, G_MAXINT, DEFAULT_BITRATE, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VBR,
+ g_object_class_install_property (gobject_class, PROP_MODE,
+ g_param_spec_enum ("mode", "Mode", "The encoding mode",
+ GST_TYPE_SPEEX_ENC_MODE, GST_SPEEX_ENC_MODE_AUTO,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VBR,
g_param_spec_boolean ("vbr", "VBR",
"Enable variable bit-rate", DEFAULT_VBR, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ABR,
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_ABR,
g_param_spec_int ("abr", "ABR",
"Enable average bit-rate (0 = disabled)",
0, G_MAXINT, DEFAULT_ABR, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_VAD,
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_VAD,
g_param_spec_boolean ("vad", "VAD",
"Enable voice activity detection", DEFAULT_VAD, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DTX,
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DTX,
g_param_spec_boolean ("dtx", "DTX",
"Enable discontinuous transmission", DEFAULT_DTX, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COMPLEXITY,
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_COMPLEXITY,
g_param_spec_int ("complexity", "Complexity",
"Set encoding complexity",
0, G_MAXINT, DEFAULT_COMPLEXITY, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NFRAMES,
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_NFRAMES,
g_param_spec_int ("nframes", "NFrames",
"Number of frames per buffer",
0, G_MAXINT, DEFAULT_NFRAMES, G_PARAM_READWRITE));
- g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
+ g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_LAST_MESSAGE,
g_param_spec_string ("last-message", "last-message",
"The last status message", NULL, G_PARAM_READABLE));
@@ -360,6 +385,12 @@ gst_speex_enc_convert_sink (GstPad * pad, GstFormat src_format,
return res;
}
+static gint64
+gst_speex_enc_get_latency (GstSpeexEnc * enc)
+{
+ return 30 * GST_MSECOND;
+}
+
static const GstQueryType *
gst_speex_enc_get_query_types (GstPad * pad)
{
@@ -367,6 +398,7 @@ gst_speex_enc_get_query_types (GstPad * pad)
GST_QUERY_POSITION,
GST_QUERY_DURATION,
GST_QUERY_CONVERT,
+ GST_QUERY_LATENCY,
0
};
@@ -438,8 +470,28 @@ gst_speex_enc_src_query (GstPad * pad, GstQuery * query)
gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
break;
}
+ case GST_QUERY_LATENCY:
+ {
+ gboolean live;
+ GstClockTime min_latency, max_latency;
+ gint64 latency;
+
+ if ((res = gst_pad_peer_query (pad, query))) {
+ gst_query_parse_latency (query, &live, &min_latency, &max_latency);
+
+ latency = gst_speex_enc_get_latency (enc);
+
+ /* add our latency */
+ min_latency += latency;
+ if (max_latency != -1)
+ max_latency += latency;
+
+ gst_query_set_latency (query, live, min_latency, max_latency);
+ }
+ break;
+ }
default:
- res = gst_pad_query_default (pad, query);
+ res = gst_pad_peer_query (pad, query);
break;
}
@@ -509,6 +561,7 @@ gst_speex_enc_init (GstSpeexEnc * enc, GstSpeexEncClass * klass)
enc->quality = DEFAULT_QUALITY;
enc->bitrate = DEFAULT_BITRATE;
+ enc->mode = DEFAULT_MODE;
enc->vbr = DEFAULT_VBR;
enc->abr = DEFAULT_ABR;
enc->vad = DEFAULT_VAD;
@@ -516,8 +569,6 @@ gst_speex_enc_init (GstSpeexEnc * enc, GstSpeexEncClass * klass)
enc->complexity = DEFAULT_COMPLEXITY;
enc->nframes = DEFAULT_NFRAMES;
- /* FIXME: what about enc->mode? */
-
enc->setup = FALSE;
enc->header_sent = FALSE;
@@ -570,22 +621,27 @@ gst_speex_enc_setup (GstSpeexEnc * enc)
switch (enc->mode) {
case GST_SPEEX_ENC_MODE_UWB:
+ GST_LOG_OBJECT (enc, "configuring for requested UWB mode");
enc->speex_mode = (SpeexMode *) & speex_uwb_mode;
break;
case GST_SPEEX_ENC_MODE_WB:
+ GST_LOG_OBJECT (enc, "configuring for requested WB mode");
enc->speex_mode = (SpeexMode *) & speex_wb_mode;
break;
case GST_SPEEX_ENC_MODE_NB:
+ GST_LOG_OBJECT (enc, "configuring for requested NB mode");
enc->speex_mode = (SpeexMode *) & speex_nb_mode;
break;
case GST_SPEEX_ENC_MODE_AUTO:
/* fall through */
+ GST_LOG_OBJECT (enc, "finding best mode");
default:
break;
}
if (enc->rate > 25000) {
if (enc->mode == GST_SPEEX_ENC_MODE_AUTO) {
+ GST_LOG_OBJECT (enc, "selected UWB mode for samplerate %d", enc->rate);
enc->speex_mode = (SpeexMode *) & speex_uwb_mode;
} else {
if (enc->speex_mode != &speex_uwb_mode) {
@@ -595,6 +651,7 @@ gst_speex_enc_setup (GstSpeexEnc * enc)
}
} else if (enc->rate > 12500) {
if (enc->mode == GST_SPEEX_ENC_MODE_AUTO) {
+ GST_LOG_OBJECT (enc, "selected WB mode for samplerate %d", enc->rate);
enc->speex_mode = (SpeexMode *) & speex_wb_mode;
} else {
if (enc->speex_mode != &speex_wb_mode) {
@@ -604,6 +661,7 @@ gst_speex_enc_setup (GstSpeexEnc * enc)
}
} else {
if (enc->mode == GST_SPEEX_ENC_MODE_AUTO) {
+ GST_LOG_OBJECT (enc, "selected NB mode for samplerate %d", enc->rate);
enc->speex_mode = (SpeexMode *) & speex_nb_mode;
} else {
if (enc->speex_mode != &speex_nb_mode) {
@@ -674,6 +732,9 @@ gst_speex_enc_setup (GstSpeexEnc * enc)
speex_encoder_ctl (enc->state, SPEEX_GET_LOOKAHEAD, &enc->lookahead);
+ GST_LOG_OBJECT (enc, "we have frame size %d, lookahead %d", enc->frame_size,
+ enc->lookahead);
+
enc->setup = TRUE;
return TRUE;
@@ -700,10 +761,15 @@ gst_speex_enc_buffer_from_data (GstSpeexEnc * enc, guchar * data,
static GstFlowReturn
gst_speex_enc_push_buffer (GstSpeexEnc * enc, GstBuffer * buffer)
{
- enc->bytes_out += GST_BUFFER_SIZE (buffer);
+ guint size;
- return gst_pad_push (enc->srcpad, buffer);
+ size = GST_BUFFER_SIZE (buffer);
+
+ enc->bytes_out += size;
+ GST_DEBUG_OBJECT (enc, "pushing output buffer of size %u", size);
+
+ return gst_pad_push (enc->srcpad, buffer);
}
static GstCaps *
@@ -822,7 +888,7 @@ gst_speex_enc_chain (GstPad * pad, GstBuffer * buf)
"channels", G_TYPE_INT, enc->channels, NULL);
/* negotiate with these caps */
- GST_DEBUG ("here are the caps: %" GST_PTR_FORMAT, caps);
+ GST_DEBUG_OBJECT (enc, "here are the caps: %" GST_PTR_FORMAT, caps);
gst_pad_set_caps (enc->srcpad, caps);
gst_buffer_set_caps (buf1, caps);
@@ -851,6 +917,9 @@ gst_speex_enc_chain (GstPad * pad, GstBuffer * buf)
gint frame_size = enc->frame_size;
gint bytes = frame_size * 2 * enc->channels;
+ GST_DEBUG_OBJECT (enc, "received buffer of %u bytes",
+ GST_BUFFER_SIZE (buf));
+
/* push buffer to adapter */
gst_adapter_push (enc->adapter, buf);
buf = NULL;
@@ -870,6 +939,9 @@ gst_speex_enc_chain (GstPad * pad, GstBuffer * buf)
enc->samples_in += frame_size;
+ GST_DEBUG_OBJECT (enc, "encoding %d samples (%d bytes)", frame_size,
+ bytes);
+
if (enc->channels == 2) {
speex_encode_stereo (enc->input, frame_size, &enc->bits);
}
@@ -941,31 +1013,34 @@ gst_speex_enc_get_property (GObject * object, guint prop_id, GValue * value,
enc = GST_SPEEX_ENC (object);
switch (prop_id) {
- case ARG_QUALITY:
+ case PROP_QUALITY:
g_value_set_float (value, enc->quality);
break;
- case ARG_BITRATE:
+ case PROP_BITRATE:
g_value_set_int (value, enc->bitrate);
break;
- case ARG_VBR:
+ case PROP_MODE:
+ g_value_set_enum (value, enc->mode);
+ break;
+ case PROP_VBR:
g_value_set_boolean (value, enc->vbr);
break;
- case ARG_ABR:
+ case PROP_ABR:
g_value_set_int (value, enc->abr);
break;
- case ARG_VAD:
+ case PROP_VAD:
g_value_set_boolean (value, enc->vad);
break;
- case ARG_DTX:
+ case PROP_DTX:
g_value_set_boolean (value, enc->dtx);
break;
- case ARG_COMPLEXITY:
+ case PROP_COMPLEXITY:
g_value_set_int (value, enc->complexity);
break;
- case ARG_NFRAMES:
+ case PROP_NFRAMES:
g_value_set_int (value, enc->nframes);
break;
- case ARG_LAST_MESSAGE:
+ case PROP_LAST_MESSAGE:
g_value_set_string (value, enc->last_message);
break;
default:
@@ -983,28 +1058,31 @@ gst_speex_enc_set_property (GObject * object, guint prop_id,
enc = GST_SPEEX_ENC (object);
switch (prop_id) {
- case ARG_QUALITY:
+ case PROP_QUALITY:
enc->quality = g_value_get_float (value);
break;
- case ARG_BITRATE:
+ case PROP_BITRATE:
enc->bitrate = g_value_get_int (value);
break;
- case ARG_VBR:
+ case PROP_MODE:
+ enc->mode = g_value_get_enum (value);
+ break;
+ case PROP_VBR:
enc->vbr = g_value_get_boolean (value);
break;
- case ARG_ABR:
+ case PROP_ABR:
enc->abr = g_value_get_int (value);
break;
- case ARG_VAD:
+ case PROP_VAD:
enc->vad = g_value_get_boolean (value);
break;
- case ARG_DTX:
+ case PROP_DTX:
enc->dtx = g_value_get_boolean (value);
break;
- case ARG_COMPLEXITY:
+ case PROP_COMPLEXITY:
enc->complexity = g_value_get_int (value);
break;
- case ARG_NFRAMES:
+ case PROP_NFRAMES:
enc->nframes = g_value_get_int (value);
break;
default: