mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
Lame cleanup
Original commit message from CVS: Lame cleanup Added EOS, flush, error reporting etc.
This commit is contained in:
parent
4f7f87d892
commit
9fdf782023
2 changed files with 176 additions and 109 deletions
|
@ -35,7 +35,8 @@
|
|||
#include "gstlame.h"
|
||||
|
||||
|
||||
static GstElementDetails gst_lame_details = {
|
||||
static GstElementDetails gst_lame_details =
|
||||
{
|
||||
"L.A.M.E. mp3 encoder",
|
||||
"Filter/Encoder/Audio",
|
||||
"High-quality free MP3 encoder",
|
||||
|
@ -167,7 +168,7 @@ enum {
|
|||
ARG_ATH_ONLY,
|
||||
ARG_ATH_SHORT,
|
||||
ARG_NO_ATH,
|
||||
// ARG_ATH_TYPE, // note: CVS has this, 3.87 doesn't
|
||||
/* ARG_ATH_TYPE, // note: CVS has this, 3.87 doesn't */
|
||||
ARG_ATH_LOWER,
|
||||
ARG_CWLIMIT,
|
||||
ARG_ALLOW_DIFF_SHORT,
|
||||
|
@ -179,14 +180,16 @@ enum {
|
|||
static void gst_lame_class_init (GstLameClass *klass);
|
||||
static void gst_lame_init (GstLame *gst_lame);
|
||||
|
||||
static void gst_lame_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
|
||||
static void gst_lame_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
|
||||
|
||||
static void gst_lame_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec);
|
||||
static void gst_lame_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec);
|
||||
static void gst_lame_chain (GstPad *pad, GstBuffer *buf);
|
||||
static gboolean gst_lame_setup (GstLame *lame);
|
||||
static GstElementStateReturn gst_lame_change_state (GstElement *element);
|
||||
|
||||
static GstElementClass *parent_class = NULL;
|
||||
//static guint gst_lame_signals[LAST_SIGNAL] = { 0 };
|
||||
/* static guint gst_lame_signals[LAST_SIGNAL] = { 0 }; */
|
||||
|
||||
GType
|
||||
gst_lame_get_type (void)
|
||||
|
@ -195,7 +198,8 @@ gst_lame_get_type (void)
|
|||
|
||||
if (!gst_lame_type) {
|
||||
static const GTypeInfo gst_lame_info = {
|
||||
sizeof(GstLameClass), NULL,
|
||||
sizeof (GstLameClass),
|
||||
NULL,
|
||||
NULL,
|
||||
(GClassInitFunc) gst_lame_class_init,
|
||||
NULL,
|
||||
|
@ -295,8 +299,8 @@ gst_lame_class_init (GstLameClass *klass)
|
|||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_NO_ATH,
|
||||
g_param_spec_boolean("no_ath","no_ath","no_ath",
|
||||
TRUE,G_PARAM_READWRITE)); // CHECKME
|
||||
// gtk_object_add_arg_type ("GstLame::ath_type", G_TYPE_INT,
|
||||
// GTK_ARG_READWRITE, ARG_ATH_TYPE);
|
||||
/* gtk_object_add_arg_type ("GstLame::ath_type", G_TYPE_INT,
|
||||
GTK_ARG_READWRITE, ARG_ATH_TYPE); */
|
||||
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_ATH_LOWER,
|
||||
g_param_spec_int("ath_lower","ath_lower","ath_lower",
|
||||
G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME
|
||||
|
@ -315,6 +319,8 @@ gst_lame_class_init (GstLameClass *klass)
|
|||
|
||||
gobject_class->set_property = gst_lame_set_property;
|
||||
gobject_class->get_property = gst_lame_get_property;
|
||||
|
||||
gstelement_class->change_state = gst_lame_change_state;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -327,9 +333,20 @@ gst_lame_newcaps (GstPad *pad, GstCaps *caps)
|
|||
lame->samplerate = gst_caps_get_int (caps, "rate");
|
||||
lame->num_channels = gst_caps_get_int (caps, "channels");
|
||||
|
||||
gst_element_send_event (GST_ELEMENT (lame),
|
||||
gst_event_new_info ("channels", GST_PROPS_INT (lame->num_channels), NULL));
|
||||
gst_element_send_event (GST_ELEMENT (lame),
|
||||
gst_event_new_info ("rate", GST_PROPS_INT (lame->samplerate), NULL));
|
||||
|
||||
GST_DEBUG (0, "rate=%d, channels=%d\n", lame->samplerate, lame->num_channels);
|
||||
|
||||
gst_lame_setup (lame);
|
||||
if (gst_lame_setup (lame)) {
|
||||
lame->initialized = TRUE;
|
||||
}
|
||||
else {
|
||||
gst_element_error (GST_ELEMENT (lame), "could not initialize encoder (wrong parameters?)");
|
||||
lame->initialized = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -351,6 +368,7 @@ gst_lame_init (GstLame *lame)
|
|||
|
||||
lame->samplerate = 44100;
|
||||
lame->num_channels = 2;
|
||||
lame->initialized = FALSE;
|
||||
|
||||
lame->bitrate = lame_get_brate (lame->lgf);
|
||||
lame->compression_ratio = lame_get_compression_ratio (lame->lgf);
|
||||
|
@ -377,14 +395,14 @@ gst_lame_init (GstLame *lame)
|
|||
lame->ath_only = lame_get_ATHonly (lame->lgf);
|
||||
lame->ath_short = lame_get_ATHshort (lame->lgf);
|
||||
lame->no_ath = lame_get_noATH (lame->lgf);
|
||||
// lame->ath_type = lame_get_ATHtype(lame->lgf);
|
||||
/* lame->ath_type = lame_get_ATHtype (lame->lgf); */
|
||||
lame->ath_lower = lame_get_ATHlower (lame->lgf);
|
||||
lame->cwlimit = lame_get_cwlimit (lame->lgf);
|
||||
lame->allow_diff_short = lame_get_allow_diff_short (lame->lgf);
|
||||
lame->no_short_blocks = lame_get_no_short_blocks (lame->lgf);
|
||||
lame->emphasis = lame_get_emphasis (lame->lgf);
|
||||
|
||||
GST_DEBUG (0,"done initializing lame element\n");;
|
||||
GST_DEBUG (0, "done initializing lame element\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -474,9 +492,9 @@ gst_lame_set_property (GObject *object, guint prop_id, const GValue *value, GPar
|
|||
case ARG_NO_ATH:
|
||||
lame->no_ath = g_value_get_boolean (value);
|
||||
break;
|
||||
// case ARG_ATH_TYPE:
|
||||
// lame->ath_type = G_VALUE_INT (*arg);
|
||||
// break;
|
||||
/* case ARG_ATH_TYPE:
|
||||
* lame->ath_type = G_VALUE_INT (*arg);
|
||||
* break; */
|
||||
case ARG_ATH_LOWER:
|
||||
lame->ath_lower = g_value_get_int (value);
|
||||
break;
|
||||
|
@ -584,9 +602,9 @@ gst_lame_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec
|
|||
case ARG_NO_ATH:
|
||||
g_value_set_boolean (value, lame->no_ath);
|
||||
break;
|
||||
// case ARG_ATH_TYPE:
|
||||
// G_VALUE_INT (*arg) = lame->ath_type;
|
||||
// break;
|
||||
/* case ARG_ATH_TYPE:
|
||||
* G_VALUE_INT (*arg) = lame->ath_type;
|
||||
* break; */
|
||||
case ARG_ATH_LOWER:
|
||||
g_value_set_int (value, lame->ath_lower);
|
||||
break;
|
||||
|
@ -615,15 +633,39 @@ gst_lame_chain (GstPad *pad, GstBuffer *buf)
|
|||
GstBuffer *outbuf;
|
||||
gchar *mp3_data;
|
||||
gint mp3_buffer_size, mp3_size = 0;
|
||||
gboolean eos = FALSE;
|
||||
|
||||
g_return_if_fail (pad != NULL);
|
||||
lame = GST_LAME (gst_pad_get_parent (pad));
|
||||
|
||||
GST_DEBUG (0, "entered\n");
|
||||
|
||||
if (!lame->initialized) {
|
||||
gst_element_error (GST_ELEMENT (lame), "encoder not initialized (input is not audio?)");
|
||||
if (GST_IS_BUFFER (buf))
|
||||
gst_buffer_unref (buf);
|
||||
else
|
||||
gst_pad_event_default (pad, GST_EVENT (buf));
|
||||
return;
|
||||
}
|
||||
|
||||
/* allocate space for output */
|
||||
mp3_buffer_size = ((GST_BUFFER_SIZE(buf) / (2+lame->num_channels)) * 1.25) + 7200;
|
||||
mp3_data = g_malloc (mp3_buffer_size);
|
||||
|
||||
if (GST_IS_EVENT (buf)) {
|
||||
switch (GST_EVENT_TYPE (buf)) {
|
||||
case GST_EVENT_EOS:
|
||||
eos = TRUE;
|
||||
case GST_EVENT_FLUSH:
|
||||
mp3_size = lame_encode_flush_nogap (lame->lgf, mp3_data, mp3_buffer_size);
|
||||
gst_event_free (GST_EVENT (buf));
|
||||
break;
|
||||
default:
|
||||
gst_pad_event_default (pad, GST_EVENT (buf));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (lame->num_channels == 2) {
|
||||
mp3_size = lame_encode_buffer_interleaved (lame->lgf, (short int *)(GST_BUFFER_DATA (buf)),
|
||||
GST_BUFFER_SIZE (buf) / 4, mp3_data, mp3_buffer_size);
|
||||
|
@ -638,6 +680,7 @@ gst_lame_chain (GstPad *pad, GstBuffer *buf)
|
|||
|
||||
GST_DEBUG (0, "encoded %d bytes of audio to %d bytes of mp3\n", GST_BUFFER_SIZE (buf), mp3_size);
|
||||
gst_buffer_unref (buf);
|
||||
}
|
||||
|
||||
if (mp3_size > 0) {
|
||||
outbuf = gst_buffer_new ();
|
||||
|
@ -646,8 +689,13 @@ gst_lame_chain (GstPad *pad, GstBuffer *buf)
|
|||
|
||||
gst_pad_push (lame->srcpad,outbuf);
|
||||
}
|
||||
else g_free (mp3_data);
|
||||
else {
|
||||
g_free (mp3_data);
|
||||
}
|
||||
|
||||
if (eos) {
|
||||
gst_pad_push (lame->srcpad, GST_BUFFER (gst_event_new (GST_EVENT_EOS)));
|
||||
}
|
||||
}
|
||||
|
||||
/* transition to the READY state by configuring the gst_lame encoder */
|
||||
|
@ -656,9 +704,9 @@ gst_lame_setup (GstLame *lame)
|
|||
{
|
||||
GST_DEBUG_ENTER ("(\"%s\")", gst_element_get_name (GST_ELEMENT (lame)));
|
||||
|
||||
// copy the parameters over
|
||||
/* copy the parameters over */
|
||||
lame_set_in_samplerate (lame->lgf, lame->samplerate);
|
||||
// force mono encoding if we only have one channel
|
||||
/* force mono encoding if we only have one channel */
|
||||
if (lame->num_channels == 1)
|
||||
lame->mode = 3;
|
||||
|
||||
|
@ -687,17 +735,20 @@ gst_lame_setup (GstLame *lame)
|
|||
lame_set_ATHonly (lame->lgf, lame->ath_only);
|
||||
lame_set_ATHshort (lame->lgf, lame->ath_short);
|
||||
lame_set_noATH (lame->lgf, lame->no_ath);
|
||||
// lame_set_ATHtype(lame->lgf, lame->ath_type);
|
||||
/* lame_set_ATHtype (lame->lgf, lame->ath_type); */
|
||||
lame_set_ATHlower (lame->lgf, lame->ath_lower);
|
||||
lame_set_cwlimit (lame->lgf, lame->cwlimit);
|
||||
lame_set_allow_diff_short (lame->lgf, lame->allow_diff_short);
|
||||
lame_set_no_short_blocks (lame->lgf, lame->no_short_blocks);
|
||||
lame_set_emphasis (lame->lgf, lame->emphasis);
|
||||
|
||||
// initialize the lame encoder
|
||||
/* initialize the lame encoder */
|
||||
if (lame_init_params (lame->lgf) < 0) {
|
||||
GST_DEBUG (0,"error initializinglame library\n");
|
||||
return FALSE;
|
||||
gst_element_error (GST_ELEMENT (lame), "could not initialize encoder (wrong parameters?)");
|
||||
lame->initialized = FALSE;
|
||||
}
|
||||
else {
|
||||
lame->initialized = TRUE;
|
||||
}
|
||||
|
||||
GST_DEBUG_LEAVE ("");
|
||||
|
@ -708,13 +759,28 @@ gst_lame_setup (GstLame *lame)
|
|||
static GstElementStateReturn
|
||||
gst_lame_change_state (GstElement *element)
|
||||
{
|
||||
GstLame *lame;
|
||||
|
||||
g_return_val_if_fail (GST_IS_LAME (element), GST_STATE_FAILURE);
|
||||
|
||||
lame = GST_LAME (element);
|
||||
|
||||
GST_DEBUG (0,"state pending %d\n", GST_STATE_PENDING (element));
|
||||
|
||||
/* if going down into NULL state, close the file if it's open */
|
||||
if (GST_STATE_PENDING (element) == GST_STATE_READY) {
|
||||
gst_lame_setup(GST_LAME(element));
|
||||
switch (GST_STATE_TRANSITION (element)) {
|
||||
case GST_STATE_NULL_TO_READY:
|
||||
if (!gst_lame_setup (lame)) {
|
||||
return GST_STATE_FAILURE;
|
||||
}
|
||||
break;
|
||||
case GST_STATE_READY_TO_NULL:
|
||||
if (lame->initialized) {
|
||||
lame_close (lame->lgf);
|
||||
lame->initialized = FALSE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* if we haven't failed already, give the parent class a chance to ;-) */
|
||||
|
|
|
@ -58,6 +58,7 @@ struct _GstLame {
|
|||
|
||||
gint samplerate;
|
||||
gint num_channels;
|
||||
gboolean initialized;
|
||||
|
||||
gint bitrate;
|
||||
gfloat compression_ratio;
|
||||
|
|
Loading…
Reference in a new issue