void MpegL2Codec::encodeData(Connector *conn,const float *pcm,int frames) { #ifdef HAVE_TWOLAME int s; unsigned char mpeg[8640]; if((s=twolame_encode_buffer_float32_interleaved(twolame_lameopts,pcm,frames, mpeg,8640))>=0) { conn->writeData(frames,mpeg,s); } #endif // HAVE_TWOLAME }
// Encode a packet's payload size_t MastCodec_MPA::encode_packet_internal( size_t inputsize, /* input size in frames */ mast_sample_t *input, size_t outputsize, /* output size in bytes */ u_int8_t *output) { int bytes_encoded = 0; // MPEG Audio header is 4 bytes at the start of the packet output[0] = 0x00; output[1] = 0x00; output[2] = 0x00; output[3] = 0x00; // Encode the audio using twolame bytes_encoded = twolame_encode_buffer_float32_interleaved( this->twolame, input, inputsize, output+4, outputsize-4 ); //MAST_DEBUG( "mast_encode_mpa: encoded %d samples to %d bytes (max %d bytes)", inputsize, bytes_encoded, outputsize ); return bytes_encoded+4; }
static GstFlowReturn gst_two_lame_chain (GstPad * pad, GstBuffer * buf) { GstTwoLame *twolame; guchar *mp3_data; gint mp3_buffer_size, mp3_size; gint64 duration; GstFlowReturn result; gint num_samples; guint8 *data; guint size; twolame = GST_TWO_LAME (GST_PAD_PARENT (pad)); GST_LOG_OBJECT (twolame, "entered chain"); if (!twolame->setup) goto not_setup; data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); if (twolame->float_input) num_samples = size / 4; else num_samples = size / 2; /* allocate space for output */ mp3_buffer_size = 1.25 * num_samples + 16384; mp3_data = g_malloc (mp3_buffer_size); if (twolame->num_channels == 1) { if (twolame->float_input) mp3_size = twolame_encode_buffer_float32 (twolame->glopts, (float *) data, (float *) data, num_samples, mp3_data, mp3_buffer_size); else mp3_size = twolame_encode_buffer (twolame->glopts, (short int *) data, (short int *) data, num_samples, mp3_data, mp3_buffer_size); } else { if (twolame->float_input) mp3_size = twolame_encode_buffer_float32_interleaved (twolame->glopts, (float *) data, num_samples / twolame->num_channels, mp3_data, mp3_buffer_size); else mp3_size = twolame_encode_buffer_interleaved (twolame->glopts, (short int *) data, num_samples / twolame->num_channels, mp3_data, mp3_buffer_size); } GST_LOG_OBJECT (twolame, "encoded %d bytes of audio to %d bytes of mp3", size, mp3_size); if (twolame->float_input) duration = gst_util_uint64_scale_int (size, GST_SECOND, 4 * twolame->samplerate * twolame->num_channels); else duration = gst_util_uint64_scale_int (size, GST_SECOND, 2 * twolame->samplerate * twolame->num_channels); if (GST_BUFFER_DURATION (buf) != GST_CLOCK_TIME_NONE && GST_BUFFER_DURATION (buf) != duration) { GST_DEBUG_OBJECT (twolame, "incoming buffer had incorrect duration %" GST_TIME_FORMAT ", outgoing buffer will have correct duration %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_TIME_ARGS (duration)); } if (twolame->last_ts == GST_CLOCK_TIME_NONE) { twolame->last_ts = GST_BUFFER_TIMESTAMP (buf); twolame->last_offs = GST_BUFFER_OFFSET (buf); twolame->last_duration = duration; } else { twolame->last_duration += duration; } gst_buffer_unref (buf); if (mp3_size < 0) { g_warning ("error %d", mp3_size); } if (mp3_size > 0) { GstBuffer *outbuf; outbuf = gst_buffer_new (); GST_BUFFER_DATA (outbuf) = mp3_data; GST_BUFFER_MALLOCDATA (outbuf) = mp3_data; GST_BUFFER_SIZE (outbuf) = mp3_size; GST_BUFFER_TIMESTAMP (outbuf) = twolame->last_ts; GST_BUFFER_OFFSET (outbuf) = twolame->last_offs; GST_BUFFER_DURATION (outbuf) = twolame->last_duration; gst_buffer_set_caps (outbuf, GST_PAD_CAPS (twolame->srcpad)); result = gst_pad_push (twolame->srcpad, outbuf); twolame->last_flow = result; if (result != GST_FLOW_OK) { GST_DEBUG_OBJECT (twolame, "flow return: %s", gst_flow_get_name (result)); } if (GST_CLOCK_TIME_IS_VALID (twolame->last_ts)) twolame->eos_ts = twolame->last_ts + twolame->last_duration; else twolame->eos_ts = GST_CLOCK_TIME_NONE; twolame->last_ts = GST_CLOCK_TIME_NONE; } else { g_free (mp3_data); result = GST_FLOW_OK; } return result; /* ERRORS */ not_setup: { gst_buffer_unref (buf); GST_ELEMENT_ERROR (twolame, CORE, NEGOTIATION, (NULL), ("encoder not initialized (input is not audio?)")); return GST_FLOW_ERROR; } }
static GstFlowReturn gst_two_lame_handle_frame (GstAudioEncoder * enc, GstBuffer * buf) { GstTwoLame *twolame; gint mp3_buffer_size, mp3_size; GstBuffer *mp3_buf; GstFlowReturn result; gint num_samples; GstMapInfo map, mp3_map; twolame = GST_TWO_LAME (enc); /* squeeze remaining and push */ if (G_UNLIKELY (buf == NULL)) return gst_two_lame_flush_full (twolame, TRUE); gst_buffer_map (buf, &map, GST_MAP_READ); if (twolame->float_input) num_samples = map.size / 4; else num_samples = map.size / 2; /* allocate space for output */ mp3_buffer_size = 1.25 * num_samples + 16384; mp3_buf = gst_buffer_new_and_alloc (mp3_buffer_size); gst_buffer_map (mp3_buf, &mp3_map, GST_MAP_WRITE); if (twolame->num_channels == 1) { if (twolame->float_input) mp3_size = twolame_encode_buffer_float32 (twolame->glopts, (float *) map.data, (float *) map.data, num_samples, mp3_map.data, mp3_buffer_size); else mp3_size = twolame_encode_buffer (twolame->glopts, (short int *) map.data, (short int *) map.data, num_samples, mp3_map.data, mp3_buffer_size); } else { if (twolame->float_input) mp3_size = twolame_encode_buffer_float32_interleaved (twolame->glopts, (float *) map.data, num_samples / twolame->num_channels, mp3_map.data, mp3_buffer_size); else mp3_size = twolame_encode_buffer_interleaved (twolame->glopts, (short int *) map.data, num_samples / twolame->num_channels, mp3_map.data, mp3_buffer_size); } GST_LOG_OBJECT (twolame, "encoded %" G_GSIZE_FORMAT " bytes of audio " "to %d bytes of mp3", map.size, mp3_size); gst_buffer_unmap (buf, &map); gst_buffer_unmap (mp3_buf, &mp3_map); if (mp3_size > 0) { gst_buffer_set_size (mp3_buf, mp3_size); result = gst_audio_encoder_finish_frame (enc, mp3_buf, -1); } else { if (mp3_size < 0) { /* eat error ? */ g_warning ("error %d", mp3_size); } gst_buffer_unref (mp3_buf); result = GST_FLOW_OK; } return result; }