/* 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: 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;
}
