/* GStreamer
 * Copyright (C) <2006> 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.
 */

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

#include <stdio.h>
#include <string.h>

#include <gst/base/gstbitreader.h>
#include <gst/rtp/gstrtpbuffer.h>
#include "gstrtph264depay.h"

GST_DEBUG_CATEGORY_STATIC (rtph264depay_debug);
#define GST_CAT_DEFAULT (rtph264depay_debug)

/* This is what we'll default to when downstream hasn't
 * expressed a restriction or preference via caps */
#define DEFAULT_BYTE_STREAM   TRUE
#define DEFAULT_ACCESS_UNIT   FALSE

/* 3 zero bytes syncword */
static const guint8 sync_bytes[] = { 0, 0, 0, 1 };

static GstStaticPadTemplate gst_rtp_h264_depay_src_template =
    GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-h264, "
        "stream-format = (string) avc, alignment = (string) au; "
        "video/x-h264, "
        "stream-format = (string) byte-stream, alignment = (string) { nal, au }")
    );

static GstStaticPadTemplate gst_rtp_h264_depay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"video\", "
        "clock-rate = (int) 90000, " "encoding-name = (string) \"H264\"")
        /** optional parameters **/
    /* "profile-level-id = (string) ANY, " */
    /* "max-mbps = (string) ANY, " */
    /* "max-fs = (string) ANY, " */
    /* "max-cpb = (string) ANY, " */
    /* "max-dpb = (string) ANY, " */
    /* "max-br = (string) ANY, " */
    /* "redundant-pic-cap = (string) { \"0\", \"1\" }, " */
    /* "sprop-parameter-sets = (string) ANY, " */
    /* "parameter-add = (string) { \"0\", \"1\" }, " */
    /* "packetization-mode = (string) { \"0\", \"1\", \"2\" }, " */
    /* "sprop-interleaving-depth = (string) ANY, " */
    /* "sprop-deint-buf-req = (string) ANY, " */
    /* "deint-buf-cap = (string) ANY, " */
    /* "sprop-init-buf-time = (string) ANY, " */
    /* "sprop-max-don-diff = (string) ANY, " */
    /* "max-rcmd-nalu-size = (string) ANY " */
    );

#define gst_rtp_h264_depay_parent_class parent_class
G_DEFINE_TYPE (GstRtpH264Depay, gst_rtp_h264_depay,
    GST_TYPE_RTP_BASE_DEPAYLOAD);

static void gst_rtp_h264_depay_finalize (GObject * object);

static GstStateChangeReturn gst_rtp_h264_depay_change_state (GstElement *
    element, GstStateChange transition);

static GstBuffer *gst_rtp_h264_depay_process (GstRTPBaseDepayload * depayload,
    GstBuffer * buf);
static gboolean gst_rtp_h264_depay_setcaps (GstRTPBaseDepayload * filter,
    GstCaps * caps);
static gboolean gst_rtp_h264_depay_handle_event (GstRTPBaseDepayload * depay,
    GstEvent * event);

static void
gst_rtp_h264_depay_class_init (GstRtpH264DepayClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstRTPBaseDepayloadClass *gstrtpbasedepayload_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstrtpbasedepayload_class = (GstRTPBaseDepayloadClass *) klass;

  gobject_class->finalize = gst_rtp_h264_depay_finalize;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_rtp_h264_depay_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_rtp_h264_depay_sink_template));

  gst_element_class_set_static_metadata (gstelement_class,
      "RTP H264 depayloader", "Codec/Depayloader/Network/RTP",
      "Extracts H264 video from RTP packets (RFC 3984)",
      "Wim Taymans <wim.taymans@gmail.com>");
  gstelement_class->change_state = gst_rtp_h264_depay_change_state;

  gstrtpbasedepayload_class->process = gst_rtp_h264_depay_process;
  gstrtpbasedepayload_class->set_caps = gst_rtp_h264_depay_setcaps;
  gstrtpbasedepayload_class->handle_event = gst_rtp_h264_depay_handle_event;
}

static void
gst_rtp_h264_depay_init (GstRtpH264Depay * rtph264depay)
{
  rtph264depay->adapter = gst_adapter_new ();
  rtph264depay->picture_adapter = gst_adapter_new ();
  rtph264depay->byte_stream = DEFAULT_BYTE_STREAM;
  rtph264depay->merge = DEFAULT_ACCESS_UNIT;
  rtph264depay->sps = g_ptr_array_new_with_free_func (
      (GDestroyNotify) gst_buffer_unref);
  rtph264depay->pps = g_ptr_array_new_with_free_func (
      (GDestroyNotify) gst_buffer_unref);
}

static void
gst_rtp_h264_depay_reset (GstRtpH264Depay * rtph264depay)
{
  gst_adapter_clear (rtph264depay->adapter);
  rtph264depay->wait_start = TRUE;
  gst_adapter_clear (rtph264depay->picture_adapter);
  rtph264depay->picture_start = FALSE;
  rtph264depay->last_keyframe = FALSE;
  rtph264depay->last_ts = 0;
  rtph264depay->current_fu_type = 0;
  rtph264depay->new_codec_data = FALSE;
  g_ptr_array_set_size (rtph264depay->sps, 0);
  g_ptr_array_set_size (rtph264depay->pps, 0);
}

