rendered paste bodystatic void
gst_gsmdec_chain (GstPad * pad, GstData * _data)
{
GstGSMDec *gsmdec;
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (_data != NULL);
gsmdec = GST_GSMDEC (gst_pad_get_parent (pad));
if (!gsmdec->sent_discontinuity) {
gst_pad_push(gsmdec->srcpad,
GST_DATA(gst_event_new_discontinuous(TRUE,
GST_FORMAT_TIME,
(gint64) 0,
GST_FORMAT_BYTES,
(gint64) 0,
GST_FORMAT_UNDEFINED)));
gsmdec->sent_discontinuity = TRUE;
}
if (GST_IS_EVENT(_data)) {
GstEvent *event = GST_EVENT(_data);
switch (GST_EVENT_TYPE (event))
{
case GST_EVENT_EOS: {
fprintf(stderr, "End of Stream\n");
gst_element_set_eos(GST_ELEMENT(gsmdec));
gst_pad_push(gsmdec->srcpad, _data);
break;
}
case GST_EVENT_DISCONTINUOUS:
{
fprintf(stderr, "Discontinuity\n");
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)) {
GstBuffer *outbuf;
memcpy (gsmdec->buffer + gsmdec->bufsize, data,
(33 - gsmdec->bufsize) * sizeof (gsm_byte));
outbuf = gst_buffer_new_and_alloc (160 * sizeof (gsm_signal));
GST_BUFFER_TIMESTAMP (outbuf) = gsmdec->timestamp;
GST_BUFFER_DURATION (outbuf) = 20 * GST_USECOND;
GST_BUFFER_OFFSET (outbuf) = gsmdec->offset;
GST_BUFFER_OFFSET_END (outbuf) = gsmdec->offset + 160 - 1;
gsmdec->timestamp += 20 * GST_USECOND;
gsmdec->offset += 160;
gsm_decode(gsmdec->state, gsmdec->buffer,
(gsm_signal *) GST_BUFFER_DATA (outbuf));
gst_pad_push (gsmdec->srcpad, GST_DATA (outbuf));
size -= (33 - gsmdec->bufsize);
data += (33 - gsmdec->bufsize);
gsmdec->bufsize = 0;
}
while (size >= 33) {
GstBuffer *outbuf;
outbuf = gst_buffer_new_and_alloc (160 * sizeof (gsm_signal));
GST_BUFFER_TIMESTAMP (outbuf) = gsmdec->timestamp;
GST_BUFFER_DURATION (outbuf) = 20 * GST_USECOND;
GST_BUFFER_OFFSET (outbuf) = gsmdec->offset;
GST_BUFFER_OFFSET_END (outbuf) = gsmdec->offset + 160 - 1;
gsmdec->timestamp += 20 * GST_USECOND;
gsmdec->offset += 160;
gsm_decode (gsmdec->state, data, (gsm_signal *) GST_BUFFER_DATA (outbuf));
gst_pad_push (gsmdec->srcpad, GST_DATA (outbuf));
size -= 33;
data += 33;
}
if (size) {
memcpy (gsmdec->buffer + gsmdec->bufsize, data, size * sizeof (gsm_byte));
gsmdec->bufsize += size;
}
gst_buffer_unref (buf);
return;
}
}