/* 
 * RTP Demux element
 *
 * Copyright (C) 2005 Nokia Corporation.
 * @author Kai Vehmanen <kai.vehmanen@nokia.com>
 *
 * Loosely based on GStreamer gstdecodebin
 * Copyright (C) <2004> Wim Taymans <wim.taymans@gmail.com>
 *
 * 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:element-rtpptdemux
 *
 * rtpptdemux acts as a demuxer for RTP packets based on the payload type of
 * the packets. Its main purpose is to allow an application to easily receive
 * and decode an RTP stream with multiple payload types.
 * 
 * For each payload type that is detected, a new pad will be created and the
 * #GstRtpPtDemux::new-payload-type signal will be emitted. When the payload for
 * the RTP stream changes, the #GstRtpPtDemux::payload-type-change signal will be
 * emitted.
 * 
 * The element will try to set complete and unique application/x-rtp caps
 * on the output pads based on the result of the #GstRtpPtDemux::request-pt-map
 * signal.
 * 
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * gst-launch-1.0 udpsrc caps="application/x-rtp" ! rtpptdemux ! fakesink
 * ]| Takes an RTP stream and send the RTP packets with the first detected
 * payload type to fakesink, discarding the other payload types.
 * </refsect2>
 */

/*
 * Contributors:
 * Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>
 */
/*
 * Status:
 *  - works with the test_rtpdemux.c tool
 *
 * Check:
 *  - is emitting a signal enough, or should we
 *    use GstEvent to notify downstream elements
 *    of the new packet... no?
 *
 * Notes:
 *  - emits event both for new PTs, and whenever
 *    a PT is changed
 */

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

#include <string.h>
#include <gst/gst.h>
#include <gst/rtp/gstrtpbuffer.h>

#include "gstrtpptdemux.h"

/* generic templates */
static GstStaticPadTemplate rtp_pt_demux_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp")
    );

static GstStaticPadTemplate rtp_pt_demux_src_template =
GST_STATIC_PAD_TEMPLATE ("src_%u",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("application/x-rtp, " "payload = (int) [ 0, 255 ]")
    );

GST_DEBUG_CATEGORY_STATIC (gst_rtp_pt_demux_debug);
#define GST_CAT_DEFAULT gst_rtp_pt_demux_debug

/*
 * Item for storing GstPad<->pt pairs.
 */
struct _GstRtpPtDemuxPad
{
  GstPad *pad;        /**< pointer to the actual pad */
  gint pt;             /**< RTP payload-type attached to pad */
  gboolean newcaps;
};

/* signals */
enum
{
  SIGNAL_REQUEST_PT_MAP,
  SIGNAL_NEW_PAYLOAD_TYPE,
  SIGNAL_PAYLOAD_TYPE_CHANGE,
  SIGNAL_CLEAR_PT_MAP,
  LAST_SIGNAL
};

#define gst_rtp_pt_demux_parent_class parent_class
G_DEFINE_TYPE (GstRtpPtDemux, gst_rtp_pt_demux, GST_TYPE_ELEMENT);

static void gst_rtp_pt_demux_finalize (GObject * object);

static void gst_rtp_pt_demux_release (GstRtpPtDemux * ptdemux);
static gboolean gst_rtp_pt_demux_setup (GstRtpPtDemux * ptdemux);

static gboolean gst_rtp_pt_demux_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static GstFlowReturn gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static GstStateChangeReturn gst_rtp_pt_demux_change_state (GstElement * element,
    GstStateChange transition);
static void gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux);

static GstPad *find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt);

static gboolean gst_rtp_pt_demux_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);


static guint gst_rtp_pt_demux_signals[LAST_SIGNAL] = { 0 };