static void
gst_rtp_h264_depay_finalize (GObject * object)
{
  GstRtpH264Depay *rtph264depay;

  rtph264depay = GST_RTP_H264_DEPAY (object);

  if (rtph264depay->codec_data)
    gst_buffer_unref (rtph264depay->codec_data);

  g_object_unref (rtph264depay->adapter);
  g_object_unref (rtph264depay->picture_adapter);

  g_ptr_array_free (rtph264depay->sps, TRUE);
  g_ptr_array_free (rtph264depay->pps, TRUE);

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

static void
gst_rtp_h264_depay_negotiate (GstRtpH264Depay * rtph264depay)
{
  GstCaps *caps;
  gint byte_stream = -1;
  gint merge = -1;

  caps =
      gst_pad_get_allowed_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (rtph264depay));

  GST_DEBUG_OBJECT (rtph264depay, "allowed caps: %" GST_PTR_FORMAT, caps);

  if (caps) {
    if (gst_caps_get_size (caps) > 0) {
      GstStructure *s = gst_caps_get_structure (caps, 0);
      const gchar *str = NULL;

      if ((str = gst_structure_get_string (s, "stream-format"))) {
        if (strcmp (str, "avc") == 0) {
          byte_stream = FALSE;
        } else if (strcmp (str, "byte-stream") == 0) {
          byte_stream = TRUE;
        } else {
          GST_DEBUG_OBJECT (rtph264depay, "unknown stream-format: %s", str);
        }
      }

      if ((str = gst_structure_get_string (s, "alignment"))) {
        if (strcmp (str, "au") == 0) {
          merge = TRUE;
        } else if (strcmp (str, "nal") == 0) {
          merge = FALSE;
        } else {
          GST_DEBUG_OBJECT (rtph264depay, "unknown alignment: %s", str);
        }
      }
    }
    gst_caps_unref (caps);
  }

  if (byte_stream != -1) {
    GST_DEBUG_OBJECT (rtph264depay, "downstream requires byte-stream %d",
        byte_stream);
    rtph264depay->byte_stream = byte_stream;
  } else {
    GST_DEBUG_OBJECT (rtph264depay, "defaulting to byte-stream %d",
        DEFAULT_BYTE_STREAM);
    rtph264depay->byte_stream = DEFAULT_BYTE_STREAM;
  }
  if (merge != -1) {
    GST_DEBUG_OBJECT (rtph264depay, "downstream requires merge %d", merge);
    rtph264depay->merge = merge;
  } else {
    GST_DEBUG_OBJECT (rtph264depay, "defaulting to merge %d",
        DEFAULT_ACCESS_UNIT);
    rtph264depay->merge = DEFAULT_ACCESS_UNIT;
  }
}

/* Stolen from bad/gst/mpegtsdemux/payloader_parsers.c */
/* variable length Exp-Golomb parsing according to H.264 spec 9.1*/
static gboolean
read_golomb (GstBitReader * br, guint32 * value)
{
  guint8 b, leading_zeros = -1;
  *value = 1;

  for (b = 0; !b; leading_zeros++) {
    if (!gst_bit_reader_get_bits_uint8 (br, &b, 1))
      return FALSE;
    *value *= 2;
  }

  *value = (*value >> 1) - 1;
  if (leading_zeros > 0) {
    guint32 tmp = 0;
    if (!gst_bit_reader_get_bits_uint32 (br, &tmp, leading_zeros))
      return FALSE;
    *value += tmp;
  }

  return TRUE;
}

static gboolean
parse_sps (GstMapInfo * map, guint32 * sps_id)
{
  GstBitReader br = GST_BIT_READER_INIT (map->data + 4,
      map->size - 4);

  if (map->size < 5)
    return FALSE;

  if (!read_golomb (&br, sps_id))
    return FALSE;

  return TRUE;
}

static gboolean
parse_pps (GstMapInfo * map, guint32 * sps_id, guint32 * pps_id)
{
  GstBitReader br = GST_BIT_READER_INIT (map->data + 1,
      map->size - 1);

  if (map->size < 2)
    return FALSE;

  if (!read_golomb (&br, pps_id))
    return FALSE;
  if (!read_golomb (&br, sps_id))
    return FALSE;

  return TRUE;
}


