/* GStreamer
 * Copyright (C) <2006> Philippe Khalaf <philippe.kalaf@collabora.co.uk>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:gstrtpbaseaudiopayload
 * @title: GstRTPBaseAudioPayload
 * @short_description: Base class for audio RTP payloader
 *
 * Provides a base class for audio RTP payloaders for frame or sample based
 * audio codecs (constant bitrate)
 *
 * This class derives from GstRTPBasePayload. It can be used for payloading
 * audio codecs. It will only work with constant bitrate codecs. It supports
 * both frame based and sample based codecs. It takes care of packing up the
 * audio data into RTP packets and filling up the headers accordingly. The
 * payloading is done based on the maximum MTU (mtu) and the maximum time per
 * packet (max-ptime). The general idea is to divide large data buffers into
 * smaller RTP packets. The RTP packet size is the minimum of either the MTU,
 * max-ptime (if set) or available data. The RTP packet size is always larger or
 * equal to min-ptime (if set). If min-ptime is not set, any residual data is
 * sent in a last RTP packet. In the case of frame based codecs, the resulting
 * RTP packets always contain full frames.
 *
 * ## Usage
 *
 * To use this base class, your child element needs to call either
 * gst_rtp_base_audio_payload_set_frame_based() or
 * gst_rtp_base_audio_payload_set_sample_based(). This is usually done in the
 * element's _init() function. Then, the child element must call either
 * gst_rtp_base_audio_payload_set_frame_options(),
 * gst_rtp_base_audio_payload_set_sample_options() or
 * gst_rtp_base_audio_payload_set_samplebits_options. Since
 * GstRTPBaseAudioPayload derives from GstRTPBasePayload, the child element
 * must set any variables or call/override any functions required by that base
 * class. The child element does not need to override any other functions
 * specific to GstRTPBaseAudioPayload.
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdlib.h>
#include <string.h>
#include <gst/rtp/gstrtpbuffer.h>
#include <gst/base/gstadapter.h>
#include <gst/audio/audio.h>

#include "gstrtpbaseaudiopayload.h"

GST_DEBUG_CATEGORY_STATIC (rtpbaseaudiopayload_debug);
#define GST_CAT_DEFAULT (rtpbaseaudiopayload_debug)

#define DEFAULT_BUFFER_LIST             FALSE

enum
{
  PROP_0,
  PROP_BUFFER_LIST,
  PROP_LAST
};

/* function to convert bytes to a time */
typedef GstClockTime (*GetBytesToTimeFunc) (GstRTPBaseAudioPayload * payload,
    guint64 bytes);
/* function to convert bytes to a RTP time */
typedef guint32 (*GetBytesToRTPTimeFunc) (GstRTPBaseAudioPayload * payload,
    guint64 bytes);
/* function to convert time to bytes */
typedef guint64 (*GetTimeToBytesFunc) (GstRTPBaseAudioPayload * payload,
    GstClockTime time);

struct _GstRTPBaseAudioPayloadPrivate
{
  GetBytesToTimeFunc bytes_to_time;
  GetBytesToRTPTimeFunc bytes_to_rtptime;
  GetTimeToBytesFunc time_to_bytes;

  GstAdapter *adapter;
  guint fragment_size;
  GstClockTime frame_duration_ns;
  gboolean discont;
  guint64 offset;
  GstClockTime last_timestamp;
  guint32 last_rtptime;
  guint align;

  guint cached_mtu;
  guint cached_min_ptime;
  guint cached_max_ptime;
  guint cached_ptime;
  guint cached_min_length;
  guint cached_max_length;
  guint cached_ptime_multiple;
  guint cached_align;

  gboolean buffer_list;
};


#define GST_RTP_BASE_AUDIO_PAYLOAD_GET_PRIVATE(o) \
  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GST_TYPE_RTP_BASE_AUDIO_PAYLOAD, \
                                GstRTPBaseAudioPayloadPrivate))

static void gst_rtp_base_audio_payload_finalize (GObject * object);

static void gst_rtp_base_audio_payload_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_rtp_base_audio_payload_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);

/* bytes to time functions */
static GstClockTime
gst_rtp_base_audio_payload_frame_bytes_to_time (GstRTPBaseAudioPayload *
    payload, guint64 bytes);
static GstClockTime
gst_rtp_base_audio_payload_sample_bytes_to_time (GstRTPBaseAudioPayload *
    payload, guint64 bytes);