static void
gst_rtp_pt_demux_class_init (GstRtpPtDemuxClass * klass)
{
  GObjectClass *gobject_klass;
  GstElementClass *gstelement_klass;

  gobject_klass = (GObjectClass *) klass;
  gstelement_klass = (GstElementClass *) klass;

  /**
   * GstRtpPtDemux::request-pt-map:
   * @demux: the object which received the signal
   * @pt: the payload type
   *
   * Request the payload type as #GstCaps for @pt.
   */
  gst_rtp_pt_demux_signals[SIGNAL_REQUEST_PT_MAP] =
      g_signal_new ("request-pt-map", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpPtDemuxClass, request_pt_map),
      NULL, NULL, g_cclosure_marshal_generic, GST_TYPE_CAPS, 1, G_TYPE_UINT);

  /**
   * GstRtpPtDemux::new-payload-type:
   * @demux: the object which received the signal
   * @pt: the payload type
   * @pad: the pad with the new payload
   *
   * Emited when a new payload type pad has been created in @demux.
   */
  gst_rtp_pt_demux_signals[SIGNAL_NEW_PAYLOAD_TYPE] =
      g_signal_new ("new-payload-type", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpPtDemuxClass, new_payload_type),
      NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2, G_TYPE_UINT,
      GST_TYPE_PAD);

  /**
   * GstRtpPtDemux::payload-type-change:
   * @demux: the object which received the signal
   * @pt: the new payload type
   *
   * Emited when the payload type changed.
   */
  gst_rtp_pt_demux_signals[SIGNAL_PAYLOAD_TYPE_CHANGE] =
      g_signal_new ("payload-type-change", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpPtDemuxClass,
          payload_type_change), NULL, NULL, g_cclosure_marshal_VOID__UINT,
      G_TYPE_NONE, 1, G_TYPE_UINT);

  /**
   * GstRtpPtDemux::clear-pt-map:
   * @demux: the object which received the signal
   *
   * The application can call this signal to instruct the element to discard the
   * currently cached payload type map.
   */
  gst_rtp_pt_demux_signals[SIGNAL_CLEAR_PT_MAP] =
      g_signal_new ("clear-pt-map", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstRtpPtDemuxClass,
          clear_pt_map), NULL, NULL, g_cclosure_marshal_VOID__VOID,
      G_TYPE_NONE, 0, G_TYPE_NONE);

  gobject_klass->finalize = gst_rtp_pt_demux_finalize;

  gstelement_klass->change_state =
      GST_DEBUG_FUNCPTR (gst_rtp_pt_demux_change_state);

  klass->clear_pt_map = GST_DEBUG_FUNCPTR (gst_rtp_pt_demux_clear_pt_map);

  gst_element_class_add_static_pad_template (gstelement_klass,
      &rtp_pt_demux_sink_template);
  gst_element_class_add_static_pad_template (gstelement_klass,
      &rtp_pt_demux_src_template);

  gst_element_class_set_static_metadata (gstelement_klass, "RTP Demux",
      "Demux/Network/RTP",
      "Parses codec streams transmitted in the same RTP session",
      "Kai Vehmanen <kai.vehmanen@nokia.com>");

  GST_DEBUG_CATEGORY_INIT (gst_rtp_pt_demux_debug,
      "rtpptdemux", 0, "RTP codec demuxer");
}

static void
gst_rtp_pt_demux_init (GstRtpPtDemux * ptdemux)
{
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (ptdemux);

  ptdemux->sink =
      gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
          "sink"), "sink");
  g_assert (ptdemux->sink != NULL);

  gst_pad_set_chain_function (ptdemux->sink, gst_rtp_pt_demux_chain);
  gst_pad_set_event_function (ptdemux->sink, gst_rtp_pt_demux_sink_event);

  gst_element_add_pad (GST_ELEMENT (ptdemux), ptdemux->sink);
}