static gboolean
gst_rtp_h264_set_src_caps (GstRtpH264Depay * rtph264depay)
{
  gboolean res;
  GstCaps *srccaps;
  guchar level = 0;
  guchar profile_compat = G_MAXUINT8;

  if (!rtph264depay->byte_stream &&
      (!rtph264depay->new_codec_data ||
          rtph264depay->sps->len == 0 || rtph264depay->pps->len == 0))
    return TRUE;

  srccaps = gst_caps_new_simple ("video/x-h264",
      "stream-format", G_TYPE_STRING,
      rtph264depay->byte_stream ? "byte-stream" : "avc",
      "alignment", G_TYPE_STRING, rtph264depay->merge ? "au" : "nal", NULL);

  if (!rtph264depay->byte_stream) {
    GstBuffer *codec_data;
    GstMapInfo map;
    GstMapInfo nalmap;
    guint8 *data;
    guint len;
    guint new_size;
    guint i;

    /* start with 7 bytes header */
    len = 7;
    /* count sps & pps */
    for (i = 0; i < rtph264depay->sps->len; i++)
      len += 2 + gst_buffer_get_size (g_ptr_array_index (rtph264depay->sps, i));
    for (i = 0; i < rtph264depay->pps->len; i++)
      len += 2 + gst_buffer_get_size (g_ptr_array_index (rtph264depay->pps, i));

    codec_data = gst_buffer_new_and_alloc (len);
    g_debug ("alloc_len: %u", len);
    gst_buffer_map (codec_data, &map, GST_MAP_READWRITE);
    data = map.data;

    /* 8 bits version == 1 */
    *data++ = 1;

    /* According to: ISO/IEC 14496-15:2004(E) section 5.2.4.1
     * The level is the max level of all SPSes
     * A profile compat bit can only be set if all SPSes include that bit
     */
    for (i = 0; i < rtph264depay->sps->len; i++) {
      gst_buffer_map (g_ptr_array_index (rtph264depay->sps, i), &nalmap,
          GST_MAP_READ);
      profile_compat &= nalmap.data[2];
      level = MAX (level, nalmap.data[3]);
      gst_buffer_unmap (g_ptr_array_index (rtph264depay->sps, i), &nalmap);
    }

    /* Assume all SPSes use the same profile, so extract from the first SPS */
    gst_buffer_map (g_ptr_array_index (rtph264depay->sps, 0), &nalmap,
        GST_MAP_READ);
    *data++ = nalmap.data[1];
    gst_buffer_unmap (g_ptr_array_index (rtph264depay->sps, 0), &nalmap);
    *data++ = profile_compat;
    *data++ = level;

    /* 6 bits reserved | 2 bits lengthSizeMinusOn */
    *data++ = 0xff;
    /* 3 bits reserved | 5 bits numOfSequenceParameterSets */
    *data++ = 0xe0 | (rtph264depay->sps->len & 0x1f);

    /* copy all SPS */
    for (i = 0; i < rtph264depay->sps->len; i++) {
      gst_buffer_map (g_ptr_array_index (rtph264depay->sps, i), &nalmap,
          GST_MAP_READ);

      GST_DEBUG_OBJECT (rtph264depay, "copy SPS %d of length %u", i,
          (guint) nalmap.size);
      GST_WRITE_UINT16_BE (data, nalmap.size);
      data += 2;
      memcpy (data, nalmap.data, nalmap.size);
      data += nalmap.size;
      gst_buffer_unmap (g_ptr_array_index (rtph264depay->sps, i), &nalmap);
    }

    /* 8 bits numOfPictureParameterSets */
    *data++ = rtph264depay->pps->len;
    /* copy all PPS */
    for (i = 0; i < rtph264depay->pps->len; i++) {
      gst_buffer_map (g_ptr_array_index (rtph264depay->pps, i), &nalmap,
          GST_MAP_READ);

      GST_DEBUG_OBJECT (rtph264depay, "copy PPS %d of length %u", i,
          (guint) nalmap.size);
      GST_WRITE_UINT16_BE (data, nalmap.size);
      data += 2;
      memcpy (data, nalmap.data, nalmap.size);
      data += nalmap.size;
      gst_buffer_unmap (g_ptr_array_index (rtph264depay->pps, i), &nalmap);
    }

    new_size = data - map.data;
    gst_buffer_unmap (codec_data, &map);
    gst_buffer_set_size (codec_data, new_size);


    gst_caps_set_simple (srccaps,
        "codec_data", GST_TYPE_BUFFER, codec_data, NULL);
    gst_buffer_unref (codec_data);
  }

  res = gst_pad_set_caps (GST_RTP_BASE_DEPAYLOAD_SRCPAD (rtph264depay),
      srccaps);
  gst_caps_unref (srccaps);

  if (res)
    rtph264depay->new_codec_data = FALSE;

  return res;
}