/* bytes to RTP time functions */
static guint32
gst_rtp_base_audio_payload_frame_bytes_to_rtptime (GstRTPBaseAudioPayload *
    payload, guint64 bytes);
static guint32
gst_rtp_base_audio_payload_sample_bytes_to_rtptime (GstRTPBaseAudioPayload *
    payload, guint64 bytes);

/* time to bytes functions */
static guint64
gst_rtp_base_audio_payload_frame_time_to_bytes (GstRTPBaseAudioPayload *
    payload, GstClockTime time);
static guint64
gst_rtp_base_audio_payload_sample_time_to_bytes (GstRTPBaseAudioPayload *
    payload, GstClockTime time);

static GstFlowReturn gst_rtp_base_audio_payload_handle_buffer (GstRTPBasePayload
    * payload, GstBuffer * buffer);
static GstStateChangeReturn gst_rtp_base_payload_audio_change_state (GstElement
    * element, GstStateChange transition);
static gboolean gst_rtp_base_payload_audio_sink_event (GstRTPBasePayload
    * payload, GstEvent * event);

#define gst_rtp_base_audio_payload_parent_class parent_class
G_DEFINE_TYPE (GstRTPBaseAudioPayload, gst_rtp_base_audio_payload,
    GST_TYPE_RTP_BASE_PAYLOAD);

static void
gst_rtp_base_audio_payload_class_init (GstRTPBaseAudioPayloadClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstRTPBasePayloadClass *gstrtpbasepayload_class;

  g_type_class_add_private (klass, sizeof (GstRTPBaseAudioPayloadPrivate));

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstrtpbasepayload_class = (GstRTPBasePayloadClass *) klass;

  gobject_class->finalize = gst_rtp_base_audio_payload_finalize;
  gobject_class->set_property = gst_rtp_base_audio_payload_set_property;
  gobject_class->get_property = gst_rtp_base_audio_payload_get_property;

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BUFFER_LIST,
      g_param_spec_boolean ("buffer-list", "Buffer List",
          "Use Buffer Lists",
          DEFAULT_BUFFER_LIST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_rtp_base_payload_audio_change_state);

  gstrtpbasepayload_class->handle_buffer =
      GST_DEBUG_FUNCPTR (gst_rtp_base_audio_payload_handle_buffer);
  gstrtpbasepayload_class->sink_event =
      GST_DEBUG_FUNCPTR (gst_rtp_base_payload_audio_sink_event);

  GST_DEBUG_CATEGORY_INIT (rtpbaseaudiopayload_debug, "rtpbaseaudiopayload", 0,
      "base audio RTP payloader");
}

static void
gst_rtp_base_audio_payload_init (GstRTPBaseAudioPayload * payload)
{
  payload->priv = GST_RTP_BASE_AUDIO_PAYLOAD_GET_PRIVATE (payload);

  /* these need to be set by child object if frame based */
  payload->frame_size = 0;
  payload->frame_duration = 0;

  /* these need to be set by child object if sample based */
  payload->sample_size = 0;

  payload->priv->adapter = gst_adapter_new ();

  payload->priv->buffer_list = DEFAULT_BUFFER_LIST;
}

static void
gst_rtp_base_audio_payload_finalize (GObject * object)
{
  GstRTPBaseAudioPayload *payload;

  payload = GST_RTP_BASE_AUDIO_PAYLOAD (object);

  g_object_unref (payload->priv->adapter);

  GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
}

