/* GStreamer RTP KLV Depayloader
 * Copyright (C) 2014-2015 Tim-Philipp Müller <tim@centricular.com>>
 * Copyright (C) 2014-2015 Centricular Ltd
 *
 * 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-rtpklvdepay
 * @see_also: rtpklvpay
 *
 * Extract KLV metadata from RTP packets according to RFC 6597.
 * For detailed information see: http://tools.ietf.org/html/rfc6597
 *
 * <refsect2>
 * <title>Example pipeline</title>
 * |[
 * gst-launch-1.0 udpsrc caps='application/x-rtp, media=(string)application, clock-rate=(int)90000, encoding-name=(string)SMPTE336M' ! rtpklvdepay ! fakesink dump=true
 * ]| This example pipeline will depayload an RTP KLV stream and display
 * a hexdump of the KLV data on stdout.
 * </refsect2>
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gstrtpklvdepay.h"

#include <string.h>

GST_DEBUG_CATEGORY_STATIC (klvdepay_debug);
#define GST_CAT_DEFAULT (klvdepay_debug)

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("meta/x-klv, parsed = (bool) true"));

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) application, clock-rate = (int) [1, MAX], "
        "encoding-name = (string) SMPTE336M")
    );

#define gst_rtp_klv_depay_parent_class parent_class
G_DEFINE_TYPE (GstRtpKlvDepay, gst_rtp_klv_depay, GST_TYPE_RTP_BASE_DEPAYLOAD);

static void gst_rtp_klv_depay_finalize (GObject * object);

static GstStateChangeReturn gst_rtp_klv_depay_change_state (GstElement *
    element, GstStateChange transition);
static gboolean gst_rtp_klv_depay_setcaps (GstRTPBaseDepayload * depayload,
    GstCaps * caps);
static GstBuffer *gst_rtp_klv_depay_process (GstRTPBaseDepayload * depayload,
    GstRTPBuffer * rtp);
static gboolean gst_rtp_klv_depay_handle_event (GstRTPBaseDepayload * depay,
    GstEvent * ev);

static void gst_rtp_klv_depay_reset (GstRtpKlvDepay * klvdepay);

static void
gst_rtp_klv_depay_class_init (GstRtpKlvDepayClass * klass)
{
  GstElementClass *element_class = (GstElementClass *) klass;
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstRTPBaseDepayloadClass *rtpbasedepayload_class;

  GST_DEBUG_CATEGORY_INIT (klvdepay_debug, "klvdepay", 0,
      "RTP KLV Depayloader");

  gobject_class->finalize = gst_rtp_klv_depay_finalize;

  element_class->change_state = gst_rtp_klv_depay_change_state;

  gst_element_class_add_static_pad_template (element_class, &src_template);
  gst_element_class_add_static_pad_template (element_class, &sink_template);

  gst_element_class_set_static_metadata (element_class,
      "RTP KLV Depayloader", "Codec/Depayloader/Network/RTP",
      "Extracts KLV (SMPTE ST 336) metadata from RTP packets",
      "Tim-Philipp Müller <tim@centricular.com>");

  rtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;

  rtpbasedepayload_class->set_caps = gst_rtp_klv_depay_setcaps;
  rtpbasedepayload_class->process_rtp_packet = gst_rtp_klv_depay_process;
  rtpbasedepayload_class->handle_event = gst_rtp_klv_depay_handle_event;
}

static void
gst_rtp_klv_depay_init (GstRtpKlvDepay * klvdepay)
{
  klvdepay->adapter = gst_adapter_new ();
}

static void
gst_rtp_klv_depay_finalize (GObject * object)
{
  GstRtpKlvDepay *klvdepay;

  klvdepay = GST_RTP_KLV_DEPAY (object);

  gst_rtp_klv_depay_reset (klvdepay);
  g_object_unref (klvdepay->adapter);

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

static void
gst_rtp_klv_depay_reset (GstRtpKlvDepay * klvdepay)
{
  GST_DEBUG_OBJECT (klvdepay, "resetting");
  gst_adapter_clear (klvdepay->adapter);
  klvdepay->resync = TRUE;
  klvdepay->last_rtp_ts = -1;
}

static gboolean
gst_rtp_klv_depay_handle_event (GstRTPBaseDepayload * depay, GstEvent * ev)
{
  switch (GST_EVENT_TYPE (ev)) {
    case GST_EVENT_STREAM_START:{
      GstStreamFlags flags;

      ev = gst_event_make_writable (ev);
      gst_event_parse_stream_flags (ev, &flags);
      gst_event_set_stream_flags (ev, flags | GST_STREAM_FLAG_SPARSE);
      break;
    }
    default:
      break;
  }

  return GST_RTP_BASE_DEPAYLOAD_CLASS (parent_class)->handle_event (depay, ev);
}

static gboolean
gst_rtp_klv_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
{
  GstStructure *s;
  GstCaps *src_caps;
  gboolean res;
  gint clock_rate;

  s = gst_caps_get_structure (caps, 0);

  if (!gst_structure_get_int (s, "clock-rate", &clock_rate))
    return FALSE;

  depayload->clock_rate = clock_rate;

  src_caps = gst_static_pad_template_get_caps (&src_template);
  res = gst_pad_set_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (depayload), src_caps);
  gst_caps_unref (src_caps);

  return res;
}

static gboolean
klv_get_vlen (const guint8 * data, guint data_len, guint64 * v_len,
    gsize * len_size)
{
  guint8 first_byte, len_len;
  guint64 len;

  g_assert (data_len > 0);

  first_byte = *data++;

  if ((first_byte & 0x80) == 0) {
    *v_len = first_byte & 0x7f;
    *len_size = 1;
    return TRUE;
  }

  len_len = first_byte & 0x7f;

  if (len_len == 0 || len_len > 8)
    return FALSE;

  if ((1 + len_len) > data_len)
    return FALSE;

  *len_size = 1 + len_len;

  len = 0;
  while (len_len > 0) {
    len = len << 8 | *data++;
    --len_len;
  }

  *v_len = len;

  return TRUE;
}

static GstBuffer *
gst_rtp_klv_depay_process_data (GstRtpKlvDepay * klvdepay)
{
  gsize avail, data_len, len_size;
  GstBuffer *outbuf;
  guint8 data[1 + 8];
  guint64 v_len;

  avail = gst_adapter_available (klvdepay->adapter);

  GST_TRACE_OBJECT (klvdepay, "%" G_GSIZE_FORMAT " bytes in adapter", avail);

  if (avail == 0)
    return NULL;

  /* need at least 16 bytes of UL key plus 1 byte of length */
  if (avail < 16 + 1)
    goto bad_klv_packet;

  /* check if the declared KLV unit size matches actual bytes available */
  data_len = MIN (avail - 16, 1 + 8);
  gst_adapter_copy (klvdepay->adapter, data, 16, data_len);
  if (!klv_get_vlen (data, data_len, &v_len, &len_size))
    goto bad_klv_packet;

  GST_LOG_OBJECT (klvdepay, "want %" G_GUINT64_FORMAT " bytes, "
      "have %" G_GSIZE_FORMAT " bytes", 16 + len_size + v_len, avail);

  if (avail < 16 + len_size + v_len)
    goto incomplete_klv_packet;

  /* something is wrong, this shouldn't ever happen */
  if (avail > 16 + len_size + v_len)
    goto bad_klv_packet;

  outbuf = gst_adapter_take_buffer (klvdepay->adapter, avail);

  /* Mark buffers as key unit to signal this is the start of a KLV unit
   * (for now all buffers will be flagged like this, since all buffers are
   * self-contained KLV units, but in future that might change) */
  outbuf = gst_buffer_make_writable (outbuf);
  GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);

  return outbuf;