gboolean
gst_rtp_h264_add_sps_pps (GstElement * rtph264, GPtrArray * sps_array,
    GPtrArray * pps_array, GstBuffer * nal)
{
  GstMapInfo map;
  guchar type;
  guint i;

  gst_buffer_map (nal, &map, GST_MAP_READ);

  type = map.data[0] & 0x1f;

  if (type == 7) {
    guint32 sps_id;

    if (!parse_sps (&map, &sps_id)) {
      GST_WARNING_OBJECT (rtph264, "Invalid SPS,"
          " can't parse seq_parameter_set_id");
      goto drop;
    }

    for (i = 0; i < sps_array->len; i++) {
      GstBuffer *sps = g_ptr_array_index (sps_array, i);
      GstMapInfo spsmap;
      guint32 tmp_sps_id;

      gst_buffer_map (sps, &spsmap, GST_MAP_READ);
      parse_sps (&spsmap, &tmp_sps_id);

      if (sps_id == tmp_sps_id) {
        if (map.size == spsmap.size &&
            memcmp (map.data, spsmap.data, spsmap.size) == 0) {
          GST_LOG_OBJECT (rtph264, "Unchanged SPS %u, not updating", sps_id);
          gst_buffer_unmap (sps, &spsmap);
          goto drop;
        } else {
          gst_buffer_unmap (sps, &spsmap);
          g_ptr_array_remove_index_fast (sps_array, i);
          g_ptr_array_add (sps_array, nal);
          GST_LOG_OBJECT (rtph264, "Modified SPS %u, replacing", sps_id);
          goto done;
        }
      }
      gst_buffer_unmap (sps, &spsmap);
    }
    GST_LOG_OBJECT (rtph264, "Adding new SPS %u", sps_id);
    g_ptr_array_add (sps_array, nal);
  } else if (type == 8) {
    guint32 sps_id;
    guint32 pps_id;

    if (!parse_pps (&map, &sps_id, &pps_id)) {
      GST_WARNING_OBJECT (rtph264, "Invalid PPS,"
          " can't parse seq_parameter_set_id or pic_parameter_set_id");
      goto drop;
    }

    for (i = 0; i < pps_array->len; i++) {
      GstBuffer *pps = g_ptr_array_index (pps_array, i);
      GstMapInfo ppsmap;
      guint32 tmp_sps_id;
      guint32 tmp_pps_id;


      gst_buffer_map (pps, &ppsmap, GST_MAP_READ);
      parse_pps (&ppsmap, &tmp_sps_id, &tmp_pps_id);

      if (sps_id == tmp_sps_id && pps_id == tmp_pps_id) {
        if (map.size == ppsmap.size &&
            memcmp (map.data, ppsmap.data, ppsmap.size) == 0) {
          GST_LOG_OBJECT (rtph264, "Unchanged PPS %u:%u, not updating", sps_id,
              pps_id);
          gst_buffer_unmap (pps, &ppsmap);
          goto drop;
        } else {
          gst_buffer_unmap (pps, &ppsmap);
          g_ptr_array_remove_index_fast (pps_array, i);
          g_ptr_array_add (pps_array, nal);
          GST_LOG_OBJECT (rtph264, "Modified PPS %u:%u, replacing",
              sps_id, pps_id);
          goto done;
        }
      }
      gst_buffer_unmap (pps, &ppsmap);
    }
    GST_LOG_OBJECT (rtph264, "Adding new PPS %u:%i", sps_id, pps_id);
    g_ptr_array_add (pps_array, nal);
  } else {
    goto drop;
  }

done:
  gst_buffer_unmap (nal, &map);

  return TRUE;

drop:
  gst_buffer_unmap (nal, &map);
  gst_buffer_unref (nal);

  return FALSE;
}


static void
gst_rtp_h264_depay_add_sps_pps (GstRtpH264Depay * rtph264depay, GstBuffer * nal)
{
  if (gst_rtp_h264_add_sps_pps (GST_ELEMENT (rtph264depay),
          rtph264depay->sps, rtph264depay->pps, nal))
    rtph264depay->new_codec_data = TRUE;
}