static void
gst_rtp_base_audio_payload_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstRTPBaseAudioPayload *payload;

  payload = GST_RTP_BASE_AUDIO_PAYLOAD (object);

  switch (prop_id) {
    case PROP_BUFFER_LIST:
#if 0
      payload->priv->buffer_list = g_value_get_boolean (value);
#endif
      payload->priv->buffer_list = FALSE;
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_base_audio_payload_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstRTPBaseAudioPayload *payload;

  payload = GST_RTP_BASE_AUDIO_PAYLOAD (object);

  switch (prop_id) {
    case PROP_BUFFER_LIST:
      g_value_set_boolean (value, payload->priv->buffer_list);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/**
 * gst_rtp_base_audio_payload_set_frame_based:
 * @rtpbaseaudiopayload: a pointer to the element.
 *
 * Tells #GstRTPBaseAudioPayload that the child element is for a frame based
 * audio codec
 */
void
gst_rtp_base_audio_payload_set_frame_based (GstRTPBaseAudioPayload *
    rtpbaseaudiopayload)
{
  g_return_if_fail (rtpbaseaudiopayload != NULL);
  g_return_if_fail (rtpbaseaudiopayload->priv->time_to_bytes == NULL);
  g_return_if_fail (rtpbaseaudiopayload->priv->bytes_to_time == NULL);
  g_return_if_fail (rtpbaseaudiopayload->priv->bytes_to_rtptime == NULL);

  rtpbaseaudiopayload->priv->bytes_to_time =
      gst_rtp_base_audio_payload_frame_bytes_to_time;
  rtpbaseaudiopayload->priv->bytes_to_rtptime =
      gst_rtp_base_audio_payload_frame_bytes_to_rtptime;
  rtpbaseaudiopayload->priv->time_to_bytes =
      gst_rtp_base_audio_payload_frame_time_to_bytes;
}

/**
 * gst_rtp_base_audio_payload_set_sample_based:
 * @rtpbaseaudiopayload: a pointer to the element.
 *
 * Tells #GstRTPBaseAudioPayload that the child element is for a sample based
 * audio codec
 */
void
gst_rtp_base_audio_payload_set_sample_based (GstRTPBaseAudioPayload *
    rtpbaseaudiopayload)
{
  g_return_if_fail (rtpbaseaudiopayload != NULL);
  g_return_if_fail (rtpbaseaudiopayload->priv->time_to_bytes == NULL);
  g_return_if_fail (rtpbaseaudiopayload->priv->bytes_to_time == NULL);
  g_return_if_fail (rtpbaseaudiopayload->priv->bytes_to_rtptime == NULL);

  rtpbaseaudiopayload->priv->bytes_to_time =
      gst_rtp_base_audio_payload_sample_bytes_to_time;
  rtpbaseaudiopayload->priv->bytes_to_rtptime =
      gst_rtp_base_audio_payload_sample_bytes_to_rtptime;
  rtpbaseaudiopayload->priv->time_to_bytes =
      gst_rtp_base_audio_payload_sample_time_to_bytes;
}

/**
 * gst_rtp_base_audio_payload_set_frame_options:
 * @rtpbaseaudiopayload: a pointer to the element.
 * @frame_duration: The duraction of an audio frame in milliseconds.
 * @frame_size: The size of an audio frame in bytes.
 *
 * Sets the options for frame based audio codecs.
 *
 */
void
gst_rtp_base_audio_payload_set_frame_options (GstRTPBaseAudioPayload
    * rtpbaseaudiopayload, gint frame_duration, gint frame_size)
{
  GstRTPBaseAudioPayloadPrivate *priv;

  g_return_if_fail (rtpbaseaudiopayload != NULL);

  priv = rtpbaseaudiopayload->priv;

  rtpbaseaudiopayload->frame_duration = frame_duration;
  priv->frame_duration_ns = frame_duration * GST_MSECOND;
  rtpbaseaudiopayload->frame_size = frame_size;
  priv->align = frame_size;

  gst_adapter_clear (priv->adapter);

  GST_DEBUG_OBJECT (rtpbaseaudiopayload, "frame set to %d ms and size %d",
      frame_duration, frame_size);
}

/**
 * gst_rtp_base_audio_payload_set_sample_options:
 * @rtpbaseaudiopayload: a pointer to the element.
 * @sample_size: Size per sample in bytes.
 *
 * Sets the options for sample based audio codecs.
 */
void
gst_rtp_base_audio_payload_set_sample_options (GstRTPBaseAudioPayload
    * rtpbaseaudiopayload, gint sample_size)
{
  g_return_if_fail (rtpbaseaudiopayload != NULL);

  /* sample_size is in bits internally */
  gst_rtp_base_audio_payload_set_samplebits_options (rtpbaseaudiopayload,
      sample_size * 8);
}

/**
 * gst_rtp_base_audio_payload_set_samplebits_options:
 * @rtpbaseaudiopayload: a pointer to the element.
 * @sample_size: Size per sample in bits.
 *
 * Sets the options for sample based audio codecs.
 */
void
gst_rtp_base_audio_payload_set_samplebits_options (GstRTPBaseAudioPayload
    * rtpbaseaudiopayload, gint sample_size)
{
  guint fragment_size;
  GstRTPBaseAudioPayloadPrivate *priv;

  g_return_if_fail (rtpbaseaudiopayload != NULL);

  priv = rtpbaseaudiopayload->priv;

  rtpbaseaudiopayload->sample_size = sample_size;

  /* sample_size is in bits and is converted into multiple bytes */
  fragment_size = sample_size;
  while ((fragment_size % 8) != 0)
    fragment_size += fragment_size;
  priv->fragment_size = fragment_size / 8;
  priv->align = priv->fragment_size;

  gst_adapter_clear (priv->adapter);

  GST_DEBUG_OBJECT (rtpbaseaudiopayload,
      "Samplebits set to sample size %d bits", sample_size);
}

static void
gst_rtp_base_audio_payload_set_meta (GstRTPBaseAudioPayload * payload,
    GstBuffer * buffer, guint payload_len, GstClockTime timestamp)
{
  GstRTPBasePayload *basepayload;
  GstRTPBaseAudioPayloadPrivate *priv;
  GstRTPBuffer rtp = { NULL };

  basepayload = GST_RTP_BASE_PAYLOAD_CAST (payload);
  priv = payload->priv;

  /* set payload type */
  gst_rtp_buffer_map (buffer, GST_MAP_WRITE, &rtp);
  gst_rtp_buffer_set_payload_type (&rtp, basepayload->pt);
  /* set marker bit for disconts */
  if (priv->discont) {
    GST_DEBUG_OBJECT (payload, "Setting marker and DISCONT");
    gst_rtp_buffer_set_marker (&rtp, TRUE);
    GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
    priv->discont = FALSE;
  }
  gst_rtp_buffer_unmap (&rtp);

  GST_BUFFER_PTS (buffer) = timestamp;

  /* get the offset in RTP time */
  GST_BUFFER_OFFSET (buffer) = priv->bytes_to_rtptime (payload, priv->offset);

  priv->offset += payload_len;

  /* Set the duration from the size */
  GST_BUFFER_DURATION (buffer) = priv->bytes_to_time (payload, payload_len);

  /* remember the last rtptime/timestamp pair. We will use this to realign our
   * RTP timestamp after a buffer discont */
  priv->last_rtptime = GST_BUFFER_OFFSET (buffer);
  priv->last_timestamp = timestamp;
}

/**
 * gst_rtp_base_audio_payload_push:
 * @baseaudiopayload: a #GstRTPBasePayload
 * @data: (array length=payload_len): data to set as payload
 * @payload_len: length of payload
 * @timestamp: a #GstClockTime
 *
 * Create an RTP buffer and store @payload_len bytes of @data as the
 * payload. Set the timestamp on the new buffer to @timestamp before pushing
 * the buffer downstream.
 *
 * Returns: a #GstFlowReturn
 */
GstFlowReturn
gst_rtp_base_audio_payload_push (GstRTPBaseAudioPayload * baseaudiopayload,
    const guint8 * data, guint payload_len, GstClockTime timestamp)
{
  GstRTPBasePayload *basepayload;
  GstBuffer *outbuf;
  guint8 *payload;
  GstFlowReturn ret;
  GstRTPBuffer rtp = { NULL };

  basepayload = GST_RTP_BASE_PAYLOAD (baseaudiopayload);

  GST_DEBUG_OBJECT (baseaudiopayload, "Pushing %d bytes ts %" GST_TIME_FORMAT,
      payload_len, GST_TIME_ARGS (timestamp));

  /* create buffer to hold the payload */
  outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);

  /* copy payload */
  gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
  payload = gst_rtp_buffer_get_payload (&rtp);
  memcpy (payload, data, payload_len);
  gst_rtp_buffer_unmap (&rtp);

  /* set metadata */
  gst_rtp_base_audio_payload_set_meta (baseaudiopayload, outbuf, payload_len,
      timestamp);

  ret = gst_rtp_base_payload_push (basepayload, outbuf);

  return ret;
}

typedef struct
{
  GstRTPBaseAudioPayload *pay;
  GstBuffer *outbuf;
} CopyMetaData;

static gboolean
foreach_metadata (GstBuffer * inbuf, GstMeta ** meta, gpointer user_data)
{
  CopyMetaData *data = user_data;
  GstRTPBaseAudioPayload *pay = data->pay;
  GstBuffer *outbuf = data->outbuf;
  const GstMetaInfo *info = (*meta)->info;
  const gchar *const *tags = gst_meta_api_type_get_tags (info->api);

  if (info->transform_func && (!tags || (g_strv_length ((gchar **) tags) == 1
              && gst_meta_api_type_has_tag (info->api,
                  g_quark_from_string (GST_META_TAG_AUDIO_STR))))) {
    GstMetaTransformCopy copy_data = { FALSE, 0, -1 };
    GST_DEBUG_OBJECT (pay, "copy metadata %s", g_type_name (info->api));
    /* simply copy then */
    info->transform_func (outbuf, *meta, inbuf,
        _gst_meta_transform_copy, &copy_data);
  } else {
    GST_DEBUG_OBJECT (pay, "not copying metadata %s", g_type_name (info->api));
  }

  return TRUE;
}

static GstFlowReturn
gst_rtp_base_audio_payload_push_buffer (GstRTPBaseAudioPayload *
    baseaudiopayload, GstBuffer * buffer, GstClockTime timestamp)
{
  GstRTPBasePayload *basepayload;
  GstRTPBaseAudioPayloadPrivate *priv;
  GstBuffer *outbuf;
  guint payload_len;
  GstFlowReturn ret;

  priv = baseaudiopayload->priv;
  basepayload = GST_RTP_BASE_PAYLOAD (baseaudiopayload);

  payload_len = gst_buffer_get_size (buffer);

  GST_DEBUG_OBJECT (baseaudiopayload, "Pushing %d bytes ts %" GST_TIME_FORMAT,
      payload_len, GST_TIME_ARGS (timestamp));

  /* create just the RTP header buffer */
  outbuf = gst_rtp_buffer_new_allocate (0, 0, 0);

  /* set metadata */
  gst_rtp_base_audio_payload_set_meta (baseaudiopayload, outbuf, payload_len,
      timestamp);

  if (priv->buffer_list) {
    GstBufferList *list;
    guint i, len;

    list = gst_buffer_list_new ();
    len = gst_buffer_list_length (list);

    for (i = 0; i < len; i++) {
      /* FIXME */
      g_warning ("bufferlist not implemented");
      gst_buffer_list_add (list, outbuf);
      gst_buffer_list_add (list, buffer);
    }

    GST_DEBUG_OBJECT (baseaudiopayload, "Pushing list %p", list);
    ret = gst_rtp_base_payload_push_list (basepayload, list);
  } else {
    CopyMetaData data;

    /* copy payload */
    data.pay = baseaudiopayload;
    data.outbuf = outbuf;
    gst_buffer_foreach_meta (buffer, foreach_metadata, &data);
    outbuf = gst_buffer_append (outbuf, buffer);

    GST_DEBUG_OBJECT (baseaudiopayload, "Pushing buffer %p", outbuf);
    ret = gst_rtp_base_payload_push (basepayload, outbuf);
  }

  return ret;
}

/**
 * gst_rtp_base_audio_payload_flush:
 * @baseaudiopayload: a #GstRTPBasePayload
 * @payload_len: length of payload
 * @timestamp: a #GstClockTime
 *
 * Create an RTP buffer and store @payload_len bytes of the adapter as the
 * payload. Set the timestamp on the new buffer to @timestamp before pushing
 * the buffer downstream.
 *
 * If @payload_len is -1, all pending bytes will be flushed. If @timestamp is
 * -1, the timestamp will be calculated automatically.
 *
 * Returns: a #GstFlowReturn
 */
GstFlowReturn
gst_rtp_base_audio_payload_flush (GstRTPBaseAudioPayload * baseaudiopayload,
    guint payload_len, GstClockTime timestamp)
{
  GstRTPBasePayload *basepayload;
  GstRTPBaseAudioPayloadPrivate *priv;
  GstBuffer *outbuf;
  GstFlowReturn ret;
  GstAdapter *adapter;
  guint64 distance;

  priv = baseaudiopayload->priv;
  adapter = priv->adapter;

  basepayload = GST_RTP_BASE_PAYLOAD (baseaudiopayload);

  if (payload_len == -1)
    payload_len = gst_adapter_available (adapter);

  /* nothing to do, just return */
  if (payload_len == 0)
    return GST_FLOW_OK;

  if (timestamp == -1) {
    /* calculate the timestamp */
    timestamp = gst_adapter_prev_pts (adapter, &distance);

    GST_LOG_OBJECT (baseaudiopayload,
        "last timestamp %" GST_TIME_FORMAT ", distance %" G_GUINT64_FORMAT,
        GST_TIME_ARGS (timestamp), distance);

    if (GST_CLOCK_TIME_IS_VALID (timestamp) && distance > 0) {
      /* convert the number of bytes since the last timestamp to time and add to
       * the last seen timestamp */
      timestamp += priv->bytes_to_time (baseaudiopayload, distance);
    }
  }

  GST_DEBUG_OBJECT (baseaudiopayload, "Pushing %d bytes ts %" GST_TIME_FORMAT,
      payload_len, GST_TIME_ARGS (timestamp));

  if (priv->buffer_list && gst_adapter_available_fast (adapter) >= payload_len) {
    GstBuffer *buffer;
    /* we can quickly take a buffer out of the adapter without having to copy
     * anything. */
    buffer = gst_adapter_take_buffer (adapter, payload_len);

    ret =
        gst_rtp_base_audio_payload_push_buffer (baseaudiopayload, buffer,
        timestamp);
  } else {
    GstBuffer *paybuf;
    CopyMetaData data;


    /* create buffer to hold the payload */
    outbuf = gst_rtp_buffer_new_allocate (0, 0, 0);

    paybuf = gst_adapter_take_buffer_fast (adapter, payload_len);

    data.pay = baseaudiopayload;
    data.outbuf = outbuf;
    gst_buffer_foreach_meta (paybuf, foreach_metadata, &data);
    outbuf = gst_buffer_append (outbuf, paybuf);

    /* set metadata */
    gst_rtp_base_audio_payload_set_meta (baseaudiopayload, outbuf, payload_len,
        timestamp);

    ret = gst_rtp_base_payload_push (basepayload, outbuf);
  }

  return ret;
}

#define ALIGN_DOWN(val,len) ((val) - ((val) % (len)))

/* calculate the min and max length of a packet. This depends on the configured
 * mtu and min/max_ptime values. We cache those so that we don't have to redo
 * all the calculations */
static gboolean
gst_rtp_base_audio_payload_get_lengths (GstRTPBasePayload *
    basepayload, guint * min_payload_len, guint * max_payload_len,
    guint * align)
{
  GstRTPBaseAudioPayload *payload;
  GstRTPBaseAudioPayloadPrivate *priv;
  guint max_mtu, mtu;
  guint maxptime_octets;
  guint minptime_octets;
  guint ptime_mult_octets;

  payload = GST_RTP_BASE_AUDIO_PAYLOAD_CAST (basepayload);
  priv = payload->priv;

  if (priv->align == 0)
    return FALSE;

  mtu = GST_RTP_BASE_PAYLOAD_MTU (payload);

  /* check cached values */
  if (G_LIKELY (priv->cached_mtu == mtu
          && priv->cached_ptime_multiple ==
          basepayload->ptime_multiple
          && priv->cached_ptime == basepayload->ptime
          && priv->cached_max_ptime == basepayload->max_ptime
          && priv->cached_min_ptime == basepayload->min_ptime)) {
    /* if nothing changed, return cached values */
    *min_payload_len = priv->cached_min_length;
    *max_payload_len = priv->cached_max_length;
    *align = priv->cached_align;
    return TRUE;
  }

  ptime_mult_octets = priv->time_to_bytes (payload,
      basepayload->ptime_multiple);
  *align = ALIGN_DOWN (MAX (priv->align, ptime_mult_octets), priv->align);

  /* ptime max */
  if (basepayload->max_ptime != -1) {
    maxptime_octets = priv->time_to_bytes (payload, basepayload->max_ptime);
  } else {
    maxptime_octets = G_MAXUINT;
  }
  /* MTU max */
  max_mtu = gst_rtp_buffer_calc_payload_len (mtu, 0, 0);
  /* round down to alignment */
  max_mtu = ALIGN_DOWN (max_mtu, *align);

  /* combine max ptime and max payload length */
  *max_payload_len = MIN (max_mtu, maxptime_octets);

  /* min number of bytes based on a given ptime */
  minptime_octets = priv->time_to_bytes (payload, basepayload->min_ptime);
  /* must be at least one frame size */
  *min_payload_len = MAX (minptime_octets, *align);

  if (*min_payload_len > *max_payload_len)
    *min_payload_len = *max_payload_len;

  /* If the ptime is specified in the caps, tried to adhere to it exactly */
  if (basepayload->ptime) {
    guint ptime_in_bytes = priv->time_to_bytes (payload,
        basepayload->ptime);

    /* clip to computed min and max lengths */
    ptime_in_bytes = MAX (*min_payload_len, ptime_in_bytes);
    ptime_in_bytes = MIN (*max_payload_len, ptime_in_bytes);

    *min_payload_len = *max_payload_len = ptime_in_bytes;
  }

  /* cache values */
  priv->cached_mtu = mtu;
  priv->cached_ptime = basepayload->ptime;
  priv->cached_min_ptime = basepayload->min_ptime;
  priv->cached_max_ptime = basepayload->max_ptime;
  priv->cached_ptime_multiple = basepayload->ptime_multiple;
  priv->cached_min_length = *min_payload_len;
  priv->cached_max_length = *max_payload_len;
  priv->cached_align = *align;

  return TRUE;
}

/* frame conversions functions */
static GstClockTime
gst_rtp_base_audio_payload_frame_bytes_to_time (GstRTPBaseAudioPayload *
    payload, guint64 bytes)
{
  guint64 framecount;

  framecount = bytes / payload->frame_size;
  if (G_UNLIKELY (bytes % payload->frame_size))
    framecount++;

  return framecount * payload->priv->frame_duration_ns;
}

static guint32
gst_rtp_base_audio_payload_frame_bytes_to_rtptime (GstRTPBaseAudioPayload *
    payload, guint64 bytes)
{
  guint64 framecount;
  guint64 time;

  framecount = bytes / payload->frame_size;
  if (G_UNLIKELY (bytes % payload->frame_size))
    framecount++;

  time = framecount * payload->priv->frame_duration_ns;

  return gst_util_uint64_scale_int (time,
      GST_RTP_BASE_PAYLOAD (payload)->clock_rate, GST_SECOND);
}

static guint64
gst_rtp_base_audio_payload_frame_time_to_bytes (GstRTPBaseAudioPayload *
    payload, GstClockTime time)
{
  return gst_util_uint64_scale (time, payload->frame_size,
      payload->priv->frame_duration_ns);
}

/* sample conversion functions */
static GstClockTime
gst_rtp_base_audio_payload_sample_bytes_to_time (GstRTPBaseAudioPayload *
    payload, guint64 bytes)
{
  guint64 rtptime;

  /* avoid division when we can */
  if (G_LIKELY (payload->sample_size != 8))
    rtptime = gst_util_uint64_scale_int (bytes, 8, payload->sample_size);
  else
    rtptime = bytes;

  return gst_util_uint64_scale_int (rtptime, GST_SECOND,
      GST_RTP_BASE_PAYLOAD (payload)->clock_rate);
}

static guint32
gst_rtp_base_audio_payload_sample_bytes_to_rtptime (GstRTPBaseAudioPayload *
    payload, guint64 bytes)
{
  /* avoid division when we can */
  if (G_LIKELY (payload->sample_size != 8))
    return gst_util_uint64_scale_int (bytes, 8, payload->sample_size);
  else
    return bytes;
}

static guint64
gst_rtp_base_audio_payload_sample_time_to_bytes (GstRTPBaseAudioPayload *
    payload, guint64 time)
{
  guint64 samples;

  samples = gst_util_uint64_scale_int (time,
      GST_RTP_BASE_PAYLOAD (payload)->clock_rate, GST_SECOND);

  /* avoid multiplication when we can */
  if (G_LIKELY (payload->sample_size != 8))
    return gst_util_uint64_scale_int (samples, payload->sample_size, 8);
  else
    return samples;
}

static GstFlowReturn
gst_rtp_base_audio_payload_handle_buffer (GstRTPBasePayload *
    basepayload, GstBuffer * buffer)
{
  GstRTPBaseAudioPayload *payload;
  GstRTPBaseAudioPayloadPrivate *priv;
  guint payload_len;
  GstFlowReturn ret;
  guint available;
  guint min_payload_len;
  guint max_payload_len;
  guint align;
  guint size;
  gboolean discont;
  GstClockTime timestamp;

  ret = GST_FLOW_OK;

  payload = GST_RTP_BASE_AUDIO_PAYLOAD_CAST (basepayload);
  priv = payload->priv;

  timestamp = GST_BUFFER_PTS (buffer);
  discont = GST_BUFFER_IS_DISCONT (buffer);
  if (discont) {

    GST_DEBUG_OBJECT (payload, "Got DISCONT");
    /* flush everything out of the adapter, mark DISCONT */
    ret = gst_rtp_base_audio_payload_flush (payload, -1, -1);
    priv->discont = TRUE;

    /* get the distance between the timestamp gap and produce the same gap in
     * the RTP timestamps */
    if (priv->last_timestamp != -1 && timestamp != -1) {
      /* we had a last timestamp, compare it to the new timestamp and update the
       * offset counter for RTP timestamps. The effect is that we will produce
       * output buffers containing the same RTP timestamp gap as the gap
       * between the GST timestamps. */
      if (timestamp > priv->last_timestamp) {
        GstClockTime diff;
        guint64 bytes;
        /* we're only going to apply a positive gap, otherwise we let the marker
         * bit do its thing. simply convert to bytes and add the current
         * offset */
        diff = timestamp - priv->last_timestamp;
        bytes = priv->time_to_bytes (payload, diff);
        priv->offset += bytes;

        GST_DEBUG_OBJECT (payload,
            "elapsed time %" GST_TIME_FORMAT ", bytes %" G_GUINT64_FORMAT
            ", new offset %" G_GUINT64_FORMAT, GST_TIME_ARGS (diff), bytes,
            priv->offset);
      }
    }
  }

  if (!gst_rtp_base_audio_payload_get_lengths (basepayload, &min_payload_len,
          &max_payload_len, &align))
    goto config_error;

  GST_DEBUG_OBJECT (payload,
      "Calculated min_payload_len %u and max_payload_len %u",
      min_payload_len, max_payload_len);

  size = gst_buffer_get_size (buffer);

  /* shortcut, we don't need to use the adapter when the packet can be pushed
   * through directly. */
  available = gst_adapter_available (priv->adapter);

  GST_DEBUG_OBJECT (payload, "got buffer size %u, available %u",
      size, available);

  if (available == 0 && (size >= min_payload_len && size <= max_payload_len) &&
      (size % align == 0)) {
    /* If buffer fits on an RTP packet, let's just push it through
     * this will check against max_ptime and max_mtu */
    GST_DEBUG_OBJECT (payload, "Fast packet push");
    ret = gst_rtp_base_audio_payload_push_buffer (payload, buffer, timestamp);
  } else {
    /* push the buffer in the adapter */
    gst_adapter_push (priv->adapter, buffer);
    available += size;

    GST_DEBUG_OBJECT (payload, "available now %u", available);

    /* as long as we have full frames */
    /* TODO: Use buffer lists here */
    while (available >= min_payload_len) {
      /* get multiple of alignment */
      payload_len = MIN (max_payload_len, available);
      payload_len = ALIGN_DOWN (payload_len, align);

      /* and flush out the bytes from the adapter, automatically set the
       * timestamp. */
      ret = gst_rtp_base_audio_payload_flush (payload, payload_len, -1);

      available -= payload_len;
      GST_DEBUG_OBJECT (payload, "available after push %u", available);
    }
  }
  return ret;

  /* ERRORS */
config_error:
  {
    GST_ELEMENT_ERROR (payload, STREAM, NOT_IMPLEMENTED, (NULL),
        ("subclass did not configure us properly"));
    gst_buffer_unref (buffer);
    return GST_FLOW_ERROR;
  }
}

static GstStateChangeReturn
gst_rtp_base_payload_audio_change_state (GstElement * element,
    GstStateChange transition)
{
  GstRTPBaseAudioPayload *rtpbasepayload;
  GstStateChangeReturn ret;

  rtpbasepayload = GST_RTP_BASE_AUDIO_PAYLOAD (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      rtpbasepayload->priv->cached_mtu = -1;
      rtpbasepayload->priv->last_rtptime = -1;
      rtpbasepayload->priv->last_timestamp = -1;
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_adapter_clear (rtpbasepayload->priv->adapter);
      break;
    default:
      break;
  }

  return ret;
}

static gboolean
gst_rtp_base_payload_audio_sink_event (GstRTPBasePayload * basep,
    GstEvent * event)
{
  GstRTPBaseAudioPayload *payload;
  gboolean res = FALSE;

  payload = GST_RTP_BASE_AUDIO_PAYLOAD (basep);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_EOS:
      /* flush remaining bytes in the adapter */
      gst_rtp_base_audio_payload_flush (payload, -1, -1);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_adapter_clear (payload->priv->adapter);
      break;
    default:
      break;
  }

  /* let parent handle the remainder of the event */
  res = GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->sink_event (basep, event);

  return res;
}

/**
 * gst_rtp_base_audio_payload_get_adapter:
 * @rtpbaseaudiopayload: a #GstRTPBaseAudioPayload
 *
 * Gets the internal adapter used by the depayloader.
 *
 * Returns: (transfer full): a #GstAdapter.
 */
GstAdapter *
gst_rtp_base_audio_payload_get_adapter (GstRTPBaseAudioPayload
    * rtpbaseaudiopayload)
{
  GstAdapter *adapter;

  if ((adapter = rtpbaseaudiopayload->priv->adapter))
    g_object_ref (adapter);

  return adapter;
}
