uint8_t	AUDMEncoder_Twolame::getPacket(uint8_t *dest, uint32_t *len, uint32_t *samples)
{
  int nbout;
  
  *samples = 1152; //FIXME
  *len = 0;
  ADM_assert(tmptail>=tmphead);
  if(!refillBuffer(_chunk ))
  {
    return 0; 
  }
        
  if(tmptail-tmphead<_chunk)
  {
    return 0; 
  }

  dither16(&(tmpbuffer[tmphead]),_chunk,_wavheader->channels);

  ADM_assert(tmptail>=tmphead);
  if (_wavheader->channels == 1)
  {
    nbout =twolame_encode_buffer(OPTIONS, (int16_t *)&(tmpbuffer[tmphead]),(int16_t *)&(tmpbuffer[tmphead]), _chunk, dest, 16 * 1024);
  }
  else
  {
    nbout = twolame_encode_buffer_interleaved(OPTIONS, (int16_t *)&(tmpbuffer[tmphead]), _chunk/2, dest, 16 * 1024);
  }
  tmphead+=_chunk;
  ADM_assert(tmptail>=tmphead);
  if (nbout < 0) {
    printf("\n Error !!! : %ld\n", nbout);
    return 0;
  }
  *len=nbout;
  return 1;
}
/**
        \fn getPacket
*/
bool 	AUDMEncoder_Twolame::encode(uint8_t *dest, uint32_t *len, uint32_t *samples)
{
  int nbout;
  int channels=wavheader.channels;
  *samples = 1152; //FIXME
  *len = 0;
  ADM_assert(tmptail>=tmphead);
  if(!refillBuffer(_chunk ))
  {
    return false;
  }

  if(tmptail-tmphead<_chunk)
  {
    return false;
  }

  dither16(&(tmpbuffer[tmphead]),_chunk,channels);

  ADM_assert(tmptail>=tmphead);
  if (channels == 1)
  {
    nbout =twolame_encode_buffer(OPTIONS, (int16_t *)&(tmpbuffer[tmphead]),(int16_t *)&(tmpbuffer[tmphead]), _chunk, dest, 16 * 1024);
  }
  else
  {
    nbout = twolame_encode_buffer_interleaved(OPTIONS, (int16_t *)&(tmpbuffer[tmphead]), _chunk/2, dest, 16 * 1024);
  }
  tmphead+=_chunk;
  ADM_assert(tmptail>=tmphead);
  if (nbout < 0) {
    printf("[TwoLame] Error !!! : %d\n", nbout);
    return false;
  }
  *len=nbout;
  return true;
}
Example #3
0
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;
}