mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-11 08:52:39 +00:00
Apply patch from Jeffrey C. Ollie. Fixes rate (now always 8kHz) and adds timestamps
Original commit message from CVS: Apply patch from Jeffrey C. Ollie. Fixes rate (now always 8kHz) and adds timestamps
This commit is contained in:
parent
5c88ccad34
commit
9d608aed4d
5 changed files with 172 additions and 213 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2005-01-24 Jeffrey C. Ollie
|
||||||
|
|
||||||
|
reviewed by: Maciej Katafiasz <mathrick@freedesktop.org>
|
||||||
|
|
||||||
|
* ext/gsm/gstgsmdec.c: (gst_gsmdec_init), (gst_gsmdec_chain):
|
||||||
|
* ext/gsm/gstgsmdec.h:
|
||||||
|
* ext/gsm/gstgsmenc.c: (gst_gsmenc_init), (gst_gsmenc_chain):
|
||||||
|
* ext/gsm/gstgsmenc.h:
|
||||||
|
Fix rate to 8kHz as per spec, removes obscure errors when no rate
|
||||||
|
was given by property. Add proper buffer timestamps and offsets.
|
||||||
|
|
||||||
2005-01-24 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
2005-01-24 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||||
|
|
||||||
* gst-libs/gst/riff/riff-media.c:
|
* gst-libs/gst/riff/riff-media.c:
|
||||||
|
|
|
@ -51,8 +51,6 @@ static void gst_gsmdec_class_init (GstGSMDec * klass);
|
||||||
static void gst_gsmdec_init (GstGSMDec * gsmdec);
|
static void gst_gsmdec_init (GstGSMDec * gsmdec);
|
||||||
|
|
||||||
static void gst_gsmdec_chain (GstPad * pad, GstData * _data);
|
static void gst_gsmdec_chain (GstPad * pad, GstData * _data);
|
||||||
static GstCaps *gst_gsmdec_getcaps (GstPad * pad);
|
|
||||||
static GstPadLinkReturn gst_gsmdec_link (GstPad * pad, const GstCaps * caps);
|
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
|
|
||||||
|
@ -86,8 +84,7 @@ static GstStaticPadTemplate gsmdec_sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
GST_PAD_SINK,
|
GST_PAD_SINK,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("audio/x-gsm, "
|
GST_STATIC_CAPS ("audio/x-gsm, " "rate = (int) 8000, " "channels = (int) 1")
|
||||||
"rate = (int) [ 1000, 48000 ], " "channels = (int) 1")
|
|
||||||
);
|
);
|
||||||
|
|
||||||
static GstStaticPadTemplate gsmdec_src_template =
|
static GstStaticPadTemplate gsmdec_src_template =
|
||||||
|
@ -98,8 +95,7 @@ GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
"endianness = (int) BYTE_ORDER, "
|
"endianness = (int) BYTE_ORDER, "
|
||||||
"signed = (boolean) true, "
|
"signed = (boolean) true, "
|
||||||
"width = (int) 16, "
|
"width = (int) 16, "
|
||||||
"depth = (int) 16, "
|
"depth = (int) 16, " "rate = (int) 8000, " "channels = (int) 1")
|
||||||
"rate = (int) [ 1000, 48000 ], " "channels = (int) 1")
|
|
||||||
);
|
);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -134,96 +130,53 @@ gst_gsmdec_init (GstGSMDec * gsmdec)
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get
|
gst_pad_new_from_template (gst_static_pad_template_get
|
||||||
(&gsmdec_sink_template), "sink");
|
(&gsmdec_sink_template), "sink");
|
||||||
gst_pad_set_chain_function (gsmdec->sinkpad, gst_gsmdec_chain);
|
gst_pad_set_chain_function (gsmdec->sinkpad, gst_gsmdec_chain);
|
||||||
gst_pad_set_getcaps_function (gsmdec->sinkpad, gst_gsmdec_getcaps);
|
|
||||||
gst_pad_set_link_function (gsmdec->sinkpad, gst_gsmdec_link);
|
|
||||||
gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->sinkpad);
|
||||||
|
|
||||||
gsmdec->srcpad =
|
gsmdec->srcpad =
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get
|
gst_pad_new_from_template (gst_static_pad_template_get
|
||||||
(&gsmdec_src_template), "src");
|
(&gsmdec_src_template), "src");
|
||||||
gst_pad_set_getcaps_function (gsmdec->srcpad, gst_gsmdec_getcaps);
|
|
||||||
gst_pad_set_link_function (gsmdec->srcpad, gst_gsmdec_link);
|
|
||||||
gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->srcpad);
|
gst_element_add_pad (GST_ELEMENT (gsmdec), gsmdec->srcpad);
|
||||||
|
|
||||||
gsmdec->state = gsm_create ();
|
gsmdec->state = gsm_create ();
|
||||||
gsmdec->bufsize = 0;
|
gsmdec->bufsize = 0;
|
||||||
}
|
gsmdec->next_ts = 0;
|
||||||
|
gsmdec->next_of = 0;
|
||||||
static GstCaps *
|
|
||||||
gst_gsmdec_getcaps (GstPad * pad)
|
|
||||||
{
|
|
||||||
GstGSMDec *gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
|
|
||||||
const GValue *rate_value;
|
|
||||||
GstPad *otherpad;
|
|
||||||
GstCaps *othercaps, *basecaps;
|
|
||||||
|
|
||||||
if (pad == gsmdec->srcpad) {
|
|
||||||
otherpad = gsmdec->sinkpad;
|
|
||||||
basecaps = gst_caps_new_simple ("audio/x-raw-int",
|
|
||||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
|
||||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
|
||||||
"width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16, NULL);
|
|
||||||
} else {
|
|
||||||
otherpad = gsmdec->srcpad;
|
|
||||||
basecaps = gst_caps_new_simple ("audio/x-gsm", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
othercaps = gst_pad_get_allowed_caps (otherpad);
|
|
||||||
rate_value = gst_structure_get_value (gst_caps_get_structure (othercaps,
|
|
||||||
0), "rate");
|
|
||||||
gst_structure_set_value (gst_caps_get_structure (basecaps, 0), "rate",
|
|
||||||
rate_value);
|
|
||||||
gst_caps_set_simple (basecaps, "channels", G_TYPE_INT, 1, NULL);
|
|
||||||
|
|
||||||
return basecaps;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstPadLinkReturn
|
|
||||||
gst_gsmdec_link (GstPad * pad, const GstCaps * caps)
|
|
||||||
{
|
|
||||||
GstGSMDec *gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
|
|
||||||
GstPad *otherpad;
|
|
||||||
GstCaps *othercaps;
|
|
||||||
gint rate;
|
|
||||||
GstStructure *structure;
|
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
|
||||||
gst_structure_get_int (structure, "rate", &rate);
|
|
||||||
|
|
||||||
if (pad == gsmdec->sinkpad) {
|
|
||||||
otherpad = gsmdec->srcpad;
|
|
||||||
othercaps = gst_caps_new_simple ("audio/x-raw-int",
|
|
||||||
"endianness", G_TYPE_INT, G_BYTE_ORDER,
|
|
||||||
"signed", G_TYPE_BOOLEAN, TRUE,
|
|
||||||
"width", G_TYPE_INT, 16, "depth", G_TYPE_INT, 16, NULL);
|
|
||||||
} else {
|
|
||||||
otherpad = gsmdec->sinkpad;
|
|
||||||
othercaps = gst_caps_new_simple ("audio/x-gsm", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
gst_caps_set_simple (othercaps,
|
|
||||||
"rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, 1, NULL);
|
|
||||||
|
|
||||||
return gst_pad_try_set_caps (otherpad, othercaps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gsmdec_chain (GstPad * pad, GstData * _data)
|
gst_gsmdec_chain (GstPad * pad, GstData * _data)
|
||||||
{
|
{
|
||||||
GstBuffer *buf = GST_BUFFER (_data);
|
|
||||||
GstGSMDec *gsmdec;
|
GstGSMDec *gsmdec;
|
||||||
gsm_byte *data;
|
|
||||||
guint size;
|
|
||||||
|
|
||||||
g_return_if_fail (pad != NULL);
|
g_return_if_fail (pad != NULL);
|
||||||
g_return_if_fail (GST_IS_PAD (pad));
|
g_return_if_fail (GST_IS_PAD (pad));
|
||||||
g_return_if_fail (buf != NULL);
|
g_return_if_fail (_data != NULL);
|
||||||
/*g_return_if_fail(GST_IS_BUFFER(buf)); */
|
|
||||||
|
|
||||||
gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
|
gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
data = (gsm_byte *) GST_BUFFER_DATA (buf);
|
if (GST_IS_EVENT (_data)) {
|
||||||
size = GST_BUFFER_SIZE (buf);
|
GstEvent *event = GST_EVENT (_data);
|
||||||
|
|
||||||
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_EOS:{
|
||||||
|
gst_element_set_eos (GST_ELEMENT (gsmdec));
|
||||||
|
gst_pad_push (gsmdec->srcpad, _data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GST_EVENT_DISCONTINUOUS:{
|
||||||
|
/* drop the discontinuity */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
gst_pad_event_default (pad, event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (GST_IS_BUFFER (_data)) {
|
||||||
|
GstBuffer *buf = GST_BUFFER (_data);
|
||||||
|
gsm_byte *data = (gsm_byte *) GST_BUFFER_DATA (buf);
|
||||||
|
guint size = GST_BUFFER_SIZE (buf);
|
||||||
|
|
||||||
if (gsmdec->bufsize && (gsmdec->bufsize + size >= 33)) {
|
if (gsmdec->bufsize && (gsmdec->bufsize + size >= 33)) {
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
|
@ -231,9 +184,13 @@ gst_gsmdec_chain (GstPad * pad, GstData * _data)
|
||||||
memcpy (gsmdec->buffer + gsmdec->bufsize, data,
|
memcpy (gsmdec->buffer + gsmdec->bufsize, data,
|
||||||
(33 - gsmdec->bufsize) * sizeof (gsm_byte));
|
(33 - gsmdec->bufsize) * sizeof (gsm_byte));
|
||||||
|
|
||||||
outbuf = gst_buffer_new ();
|
outbuf = gst_buffer_new_and_alloc (160 * sizeof (gsm_signal));
|
||||||
GST_BUFFER_DATA (outbuf) = g_malloc (160 * sizeof (gsm_signal));
|
GST_BUFFER_TIMESTAMP (outbuf) = gsmdec->next_ts;
|
||||||
GST_BUFFER_SIZE (outbuf) = 160 * sizeof (gsm_signal);
|
GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND;
|
||||||
|
GST_BUFFER_OFFSET (outbuf) = gsmdec->next_of;
|
||||||
|
GST_BUFFER_OFFSET_END (outbuf) = gsmdec->next_of + 160 - 1;
|
||||||
|
gsmdec->next_ts += 20 * GST_MSECOND;
|
||||||
|
gsmdec->next_of += 160;
|
||||||
|
|
||||||
gsm_decode (gsmdec->state, gsmdec->buffer,
|
gsm_decode (gsmdec->state, gsmdec->buffer,
|
||||||
(gsm_signal *) GST_BUFFER_DATA (outbuf));
|
(gsm_signal *) GST_BUFFER_DATA (outbuf));
|
||||||
|
@ -249,6 +206,13 @@ gst_gsmdec_chain (GstPad * pad, GstData * _data)
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
|
|
||||||
outbuf = gst_buffer_new_and_alloc (160 * sizeof (gsm_signal));
|
outbuf = gst_buffer_new_and_alloc (160 * sizeof (gsm_signal));
|
||||||
|
GST_BUFFER_TIMESTAMP (outbuf) = gsmdec->next_ts;
|
||||||
|
GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND;
|
||||||
|
GST_BUFFER_OFFSET (outbuf) = gsmdec->next_of;
|
||||||
|
GST_BUFFER_OFFSET_END (outbuf) = gsmdec->next_of + 160 - 1;
|
||||||
|
gsmdec->next_ts += 20 * GST_MSECOND;
|
||||||
|
gsmdec->next_of += 160;
|
||||||
|
|
||||||
gsm_decode (gsmdec->state, data, (gsm_signal *) GST_BUFFER_DATA (outbuf));
|
gsm_decode (gsmdec->state, data, (gsm_signal *) GST_BUFFER_DATA (outbuf));
|
||||||
gst_pad_push (gsmdec->srcpad, GST_DATA (outbuf));
|
gst_pad_push (gsmdec->srcpad, GST_DATA (outbuf));
|
||||||
|
|
||||||
|
@ -262,4 +226,6 @@ gst_gsmdec_chain (GstPad * pad, GstData * _data)
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,9 @@
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GST_GSMDEC_H__
|
#ifndef __GST_GSMDEC_H__
|
||||||
#define __GST_GSMDEC_H__
|
#define __GST_GSMDEC_H__
|
||||||
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
#ifdef GSM_HEADER_IN_SUBDIR
|
#ifdef GSM_HEADER_IN_SUBDIR
|
||||||
|
@ -30,10 +28,7 @@
|
||||||
#include <gsm.h>
|
#include <gsm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
G_BEGIN_DECLS
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
#define GST_TYPE_GSMDEC \
|
#define GST_TYPE_GSMDEC \
|
||||||
(gst_gsmdec_get_type())
|
(gst_gsmdec_get_type())
|
||||||
|
@ -49,7 +44,8 @@ extern "C" {
|
||||||
typedef struct _GstGSMDec GstGSMDec;
|
typedef struct _GstGSMDec GstGSMDec;
|
||||||
typedef struct _GstGSMDecClass GstGSMDecClass;
|
typedef struct _GstGSMDecClass GstGSMDecClass;
|
||||||
|
|
||||||
struct _GstGSMDec {
|
struct _GstGSMDec
|
||||||
|
{
|
||||||
GstElement element;
|
GstElement element;
|
||||||
|
|
||||||
/* pads */
|
/* pads */
|
||||||
|
@ -58,18 +54,17 @@ struct _GstGSMDec {
|
||||||
gsm state;
|
gsm state;
|
||||||
gsm_byte buffer[33];
|
gsm_byte buffer[33];
|
||||||
gint bufsize;
|
gint bufsize;
|
||||||
|
GstClockTime next_ts;
|
||||||
|
gint64 next_of;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGSMDecClass {
|
struct _GstGSMDecClass
|
||||||
|
{
|
||||||
GstElementClass parent_class;
|
GstElementClass parent_class;
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_gsmdec_get_type (void);
|
GType gst_gsmdec_get_type (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GST_GSMDEC_H__ */
|
#endif /* __GST_GSMDEC_H__ */
|
||||||
|
|
|
@ -52,8 +52,6 @@ static void gst_gsmenc_class_init (GstGSMEnc * klass);
|
||||||
static void gst_gsmenc_init (GstGSMEnc * gsmenc);
|
static void gst_gsmenc_init (GstGSMEnc * gsmenc);
|
||||||
|
|
||||||
static void gst_gsmenc_chain (GstPad * pad, GstData * _data);
|
static void gst_gsmenc_chain (GstPad * pad, GstData * _data);
|
||||||
static GstPadLinkReturn gst_gsmenc_sinkconnect (GstPad * pad,
|
|
||||||
const GstCaps * caps);
|
|
||||||
|
|
||||||
static GstElementClass *parent_class = NULL;
|
static GstElementClass *parent_class = NULL;
|
||||||
static guint gst_gsmenc_signals[LAST_SIGNAL] = { 0 };
|
static guint gst_gsmenc_signals[LAST_SIGNAL] = { 0 };
|
||||||
|
@ -86,8 +84,7 @@ static GstStaticPadTemplate gsmenc_src_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("src",
|
GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
GST_PAD_SRC,
|
GST_PAD_SRC,
|
||||||
GST_PAD_ALWAYS,
|
GST_PAD_ALWAYS,
|
||||||
GST_STATIC_CAPS ("audio/x-gsm, "
|
GST_STATIC_CAPS ("audio/x-gsm, " "rate = (int) 8000, " "channels = (int) 1")
|
||||||
"rate = (int) [ 1000, 48000 ], " "channels = (int) 1")
|
|
||||||
);
|
);
|
||||||
|
|
||||||
static GstStaticPadTemplate gsmenc_sink_template =
|
static GstStaticPadTemplate gsmenc_sink_template =
|
||||||
|
@ -98,8 +95,7 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
||||||
"endianness = (int) BYTE_ORDER, "
|
"endianness = (int) BYTE_ORDER, "
|
||||||
"signed = (boolean) true, "
|
"signed = (boolean) true, "
|
||||||
"width = (int) 16, "
|
"width = (int) 16, "
|
||||||
"depth = (int) 16, "
|
"depth = (int) 16, " "rate = (int) 8000, " "channels = (int) 1")
|
||||||
"rate = (int) [ 1000, 48000 ], " "channels = (int) 1")
|
|
||||||
);
|
);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -141,7 +137,6 @@ gst_gsmenc_init (GstGSMEnc * gsmenc)
|
||||||
(&gsmenc_sink_template), "sink");
|
(&gsmenc_sink_template), "sink");
|
||||||
gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->sinkpad);
|
gst_element_add_pad (GST_ELEMENT (gsmenc), gsmenc->sinkpad);
|
||||||
gst_pad_set_chain_function (gsmenc->sinkpad, gst_gsmenc_chain);
|
gst_pad_set_chain_function (gsmenc->sinkpad, gst_gsmenc_chain);
|
||||||
gst_pad_set_link_function (gsmenc->sinkpad, gst_gsmenc_sinkconnect);
|
|
||||||
|
|
||||||
gsmenc->srcpad =
|
gsmenc->srcpad =
|
||||||
gst_pad_new_from_template (gst_static_pad_template_get
|
gst_pad_new_from_template (gst_static_pad_template_get
|
||||||
|
@ -151,43 +146,43 @@ gst_gsmenc_init (GstGSMEnc * gsmenc)
|
||||||
gsmenc->state = gsm_create ();
|
gsmenc->state = gsm_create ();
|
||||||
gsmenc->bufsize = 0;
|
gsmenc->bufsize = 0;
|
||||||
gsmenc->next_ts = 0;
|
gsmenc->next_ts = 0;
|
||||||
gsmenc->rate = 8000;
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstPadLinkReturn
|
|
||||||
gst_gsmenc_sinkconnect (GstPad * pad, const GstCaps * caps)
|
|
||||||
{
|
|
||||||
GstGSMEnc *gsmenc;
|
|
||||||
GstStructure *structure;
|
|
||||||
|
|
||||||
gsmenc = GST_GSMENC (gst_pad_get_parent (pad));
|
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
|
||||||
gst_structure_get_int (structure, "rate", &gsmenc->rate);
|
|
||||||
if (gst_pad_try_set_caps (gsmenc->srcpad,
|
|
||||||
gst_caps_new_simple ("audio/x-gsm",
|
|
||||||
"rate", G_TYPE_INT, gsmenc->rate,
|
|
||||||
"channels", G_TYPE_INT, 1, NULL)) > 0) {
|
|
||||||
return GST_PAD_LINK_OK;
|
|
||||||
}
|
|
||||||
return GST_PAD_LINK_REFUSED;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_gsmenc_chain (GstPad * pad, GstData * _data)
|
gst_gsmenc_chain (GstPad * pad, GstData * _data)
|
||||||
{
|
{
|
||||||
GstBuffer *buf = GST_BUFFER (_data);
|
|
||||||
GstGSMEnc *gsmenc;
|
GstGSMEnc *gsmenc;
|
||||||
gsm_signal *data;
|
|
||||||
guint size;
|
|
||||||
|
|
||||||
g_return_if_fail (pad != NULL);
|
g_return_if_fail (pad != NULL);
|
||||||
g_return_if_fail (GST_IS_PAD (pad));
|
g_return_if_fail (GST_IS_PAD (pad));
|
||||||
g_return_if_fail (buf != NULL);
|
g_return_if_fail (_data != NULL);
|
||||||
|
|
||||||
gsmenc = GST_GSMENC (GST_OBJECT_PARENT (pad));
|
gsmenc = GST_GSMENC (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
|
if (GST_IS_EVENT (_data)) {
|
||||||
|
GstEvent *event = GST_EVENT (_data);
|
||||||
|
|
||||||
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_EOS:{
|
||||||
|
gst_element_set_eos (GST_ELEMENT (gsmenc));
|
||||||
|
gst_pad_push (gsmenc->srcpad, _data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GST_EVENT_DISCONTINUOUS:{
|
||||||
|
/* drop the discontinuity */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
gst_pad_event_default (pad, event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else if (GST_IS_BUFFER (_data)) {
|
||||||
|
GstBuffer *buf = GST_BUFFER (_data);
|
||||||
|
gsm_signal *data;
|
||||||
|
guint size;
|
||||||
|
|
||||||
data = (gsm_signal *) GST_BUFFER_DATA (buf);
|
data = (gsm_signal *) GST_BUFFER_DATA (buf);
|
||||||
size = GST_BUFFER_SIZE (buf) / sizeof (gsm_signal);
|
size = GST_BUFFER_SIZE (buf) / sizeof (gsm_signal);
|
||||||
|
|
||||||
|
@ -197,16 +192,15 @@ gst_gsmenc_chain (GstPad * pad, GstData * _data)
|
||||||
memcpy (gsmenc->buffer + gsmenc->bufsize, data,
|
memcpy (gsmenc->buffer + gsmenc->bufsize, data,
|
||||||
(160 - gsmenc->bufsize) * sizeof (gsm_signal));
|
(160 - gsmenc->bufsize) * sizeof (gsm_signal));
|
||||||
|
|
||||||
outbuf = gst_buffer_new ();
|
outbuf = gst_buffer_new_and_alloc (33 * sizeof (gsm_byte));
|
||||||
GST_BUFFER_DATA (outbuf) = g_malloc (33 * sizeof (gsm_byte));
|
GST_BUFFER_TIMESTAMP (outbuf) = gsmenc->next_ts;
|
||||||
GST_BUFFER_SIZE (outbuf) = 33 * sizeof (gsm_byte);
|
GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND;
|
||||||
|
gsmenc->next_ts += 20 * GST_MSECOND;
|
||||||
|
|
||||||
gsm_encode (gsmenc->state, gsmenc->buffer,
|
gsm_encode (gsmenc->state, gsmenc->buffer,
|
||||||
(gsm_byte *) GST_BUFFER_DATA (outbuf));
|
(gsm_byte *) GST_BUFFER_DATA (outbuf));
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = gsmenc->next_ts;
|
|
||||||
gst_pad_push (gsmenc->srcpad, GST_DATA (outbuf));
|
gst_pad_push (gsmenc->srcpad, GST_DATA (outbuf));
|
||||||
gsmenc->next_ts += (160.0 / gsmenc->rate) * 1000000;
|
|
||||||
|
|
||||||
size -= (160 - gsmenc->bufsize);
|
size -= (160 - gsmenc->bufsize);
|
||||||
data += (160 - gsmenc->bufsize);
|
data += (160 - gsmenc->bufsize);
|
||||||
|
@ -216,24 +210,26 @@ gst_gsmenc_chain (GstPad * pad, GstData * _data)
|
||||||
while (size >= 160) {
|
while (size >= 160) {
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
|
|
||||||
outbuf = gst_buffer_new ();
|
outbuf = gst_buffer_new_and_alloc (33 * sizeof (gsm_byte));
|
||||||
GST_BUFFER_DATA (outbuf) = g_malloc (33 * sizeof (gsm_byte));
|
GST_BUFFER_TIMESTAMP (outbuf) = gsmenc->next_ts;
|
||||||
GST_BUFFER_SIZE (outbuf) = 33 * sizeof (gsm_byte);
|
GST_BUFFER_DURATION (outbuf) = 20 * GST_MSECOND;
|
||||||
|
gsmenc->next_ts += 20 * GST_MSECOND;
|
||||||
|
|
||||||
gsm_encode (gsmenc->state, data, (gsm_byte *) GST_BUFFER_DATA (outbuf));
|
gsm_encode (gsmenc->state, data, (gsm_byte *) GST_BUFFER_DATA (outbuf));
|
||||||
|
|
||||||
GST_BUFFER_TIMESTAMP (outbuf) = gsmenc->next_ts;
|
|
||||||
gst_pad_push (gsmenc->srcpad, GST_DATA (outbuf));
|
gst_pad_push (gsmenc->srcpad, GST_DATA (outbuf));
|
||||||
gsmenc->next_ts += (160 / gsmenc->rate) * GST_SECOND;
|
|
||||||
|
|
||||||
size -= 160;
|
size -= 160;
|
||||||
data += 160;
|
data += 160;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (size) {
|
if (size) {
|
||||||
memcpy (gsmenc->buffer + gsmenc->bufsize, data, size * sizeof (gsm_signal));
|
memcpy (gsmenc->buffer + gsmenc->bufsize, data,
|
||||||
|
size * sizeof (gsm_signal));
|
||||||
gsmenc->bufsize += size;
|
gsmenc->bufsize += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_buffer_unref (buf);
|
gst_buffer_unref (buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,9 @@
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __GST_GSMENC_H__
|
#ifndef __GST_GSMENC_H__
|
||||||
#define __GST_GSMENC_H__
|
#define __GST_GSMENC_H__
|
||||||
|
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
|
||||||
#ifdef GSM_HEADER_IN_SUBDIR
|
#ifdef GSM_HEADER_IN_SUBDIR
|
||||||
|
@ -30,10 +28,7 @@
|
||||||
#include <gsm.h>
|
#include <gsm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
G_BEGIN_DECLS
|
||||||
extern "C" {
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
#define GST_TYPE_GSMENC \
|
#define GST_TYPE_GSMENC \
|
||||||
(gst_gsmenc_get_type())
|
(gst_gsmenc_get_type())
|
||||||
|
@ -49,7 +44,8 @@ extern "C" {
|
||||||
typedef struct _GstGSMEnc GstGSMEnc;
|
typedef struct _GstGSMEnc GstGSMEnc;
|
||||||
typedef struct _GstGSMEncClass GstGSMEncClass;
|
typedef struct _GstGSMEncClass GstGSMEncClass;
|
||||||
|
|
||||||
struct _GstGSMEnc {
|
struct _GstGSMEnc
|
||||||
|
{
|
||||||
GstElement element;
|
GstElement element;
|
||||||
|
|
||||||
/* pads */
|
/* pads */
|
||||||
|
@ -58,12 +54,11 @@ struct _GstGSMEnc {
|
||||||
gsm state;
|
gsm state;
|
||||||
gsm_signal buffer[160];
|
gsm_signal buffer[160];
|
||||||
gint bufsize;
|
gint bufsize;
|
||||||
|
GstClockTime next_ts;
|
||||||
guint64 next_ts;
|
|
||||||
gint rate;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstGSMEncClass {
|
struct _GstGSMEncClass
|
||||||
|
{
|
||||||
GstElementClass parent_class;
|
GstElementClass parent_class;
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
|
@ -72,10 +67,6 @@ struct _GstGSMEncClass {
|
||||||
|
|
||||||
GType gst_gsmenc_get_type (void);
|
GType gst_gsmenc_get_type (void);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif /* __cplusplus */
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* __GST_GSMENC_H__ */
|
#endif /* __GST_GSMENC_H__ */
|
||||||
|
|
Loading…
Reference in a new issue