/* GStreamer ASF/WMV/WMA demuxer
 * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net>
 *
 * 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.
 */

/* FIXME:
 *  file:///home/tpm/samples/video/asf//336370-regis-velo862.wmv
 *  file:///home/tpm/samples/video/asf//336370-eichhoer.wmv
 * throw errors (not always necessarily) in this code path
 * (looks like they carry broken payloads/packets though) */

#include "asfpacket.h"

#include <gst/gstutils.h>
#include <gst/gstinfo.h>
#include <string.h>

#define GST_ASF_PAYLOAD_KF_COMPLETE(stream, payload) (stream->is_video && payload->keyframe && payload->buf_filled >= payload->mo_size)

/* we are unlikely to deal with lengths > 2GB here any time soon, so just
 * return a signed int and use that for error reporting */
static inline gint
asf_packet_read_varlen_int (guint lentype_flags, guint lentype_bit_offset,
    const guint8 ** p_data, guint * p_size)
{
  static const guint lens[4] = { 0, 1, 2, 4 };
  guint len, val;

  len = lens[(lentype_flags >> lentype_bit_offset) & 0x03];

  /* will make caller bail out with a short read if there's not enough data */
  if (G_UNLIKELY (*p_size < len)) {
    GST_WARNING ("need %u bytes, but only %u bytes available", len, *p_size);
    return -1;
  }

  switch (len) {
    case 0:
      val = 0;
      break;
    case 1:
      val = GST_READ_UINT8 (*p_data);
      break;
    case 2:
      val = GST_READ_UINT16_LE (*p_data);
      break;
    case 4:
      val = GST_READ_UINT32_LE (*p_data);
      break;
    default:
      val = 0;
      g_assert_not_reached ();
  }

  *p_data += len;
  *p_size -= len;

  return (gint) val;
}

static GstBuffer *
asf_packet_create_payload_buffer (AsfPacket * packet, const guint8 ** p_data,
    guint * p_size, guint payload_len)
{
  guint off;

  g_assert (payload_len <= *p_size);

  off = (guint) (*p_data - packet->bdata);
  g_assert (off < gst_buffer_get_size (packet->buf));

  *p_data += payload_len;
  *p_size -= payload_len;

  return gst_buffer_copy_region (packet->buf, GST_BUFFER_COPY_ALL, off,
      payload_len);
}

static AsfPayload *
asf_payload_search_payloads_queue (AsfPayload * payload, GArray * payload_list)
{
  AsfPayload *ret = NULL;
  gint idx;
  for (idx = payload_list->len - 1; idx >= 0; idx--) {
    ret = &g_array_index (payload_list, AsfPayload, idx);

    if (G_UNLIKELY (ret->mo_size == payload->mo_size &&
            ret->mo_number == payload->mo_number)) {
      return ret;
    }
  }
  return NULL;
}

static AsfPayload *
asf_payload_find_previous_fragment (GstASFDemux * demux, AsfPayload * payload,
    AsfStream * stream)
{
  AsfPayload *ret = NULL;

  if (GST_ASF_DEMUX_IS_REVERSE_PLAYBACK (demux->segment)) {

    /* Search in queued payloads list */
    ret = asf_payload_search_payloads_queue (payload, stream->payloads);
    if (ret) {
      GST_DEBUG
          ("previous fragments found in payloads queue for reverse playback : object ID %d",
          ret->mo_number);
      return ret;
    }

    /* Search in payloads 'to be queued' list */
    ret = asf_payload_search_payloads_queue (payload, stream->payloads_rev);
    if (ret) {
      GST_DEBUG
          ("previous fragments found in temp payload queue for reverse playback : object ID %d",
          ret->mo_number);
      return ret;
    }
  } else {
    if (G_UNLIKELY (stream->payloads->len == 0)) {
      GST_DEBUG ("No previous fragments to merge with for stream %u",
          stream->id);
      return NULL;
    }

    ret =
        &g_array_index (stream->payloads, AsfPayload,
        stream->payloads->len - 1);

    if (G_UNLIKELY (ret->mo_size != payload->mo_size ||
            ret->mo_number != payload->mo_number || ret->mo_offset != 0)) {
      if (payload->mo_size != 0) {
        GST_WARNING ("Previous fragment does not match continued fragment");
        return NULL;
      } else {
        /* Warn about this case, but accept it anyway: files in the wild sometimes
         * have continued packets where the subsequent fragments say that they're
         * zero-sized. */
        GST_WARNING ("Previous fragment found, but current fragment has "
            "zero size, accepting anyway");
      }
    }
  }

#if 0
  if (this_fragment->mo_offset + this_payload_len > first_fragment->mo_size) {
    GST_WARNING ("Merged fragments would be bigger than the media object");
    return FALSE;
  }
#endif

  return ret;
}