/* ERRORS */
bad_klv_packet:
  {
    GST_WARNING_OBJECT (klvdepay, "bad KLV packet, dropping");
    gst_rtp_klv_depay_reset (klvdepay);
    return NULL;
  }
incomplete_klv_packet:
  {
    GST_DEBUG_OBJECT (klvdepay, "partial KLV packet: have %u bytes, want %u",
        (guint) avail, (guint) (16 + len_size + v_len));
    return NULL;
  }
}

/* We're trying to be pragmatic here, not quite as strict as the spec wants
 * us to be with regard to marker bits and resyncing after packet loss */
static GstBuffer *
gst_rtp_klv_depay_process (GstRTPBaseDepayload * depayload, GstRTPBuffer * rtp)
{
  GstRtpKlvDepay *klvdepay = GST_RTP_KLV_DEPAY (depayload);
  GstBuffer *payload, *outbuf = NULL;
  gboolean marker, start = FALSE, maybe_start;
  guint32 rtp_ts;
  guint16 seq;
  guint payload_len;

  /* Ignore DISCONT on first buffer and on buffers following a discont */
  if (GST_BUFFER_IS_DISCONT (rtp->buffer) && klvdepay->last_rtp_ts != -1) {
    GST_WARNING_OBJECT (klvdepay, "DISCONT, need to resync");
    gst_rtp_klv_depay_reset (klvdepay);
  }

  payload_len = gst_rtp_buffer_get_payload_len (rtp);

  /* marker bit signals last fragment of a KLV unit */
  marker = gst_rtp_buffer_get_marker (rtp);

  seq = gst_rtp_buffer_get_seq (rtp);

  /* packet directly after one with marker bit set => start */
  start = klvdepay->last_marker_seq != -1
      && gst_rtp_buffer_compare_seqnum (klvdepay->last_marker_seq, seq) == 1;

  /* deduce start of new KLV unit in case sender doesn't set marker bits
   * (it's not like the spec is ambiguous about that, but what can you do) */
  rtp_ts = gst_rtp_buffer_get_timestamp (rtp);

  maybe_start = klvdepay->last_rtp_ts == -1 || klvdepay->last_rtp_ts != rtp_ts;

  klvdepay->last_rtp_ts = rtp_ts;

  /* fallback to detect self-contained single KLV unit (usual case) */
  if ((!start || !marker || maybe_start) && payload_len > 16) {
    const guint8 *data;
    guint64 v_len;
    gsize len_size;

    data = gst_rtp_buffer_get_payload (rtp);
    if (GST_READ_UINT32_BE (data) == 0x060e2b34 &&
        klv_get_vlen (data + 16, payload_len - 16, &v_len, &len_size)) {
      if (16 + len_size + v_len == payload_len) {
        GST_LOG_OBJECT (klvdepay, "Looks like a self-contained KLV unit");
        marker = TRUE;
        start = TRUE;
      } else if (16 + len_size + v_len > payload_len) {
        GST_LOG_OBJECT (klvdepay,
            "Looks like the start of a fragmented KLV unit");
        start = TRUE;
      }
    }
  }

  /* If this is the first packet and looks like a start, clear resync flag */
  if (klvdepay->resync && klvdepay->last_marker_seq == -1 && start)
    klvdepay->resync = FALSE;

  if (marker)
    klvdepay->last_marker_seq = seq;

  GST_LOG_OBJECT (klvdepay, "payload of %u bytes, marker=%d, start=%d",
      payload_len, marker, start);

  if (klvdepay->resync && !start) {
    GST_DEBUG_OBJECT (klvdepay, "Dropping buffer, waiting to resync");

    if (marker)
      klvdepay->resync = FALSE;

    goto done;
  }

  if (start && !marker)
    outbuf = gst_rtp_klv_depay_process_data (klvdepay);

  payload = gst_rtp_buffer_get_payload_buffer (rtp);
  gst_adapter_push (klvdepay->adapter, payload);

  if (marker)
    outbuf = gst_rtp_klv_depay_process_data (klvdepay);

done:

  return outbuf;
}

static GstStateChangeReturn
gst_rtp_klv_depay_change_state (GstElement * element, GstStateChange transition)
{
  GstRtpKlvDepay *klvdepay;
  GstStateChangeReturn ret;

  klvdepay = GST_RTP_KLV_DEPAY (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_rtp_klv_depay_reset (klvdepay);
      klvdepay->last_marker_seq = -1;
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_rtp_klv_depay_reset (klvdepay);
      break;
    default:
      break;
  }
  return ret;
}

gboolean
gst_rtp_klv_depay_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "rtpklvdepay",
      GST_RANK_SECONDARY, GST_TYPE_RTP_KLV_DEPAY);
}
