static GstFlowReturn gst_mulawdec_handle_frame (GstAudioDecoder * dec, GstBuffer * buffer) { GstMapInfo inmap, outmap; gint16 *linear_data; guint8 *mulaw_data; gsize mulaw_size, linear_size; GstBuffer *outbuf; if (!buffer) { return GST_FLOW_OK; } if (!gst_buffer_map (buffer, &inmap, GST_MAP_READ)) { GST_ERROR ("failed to map input buffer"); goto error_failed_map_input_buffer; } mulaw_data = inmap.data; mulaw_size = inmap.size; linear_size = mulaw_size * 2; outbuf = gst_audio_decoder_allocate_output_buffer (dec, linear_size); if (!gst_buffer_map (outbuf, &outmap, GST_MAP_WRITE)) { GST_ERROR ("failed to map input buffer"); goto error_failed_map_output_buffer; } linear_data = (gint16 *) outmap.data; mulaw_decode (mulaw_data, linear_data, mulaw_size); gst_buffer_unmap (outbuf, &outmap); gst_buffer_unmap (buffer, &inmap); return gst_audio_decoder_finish_frame (dec, outbuf, -1); error_failed_map_output_buffer: gst_buffer_unref (outbuf); error_failed_map_input_buffer: return GST_FLOW_ERROR; }
static int convert_mulaw_pcm_sample_rate(char* out_buf, int out_buf_size, char* in_buf, int in_buf_size, int in_sr, int out_sr, int num_of_channels, int sample_size, int num_of_in_samples){ int result = 0; int i,j,k; if (sample_size == 8){ unsigned char* ip = (unsigned char*) in_buf; short* op = (short*)out_buf; int multiplier = out_sr / in_sr; int iss = num_of_channels; int oss = num_of_channels * multiplier; int ocs = num_of_channels; for(i = 0; i < num_of_in_samples; ++i){ for(k = 0; k < multiplier; ++k){ for(j = 0; j < num_of_channels; ++j){ op[i * oss + k * ocs + j] = mulaw_decode(ip[i * iss + j]); } } } if (((num_of_in_samples * multiplier) % MPEG_LAYER_2_PACKET_SIZE) == 0) result = ((num_of_in_samples * multiplier) / MPEG_LAYER_2_PACKET_SIZE ) ; else result = ((num_of_in_samples * multiplier) / MPEG_LAYER_2_PACKET_SIZE + 1) * MPEG_LAYER_2_PACKET_SIZE; } return result; }
static GstFlowReturn gst_mulawdec_chain (GstPad * pad, GstBuffer * buffer) { GstMuLawDec *mulawdec; gint16 *linear_data; guint8 *mulaw_data; guint mulaw_size; GstBuffer *outbuf; GstFlowReturn ret; mulawdec = GST_MULAWDEC (GST_PAD_PARENT (pad)); if (G_UNLIKELY (mulawdec->rate == 0)) goto not_negotiated; mulaw_data = (guint8 *) GST_BUFFER_DATA (buffer); mulaw_size = GST_BUFFER_SIZE (buffer); ret = gst_pad_alloc_buffer_and_set_caps (mulawdec->srcpad, GST_BUFFER_OFFSET_NONE, mulaw_size * 2, GST_PAD_CAPS (mulawdec->srcpad), &outbuf); if (ret != GST_FLOW_OK) goto alloc_failed; linear_data = (gint16 *) GST_BUFFER_DATA (outbuf); /* copy discont flag */ if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT); GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buffer); if (GST_BUFFER_DURATION (outbuf) == GST_CLOCK_TIME_NONE) GST_BUFFER_DURATION (outbuf) = gst_util_uint64_scale_int (GST_SECOND, mulaw_size * 2, 2 * mulawdec->rate * mulawdec->channels); else GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buffer); gst_buffer_set_caps (outbuf, GST_PAD_CAPS (mulawdec->srcpad)); mulaw_decode (mulaw_data, linear_data, mulaw_size); gst_buffer_unref (buffer); ret = gst_pad_push (mulawdec->srcpad, outbuf); return ret; /* ERRORS */ not_negotiated: { GST_WARNING_OBJECT (mulawdec, "no input format set: not-negotiated"); gst_buffer_unref (buffer); return GST_FLOW_NOT_NEGOTIATED; } alloc_failed: { GST_DEBUG_OBJECT (mulawdec, "pad alloc failed, flow: %s", gst_flow_get_name (ret)); gst_buffer_unref (buffer); return ret; } }