static void
gst_rtp_pt_demux_finalize (GObject * object)
{
  gst_rtp_pt_demux_release (GST_RTP_PT_DEMUX (object));

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static GstCaps *
gst_rtp_pt_demux_get_caps (GstRtpPtDemux * rtpdemux, guint pt)
{
  GstCaps *caps;
  GValue ret = { 0 };
  GValue args[2] = { {0}, {0} };
  GstCaps *sink_caps;

  /* figure out the caps */
  g_value_init (&args[0], GST_TYPE_ELEMENT);
  g_value_set_object (&args[0], rtpdemux);
  g_value_init (&args[1], G_TYPE_UINT);
  g_value_set_uint (&args[1], pt);

  g_value_init (&ret, GST_TYPE_CAPS);
  g_value_set_boxed (&ret, NULL);

  g_signal_emitv (args, gst_rtp_pt_demux_signals[SIGNAL_REQUEST_PT_MAP], 0,
      &ret);

  g_value_unset (&args[0]);
  g_value_unset (&args[1]);
  caps = g_value_dup_boxed (&ret);
  g_value_unset (&ret);

  sink_caps = gst_pad_get_current_caps (rtpdemux->sink);
  if (caps == NULL) {
    caps = gst_caps_ref (sink_caps);
  } else {
    GstStructure *s1;
    GstStructure *s2;
    guint ssrc;

    caps = gst_caps_make_writable (caps);
    s1 = gst_caps_get_structure (sink_caps, 0);
    s2 = gst_caps_get_structure (caps, 0);

    gst_structure_get_uint (s1, "ssrc", &ssrc);
    gst_structure_set (s2, "ssrc", G_TYPE_UINT, ssrc, NULL);
  }

  gst_caps_unref (sink_caps);

  GST_DEBUG ("pt %d, got caps %" GST_PTR_FORMAT, pt, caps);

  return caps;
}

static void
gst_rtp_pt_demux_clear_pt_map (GstRtpPtDemux * rtpdemux)
{
  GSList *walk;

  GST_OBJECT_LOCK (rtpdemux);
  GST_DEBUG ("clearing pt map");
  for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) {
    GstRtpPtDemuxPad *pad = walk->data;

    pad->newcaps = TRUE;
  }
  GST_OBJECT_UNLOCK (rtpdemux);
}

static gboolean
need_caps_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt)
{
  GSList *walk;
  gboolean ret = FALSE;

  GST_OBJECT_LOCK (rtpdemux);
  for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) {
    GstRtpPtDemuxPad *pad = walk->data;

    if (pad->pt == pt) {
      ret = pad->newcaps;
    }
  }
  GST_OBJECT_UNLOCK (rtpdemux);

  return ret;
}


static void
clear_newcaps_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt)
{
  GSList *walk;

  GST_OBJECT_LOCK (rtpdemux);
  for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) {
    GstRtpPtDemuxPad *pad = walk->data;

    if (pad->pt == pt) {
      pad->newcaps = FALSE;
      break;
    }
  }
  GST_OBJECT_UNLOCK (rtpdemux);
}

static gboolean
forward_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
{
  GstPad *srcpad = GST_PAD_CAST (user_data);

  /* Stream start and caps have already been pushed */
  if (GST_EVENT_TYPE (*event) >= GST_EVENT_SEGMENT)
    gst_pad_push_event (srcpad, gst_event_ref (*event));

  return TRUE;
}