static gboolean
gst_rtp_h264_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
{
  gint clock_rate;
  GstStructure *structure = gst_caps_get_structure (caps, 0);
  GstRtpH264Depay *rtph264depay;
  const gchar *ps;
  GstBuffer *codec_data;
  GstMapInfo map;
  guint8 *ptr;

  rtph264depay = GST_RTP_H264_DEPAY (depayload);

  if (!gst_structure_get_int (structure, "clock-rate", &clock_rate))
    clock_rate = 90000;
  depayload->clock_rate = clock_rate;

  /* Base64 encoded, comma separated config NALs */
  ps = gst_structure_get_string (structure, "sprop-parameter-sets");

  /* negotiate with downstream w.r.t. output format and alignment */
  gst_rtp_h264_depay_negotiate (rtph264depay);

  if (rtph264depay->byte_stream && ps != NULL) {
    /* for bytestream we only need the parameter sets but we don't error out
     * when they are not there, we assume they are in the stream. */
    gchar **params;
    guint len, total;
    gint i;

    params = g_strsplit (ps, ",", 0);

    /* count total number of bytes in base64. Also include the sync bytes in
     * front of the params. */
    len = 0;
    for (i = 0; params[i]; i++) {
      len += strlen (params[i]);
      len += sizeof (sync_bytes);
    }
    /* we seriously overshoot the length, but it's fine. */
    codec_data = gst_buffer_new_and_alloc (len);

    gst_buffer_map (codec_data, &map, GST_MAP_WRITE);
    ptr = map.data;
    total = 0;
    for (i = 0; params[i]; i++) {
      guint save = 0;
      gint state = 0;

      GST_DEBUG_OBJECT (depayload, "decoding param %d (%s)", i, params[i]);
      memcpy (ptr, sync_bytes, sizeof (sync_bytes));
      ptr += sizeof (sync_bytes);
      len =
          g_base64_decode_step (params[i], strlen (params[i]), ptr, &state,
          &save);
      GST_DEBUG_OBJECT (depayload, "decoded %d bytes", len);
      total += len + sizeof (sync_bytes);
      ptr += len;
    }
    gst_buffer_unmap (codec_data, &map);
    gst_buffer_resize (codec_data, 0, total);
    g_strfreev (params);

    /* keep the codec_data, we need to send it as the first buffer. We cannot
     * push it in the adapter because the adapter might be flushed on discont.
     */
    if (rtph264depay->codec_data)
      gst_buffer_unref (rtph264depay->codec_data);
    rtph264depay->codec_data = codec_data;
  } else if (!rtph264depay->byte_stream) {
    gchar **params;
    gint i;

    if (ps == NULL)
      goto incomplete_caps;

    params = g_strsplit (ps, ",", 0);

    GST_DEBUG_OBJECT (depayload, "we have %d params", g_strv_length (params));

    /* start with 7 bytes header */
    for (i = 0; params[i]; i++) {
      GstBuffer *nal;
      GstMapInfo nalmap;
      gsize nal_len;
      guint save = 0;
      gint state = 0;

      nal_len = strlen (params[i]);
      nal = gst_buffer_new_and_alloc (nal_len);
      gst_buffer_map (nal, &nalmap, GST_MAP_READWRITE);

      nal_len =
          g_base64_decode_step (params[i], nal_len, nalmap.data, &state, &save);

      GST_DEBUG_OBJECT (depayload, "adding param %d as %s", i,
          ((nalmap.data[0] & 0x1f) == 7) ? "SPS" : "PPS");

      gst_buffer_unmap (nal, &nalmap);
      gst_buffer_set_size (nal, nal_len);

      gst_rtp_h264_depay_add_sps_pps (rtph264depay, nal);
    }
    g_strfreev (params);

    if (rtph264depay->sps->len == 0 || rtph264depay->pps->len == 0)
      goto incomplete_caps;
  }

  return gst_rtp_h264_set_src_caps (rtph264depay);

  /* ERRORS */
incomplete_caps:
  {
    GST_DEBUG_OBJECT (depayload, "we have incomplete caps,"
        " doing setcaps later");
    return TRUE;
  }
}

static GstBuffer *
gst_rtp_h264_complete_au (GstRtpH264Depay * rtph264depay,
    GstClockTime * out_timestamp, gboolean * out_keyframe)
{
  guint outsize;
  GstBuffer *outbuf;

  /* we had a picture in the adapter and we completed it */
  GST_DEBUG_OBJECT (rtph264depay, "taking completed AU");
  outsize = gst_adapter_available (rtph264depay->picture_adapter);
  outbuf = gst_adapter_take_buffer (rtph264depay->picture_adapter, outsize);

  *out_timestamp = rtph264depay->last_ts;
  *out_keyframe = rtph264depay->last_keyframe;

  rtph264depay->last_keyframe = FALSE;
  rtph264depay->picture_start = FALSE;

  return outbuf;
}

/* SPS/PPS/IDR considered key, all others DELTA;
 * so downstream waiting for keyframe can pick up at SPS/PPS/IDR */
#define NAL_TYPE_IS_KEY(nt) (((nt) == 5) || ((nt) == 7) || ((nt) == 8))