/* TODO: if we have another payload already queued for this stream and that
 * payload doesn't have a duration, maybe we can calculate a duration for it
 * (if the previous timestamp is smaller etc. etc.) */
static void
gst_asf_payload_queue_for_stream_forward (GstASFDemux * demux,
    AsfPayload * payload, AsfStream * stream)
{
  GST_DEBUG_OBJECT (demux, "Got payload for stream %d ts:%" GST_TIME_FORMAT,
      stream->id, GST_TIME_ARGS (payload->ts));

  /* make timestamps start from 0; first_ts will be determined during activation (once we have enough data),
     which will also update ts of all packets queued before we knew first_ts;  */
  if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (demux->first_ts)
          && GST_CLOCK_TIME_IS_VALID (payload->ts))) {
    if (payload->ts > demux->first_ts)
      payload->ts -= demux->first_ts;
    else
      payload->ts = 0;
  }

  /* remove any incomplete payloads that will never be completed */
  while (stream->payloads->len > 0) {
    AsfPayload *prev;
    guint idx_last;

    idx_last = stream->payloads->len - 1;
    prev = &g_array_index (stream->payloads, AsfPayload, idx_last);

    if (G_UNLIKELY (gst_asf_payload_is_complete (prev)))
      break;

    GST_DEBUG_OBJECT (demux, "Dropping incomplete fragmented media object "
        "queued for stream %u", stream->id);

    gst_buffer_replace (&prev->buf, NULL);
    g_array_remove_index (stream->payloads, idx_last);

    /* there's data missing, so there's a discontinuity now */
    GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DISCONT);
  }

  /* If we're about to queue a key frame that is before the segment start, we
   * can ditch any previously queued payloads (which would also be before the
   * segment start). This makes sure the decoder doesn't decode more than
   * absolutely necessary after a seek (we don't push out payloads that are
   * before the segment start until we have at least one that falls within the
   * segment) */
  if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (payload->ts) &&
          payload->ts < demux->segment.start && payload->keyframe)) {
    GST_DEBUG_OBJECT (demux, "Queueing keyframe before segment start, removing"
        " %u previously-queued payloads, which would be out of segment too and"
        " hence don't have to be decoded", stream->payloads->len);
    while (stream->payloads->len > 0) {
      AsfPayload *last;
      guint idx_last;

      idx_last = stream->payloads->len - 1;
      last = &g_array_index (stream->payloads, AsfPayload, idx_last);
      gst_buffer_replace (&last->buf, NULL);
      g_array_remove_index (stream->payloads, idx_last);
    }

    /* Mark discontinuity (should be done via stream->discont anyway though) */
    GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DISCONT);
  }

  g_array_append_vals (stream->payloads, payload, 1);
}

static void
gst_asf_payload_queue_for_stream_reverse (GstASFDemux * demux,
    AsfPayload * payload, AsfStream * stream)
{
  GST_DEBUG_OBJECT (demux, "Got payload for stream %d ts:%" GST_TIME_FORMAT,
      stream->id, GST_TIME_ARGS (payload->ts));

  if (demux->multiple_payloads) {
    /* store the payload in temporary buffer, until we parse all payloads in this packet */
    g_array_append_vals (stream->payloads_rev, payload, 1);
  } else {
    if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (payload->ts))) {
      g_array_append_vals (stream->payloads, payload, 1);
      if (GST_ASF_PAYLOAD_KF_COMPLETE (stream, payload)) {
        stream->kf_pos = stream->payloads->len - 1;
      }
    } else {
      gst_buffer_unref (payload->buf);
    }
  }
}


static void
gst_asf_payload_queue_for_stream (GstASFDemux * demux, AsfPayload * payload,
    AsfStream * stream)
{
  GST_DEBUG_OBJECT (demux, "Got payload for stream %d ts:%" GST_TIME_FORMAT,
      stream->id, GST_TIME_ARGS (payload->ts));

  if (GST_ASF_DEMUX_IS_REVERSE_PLAYBACK (demux->segment)) {
    gst_asf_payload_queue_for_stream_reverse (demux, payload, stream);
  } else {
    gst_asf_payload_queue_for_stream_forward (demux, payload, stream);
  }

}