static GstFlowReturn
gst_rtp_pt_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstRtpPtDemux *rtpdemux;
  guint8 pt;
  GstPad *srcpad;
  GstCaps *caps;
  GstRTPBuffer rtp = { NULL };

  rtpdemux = GST_RTP_PT_DEMUX (parent);

  if (!gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp))
    goto invalid_buffer;

  pt = gst_rtp_buffer_get_payload_type (&rtp);
  gst_rtp_buffer_unmap (&rtp);

  GST_DEBUG_OBJECT (rtpdemux, "received buffer for pt %d", pt);

  srcpad = find_pad_for_pt (rtpdemux, pt);
  if (srcpad == NULL) {
    /* new PT, create a src pad */
    GstRtpPtDemuxPad *rtpdemuxpad;
    GstElementClass *klass;
    GstPadTemplate *templ;
    gchar *padname;

    caps = gst_rtp_pt_demux_get_caps (rtpdemux, pt);
    if (!caps)
      goto no_caps;

    klass = GST_ELEMENT_GET_CLASS (rtpdemux);
    templ = gst_element_class_get_pad_template (klass, "src_%u");
    padname = g_strdup_printf ("src_%u", pt);
    srcpad = gst_pad_new_from_template (templ, padname);
    gst_pad_use_fixed_caps (srcpad);
    g_free (padname);
    gst_pad_set_event_function (srcpad, gst_rtp_pt_demux_src_event);

    GST_DEBUG ("Adding pt=%d to the list.", pt);
    rtpdemuxpad = g_slice_new0 (GstRtpPtDemuxPad);
    rtpdemuxpad->pt = pt;
    rtpdemuxpad->newcaps = FALSE;
    rtpdemuxpad->pad = srcpad;
    gst_object_ref (srcpad);
    GST_OBJECT_LOCK (rtpdemux);
    rtpdemux->srcpads = g_slist_append (rtpdemux->srcpads, rtpdemuxpad);
    GST_OBJECT_UNLOCK (rtpdemux);

    gst_pad_set_active (srcpad, TRUE);


    /* First push the stream-start event, it must always come first */
    gst_pad_push_event (srcpad,
        gst_pad_get_sticky_event (rtpdemux->sink, GST_EVENT_STREAM_START, 0));

    /* Then caps event is sent */
    caps = gst_caps_make_writable (caps);
    gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL);
    gst_pad_set_caps (srcpad, caps);
    gst_caps_unref (caps);

    /* First sticky events on sink pad are forwarded to the new src pad */
    gst_pad_sticky_events_foreach (rtpdemux->sink, forward_sticky_events,
        srcpad);

    gst_element_add_pad (GST_ELEMENT_CAST (rtpdemux), srcpad);

    GST_DEBUG ("emitting new-payload-type for pt %d", pt);
    g_signal_emit (G_OBJECT (rtpdemux),
        gst_rtp_pt_demux_signals[SIGNAL_NEW_PAYLOAD_TYPE], 0, pt, srcpad);
  }

  if (pt != rtpdemux->last_pt) {
    gint emit_pt = pt;

    /* our own signal with an extra flag that this is the only pad */
    rtpdemux->last_pt = pt;
    GST_DEBUG ("emitting payload-type-changed for pt %d", emit_pt);
    g_signal_emit (G_OBJECT (rtpdemux),
        gst_rtp_pt_demux_signals[SIGNAL_PAYLOAD_TYPE_CHANGE], 0, emit_pt);
  }

  while (need_caps_for_pt (rtpdemux, pt)) {
    GST_DEBUG ("need new caps for %d", pt);
    caps = gst_rtp_pt_demux_get_caps (rtpdemux, pt);
    if (!caps)
      goto no_caps;

    clear_newcaps_for_pt (rtpdemux, pt);

    caps = gst_caps_make_writable (caps);
    gst_caps_set_simple (caps, "payload", G_TYPE_INT, pt, NULL);
    gst_pad_set_caps (srcpad, caps);
    gst_caps_unref (caps);
  }

  /* push to srcpad */
  ret = gst_pad_push (srcpad, buf);

  gst_object_unref (srcpad);

  return ret;

  /* ERRORS */
invalid_buffer:
  {
    /* this should not be fatal */
    GST_ELEMENT_WARNING (rtpdemux, STREAM, DEMUX, (NULL),
        ("Dropping invalid RTP payload"));
    gst_buffer_unref (buf);
    return GST_FLOW_ERROR;
  }
no_caps:
  {
    GST_ELEMENT_ERROR (rtpdemux, STREAM, DECODE, (NULL),
        ("Could not get caps for payload"));
    gst_buffer_unref (buf);
    if (srcpad)
      gst_object_unref (srcpad);
    return GST_FLOW_ERROR;
  }
}

static GstPad *
find_pad_for_pt (GstRtpPtDemux * rtpdemux, guint8 pt)
{
  GstPad *respad = NULL;
  GSList *walk;

  GST_OBJECT_LOCK (rtpdemux);
  for (walk = rtpdemux->srcpads; walk; walk = g_slist_next (walk)) {
    GstRtpPtDemuxPad *pad = walk->data;

    if (pad->pt == pt) {
      respad = gst_object_ref (pad->pad);
      break;
    }
  }
  GST_OBJECT_UNLOCK (rtpdemux);

  return respad;
}