static GstBuffer *
gst_rtp_h264_depay_handle_nal (GstRtpH264Depay * rtph264depay, GstBuffer * nal,
    GstClockTime in_timestamp, gboolean marker)
{
  GstRTPBaseDepayload *depayload = GST_RTP_BASE_DEPAYLOAD (rtph264depay);
  gint nal_type;
  GstMapInfo map;
  GstBuffer *outbuf = NULL;
  GstClockTime out_timestamp;
  gboolean keyframe, out_keyframe;

  gst_buffer_map (nal, &map, GST_MAP_READ);
  if (G_UNLIKELY (map.size < 5))
    goto short_nal;

  nal_type = map.data[4] & 0x1f;
  GST_DEBUG_OBJECT (rtph264depay, "handle NAL type %d", nal_type);

  keyframe = NAL_TYPE_IS_KEY (nal_type);

  out_keyframe = keyframe;
  out_timestamp = in_timestamp;

  if (!rtph264depay->byte_stream) {
    if (nal_type == 7 || nal_type == 8) {
      gst_rtp_h264_depay_add_sps_pps (rtph264depay,
          gst_buffer_copy_region (nal, GST_BUFFER_COPY_ALL,
              4, gst_buffer_get_size (nal) - 4));
      gst_buffer_unmap (nal, &map);
      gst_buffer_unref (nal);
      return NULL;
    } else if (rtph264depay->sps->len == 0 || rtph264depay->pps->len == 0) {
      /* Down push down any buffer in non-bytestream mode if the SPS/PPS haven't
       * go through yet
       */
      gst_pad_push_event (GST_RTP_BASE_DEPAYLOAD_SINKPAD (depayload),
          gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM,
              gst_structure_new ("GstForceKeyUnit",
                  "all-headers", G_TYPE_BOOLEAN, TRUE, NULL)));
      gst_buffer_unmap (nal, &map);
      gst_buffer_unref (nal);
      return NULL;
    }

    if (rtph264depay->new_codec_data &&
        rtph264depay->sps->len > 0 && rtph264depay->pps->len > 0)
      gst_rtp_h264_set_src_caps (rtph264depay);
  }


  if (rtph264depay->merge) {
    gboolean start = FALSE, complete = FALSE;

    /* marker bit isn't mandatory so in the following code we try to guess
     * an AU boundary by detecting a new picture start */
    if (!marker) {
      /* consider a coded slices (IDR or not) to start a picture,
       * (so ending the previous one) if first_mb_in_slice == 0
       * (non-0 is part of previous one) */
      /* NOTE this is not entirely according to Access Unit specs in 7.4.1.2.4,
       * but in practice it works in sane cases, needs not much parsing,
       * and also works with broken frame_num in NAL (where spec-wise would fail) */
      /* FIXME: this code isn't correct for interlaced content as AUs should be
       * constructed with pairs of fields and the guess here will just push out
       * AUs with a single field in it */
      if (nal_type == 1 || nal_type == 2 || nal_type == 5) {
        /* we have a picture start */
        start = TRUE;
        if (map.data[5] & 0x80) {
          /* first_mb_in_slice == 0 completes a picture */
          complete = TRUE;
        }
      } else if (nal_type >= 6 && nal_type <= 9) {
        /* SEI, SPS, PPS, AU terminate picture */
        complete = TRUE;
      }
      GST_DEBUG_OBJECT (depayload, "start %d, complete %d", start, complete);

      if (complete && rtph264depay->picture_start)
        outbuf = gst_rtp_h264_complete_au (rtph264depay, &out_timestamp,
            &out_keyframe);
    }
    /* add to adapter */
    gst_buffer_unmap (nal, &map);

    GST_DEBUG_OBJECT (depayload, "adding NAL to picture adapter");
    gst_adapter_push (rtph264depay->picture_adapter, nal);
    rtph264depay->last_ts = in_timestamp;
    rtph264depay->last_keyframe |= keyframe;
    rtph264depay->picture_start |= start;

    if (marker)
      outbuf = gst_rtp_h264_complete_au (rtph264depay, &out_timestamp,
          &out_keyframe);
  } else {
    /* no merge, output is input nal */
    GST_DEBUG_OBJECT (depayload, "using NAL as output");
    outbuf = nal;
    gst_buffer_unmap (nal, &map);
  }

  if (outbuf) {
    /* prepend codec_data */
    if (rtph264depay->codec_data) {
      GST_DEBUG_OBJECT (depayload, "prepending codec_data");
      outbuf = gst_buffer_append (rtph264depay->codec_data, outbuf);
      rtph264depay->codec_data = NULL;
      out_keyframe = TRUE;
    }
    outbuf = gst_buffer_make_writable (outbuf);

    GST_BUFFER_TIMESTAMP (outbuf) = out_timestamp;

    if (out_keyframe)
      GST_BUFFER_FLAG_UNSET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
    else
      GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
  }

  return outbuf;

  /* ERRORS */
short_nal:
  {
    GST_WARNING_OBJECT (depayload, "dropping short NAL");
    gst_buffer_unmap (nal, &map);
    gst_buffer_unref (nal);
    return NULL;
  }
}

static GstBuffer *
gst_rtp_h264_push_fragmentation_unit (GstRtpH264Depay * rtph264depay,
    gboolean send)
{
  guint outsize;
  GstMapInfo map;
  GstBuffer *outbuf;

  outsize = gst_adapter_available (rtph264depay->adapter);
  outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);

  gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
  GST_DEBUG_OBJECT (rtph264depay, "output %d bytes", outsize);

  if (rtph264depay->byte_stream) {
    memcpy (map.data, sync_bytes, sizeof (sync_bytes));
  } else {
    outsize -= 4;
    map.data[0] = (outsize >> 24);
    map.data[1] = (outsize >> 16);
    map.data[2] = (outsize >> 8);
    map.data[3] = (outsize);
  }
  gst_buffer_unmap (outbuf, &map);

  rtph264depay->current_fu_type = 0;

  outbuf = gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf,
      rtph264depay->fu_timestamp, rtph264depay->fu_marker);

  if (send && outbuf) {
    gst_rtp_base_depayload_push (GST_RTP_BASE_DEPAYLOAD (rtph264depay), outbuf);
    outbuf = NULL;
  }
  return outbuf;
}