static void
asf_payload_parse_replicated_data_extensions (AsfStream * stream,
    AsfPayload * payload)
{
  AsfPayloadExtension *ext;
  guint off;
  guint16 ext_len;

  if (!stream->ext_props.valid || stream->ext_props.payload_extensions == NULL)
    return;

  off = 8;
  for (ext = stream->ext_props.payload_extensions; ext->len > 0; ++ext) {
    ext_len = ext->len;
    if (ext_len == 0xFFFF) {    /* extension length is determined by first two bytes in replicated data */
      ext_len = GST_READ_UINT16_LE (payload->rep_data + off);
      off += 2;
    }
    if (G_UNLIKELY (off + ext_len > payload->rep_data_len)) {
      GST_WARNING ("not enough replicated data for defined extensions");
      return;
    }
    switch (ext->id) {
      case ASF_PAYLOAD_EXTENSION_DURATION:
        if (G_LIKELY (ext_len == 2)) {
          guint16 tdur = GST_READ_UINT16_LE (payload->rep_data + off);
          /* packet durations of 1ms are mostly invalid */
          if (tdur != 1)
            payload->duration = tdur * GST_MSECOND;
        } else {
          GST_WARNING ("unexpected DURATION extensions len %u", ext_len);
        }
        break;
      case ASF_PAYLOAD_EXTENSION_SYSTEM_CONTENT:
        if (G_LIKELY (ext_len == 1)) {
          guint8 data = payload->rep_data[off];

          payload->interlaced = data & 0x1;
          payload->rff = data & 0x8;
          payload->tff = (data & 0x2) || !(data & 0x4);
          GST_DEBUG ("SYSTEM_CONTENT: interlaced:%d, rff:%d, tff:%d",
              payload->interlaced, payload->rff, payload->tff);
        } else {
          GST_WARNING ("unexpected SYSTEM_CONTE extensions len %u", ext_len);
        }
        break;
      case ASF_PAYLOAD_EXTENSION_SYSTEM_PIXEL_ASPECT_RATIO:
        if (G_LIKELY (ext_len == 2)) {
          payload->par_x = payload->rep_data[off];
          payload->par_y = payload->rep_data[off + 1];
          GST_DEBUG ("PAR %d / %d", payload->par_x, payload->par_y);
        } else {
          GST_WARNING ("unexpected SYSTEM_PIXEL_ASPECT_RATIO extensions len %u",
              ext_len);
        }
        break;
      case ASF_PAYLOAD_EXTENSION_TIMING:
      {
        /* dvr-ms timing - this will override packet timestamp */
        guint64 time = GST_READ_UINT64_LE (payload->rep_data + off + 8);
        if (time != 0xFFFFFFFFFFFFFFFF)
          payload->ts = time * 100;
        else
          payload->ts = GST_CLOCK_TIME_NONE;
      }
        break;
      default:
        GST_LOG ("UNKNOWN PAYLOAD EXTENSION!");
        break;
    }
    off += ext_len;
  }
}