static gboolean
gst_rtp_pt_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstRtpPtDemux *rtpdemux;
  gboolean res = FALSE;

  rtpdemux = GST_RTP_PT_DEMUX (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CAPS:
    {
      gst_rtp_pt_demux_clear_pt_map (rtpdemux);
      /* don't forward the event, we cleared the ptmap and on the next buffer we
       * will add the pt to the caps and push a new caps event */
      gst_event_unref (event);
      res = TRUE;
      break;
    }
    case GST_EVENT_CUSTOM_DOWNSTREAM:
    {
      const GstStructure *s;

      s = gst_event_get_structure (event);

      if (gst_structure_has_name (s, "GstRTPPacketLost")) {
        GstPad *srcpad = find_pad_for_pt (rtpdemux, rtpdemux->last_pt);

        if (srcpad) {
          res = gst_pad_push_event (srcpad, event);
          gst_object_unref (srcpad);
        } else {
          gst_event_unref (event);
        }

      } else {
        res = gst_pad_event_default (pad, parent, event);
      }
      break;
    }
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }

  return res;
}


static gboolean
gst_rtp_pt_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstRtpPtDemux *demux;
  const GstStructure *s;

  demux = GST_RTP_PT_DEMUX (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_CUSTOM_UPSTREAM:
    case GST_EVENT_CUSTOM_BOTH:
    case GST_EVENT_CUSTOM_BOTH_OOB:
      s = gst_event_get_structure (event);
      if (s && !gst_structure_has_field (s, "payload")) {
        GSList *walk;

        GST_OBJECT_LOCK (demux);
        for (walk = demux->srcpads; walk; walk = g_slist_next (walk)) {
          GstRtpPtDemuxPad *dpad = (GstRtpPtDemuxPad *) walk->data;

          if (dpad->pad == pad) {
            GstStructure *ws;

            event =
                GST_EVENT_CAST (gst_mini_object_make_writable
                (GST_MINI_OBJECT_CAST (event)));
            ws = gst_event_writable_structure (event);
            gst_structure_set (ws, "payload", G_TYPE_UINT, dpad->pt, NULL);
            break;
          }
        }
        GST_OBJECT_UNLOCK (demux);
      }
      break;
    default:
      break;
  }

  return gst_pad_event_default (pad, parent, event);
}

/*
 * Reserves resources for the object.
 */
static gboolean
gst_rtp_pt_demux_setup (GstRtpPtDemux * ptdemux)
{
  ptdemux->srcpads = NULL;
  ptdemux->last_pt = 0xFFFF;

  return TRUE;
}

/*
 * Free resources for the object.
 */
static void
gst_rtp_pt_demux_release (GstRtpPtDemux * ptdemux)
{
  GSList *tmppads;
  GSList *walk;

  GST_OBJECT_LOCK (ptdemux);
  tmppads = ptdemux->srcpads;
  ptdemux->srcpads = NULL;
  GST_OBJECT_UNLOCK (ptdemux);

  for (walk = tmppads; walk; walk = g_slist_next (walk)) {
    GstRtpPtDemuxPad *pad = walk->data;

    gst_pad_set_active (pad->pad, FALSE);
    gst_element_remove_pad (GST_ELEMENT_CAST (ptdemux), pad->pad);
    g_slice_free (GstRtpPtDemuxPad, pad);
  }
  g_slist_free (tmppads);
}

static GstStateChangeReturn
gst_rtp_pt_demux_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstRtpPtDemux *ptdemux;

  ptdemux = GST_RTP_PT_DEMUX (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (gst_rtp_pt_demux_setup (ptdemux) != TRUE)
        ret = GST_STATE_CHANGE_FAILURE;
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      gst_rtp_pt_demux_release (ptdemux);
      break;
    default:
      break;
  }

  return ret;
}