static GstBuffer *
gst_rtp_h264_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
{
  GstRtpH264Depay *rtph264depay;
  GstBuffer *outbuf = NULL;
  guint8 nal_unit_type;
  GstRTPBuffer rtp = { NULL };

  rtph264depay = GST_RTP_H264_DEPAY (depayload);

  /* flush remaining data on discont */
  if (GST_BUFFER_IS_DISCONT (buf)) {
    gst_adapter_clear (rtph264depay->adapter);
    rtph264depay->wait_start = TRUE;
    rtph264depay->current_fu_type = 0;
  }

  {
    gint payload_len;
    guint8 *payload;
    guint header_len;
    guint8 nal_ref_idc;
    GstMapInfo map;
    guint outsize, nalu_size;
    GstClockTime timestamp;
    gboolean marker;

    timestamp = GST_BUFFER_TIMESTAMP (buf);

    gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp);

    payload_len = gst_rtp_buffer_get_payload_len (&rtp);
    payload = gst_rtp_buffer_get_payload (&rtp);
    marker = gst_rtp_buffer_get_marker (&rtp);

    GST_DEBUG_OBJECT (rtph264depay, "receiving %d bytes", payload_len);

    if (payload_len == 0)
      goto empty_packet;

    /* +---------------+
     * |0|1|2|3|4|5|6|7|
     * +-+-+-+-+-+-+-+-+
     * |F|NRI|  Type   |
     * +---------------+
     *
     * F must be 0.
     */
    nal_ref_idc = (payload[0] & 0x60) >> 5;
    nal_unit_type = payload[0] & 0x1f;

    /* at least one byte header with type */
    header_len = 1;

    GST_DEBUG_OBJECT (rtph264depay, "NRI %d, Type %d", nal_ref_idc,
        nal_unit_type);

    /* If FU unit was being processed, but the current nal is of a different
     * type.  Assume that the remote payloader is buggy (didn't set the end bit
     * when the FU ended) and send out what we gathered thusfar */
    if (G_UNLIKELY (rtph264depay->current_fu_type != 0 &&
            nal_unit_type != rtph264depay->current_fu_type))
      gst_rtp_h264_push_fragmentation_unit (rtph264depay, TRUE);

    switch (nal_unit_type) {
      case 0:
      case 30:
      case 31:
        /* undefined */
        goto undefined_type;
      case 25:
        /* STAP-B    Single-time aggregation packet     5.7.1 */
        /* 2 byte extra header for DON */
        header_len += 2;
        /* fallthrough */
      case 24:
      {
        /* strip headers */
        payload += header_len;
        payload_len -= header_len;

        rtph264depay->wait_start = FALSE;


        /* STAP-A    Single-time aggregation packet     5.7.1 */
        while (payload_len > 2) {
          /*                      1          
           *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           * |         NALU Size             |
           * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           */
          nalu_size = (payload[0] << 8) | payload[1];

          /* dont include nalu_size */
          if (nalu_size > (payload_len - 2))
            nalu_size = payload_len - 2;

          outsize = nalu_size + sizeof (sync_bytes);
          outbuf = gst_buffer_new_and_alloc (outsize);

          gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
          if (rtph264depay->byte_stream) {
            memcpy (map.data, sync_bytes, sizeof (sync_bytes));
          } else {
            map.data[0] = map.data[1] = 0;
            map.data[2] = payload[0];
            map.data[3] = payload[1];
          }

          /* strip NALU size */
          payload += 2;
          payload_len -= 2;

          memcpy (map.data + sizeof (sync_bytes), payload, nalu_size);
          gst_buffer_unmap (outbuf, &map);

          outbuf =
              gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp,
              marker);
          if (outbuf)
            gst_adapter_push (rtph264depay->adapter, outbuf);

          payload += nalu_size;
          payload_len -= nalu_size;
        }

        outsize = gst_adapter_available (rtph264depay->adapter);
        if (outsize > 0) {
          outbuf = gst_adapter_take_buffer (rtph264depay->adapter, outsize);
          outbuf =
              gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp,
              marker);
        }
        break;
      }
      case 26:
        /* MTAP16    Multi-time aggregation packet      5.7.2 */
        // header_len = 5;
        /* fallthrough, not implemented */
      case 27:
        /* MTAP24    Multi-time aggregation packet      5.7.2 */
        // header_len = 6;
        goto not_implemented;
        break;
      case 28:
      case 29:
      {
        /* FU-A      Fragmentation unit                 5.8 */
        /* FU-B      Fragmentation unit                 5.8 */
        gboolean S, E;

        /* +---------------+
         * |0|1|2|3|4|5|6|7|
         * +-+-+-+-+-+-+-+-+
         * |S|E|R|  Type   |
         * +---------------+
         *
         * R is reserved and always 0
         */
        S = (payload[1] & 0x80) == 0x80;
        E = (payload[1] & 0x40) == 0x40;

        GST_DEBUG_OBJECT (rtph264depay, "S %d, E %d", S, E);

        if (rtph264depay->wait_start && !S)
          goto waiting_start;

        if (S) {
          /* NAL unit starts here */
          guint8 nal_header;

          /* If a new FU unit started, while still processing an older one.
           * Assume that the remote payloader is buggy (doesn't set the end
           * bit) and send out what we've gathered thusfar */
          if (G_UNLIKELY (rtph264depay->current_fu_type != 0))
            gst_rtp_h264_push_fragmentation_unit (rtph264depay, TRUE);

          rtph264depay->current_fu_type = nal_unit_type;
          rtph264depay->fu_timestamp = timestamp;

          rtph264depay->wait_start = FALSE;

          /* reconstruct NAL header */
          nal_header = (payload[0] & 0xe0) | (payload[1] & 0x1f);

          /* strip type header, keep FU header, we'll reuse it to reconstruct
           * the NAL header. */
          payload += 1;
          payload_len -= 1;

          nalu_size = payload_len;
          outsize = nalu_size + sizeof (sync_bytes);
          outbuf = gst_buffer_new_and_alloc (outsize);

          gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
          memcpy (map.data + sizeof (sync_bytes), payload, nalu_size);
          map.data[sizeof (sync_bytes)] = nal_header;
          gst_buffer_unmap (outbuf, &map);

          GST_DEBUG_OBJECT (rtph264depay, "queueing %d bytes", outsize);

          /* and assemble in the adapter */
          gst_adapter_push (rtph264depay->adapter, outbuf);
        } else {
          /* strip off FU indicator and FU header bytes */
          payload += 2;
          payload_len -= 2;

          outsize = payload_len;
          outbuf = gst_buffer_new_and_alloc (outsize);
          gst_buffer_fill (outbuf, 0, payload, outsize);

          GST_DEBUG_OBJECT (rtph264depay, "queueing %d bytes", outsize);

          /* and assemble in the adapter */
          gst_adapter_push (rtph264depay->adapter, outbuf);
        }

        outbuf = NULL;
        rtph264depay->fu_marker = marker;

        /* if NAL unit ends, flush the adapter */
        if (E)
          outbuf = gst_rtp_h264_push_fragmentation_unit (rtph264depay, FALSE);
        break;
      }
      default:
      {
        rtph264depay->wait_start = FALSE;

        /* 1-23   NAL unit  Single NAL unit packet per H.264   5.6 */
        /* the entire payload is the output buffer */
        nalu_size = payload_len;
        outsize = nalu_size + sizeof (sync_bytes);
        outbuf = gst_buffer_new_and_alloc (outsize);

        gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
        if (rtph264depay->byte_stream) {
          memcpy (map.data, sync_bytes, sizeof (sync_bytes));
        } else {
          map.data[0] = map.data[1] = 0;
          map.data[2] = nalu_size >> 8;
          map.data[3] = nalu_size & 0xff;
        }
        memcpy (map.data + sizeof (sync_bytes), payload, nalu_size);
        gst_buffer_unmap (outbuf, &map);

        outbuf = gst_rtp_h264_depay_handle_nal (rtph264depay, outbuf, timestamp,
            marker);
        break;
      }
    }
    gst_rtp_buffer_unmap (&rtp);
  }

  return outbuf;

  /* ERRORS */