static gboolean
gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet,
    gint lentype, const guint8 ** p_data, guint * p_size)
{
  AsfPayload payload = { 0, };
  AsfStream *stream;
  gboolean is_compressed;
  guint payload_len;
  guint stream_num;

  if (G_UNLIKELY (*p_size < 1)) {
    GST_WARNING_OBJECT (demux, "Short packet!");
    return FALSE;
  }

  stream_num = GST_READ_UINT8 (*p_data) & 0x7f;
  payload.keyframe = ((GST_READ_UINT8 (*p_data) & 0x80) != 0);

  *p_data += 1;
  *p_size -= 1;

  payload.ts = GST_CLOCK_TIME_NONE;
  payload.duration = GST_CLOCK_TIME_NONE;
  payload.par_x = 0;
  payload.par_y = 0;
  payload.interlaced = FALSE;
  payload.tff = FALSE;
  payload.rff = FALSE;

  payload.mo_number =
      asf_packet_read_varlen_int (packet->prop_flags, 4, p_data, p_size);
  payload.mo_offset =
      asf_packet_read_varlen_int (packet->prop_flags, 2, p_data, p_size);
  payload.rep_data_len =
      asf_packet_read_varlen_int (packet->prop_flags, 0, p_data, p_size);

  is_compressed = (payload.rep_data_len == 1);

  GST_LOG_OBJECT (demux, "payload for stream %u", stream_num);
  GST_LOG_OBJECT (demux, "keyframe   : %s", (payload.keyframe) ? "yes" : "no");
  GST_LOG_OBJECT (demux, "compressed : %s", (is_compressed) ? "yes" : "no");

  if (G_UNLIKELY (*p_size < payload.rep_data_len)) {
    GST_WARNING_OBJECT (demux, "Short packet! rep_data_len=%u, size=%u",
        payload.rep_data_len, *p_size);
    return FALSE;
  }

  memcpy (payload.rep_data, *p_data,
      MIN (sizeof (payload.rep_data), payload.rep_data_len));

  *p_data += payload.rep_data_len;
  *p_size -= payload.rep_data_len;

  if (G_UNLIKELY (*p_size == 0)) {
    GST_WARNING_OBJECT (demux, "payload without data!?");
    return FALSE;
  }

  /* we use -1 as lentype for a single payload that's the size of the packet */
  if (G_UNLIKELY ((lentype >= 0 && lentype <= 3))) {
    payload_len = asf_packet_read_varlen_int (lentype, 0, p_data, p_size);
    if (*p_size < payload_len) {
      GST_WARNING_OBJECT (demux, "Short packet! payload_len=%u, size=%u",
          payload_len, *p_size);
      return FALSE;
    }
  } else {
    payload_len = *p_size;
  }

  GST_LOG_OBJECT (demux, "payload length: %u", payload_len);

  stream = gst_asf_demux_get_stream (demux, stream_num);

  if (G_UNLIKELY (stream == NULL)) {
    if (gst_asf_demux_is_unknown_stream (demux, stream_num)) {
      GST_WARNING_OBJECT (demux, "Payload for unknown stream %u, skipping",
          stream_num);
    }
    if (*p_size < payload_len) {
      *p_data += *p_size;
      *p_size = 0;
    } else {
      *p_data += payload_len;
      *p_size -= payload_len;
    }
    return TRUE;
  }

  if (!stream->is_video)
    stream->kf_pos = 0;

  if (G_UNLIKELY (!is_compressed)) {
    GST_LOG_OBJECT (demux, "replicated data length: %u", payload.rep_data_len);

    if (payload.rep_data_len >= 8) {
      payload.mo_size = GST_READ_UINT32_LE (payload.rep_data);
      payload.ts = GST_READ_UINT32_LE (payload.rep_data + 4) * GST_MSECOND;
      if (G_UNLIKELY (payload.ts < demux->preroll))
        payload.ts = 0;
      else
        payload.ts -= demux->preroll;
      asf_payload_parse_replicated_data_extensions (stream, &payload);

      GST_LOG_OBJECT (demux, "media object size   : %u", payload.mo_size);
      GST_LOG_OBJECT (demux, "media object ts     : %" GST_TIME_FORMAT,
          GST_TIME_ARGS (payload.ts));
      GST_LOG_OBJECT (demux, "media object dur    : %" GST_TIME_FORMAT,
          GST_TIME_ARGS (payload.duration));
    } else if (payload.rep_data_len == 0) {
      payload.mo_size = 0;
    } else if (payload.rep_data_len != 0) {
      GST_WARNING_OBJECT (demux, "invalid replicated data length, very bad");
      *p_data += payload_len;
      *p_size -= payload_len;
      return FALSE;
    }

    GST_LOG_OBJECT (demux, "media object offset : %u", payload.mo_offset);

    GST_LOG_OBJECT (demux, "payload length: %u", payload_len);

    if (payload_len == 0) {
      GST_DEBUG_OBJECT (demux, "skipping empty payload");
    } else if (payload.mo_offset == 0 && payload.mo_size == payload_len) {
      /* if the media object is not fragmented, just create a sub-buffer */
      GST_LOG_OBJECT (demux, "unfragmented media object size %u", payload_len);
      payload.buf = asf_packet_create_payload_buffer (packet, p_data, p_size,
          payload_len);
      payload.buf_filled = payload_len;
      gst_asf_payload_queue_for_stream (demux, &payload, stream);
    } else if (GST_ASF_DEMUX_IS_REVERSE_PLAYBACK (demux->segment)) {
      /* Handle fragmented payloads for reverse playback */
      AsfPayload *prev;
      const guint8 *payload_data = *p_data;
      prev = asf_payload_find_previous_fragment (demux, &payload, stream);

      if (prev) {
        gint idx;
        AsfPayload *p;
        gst_buffer_fill (prev->buf, payload.mo_offset,
            payload_data, payload_len);
        prev->buf_filled += payload_len;
        if (payload.keyframe && payload.mo_offset == 0) {
          stream->reverse_kf_ready = TRUE;

          for (idx = stream->payloads->len - 1; idx >= 0; idx--) {
            p = &g_array_index (stream->payloads, AsfPayload, idx);
            if (p->mo_number == payload.mo_number) {
              /* Mark position of KF for reverse play */
              stream->kf_pos = idx;
            }
          }
        }
      } else {
        payload.buf = gst_buffer_new_allocate (NULL, payload.mo_size, NULL);    /* can we use (mo_size - offset) for size? */
        gst_buffer_fill (payload.buf, payload.mo_offset,
            payload_data, payload_len);
        payload.buf_filled = payload.mo_size - (payload.mo_offset);
        gst_asf_payload_queue_for_stream (demux, &payload, stream);
      }
      *p_data += payload_len;
      *p_size -= payload_len;
    } else {
      const guint8 *payload_data = *p_data;

      g_assert (payload_len <= *p_size);

      *p_data += payload_len;
      *p_size -= payload_len;

      /* n-th fragment of a fragmented media object? */
      if (payload.mo_offset != 0) {
        AsfPayload *prev;

        if ((prev =
                asf_payload_find_previous_fragment (demux, &payload, stream))) {
          if (prev->buf == NULL || (payload.mo_size > 0
                  && payload.mo_size != prev->mo_size)
              || payload.mo_offset >= gst_buffer_get_size (prev->buf)
              || payload.mo_offset + payload_len >
              gst_buffer_get_size (prev->buf)) {
            GST_WARNING_OBJECT (demux, "Offset doesn't match previous data?!");
          } else {
            /* we assume fragments are payloaded with increasing mo_offset */
            if (payload.mo_offset != prev->buf_filled) {
              GST_WARNING_OBJECT (demux, "media object payload discontinuity: "
                  "offset=%u vs buf_filled=%u", payload.mo_offset,
                  prev->buf_filled);
            }
            gst_buffer_fill (prev->buf, payload.mo_offset,
                payload_data, payload_len);
            prev->buf_filled =
                MAX (prev->buf_filled, payload.mo_offset + payload_len);
            GST_LOG_OBJECT (demux, "Merged media object fragments, size now %u",
                prev->buf_filled);
          }
        } else {
          GST_DEBUG_OBJECT (demux, "n-th payload fragment, but don't have "
              "any previous fragment, ignoring payload");
        }
      } else {
        GST_LOG_OBJECT (demux, "allocating buffer of size %u for fragmented "
            "media object", payload.mo_size);
        payload.buf = gst_buffer_new_allocate (NULL, payload.mo_size, NULL);
        gst_buffer_fill (payload.buf, 0, payload_data, payload_len);
        payload.buf_filled = payload_len;

        gst_asf_payload_queue_for_stream (demux, &payload, stream);
      }
    }
  } else {
    const guint8 *payload_data;
    GstClockTime ts, ts_delta;
    guint num;

    GST_LOG_OBJECT (demux, "Compressed payload, length=%u", payload_len);

    payload_data = *p_data;

    *p_data += payload_len;
    *p_size -= payload_len;

    ts = payload.mo_offset * GST_MSECOND;
    if (G_UNLIKELY (ts < demux->preroll))
      ts = 0;
    else
      ts -= demux->preroll;
    ts_delta = payload.rep_data[0] * GST_MSECOND;

    for (num = 0; payload_len > 0; ++num) {
      guint sub_payload_len;

      sub_payload_len = GST_READ_UINT8 (payload_data);

      GST_LOG_OBJECT (demux, "subpayload #%u: len=%u, ts=%" GST_TIME_FORMAT,
          num, sub_payload_len, GST_TIME_ARGS (ts));

      ++payload_data;
      --payload_len;

      if (G_UNLIKELY (payload_len < sub_payload_len)) {
        GST_WARNING_OBJECT (demux, "Short payload! %u bytes left", payload_len);
        return FALSE;
      }

      if (G_LIKELY (sub_payload_len > 0)) {
        payload.buf = asf_packet_create_payload_buffer (packet,
            &payload_data, &payload_len, sub_payload_len);
        payload.buf_filled = sub_payload_len;

        payload.ts = ts;
        if (G_LIKELY (ts_delta))
          payload.duration = ts_delta;
        else
          payload.duration = GST_CLOCK_TIME_NONE;

        gst_asf_payload_queue_for_stream (demux, &payload, stream);
      }

      ts += ts_delta;
    }
  }

  return TRUE;
}