empty_packet:
  {
    GST_DEBUG_OBJECT (rtph264depay, "empty packet");
    gst_rtp_buffer_unmap (&rtp);
    return NULL;
  }
undefined_type:
  {
    GST_ELEMENT_WARNING (rtph264depay, STREAM, DECODE,
        (NULL), ("Undefined packet type"));
    gst_rtp_buffer_unmap (&rtp);
    return NULL;
  }
waiting_start:
  {
    GST_DEBUG_OBJECT (rtph264depay, "waiting for start");
    gst_rtp_buffer_unmap (&rtp);
    return NULL;
  }
not_implemented:
  {
    GST_ELEMENT_ERROR (rtph264depay, STREAM, FORMAT,
        (NULL), ("NAL unit type %d not supported yet", nal_unit_type));
    gst_rtp_buffer_unmap (&rtp);
    return NULL;
  }
}

static gboolean
gst_rtp_h264_depay_handle_event (GstRTPBaseDepayload * depay, GstEvent * event)
{
  GstRtpH264Depay *rtph264depay;

  rtph264depay = GST_RTP_H264_DEPAY (depay);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      gst_rtp_h264_depay_reset (rtph264depay);
      break;
    default:
      break;
  }

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

static GstStateChangeReturn
gst_rtp_h264_depay_change_state (GstElement * element,
    GstStateChange transition)
{
  GstRtpH264Depay *rtph264depay;
  GstStateChangeReturn ret;

  rtph264depay = GST_RTP_H264_DEPAY (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_rtp_h264_depay_reset (rtph264depay);
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }
  return ret;
}

gboolean
gst_rtp_h264_depay_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (rtph264depay_debug, "rtph264depay", 0,
      "H264 Video RTP Depayloader");

  return gst_element_register (plugin, "rtph264depay",
      GST_RANK_SECONDARY, GST_TYPE_RTP_H264_DEPAY);
}