GstAsfDemuxParsePacketError
gst_asf_demux_parse_packet (GstASFDemux * demux, GstBuffer * buf)
{
  AsfPacket packet = { 0, };
  GstMapInfo map;
  const guint8 *data;
  gboolean has_multiple_payloads;
  GstAsfDemuxParsePacketError ret = GST_ASF_DEMUX_PARSE_PACKET_ERROR_NONE;
  guint8 ec_flags, flags1;
  guint size;

  gst_buffer_map (buf, &map, GST_MAP_READ);
  data = map.data;
  size = map.size;
  GST_LOG_OBJECT (demux, "Buffer size: %u", size);

  /* need at least two payload flag bytes, send time, and duration */
  if (G_UNLIKELY (size < 2 + 4 + 2)) {
    GST_WARNING_OBJECT (demux, "Packet size is < 8");
    ret = GST_ASF_DEMUX_PARSE_PACKET_ERROR_RECOVERABLE;
    goto done;
  }

  packet.buf = buf;
  /* evidently transient */
  packet.bdata = data;

  ec_flags = GST_READ_UINT8 (data);

  /* skip optional error correction stuff */
  if ((ec_flags & 0x80) != 0) {
    guint ec_len_type, ec_len;

    ec_len_type = (ec_flags & 0x60) >> 5;
    if (ec_len_type == 0) {
      ec_len = ec_flags & 0x0f;
    } else {
      GST_WARNING_OBJECT (demux, "unexpected error correction length type %u",
          ec_len_type);
      ec_len = 2;
    }
    GST_LOG_OBJECT (demux, "packet has error correction (%u bytes)", ec_len);

    /* still need at least two payload flag bytes, send time, and duration */
    if (size <= (1 + ec_len) + 2 + 4 + 2) {
      GST_WARNING_OBJECT (demux, "Packet size is < 8 with Error Correction");
      ret = GST_ASF_DEMUX_PARSE_PACKET_ERROR_FATAL;
      goto done;
    }

    data += 1 + ec_len;
    size -= 1 + ec_len;
  }

  /* parse payload info */
  flags1 = GST_READ_UINT8 (data);
  packet.prop_flags = GST_READ_UINT8 (data + 1);

  data += 2;
  size -= 2;

  has_multiple_payloads = (flags1 & 0x01) != 0;

  packet.length = asf_packet_read_varlen_int (flags1, 5, &data, &size);

  packet.sequence = asf_packet_read_varlen_int (flags1, 1, &data, &size);

  packet.padding = asf_packet_read_varlen_int (flags1, 3, &data, &size);

  if (G_UNLIKELY (size < 6)) {
    GST_WARNING_OBJECT (demux, "Packet size is < 6");
    ret = GST_ASF_DEMUX_PARSE_PACKET_ERROR_FATAL;
    goto done;
  }

  packet.send_time = GST_READ_UINT32_LE (data) * GST_MSECOND;
  packet.duration = GST_READ_UINT16_LE (data + 4) * GST_MSECOND;

  data += 4 + 2;
  size -= 4 + 2;

  GST_LOG_OBJECT (demux, "flags            : 0x%x", flags1);
  GST_LOG_OBJECT (demux, "multiple payloads: %u", has_multiple_payloads);
  GST_LOG_OBJECT (demux, "packet length    : %u", packet.length);
  GST_LOG_OBJECT (demux, "sequence         : %u", packet.sequence);
  GST_LOG_OBJECT (demux, "padding          : %u", packet.padding);
  GST_LOG_OBJECT (demux, "send time        : %" GST_TIME_FORMAT,
      GST_TIME_ARGS (packet.send_time));

  GST_LOG_OBJECT (demux, "duration         : %" GST_TIME_FORMAT,
      GST_TIME_ARGS (packet.duration));

  if (GST_ASF_DEMUX_IS_REVERSE_PLAYBACK (demux->segment)
      && demux->seek_to_cur_pos == TRUE) {
    /* For reverse playback, initially parse packets forward until we reach packet with 'seek' timestamp */
    if (packet.send_time - demux->preroll > demux->segment.stop) {
      demux->seek_to_cur_pos = FALSE;
    }
    ret = GST_ASF_DEMUX_PARSE_PACKET_ERROR_NONE;
    goto done;
  }

  if (G_UNLIKELY (packet.padding == (guint) - 1 || size < packet.padding)) {
    GST_WARNING_OBJECT (demux, "No padding, or padding bigger than buffer");
    ret = GST_ASF_DEMUX_PARSE_PACKET_ERROR_RECOVERABLE;
    goto done;
  }

  size -= packet.padding;

  /* adjust available size for parsing if there's less actual packet data for
   * parsing than there is data in bytes (for sample see bug 431318) */
  if (G_UNLIKELY (packet.length != 0 && packet.padding == 0
          && packet.length < demux->packet_size)) {
    GST_LOG_OBJECT (demux, "shortened packet with implicit padding, "
        "adjusting available data size");
    if (size < demux->packet_size - packet.length) {
      /* the buffer is smaller than the implicit padding */
      GST_WARNING_OBJECT (demux, "Buffer is smaller than the implicit padding");
      ret = GST_ASF_DEMUX_PARSE_PACKET_ERROR_RECOVERABLE;
      goto done;
    } else {
      /* subtract the implicit padding */
      size -= (demux->packet_size - packet.length);
    }
  }

  if (has_multiple_payloads) {
    guint i, num, lentype;
    demux->multiple_payloads = TRUE;

    if (G_UNLIKELY (size < 1)) {
      GST_WARNING_OBJECT (demux, "No room more in buffer");
      ret = GST_ASF_DEMUX_PARSE_PACKET_ERROR_RECOVERABLE;
      goto done;
    }

    num = (GST_READ_UINT8 (data) & 0x3F) >> 0;
    lentype = (GST_READ_UINT8 (data) & 0xC0) >> 6;

    ++data;
    --size;

    GST_LOG_OBJECT (demux, "num payloads     : %u", num);

    for (i = 0; i < num; ++i) {
      GST_LOG_OBJECT (demux, "Parsing payload %u/%u, size left: %u", i + 1, num,
          size);

      if (G_UNLIKELY (!gst_asf_demux_parse_payload (demux, &packet, lentype,
                  &data, &size))) {
        GST_WARNING_OBJECT (demux, "Failed to parse payload %u/%u", i + 1, num);
        ret = GST_ASF_DEMUX_PARSE_PACKET_ERROR_FATAL;
        break;
      }
    }

    if (GST_ASF_DEMUX_IS_REVERSE_PLAYBACK (demux->segment)) {
      /* In reverse playback, we parsed the packet (with multiple payloads) and stored the payloads in temporary queue.
         Now, add them to the stream's payload queue */
      for (i = 0; i < demux->num_streams; i++) {
        AsfStream *s = &demux->stream[i];
        while (s->payloads_rev->len > 0) {
          AsfPayload *p;
          p = &g_array_index (s->payloads_rev, AsfPayload,
              s->payloads_rev->len - 1);
          g_array_append_vals (s->payloads, p, 1);
          if (GST_ASF_PAYLOAD_KF_COMPLETE (s, p)) {
            /* Mark position of KF for reverse play */
            s->kf_pos = s->payloads->len - 1;
          }
          g_array_remove_index (s->payloads_rev, (s->payloads_rev->len - 1));
        }
      }
    }

  } else {
    GST_LOG_OBJECT (demux, "Parsing single payload");
    demux->multiple_payloads = FALSE;
    if (G_UNLIKELY (!gst_asf_demux_parse_payload (demux, &packet, -1, &data,
                &size))) {
      GST_WARNING_OBJECT (demux, "Failed to parse payload");
      ret = GST_ASF_DEMUX_PARSE_PACKET_ERROR_RECOVERABLE;
    }
  }

done:
  gst_buffer_unmap (buf, &map);
  return ret;
}
