/*
 * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
 *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation
 * version 2.1 of the License.
 *
 * 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
 *
 */

/*
 * Information about the caps fields:
 *
 * header-format:
 *   none: No codec_data and only in-stream headers
 *
 *   asf: codec_data as specified in the ASF specification
 *       Simple/Main profile: 4 byte sequence header without startcode
 *       Advanced profile: Sequence header and entrypoint with startcodes
 *
 *   sequence-layer: codec_data as specified in SMPTE 421M Annex L.2
 *
 *
 * stream-format:
 *   bdu: BDUs with startcodes
 *
 *   bdu-frame: BDUs with startcodes, everything up to and including a frame
 *       per buffer. This also means everything needed to decode a frame, i.e.
 *       field and slice BDUs
 *
 *   sequence-layer-bdu: Sequence layer in first buffer, then BDUs with startcodes
 *
 *   sequence-layer-bdu-frame: Sequence layer in first buffer, then only frame
 *       BDUs with startcodes, i.e. everything up to and including a frame.
 *
 *   sequence-layer-raw-frame: Sequence layer in first buffer, then only frame
 *       BDUs without startcodes. Only for simple/main profile.
 *
 *   sequence-layer-frame-layer: As specified in SMPTE 421M Annex L, sequence-layer
 *       first, then BDUs inside frame-layer
 *
 *   asf: As specified in the ASF specification.
 *       For simple/main profile a single frame BDU without startcodes per buffer
 *       For advanced profile one or many BDUs with/without startcodes:
 *           Startcodes required if non-frame BDU or multiple BDUs per buffer
 *           unless frame BDU followed by field BDU. In that case only second (field)
 *           startcode required.
 *
 *   frame-layer: As specified in SMPTE 421M Annex L.2
 *
 *
 * If no stream-format is given in the caps we do the following:
 *
 *   0) If header-format=asf we assume stream-format=asf
 *   1) If first buffer starts with sequence header startcode
 *      we assume stream-format=bdu (or bdu-frame, doesn't matter
 *      for the input because we're parsing anyway)
 *   2) If first buffer starts with sequence layer startcode
 *      1) If followed by sequence header or frame startcode
 *         we assume stream-format=sequence-layer-bdu (or -bdu-frame,
 *         doesn't matter for the input because we're parsing anyway)
 *      2) Otherwise we assume stream-format=sequence-layer-frame-layer
 *   3) Otherwise
 *      1) If header-format=sequence-layer we assume stream-format=frame-layer
 *      2) If header-format=none we error out
 */

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

#include "gstvc1parse.h"

#include <gst/base/base.h>
#include <gst/pbutils/pbutils.h>
#include <string.h>

GST_DEBUG_CATEGORY (vc1_parse_debug);
#define GST_CAT_DEFAULT vc1_parse_debug

static const struct
{
  gchar str[15];
  VC1HeaderFormat en;
} header_formats[] = {
  {
  "none", VC1_HEADER_FORMAT_NONE}, {
  "asf", VC1_HEADER_FORMAT_ASF}, {
  "sequence-layer", VC1_HEADER_FORMAT_SEQUENCE_LAYER}
};

static const struct
{
  gchar str[27];
  VC1StreamFormat en;
} stream_formats[] = {
  {
  "bdu", VC1_STREAM_FORMAT_BDU}, {
  "bdu-frame", VC1_STREAM_FORMAT_BDU_FRAME}, {
  "sequence-layer-bdu", VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU}, {
  "sequence-layer-bdu-frame", VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME}, {
  "sequence-layer-raw-frame", VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME}, {
  "sequence-layer-frame-layer", VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER}, {
  "asf", VC1_STREAM_FORMAT_ASF}, {
  "frame-layer", VC1_STREAM_FORMAT_FRAME_LAYER}
};

static const struct
{
  gchar str[5];
  GstVC1ParseFormat en;
} parse_formats[] = {
  {
  "WMV3", GST_VC1_PARSE_FORMAT_WMV3}, {
  "WVC1", GST_VC1_PARSE_FORMAT_WVC1}
};

static const gchar *
stream_format_to_string (VC1StreamFormat stream_format)
{
  return stream_formats[stream_format].str;
}

static VC1StreamFormat
stream_format_from_string (const gchar * stream_format)
{
  gint i;

  for (i = 0; i < G_N_ELEMENTS (stream_formats); i++) {
    if (strcmp (stream_formats[i].str, stream_format) == 0)
      return stream_formats[i].en;
  }
  return -1;
}

static const gchar *
header_format_to_string (VC1HeaderFormat header_format)
{
  return header_formats[header_format].str;
}

static VC1HeaderFormat
header_format_from_string (const gchar * header_format)
{
  gint i;

  for (i = 0; i < G_N_ELEMENTS (header_formats); i++) {
    if (strcmp (header_formats[i].str, header_format) == 0)
      return header_formats[i].en;
  }
  return -1;
}

static const gchar *
parse_format_to_string (GstVC1ParseFormat format)
{
  return parse_formats[format].str;
}

static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-wmv, wmvversion=(int) 3, "
        "format=(string) {WVC1, WMV3}"));

static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-wmv, wmvversion=(int) 3, "
        "format=(string) {WVC1, WMV3}, "
        "stream-format=(string) {bdu, bdu-frame, sequence-layer-bdu, "
        "sequence-layer-bdu-frame, sequence-layer-raw-frame, "
        "sequence-layer-frame-layer, asf, frame-layer}, "
        "header-format=(string) {none, asf, sequence-layer}"));


#define parent_class gst_vc1_parse_parent_class
G_DEFINE_TYPE (GstVC1Parse, gst_vc1_parse, GST_TYPE_BASE_PARSE);

static void gst_vc1_parse_finalize (GObject * object);

static gboolean gst_vc1_parse_start (GstBaseParse * parse);
static gboolean gst_vc1_parse_stop (GstBaseParse * parse);
static GstFlowReturn gst_vc1_parse_handle_frame (GstBaseParse * parse,
    GstBaseParseFrame * frame, gint * skipsize);
static GstFlowReturn gst_vc1_parse_pre_push_frame (GstBaseParse * parse,
    GstBaseParseFrame * frame);
static gboolean gst_vc1_parse_set_caps (GstBaseParse * parse, GstCaps * caps);
static GstCaps *gst_vc1_parse_get_sink_caps (GstBaseParse * parse,
    GstCaps * filter);
static GstFlowReturn gst_vc1_parse_detect (GstBaseParse * parse,
    GstBuffer * buffer);

static void gst_vc1_parse_reset (GstVC1Parse * vc1parse);
static gboolean gst_vc1_parse_handle_seq_layer (GstVC1Parse * vc1parse,
    GstBuffer * buf, guint offset, guint size);
static gboolean gst_vc1_parse_handle_seq_hdr (GstVC1Parse * vc1parse,
    GstBuffer * buf, guint offset, guint size);
static gboolean gst_vc1_parse_handle_entrypoint (GstVC1Parse * vc1parse,
    GstBuffer * buf, guint offset, guint size);
static void gst_vc1_parse_update_stream_format_properties (GstVC1Parse *
    vc1parse);

static void
gst_vc1_parse_class_init (GstVC1ParseClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (vc1_parse_debug, "vc1parse", 0, "vc1 parser");

  gobject_class->finalize = gst_vc1_parse_finalize;

  gst_element_class_add_static_pad_template (element_class, &srctemplate);
  gst_element_class_add_static_pad_template (element_class, &sinktemplate);

  gst_element_class_set_static_metadata (element_class, "VC1 parser",
      "Codec/Parser/Converter/Video",
      "Parses VC1 streams",
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  parse_class->start = GST_DEBUG_FUNCPTR (gst_vc1_parse_start);
  parse_class->stop = GST_DEBUG_FUNCPTR (gst_vc1_parse_stop);
  parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_vc1_parse_handle_frame);
  parse_class->pre_push_frame =
      GST_DEBUG_FUNCPTR (gst_vc1_parse_pre_push_frame);
  parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_vc1_parse_set_caps);
  parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_vc1_parse_get_sink_caps);
  parse_class->detect = GST_DEBUG_FUNCPTR (gst_vc1_parse_detect);
}

static void
gst_vc1_parse_init (GstVC1Parse * vc1parse)
{
  /* Default values for stream-format=raw, i.e.
   * raw VC1 frames with startcodes */
  gst_base_parse_set_syncable (GST_BASE_PARSE (vc1parse), TRUE);
  gst_base_parse_set_has_timing_info (GST_BASE_PARSE (vc1parse), FALSE);

  gst_vc1_parse_reset (vc1parse);
  GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (vc1parse));
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (vc1parse));
}

static void
gst_vc1_parse_finalize (GObject * object)
{
  /*GstVC1Parse *vc1parse = GST_VC1_PARSE (object); */

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

static void
gst_vc1_parse_reset (GstVC1Parse * vc1parse)
{
  vc1parse->profile = -1;
  vc1parse->level = -1;
  vc1parse->format = 0;
  vc1parse->width = 0;
  vc1parse->height = 0;
  vc1parse->fps_n = vc1parse->fps_d = 0;
  vc1parse->frame_duration = GST_CLOCK_TIME_NONE;
  vc1parse->fps_from_caps = FALSE;
  vc1parse->par_n = vc1parse->par_d = 0;
  vc1parse->par_from_caps = FALSE;

  vc1parse->renegotiate = TRUE;
  vc1parse->update_caps = TRUE;
  vc1parse->sent_codec_tag = FALSE;

  vc1parse->input_header_format = VC1_HEADER_FORMAT_NONE;
  vc1parse->input_stream_format = VC1_STREAM_FORMAT_BDU;
  vc1parse->output_header_format = VC1_HEADER_FORMAT_NONE;
  vc1parse->output_stream_format = VC1_STREAM_FORMAT_BDU;
  gst_buffer_replace (&vc1parse->seq_layer_buffer, NULL);
  gst_buffer_replace (&vc1parse->seq_hdr_buffer, NULL);
  gst_buffer_replace (&vc1parse->entrypoint_buffer, NULL);

  vc1parse->seq_layer_sent = FALSE;
  vc1parse->frame_layer_first_frame_sent = FALSE;
}

static gboolean
gst_vc1_parse_start (GstBaseParse * parse)
{
  GstVC1Parse *vc1parse = GST_VC1_PARSE (parse);

  GST_DEBUG_OBJECT (parse, "start");
  gst_vc1_parse_reset (vc1parse);

  vc1parse->detecting_stream_format = TRUE;

  return TRUE;
}

static gboolean
gst_vc1_parse_stop (GstBaseParse * parse)
{
  GstVC1Parse *vc1parse = GST_VC1_PARSE (parse);

  GST_DEBUG_OBJECT (parse, "stop");
  gst_vc1_parse_reset (vc1parse);

  return TRUE;
}

static gboolean
gst_vc1_parse_is_format_allowed (GstVC1Parse * vc1parse)
{
  if (vc1parse->profile == GST_VC1_PROFILE_ADVANCED &&
      vc1parse->output_stream_format ==
      VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME) {
    GST_ERROR_OBJECT (vc1parse,
        "sequence-layer-raw-frame is not allowed in advanced profile");
    return FALSE;
  } else if (vc1parse->profile == GST_VC1_PROFILE_SIMPLE &&
      (vc1parse->output_stream_format == VC1_STREAM_FORMAT_BDU ||
          vc1parse->output_stream_format == VC1_STREAM_FORMAT_BDU_FRAME ||
          vc1parse->output_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU ||
          vc1parse->output_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME)) {
    GST_ERROR_OBJECT (vc1parse,
        "output stream-format not allowed in simple profile");
    return FALSE;
  }

  GST_DEBUG_OBJECT (vc1parse, "check output header-format");
  switch (vc1parse->output_header_format) {
    case VC1_HEADER_FORMAT_ASF:
    case VC1_HEADER_FORMAT_SEQUENCE_LAYER:
      /* Doesn't make sense to have sequence-layer-* stream-format */
      if (vc1parse->output_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU ||
          vc1parse->output_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME ||
          vc1parse->output_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME ||
          vc1parse->output_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER)
        return FALSE;
      break;
    case VC1_HEADER_FORMAT_NONE:
      /* In simple/main profile, there is no sequence header BDU */
      if (vc1parse->profile != GST_VC1_PROFILE_ADVANCED &&
          (vc1parse->output_stream_format == VC1_STREAM_FORMAT_BDU ||
              vc1parse->output_stream_format == VC1_STREAM_FORMAT_BDU_FRAME ||
              vc1parse->output_stream_format == VC1_STREAM_FORMAT_FRAME_LAYER))
        return FALSE;

      /* ASF stream-format doesn't carry sequence header */
      if (vc1parse->output_stream_format == VC1_STREAM_FORMAT_ASF)
        return FALSE;
      break;
    default:
      g_assert_not_reached ();
      break;
  }

  if (vc1parse->output_stream_format == vc1parse->input_stream_format)
    return TRUE;

  GST_DEBUG_OBJECT (vc1parse, "check stream-format conversion");
  switch (vc1parse->output_stream_format) {
    case VC1_STREAM_FORMAT_BDU:
      if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU_FRAME ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER ||
          vc1parse->input_stream_format == VC1_STREAM_FORMAT_FRAME_LAYER)
        goto conversion_not_supported;
      break;

    case VC1_STREAM_FORMAT_BDU_FRAME:
      if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER ||
          vc1parse->input_stream_format == VC1_STREAM_FORMAT_ASF ||
          vc1parse->input_stream_format == VC1_STREAM_FORMAT_FRAME_LAYER)
        goto conversion_not_supported;

      if (vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME)
        return FALSE;
      break;

    case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU:
      if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU_FRAME ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER ||
          vc1parse->input_stream_format == VC1_STREAM_FORMAT_FRAME_LAYER)
        goto conversion_not_supported;
      break;

    case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME:
      if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER ||
          vc1parse->input_stream_format == VC1_STREAM_FORMAT_ASF ||
          vc1parse->input_stream_format == VC1_STREAM_FORMAT_FRAME_LAYER)
        goto conversion_not_supported;

      if (vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME)
        return FALSE;
      break;

    case VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME:
      if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU ||
          vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU_FRAME ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME ||
          vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER ||
          vc1parse->input_stream_format == VC1_STREAM_FORMAT_FRAME_LAYER)
        goto conversion_not_supported;
      break;

    case VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER:
      if (vc1parse->input_stream_format != VC1_STREAM_FORMAT_FRAME_LAYER &&
          vc1parse->input_stream_format != VC1_STREAM_FORMAT_ASF)
        goto conversion_not_supported;
      break;

    case VC1_STREAM_FORMAT_ASF:
      goto conversion_not_supported;
      break;

    case VC1_STREAM_FORMAT_FRAME_LAYER:
      if (vc1parse->input_stream_format !=
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER &&
          vc1parse->input_stream_format != VC1_STREAM_FORMAT_ASF)
        goto conversion_not_supported;
      break;

    default:
      g_assert_not_reached ();
      break;
  }

  return TRUE;

conversion_not_supported:
  GST_ERROR_OBJECT (vc1parse, "stream conversion not implemented yet");
  return FALSE;
}

static gboolean
gst_vc1_parse_renegotiate (GstVC1Parse * vc1parse)
{
  GstCaps *in_caps;
  GstCaps *allowed_caps;
  GstCaps *tmp;

  /* Negotiate with downstream here */
  GST_DEBUG_OBJECT (vc1parse, "Renegotiating");

  gst_pad_check_reconfigure (GST_BASE_PARSE_SRC_PAD (vc1parse));

  allowed_caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (vc1parse));
  if (allowed_caps && !gst_caps_is_empty (allowed_caps)
      && !gst_caps_is_any (allowed_caps)) {
    GstStructure *s;
    const gchar *stream_format, *header_format;

    GST_DEBUG_OBJECT (vc1parse, "Downstream allowed caps: %" GST_PTR_FORMAT,
        allowed_caps);

    /* Downstream element can have differents caps according to wmv format
     * so intersect to select the good caps */
    in_caps = gst_caps_new_simple ("video/x-wmv",
        "format", G_TYPE_STRING, parse_format_to_string (vc1parse->format),
        NULL);

    tmp = gst_caps_intersect_full (allowed_caps, in_caps,
        GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (in_caps);

    if (gst_caps_is_empty (tmp)) {
      GST_ERROR_OBJECT (vc1parse, "Empty caps, downstream doesn't support %s",
          parse_format_to_string (vc1parse->format));
      gst_caps_unref (tmp);
      gst_pad_mark_reconfigure (GST_BASE_PARSE_SRC_PAD (vc1parse));
      return FALSE;
    }

    tmp = gst_caps_make_writable (tmp);
    s = gst_caps_get_structure (tmp, 0);

    /* If already fixed this does nothing */
    gst_structure_fixate_field_string (s, "header-format", "asf");
    header_format = gst_structure_get_string (s, "header-format");
    if (!header_format) {
      vc1parse->output_header_format = vc1parse->input_header_format;
      header_format = header_format_to_string (vc1parse->output_header_format);
      gst_structure_set (s, "header-format", G_TYPE_STRING, header_format,
          NULL);
    } else {
      vc1parse->output_header_format =
          header_format_from_string (header_format);
    }

    /* If already fixed this does nothing */
    gst_structure_fixate_field_string (s, "stream-format", "asf");
    stream_format = gst_structure_get_string (s, "stream-format");
    if (!stream_format) {
      vc1parse->output_stream_format = vc1parse->input_stream_format;
      stream_format = stream_format_to_string (vc1parse->output_stream_format);
      gst_structure_set (s, "stream-format", G_TYPE_STRING, stream_format,
          NULL);
    } else {
      vc1parse->output_stream_format =
          stream_format_from_string (stream_format);
    }
    gst_caps_unref (tmp);
  } else if (gst_caps_is_empty (allowed_caps)) {
    GST_ERROR_OBJECT (vc1parse, "Empty caps");
    gst_caps_unref (allowed_caps);
    gst_pad_mark_reconfigure (GST_BASE_PARSE_SRC_PAD (vc1parse));
    return FALSE;
  } else {
    GST_DEBUG_OBJECT (vc1parse, "Using input header/stream format");
    vc1parse->output_header_format = vc1parse->input_header_format;
    vc1parse->output_stream_format = vc1parse->input_stream_format;
  }

  if (allowed_caps)
    gst_caps_unref (allowed_caps);

  if (!gst_vc1_parse_is_format_allowed (vc1parse)) {
    gst_pad_mark_reconfigure (GST_BASE_PARSE_SRC_PAD (vc1parse));
    return FALSE;
  }

  vc1parse->renegotiate = FALSE;
  vc1parse->update_caps = TRUE;

  GST_INFO_OBJECT (vc1parse, "input %s/%s, negotiated %s/%s with downstream",
      header_format_to_string (vc1parse->input_header_format),
      stream_format_to_string (vc1parse->input_stream_format),
      header_format_to_string (vc1parse->output_header_format),
      stream_format_to_string (vc1parse->output_stream_format));

  return TRUE;
}

static void
remove_fields (GstCaps * caps)
{
  guint i, n;

  n = gst_caps_get_size (caps);
  for (i = 0; i < n; i++) {
    GstStructure *s = gst_caps_get_structure (caps, i);

    gst_structure_remove_field (s, "stream-format");
    gst_structure_remove_field (s, "header-format");
  }
}

static GstCaps *
gst_vc1_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
{
  GstCaps *peercaps;
  GstCaps *templ;
  GstCaps *ret;

  templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
  if (filter) {
    GstCaps *fcopy = gst_caps_copy (filter);
    /* Remove the fields we convert */
    remove_fields (fcopy);
    peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
    gst_caps_unref (fcopy);
  } else
    peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);

  if (peercaps) {
    /* Remove the stream-format and header-format fields
     * and add the generic ones again by intersecting
     * with our template */
    peercaps = gst_caps_make_writable (peercaps);
    remove_fields (peercaps);

    ret = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (peercaps);
    gst_caps_unref (templ);
  } else {
    ret = templ;
  }

  if (filter) {
    GstCaps *tmp =
        gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (ret);
    ret = tmp;
  }

  return ret;
}

static GstFlowReturn
gst_vc1_parse_detect (GstBaseParse * parse, GstBuffer * buffer)
{
  GstVC1Parse *vc1parse = GST_VC1_PARSE (parse);
  GstMapInfo minfo;
  guint8 *data;
  gint size;

  if (!vc1parse->detecting_stream_format)
    return GST_FLOW_OK;

  if (!gst_buffer_map (buffer, &minfo, GST_MAP_READ))
    return GST_FLOW_ERROR;

  data = minfo.data;
  size = minfo.size;

#if 0
  /* FIXME: disable BDU check for now as BDU parsing needs more work.
   */
  while (size >= 4) {
    guint32 startcode = GST_READ_UINT32_BE (data);

    if ((startcode & 0xffffff00) == 0x00000100) {
      GST_DEBUG_OBJECT (vc1parse, "Found BDU startcode");
      vc1parse->input_stream_format = VC1_STREAM_FORMAT_BDU_FRAME;
      goto detected;
    }

    data += 4;
    size -= 4;
  }
#endif

  while (size >= 40) {
    if (data[3] == 0xc5 && GST_READ_UINT32_LE (data + 4) == 0x00000004 &&
        GST_READ_UINT32_LE (data + 20) == 0x0000000c) {
      guint32 startcode;

      GST_DEBUG_OBJECT (vc1parse, "Found sequence layer");
      startcode = GST_READ_UINT32_BE (data + 36);
      if ((startcode & 0xffffff00) == 0x00000100) {
        GST_DEBUG_OBJECT (vc1parse, "Found BDU startcode after sequence layer");
        vc1parse->input_stream_format =
            VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME;
        goto detected;
      } else {
        GST_DEBUG_OBJECT (vc1parse,
            "Assuming sequence-layer-frame-layer stream format");
        vc1parse->input_stream_format =
            VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER;
        goto detected;
      }
    }
    data += 4;
    size -= 4;
  }

  if (gst_buffer_get_size (buffer) <= 128) {
    GST_DEBUG_OBJECT (vc1parse, "Requesting more data");
    gst_buffer_unmap (buffer, &minfo);
    return GST_FLOW_NOT_NEGOTIATED;
  }

  if (GST_BASE_PARSE_DRAINING (vc1parse)) {
    GST_ERROR_OBJECT (vc1parse, "Failed to detect or assume a stream format "
        "and draining now");
    gst_buffer_unmap (buffer, &minfo);
    return GST_FLOW_ERROR;
  }

  /* Otherwise we try some heuristics */
  if (vc1parse->input_header_format == VC1_HEADER_FORMAT_ASF) {
    GST_DEBUG_OBJECT (vc1parse, "Assuming ASF stream format");
    vc1parse->input_stream_format = VC1_STREAM_FORMAT_ASF;
    goto detected;
  } else if (vc1parse->input_header_format == VC1_HEADER_FORMAT_SEQUENCE_LAYER) {
    GST_DEBUG_OBJECT (vc1parse, "Assuming frame-layer stream format");
    vc1parse->input_stream_format = VC1_STREAM_FORMAT_FRAME_LAYER;
    goto detected;
  } else {
    GST_ERROR_OBJECT (vc1parse, "Can't detect or assume a stream format");
    gst_buffer_unmap (buffer, &minfo);
    return GST_FLOW_ERROR;
  }

  g_assert_not_reached ();
  return GST_FLOW_ERROR;

detected:

  gst_buffer_unmap (buffer, &minfo);
  vc1parse->detecting_stream_format = FALSE;
  gst_vc1_parse_update_stream_format_properties (vc1parse);
  return GST_FLOW_OK;
}

static int
gst_vc1_parse_get_max_framerate (GstVC1Parse * vc1parse)
{
  /* http://wiki.multimedia.cx/index.php?title=VC-1#Setup_Data_.2F_Sequence_Layer */
  switch (vc1parse->profile) {
    case GST_VC1_PROFILE_SIMPLE:
      switch (vc1parse->level) {
        case GST_VC1_LEVEL_LOW:
          return 15;
        case GST_VC1_LEVEL_MEDIUM:
          return 30;
        default:
          g_assert_not_reached ();
          return 0;
      }
      break;
    case GST_VC1_PROFILE_MAIN:
      switch (vc1parse->level) {
        case GST_VC1_LEVEL_LOW:
          return 24;
        case GST_VC1_LEVEL_MEDIUM:
          return 30;
        case GST_VC1_LEVEL_HIGH:
          return 30;
        default:
          g_assert_not_reached ();
          return 0;
      }
      break;
    case GST_VC1_PROFILE_ADVANCED:
      switch (vc1parse->level) {
        case GST_VC1_LEVEL_L0:
          return 30;
        case GST_VC1_LEVEL_L1:
          return 30;
        case GST_VC1_LEVEL_L2:
          return 60;
        case GST_VC1_LEVEL_L3:
          return 60;
        case GST_VC1_LEVEL_L4:
          return 60;
        default:
          g_assert_not_reached ();
          return 0;
      }
      break;
    default:
      g_assert_not_reached ();
      return 0;
  }
}

static GstBuffer *
gst_vc1_parse_make_sequence_layer (GstVC1Parse * vc1parse)
{
  GstBuffer *seq_layer_buffer;
  guint8 *data;
  guint32 structC = 0;
  GstMapInfo minfo;

  seq_layer_buffer = gst_buffer_new_and_alloc (36);
  gst_buffer_map (seq_layer_buffer, &minfo, GST_MAP_WRITE);

  data = minfo.data;
  /* According to SMPTE 421M Annex L, the sequence layer shall be
   * represented as a sequence of 32 bit unsigned integers and each
   * integers should be serialized in little-endian byte-order except for
   * STRUCT_C which should be serialized in big-endian byte-order. */

  /* Unknown number of frames and start code */
  data[0] = 0xff;
  data[1] = 0xff;
  data[2] = 0xff;
  data[3] = 0xc5;

  /* 0x00000004 */
  GST_WRITE_UINT32_LE (data + 4, 4);

  /* structC */
  structC |= (vc1parse->profile << 30);
  if (vc1parse->profile != GST_VC1_PROFILE_ADVANCED) {
    /* Build simple/main structC from sequence header */
    structC |= (vc1parse->seq_hdr.struct_c.wmvp << 28);
    structC |= (vc1parse->seq_hdr.struct_c.frmrtq_postproc << 25);
    structC |= (vc1parse->seq_hdr.struct_c.bitrtq_postproc << 20);
    structC |= (vc1parse->seq_hdr.struct_c.loop_filter << 19);
    /* Reserved3 shall be set to zero */
    structC |= (vc1parse->seq_hdr.struct_c.multires << 17);
    /* Reserved4 shall be set to one */
    structC |= (1 << 16);
    structC |= (vc1parse->seq_hdr.struct_c.fastuvmc << 15);
    structC |= (vc1parse->seq_hdr.struct_c.extended_mv << 14);
    structC |= (vc1parse->seq_hdr.struct_c.dquant << 12);
    structC |= (vc1parse->seq_hdr.struct_c.vstransform << 11);
    /* Reserved5 shall be set to zero */
    structC |= (vc1parse->seq_hdr.struct_c.overlap << 9);
    structC |= (vc1parse->seq_hdr.struct_c.syncmarker << 8);
    structC |= (vc1parse->seq_hdr.struct_c.rangered << 7);
    structC |= (vc1parse->seq_hdr.struct_c.maxbframes << 4);
    structC |= (vc1parse->seq_hdr.struct_c.quantizer << 2);
    structC |= (vc1parse->seq_hdr.struct_c.finterpflag << 1);
    /* Reserved6 shall be set to one */
    structC |= 1;
  }
  GST_WRITE_UINT32_BE (data + 8, structC);

  /* structA */
  if (vc1parse->profile != GST_VC1_PROFILE_ADVANCED) {
    GST_WRITE_UINT32_LE (data + 12, vc1parse->height);
    GST_WRITE_UINT32_LE (data + 16, vc1parse->width);
  } else {
    GST_WRITE_UINT32_LE (data + 12, 0);
    GST_WRITE_UINT32_LE (data + 16, 0);
  }

  /* 0x0000000c */
  GST_WRITE_UINT32_LE (data + 20, 0x0000000c);

  /* structB */
  /* Unknown HRD_BUFFER */
  GST_WRITE_UINT24_LE (data + 24, 0);
  if ((gint) vc1parse->level != -1)
    data[27] = (vc1parse->level << 5);
  else
    data[27] = (0x4 << 5);      /* Use HIGH level */
  /* Unknown HRD_RATE */
  GST_WRITE_UINT32_LE (data + 28, 0);
  /* Framerate */
  if (vc1parse->fps_d == 0) {
    /* If not known, it seems we need to put in the maximum framerate
       possible for the profile/level used (this is for RTP
       (https://tools.ietf.org/html/draft-ietf-avt-rtp-vc1-06#section-6.1),
       so likely elsewhere too */
    GST_WRITE_UINT32_LE (data + 32, gst_vc1_parse_get_max_framerate (vc1parse));
  } else {
    GST_WRITE_UINT32_LE (data + 32,
        ((guint32) (((gdouble) vc1parse->fps_n) /
                ((gdouble) vc1parse->fps_d) + 0.5)));
  }

  gst_buffer_unmap (seq_layer_buffer, &minfo);

  return seq_layer_buffer;
}

static gboolean
gst_vc1_parse_update_caps (GstVC1Parse * vc1parse)
{
  GstCaps *caps;
  GstVC1Profile profile = -1;
  const gchar *stream_format, *header_format;

  if (gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (vc1parse))
      && !vc1parse->update_caps)
    return TRUE;

  caps = gst_caps_new_simple ("video/x-wmv", "wmvversion", G_TYPE_INT, 3, NULL);

  header_format = header_format_to_string (vc1parse->output_header_format);
  stream_format = stream_format_to_string (vc1parse->output_stream_format);
  gst_caps_set_simple (caps, "header-format", G_TYPE_STRING, header_format,
      "stream-format", G_TYPE_STRING, stream_format, NULL);

  /* Must have this here from somewhere */
  g_assert (vc1parse->width != 0 && vc1parse->height != 0);
  gst_caps_set_simple (caps, "width", G_TYPE_INT, vc1parse->width, "height",
      G_TYPE_INT, vc1parse->height, NULL);
  if (vc1parse->fps_d != 0) {
    gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, vc1parse->fps_n,
        vc1parse->fps_d, NULL);

    vc1parse->frame_duration = gst_util_uint64_scale (GST_SECOND,
        vc1parse->fps_d, vc1parse->fps_n);
  }

  if (vc1parse->par_n != 0 && vc1parse->par_d != 0)
    gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
        vc1parse->par_n, vc1parse->par_d, NULL);

  if (vc1parse->seq_hdr_buffer)
    profile = vc1parse->seq_hdr.profile;
  else if (vc1parse->seq_layer_buffer)
    profile = vc1parse->seq_layer.struct_c.profile;
  else
    g_assert_not_reached ();

  if (profile == GST_VC1_PROFILE_ADVANCED) {
    const gchar *level = NULL;
    /* Caller must make sure this is valid here */
    g_assert (vc1parse->seq_hdr_buffer);
    switch ((GstVC1Level) vc1parse->seq_hdr.advanced.level) {
      case GST_VC1_LEVEL_L0:
        level = "0";
        break;
      case GST_VC1_LEVEL_L1:
        level = "1";
        break;
      case GST_VC1_LEVEL_L2:
        level = "2";
        break;
      case GST_VC1_LEVEL_L3:
        level = "3";
        break;
      case GST_VC1_LEVEL_L4:
        level = "4";
        break;
      default:
        g_assert_not_reached ();
        break;
    }

    gst_caps_set_simple (caps, "format", G_TYPE_STRING, "WVC1",
        "profile", G_TYPE_STRING, "advanced",
        "level", G_TYPE_STRING, level, NULL);
  } else if (profile == GST_VC1_PROFILE_SIMPLE
      || profile == GST_VC1_PROFILE_MAIN) {
    const gchar *profile_str;

    if (profile == GST_VC1_PROFILE_SIMPLE)
      profile_str = "simple";
    else
      profile_str = "main";

    gst_caps_set_simple (caps, "format", G_TYPE_STRING, "WMV3",
        "profile", G_TYPE_STRING, profile_str, NULL);

    if (vc1parse->seq_layer_buffer) {
      const gchar *level = NULL;
      switch (vc1parse->seq_layer.struct_b.level) {
        case GST_VC1_LEVEL_LOW:
          level = "low";
          break;
        case GST_VC1_LEVEL_MEDIUM:
          level = "medium";
          break;
        case GST_VC1_LEVEL_HIGH:
          level = "high";
          break;
        default:
          g_assert_not_reached ();
          break;
      }

      gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
    }
  } else {
    g_assert_not_reached ();
  }

  switch (vc1parse->output_header_format) {
    case VC1_HEADER_FORMAT_ASF:
      if (vc1parse->profile != GST_VC1_PROFILE_ADVANCED) {
        GstBuffer *codec_data;

        if (vc1parse->seq_hdr_buffer) {
          codec_data =
              gst_buffer_copy_region (vc1parse->seq_hdr_buffer,
              GST_BUFFER_COPY_ALL, 0, 4);
        } else {
          GstMapInfo minfo;
          guint32 seq_hdr = 0;

          /* Build simple/main sequence header from sequence layer */
          seq_hdr |= (vc1parse->profile << 30);
          seq_hdr |= (vc1parse->seq_layer.struct_c.wmvp << 28);
          seq_hdr |= (vc1parse->seq_layer.struct_c.frmrtq_postproc << 25);
          seq_hdr |= (vc1parse->seq_layer.struct_c.bitrtq_postproc << 20);
          seq_hdr |= (vc1parse->seq_layer.struct_c.loop_filter << 19);
          /* Reserved3 shall be set to zero */
          seq_hdr |= (vc1parse->seq_layer.struct_c.multires << 17);
          /* Reserved4 shall be set to one */
          seq_hdr |= (1 << 16);
          seq_hdr |= (vc1parse->seq_layer.struct_c.fastuvmc << 15);
          seq_hdr |= (vc1parse->seq_layer.struct_c.extended_mv << 14);
          seq_hdr |= (vc1parse->seq_layer.struct_c.dquant << 12);
          seq_hdr |= (vc1parse->seq_layer.struct_c.vstransform << 11);
          /* Reserved5 shall be set to zero */
          seq_hdr |= (vc1parse->seq_layer.struct_c.overlap << 9);
          seq_hdr |= (vc1parse->seq_layer.struct_c.syncmarker << 8);
          seq_hdr |= (vc1parse->seq_layer.struct_c.rangered << 7);
          seq_hdr |= (vc1parse->seq_layer.struct_c.maxbframes << 4);
          seq_hdr |= (vc1parse->seq_layer.struct_c.quantizer << 2);
          seq_hdr |= (vc1parse->seq_layer.struct_c.finterpflag << 1);
          /* Reserved6 shall be set to one */
          seq_hdr |= 1;
          codec_data = gst_buffer_new_and_alloc (4);

          gst_buffer_map (codec_data, &minfo, GST_MAP_WRITE);
          GST_WRITE_UINT32_BE (minfo.data, seq_hdr);
          gst_buffer_unmap (codec_data, &minfo);
        }

        gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data,
            NULL);
        gst_buffer_unref (codec_data);
      } else {
        GstBuffer *codec_data;
        GstMapInfo minfo, sminfo, eminfo;

        /* Should have seqhdr and entrypoint for the advanced profile here */
        g_assert (vc1parse->seq_hdr_buffer && vc1parse->entrypoint_buffer);
        codec_data =
            gst_buffer_new_and_alloc (1 + 4 +
            gst_buffer_get_size (vc1parse->seq_hdr_buffer) + 4 +
            gst_buffer_get_size (vc1parse->entrypoint_buffer));

        gst_buffer_map (codec_data, &minfo, GST_MAP_WRITE);
        gst_buffer_map (vc1parse->seq_hdr_buffer, &sminfo, GST_MAP_READ);
        gst_buffer_map (vc1parse->entrypoint_buffer, &eminfo, GST_MAP_READ);

        if (vc1parse->profile == GST_VC1_PROFILE_SIMPLE)
          GST_WRITE_UINT8 (minfo.data, 0x29);
        else
          GST_WRITE_UINT8 (minfo.data, 0x2b);

        GST_WRITE_UINT32_BE (minfo.data + 1, 0x0000010f);
        memcpy (minfo.data + 1 + 4, sminfo.data, sminfo.size);
        GST_WRITE_UINT32_BE (minfo.data + 1 + 4 +
            gst_buffer_get_size (vc1parse->seq_hdr_buffer), 0x0000010e);
        memcpy (minfo.data + 1 + 4 + sminfo.size + 4, eminfo.data, eminfo.size);
        gst_buffer_unmap (codec_data, &minfo);
        gst_buffer_unmap (vc1parse->seq_hdr_buffer, &sminfo);
        gst_buffer_unmap (vc1parse->entrypoint_buffer, &eminfo);

        gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data,
            NULL);
        gst_buffer_unref (codec_data);
      }
      break;
    case VC1_HEADER_FORMAT_SEQUENCE_LAYER:
      if (vc1parse->seq_layer_buffer) {
        gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER,
            vc1parse->seq_layer_buffer, NULL);
      } else {
        GstBuffer *codec_data;

        codec_data = gst_vc1_parse_make_sequence_layer (vc1parse);

        gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, codec_data,
            NULL);
        gst_buffer_unref (codec_data);
      }
      break;
    case VC1_HEADER_FORMAT_NONE:
    default:
      /* Nothing here */
      break;
  }

  GST_DEBUG_OBJECT (vc1parse, "Setting caps %" GST_PTR_FORMAT, caps);
  gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (vc1parse), caps);
  gst_caps_unref (caps);
  vc1parse->update_caps = FALSE;
  return TRUE;
}

static inline void
calculate_mb_size (GstVC1SeqHdr * seqhdr, guint width, guint height)
{
  seqhdr->mb_width = (width + 15) >> 4;
  seqhdr->mb_height = (height + 15) >> 4;
  seqhdr->mb_stride = seqhdr->mb_width + 1;
}

static gboolean
gst_vc1_parse_handle_bdu (GstVC1Parse * vc1parse, GstVC1StartCode startcode,
    GstBuffer * buffer, guint offset, guint size)
{
  GST_DEBUG_OBJECT (vc1parse, "Handling BDU with startcode 0x%02x", startcode);

  switch (startcode) {
    case GST_VC1_SEQUENCE:{
      GST_DEBUG_OBJECT (vc1parse, "Have new SequenceHeader header");
      if (!gst_vc1_parse_handle_seq_hdr (vc1parse, buffer, offset, size)) {
        GST_ERROR_OBJECT (vc1parse, "Invalid VC1 sequence header");
        return FALSE;
      }
      break;
    }
    case GST_VC1_ENTRYPOINT:
      GST_DEBUG_OBJECT (vc1parse, "Have new EntryPoint header");
      if (!gst_vc1_parse_handle_entrypoint (vc1parse, buffer, offset, size)) {
        GST_ERROR_OBJECT (vc1parse, "Invalid VC1 entrypoint");
        return FALSE;
      }
      break;
    case GST_VC1_FRAME:
      /* TODO: Check if keyframe */
      break;
    default:
      break;
  }

  return TRUE;
}

static gboolean
gst_vc1_parse_handle_bdus (GstVC1Parse * vc1parse, GstBuffer * buffer,
    guint offset, guint size)
{
  GstVC1BDU bdu;
  GstVC1ParserResult pres;
  guint8 *data;
  GstMapInfo minfo;

  gst_buffer_map (buffer, &minfo, GST_MAP_READ);

  data = minfo.data + offset;

  do {
    memset (&bdu, 0, sizeof (bdu));
    pres = gst_vc1_identify_next_bdu (data, size, &bdu);
    if (pres == GST_VC1_PARSER_OK || pres == GST_VC1_PARSER_NO_BDU_END) {
      if (pres == GST_VC1_PARSER_NO_BDU_END) {
        pres = GST_VC1_PARSER_OK;
        bdu.size = size - bdu.offset;
      }

      data += bdu.offset;
      size -= bdu.offset;

      if (!gst_vc1_parse_handle_bdu (vc1parse, bdu.type, buffer,
              data - minfo.data, bdu.size)) {
        gst_buffer_unmap (buffer, &minfo);
        return FALSE;
      }

      data += bdu.size;
      size -= bdu.size;
    }
  } while (pres == GST_VC1_PARSER_OK && size > 0);

  gst_buffer_unmap (buffer, &minfo);

  if (pres != GST_VC1_PARSER_OK) {
    GST_DEBUG_OBJECT (vc1parse, "Failed to parse BDUs");
    return FALSE;
  }
  return TRUE;
}

static GstFlowReturn
gst_vc1_parse_handle_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
    gint * skipsize)
{
  GstVC1Parse *vc1parse = GST_VC1_PARSE (parse);
  GstBuffer *buffer = frame->buffer;
  guint8 *data;
  gsize size;
  gsize framesize = -1;
  GstFlowReturn ret = GST_FLOW_OK;
  GstMapInfo minfo;

  memset (&minfo, 0, sizeof (minfo));

  *skipsize = 0;

  if (vc1parse->renegotiate
      || gst_pad_check_reconfigure (GST_BASE_PARSE_SRC_PAD (parse))) {
    if (!gst_vc1_parse_renegotiate (vc1parse)) {
      GST_ERROR_OBJECT (vc1parse, "Failed to negotiate with downstream");
      gst_pad_mark_reconfigure (GST_BASE_PARSE_SRC_PAD (parse));
      if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse)))
        ret = GST_FLOW_FLUSHING;
      else
        ret = GST_FLOW_NOT_NEGOTIATED;
      goto done;
    }
  }

  if (!gst_buffer_map (buffer, &minfo, GST_MAP_READ)) {
    GST_ERROR_OBJECT (vc1parse, "Failed to map buffer");
    ret = GST_FLOW_ERROR;
    goto done;
  }

  data = minfo.data;
  size = minfo.size;

  /* First check if we have a valid, complete frame here */
  if (!vc1parse->seq_layer_buffer
      && (vc1parse->input_stream_format == VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU
          || vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME
          || vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME
          || vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER)) {
    if (data[3] == 0xc5 && GST_READ_UINT32_LE (data + 4) == 0x00000004
        && GST_READ_UINT32_LE (data + 20) == 0x0000000c) {
      framesize = 36;
    } else {
      *skipsize = 1;
    }
  } else if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU ||
      vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU_FRAME ||
      (vc1parse->seq_layer_buffer
          && (vc1parse->input_stream_format ==
              VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU
              || vc1parse->input_stream_format ==
              VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME))) {
    GstVC1ParserResult pres;
    GstVC1BDU bdu;

    g_assert (size >= 4);
    memset (&bdu, 0, sizeof (bdu));
    GST_DEBUG_OBJECT (vc1parse,
        "Handling buffer of size %" G_GSIZE_FORMAT " at offset %"
        G_GUINT64_FORMAT, size, GST_BUFFER_OFFSET (buffer));
    /* XXX: when a buffer contains multiple BDUs, does the first one start with
     * a startcode?
     */
    pres = gst_vc1_identify_next_bdu (data, size, &bdu);
    switch (pres) {
      case GST_VC1_PARSER_OK:
        GST_DEBUG_OBJECT (vc1parse, "Have complete BDU");
        if (bdu.sc_offset > 4) {
          *skipsize = bdu.sc_offset;
        } else {
          framesize = bdu.offset + bdu.size;
        }
        break;
      case GST_VC1_PARSER_BROKEN_DATA:
        GST_ERROR_OBJECT (vc1parse, "Broken data");
        *skipsize = 1;
        break;
      case GST_VC1_PARSER_NO_BDU:
        GST_DEBUG_OBJECT (vc1parse, "Found no BDU startcode");
        *skipsize = size - 3;
        break;
      case GST_VC1_PARSER_NO_BDU_END:
        GST_DEBUG_OBJECT (vc1parse, "Found no BDU end");
        if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (vc1parse))) {
          GST_DEBUG_OBJECT (vc1parse, "Draining - assuming complete frame");
          framesize = size;
        } else {
          /* Need more data */
          *skipsize = 0;
        }
        break;
      case GST_VC1_PARSER_ERROR:
        GST_ERROR_OBJECT (vc1parse, "Parsing error");
        break;
      default:
        g_assert_not_reached ();
        break;
    }
  } else if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_ASF ||
      (vc1parse->seq_layer_buffer
          && vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME)) {
    /* Must be packetized already */
    framesize = size;
  } else {
    /* frame-layer or sequence-layer-frame-layer */
    g_assert (size >= 8);
    /* Parse frame layer size */
    framesize = GST_READ_UINT24_LE (data) + 8;
  }


  if (framesize == -1) {
    GST_DEBUG_OBJECT (vc1parse, "Not a complete frame, skipping %d", *skipsize);
    ret = GST_FLOW_OK;
    goto done;
  }
  g_assert (*skipsize == 0);

  /* We have a complete frame at this point */

  if (!vc1parse->seq_layer_buffer
      && (vc1parse->input_stream_format == VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU
          || vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME
          || vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME
          || vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER)) {
    g_assert (size >= 36);
    if (!gst_vc1_parse_handle_seq_layer (vc1parse, buffer, 0, size)) {
      GST_ERROR_OBJECT (vc1parse, "Invalid sequence layer");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    frame->flags |= GST_BASE_PARSE_FRAME_FLAG_NO_FRAME;

    if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU
        || vc1parse->input_stream_format ==
        VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME) {
      gst_base_parse_set_min_frame_size (GST_BASE_PARSE (vc1parse), 4);
    } else if (vc1parse->input_stream_format ==
        VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME) {
      gst_base_parse_set_min_frame_size (GST_BASE_PARSE (vc1parse), 1);
    } else {
      /* frame-layer */
      gst_base_parse_set_min_frame_size (GST_BASE_PARSE (vc1parse), 8);
    }
  } else if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU ||
      vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU_FRAME ||
      (vc1parse->seq_layer_buffer
          && (vc1parse->input_stream_format ==
              VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU
              || vc1parse->input_stream_format ==
              VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME))) {
    GstVC1StartCode startcode;

    /* Is already a complete BDU, should have at least the startcode */
    g_assert (size >= 4);
    startcode = data[3];

    if (startcode != GST_VC1_SEQUENCE) {
      if (!vc1parse->seq_hdr_buffer && !vc1parse->seq_layer_buffer) {
        GST_ERROR_OBJECT (vc1parse,
            "Need sequence header/layer before anything else");
        ret = GST_FLOW_ERROR;
        goto done;
      }
    } else if (startcode != GST_VC1_ENTRYPOINT
        && vc1parse->profile == GST_VC1_PROFILE_ADVANCED) {
      if (vc1parse->seq_hdr_buffer && !vc1parse->entrypoint_buffer) {
        GST_ERROR_OBJECT (vc1parse,
            "Need entrypoint header after the sequence header for the "
            "advanced profile");
        ret = GST_FLOW_ERROR;
        goto done;
      }
    }

    if (!gst_vc1_parse_handle_bdu (vc1parse, startcode, buffer, 4, size - 4)) {
      ret = GST_FLOW_ERROR;
      goto done;
    }
  } else if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_ASF ||
      (vc1parse->seq_layer_buffer
          && vc1parse->input_stream_format ==
          VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME)) {
    GST_LOG_OBJECT (vc1parse, "Have new ASF or RAW data unit");

    if (!vc1parse->seq_hdr_buffer && !vc1parse->seq_layer_buffer) {
      GST_ERROR_OBJECT (vc1parse, "Need a sequence header or sequence layer");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    if (GST_CLOCK_TIME_IS_VALID (vc1parse->frame_duration))
      GST_BUFFER_DURATION (buffer) = vc1parse->frame_duration;

    /* Might be multiple BDUs here, complex... */
    if (vc1parse->profile == GST_VC1_PROFILE_ADVANCED) {
      gboolean startcodes = FALSE;

      if (size >= 4) {
        guint32 startcode = GST_READ_UINT32_BE (data + 4);

        startcodes = ((startcode & 0xffffff00) == 0x00000100);
      }

      if (startcodes) {
        if (!gst_vc1_parse_handle_bdus (vc1parse, buffer, 0, size)) {
          ret = GST_FLOW_ERROR;
          goto done;
        }

        /* For the advanced profile we need a sequence header here */
        if (!vc1parse->seq_hdr_buffer) {
          GST_ERROR_OBJECT (vc1parse, "Need sequence header");
          ret = GST_FLOW_ERROR;
          goto done;
        }
      } else {
        /* Must be a frame or a frame + field */
        /* TODO: Check if keyframe */
      }
    } else {
      /* In simple/main, we basically have a raw frame, so parse it */
      GstVC1ParserResult pres;
      GstVC1FrameHdr frame_hdr;
      GstVC1SeqHdr seq_hdr;

      if (!vc1parse->seq_hdr_buffer) {
        /* Build seq_hdr from sequence-layer to be able to parse frame */
        seq_hdr.profile = vc1parse->profile;
        seq_hdr.struct_c = vc1parse->seq_layer.struct_c;
        calculate_mb_size (&seq_hdr, vc1parse->seq_layer.struct_a.horiz_size,
            vc1parse->seq_layer.struct_a.vert_size);
      } else {
        seq_hdr = vc1parse->seq_hdr;
      }

      pres = gst_vc1_parse_frame_header (data, size, &frame_hdr,
          &seq_hdr, NULL);
      if (pres != GST_VC1_PARSER_OK) {
        GST_ERROR_OBJECT (vc1parse, "Invalid VC1 frame header");
        ret = GST_FLOW_ERROR;
        goto done;
      }

      if (frame_hdr.ptype == GST_VC1_PICTURE_TYPE_I)
        GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
      else
        GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
    }
  } else {
    GstVC1ParserResult pres;
    GstVC1FrameLayer flayer;
    gboolean startcodes = FALSE;

    /* frame-layer or sequence-layer-frame-layer */

    /* Check if the frame-layer data contains BDUs with startcodes.
     * Startcodes are not allowed in raw WMV9/VC1 streams
     */
    if (size >= 8 + 4) {
      guint32 startcode = GST_READ_UINT32_BE (data + 8);

      startcodes = ((startcode & 0xffffff00) == 0x00000100);
    }

    /* We either need a sequence layer or sequence header here
     * or this has to be an advanced profile stream.
     *
     * For the advanced profile the frame-layer data contains
     * BDUs with startcodes and includes the sequence header
     */
    if (!vc1parse->seq_layer_buffer && !vc1parse->seq_hdr_buffer && !startcodes) {
      GST_ERROR_OBJECT (vc1parse, "Need a sequence header or sequence layer");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    if ((vc1parse->seq_layer_buffer || vc1parse->seq_hdr_buffer)
        && vc1parse->profile == GST_VC1_PROFILE_ADVANCED && !startcodes) {
      GST_ERROR_OBJECT (vc1parse,
          "Advanced profile frame-layer data must start with startcodes");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    memset (&flayer, 0, sizeof (flayer));

    pres = gst_vc1_parse_frame_layer (data, size, &flayer);

    if (pres != GST_VC1_PARSER_OK) {
      GST_ERROR_OBJECT (vc1parse, "Invalid VC1 frame layer");
      ret = GST_FLOW_ERROR;
      goto done;
    }

    GST_BUFFER_TIMESTAMP (buffer) =
        gst_util_uint64_scale (flayer.timestamp, GST_MSECOND, 1);
    if (!flayer.key)
      GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
    else
      GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);

    /* For the simple/main profile this contains a single frame BDU without
     * startcodes and for the advanced profile this contains BDUs with
     * startcodes. In the case of the advanced profile parse them.
     *
     * Also for wrongly muxed simple/main profile streams with startcodes
     * we do the same.
     */
    if (startcodes) {
      /* skip frame layer header */
      if (!gst_vc1_parse_handle_bdus (vc1parse, buffer, 8, size - 8)) {
        ret = GST_FLOW_ERROR;
        goto done;
      }

      /* For the advanced profile we need a sequence header here */
      if (!vc1parse->seq_hdr_buffer) {
        GST_ERROR_OBJECT (vc1parse, "Need sequence header");
        ret = GST_FLOW_ERROR;
        goto done;
      }
    }
  }

  /* Need sequence header or sequence layer here, above code
   * checks this already */
  g_assert (vc1parse->seq_layer_buffer || vc1parse->seq_hdr_buffer);

  /* We need the entrypoint BDU for the advanced profile before we can set
   * the caps. For the ASF header format it will already be in the codec_data,
   * for the frame-layer stream format it will be in the first frame already.
   *
   * The only case where we wait another frame is the raw stream format, where
   * it will be the second BDU
   */
  if (vc1parse->profile == GST_VC1_PROFILE_ADVANCED
      && !vc1parse->entrypoint_buffer) {
    if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU
        || vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU_FRAME
        || vc1parse->input_stream_format == VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU
        || vc1parse->input_stream_format ==
        VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME) {
      frame->flags |= GST_BASE_PARSE_FRAME_FLAG_QUEUE;
    } else {
      GST_ERROR_OBJECT (vc1parse, "Need entrypoint for the advanced profile");
      ret = GST_FLOW_ERROR;
      goto done;
    }
  }

  if (!gst_vc1_parse_update_caps (vc1parse)) {
    ret = GST_FLOW_NOT_NEGOTIATED;
    goto done;
  }

  gst_buffer_unmap (buffer, &minfo);
  memset (&minfo, 0, sizeof (minfo));
  GST_DEBUG_OBJECT (vc1parse, "Finishing frame of size %" G_GSIZE_FORMAT,
      framesize);
  ret = gst_base_parse_finish_frame (parse, frame, framesize);

done:
  if (minfo.data)
    gst_buffer_unmap (buffer, &minfo);

  return ret;
}

static GstFlowReturn
gst_vc1_parse_push_sequence_layer (GstVC1Parse * vc1parse)
{
  GstBuffer *seq_layer;

  if ((seq_layer = vc1parse->seq_layer_buffer))
    gst_buffer_ref (seq_layer);
  else
    seq_layer = gst_vc1_parse_make_sequence_layer (vc1parse);

  return gst_pad_push (GST_BASE_PARSE_SRC_PAD (vc1parse), seq_layer);
}

static GstFlowReturn
gst_vc1_parse_convert_asf_to_bdu (GstVC1Parse * vc1parse,
    GstBaseParseFrame * frame)
{
  GstByteWriter bw;
  GstBuffer *buffer;
  GstBuffer *tmp;
  GstMemory *mem;
  guint8 sc_data[4];
  guint32 startcode;
  gboolean ok;
  GstFlowReturn ret = GST_FLOW_OK;

  buffer = frame->buffer;

  /* Simple profile doesn't have start codes so bdu format is not possible */
  if (vc1parse->profile == GST_VC1_PROFILE_SIMPLE) {
    GST_ERROR_OBJECT (vc1parse, "can't convert to bdu in simple profile");
    ret = GST_FLOW_NOT_NEGOTIATED;
    goto done;
  }

  /* ASF frame could have a start code at the beginning or not. So we first
   * check for a start code if we have at least 4 bytes in the buffer. */
  if (gst_buffer_extract (buffer, 0, sc_data, 4) == 4) {
    startcode = GST_READ_UINT32_BE (sc_data);
    if (((startcode & 0xffffff00) == 0x00000100)) {
      /* Start code found */
      goto done;
    }
  }

  /* Yes, a frame could be smaller than 4 bytes and valid, for instance
   * black video. */

  /* We will prepend 4 bytes to buffer */
  gst_byte_writer_init_with_size (&bw, 4, TRUE);

  /* Set start code and suffixe, we assume raw asf data is a frame */
  ok = gst_byte_writer_put_uint24_be (&bw, 0x000001);
  ok &= gst_byte_writer_put_uint8 (&bw, 0x0D);
  tmp = gst_byte_writer_reset_and_get_buffer (&bw);

  /* Prepend startcode buffer to frame buffer */
  mem = gst_buffer_get_all_memory (tmp);
  gst_buffer_prepend_memory (buffer, mem);
  gst_buffer_unref (tmp);

  if (G_UNLIKELY (!ok)) {
    GST_ERROR_OBJECT (vc1parse, "convert asf to bdu failed");
    ret = GST_FLOW_ERROR;
  }

done:
  return ret;
}

static GstFlowReturn
gst_vc1_parse_convert_to_frame_layer (GstVC1Parse * vc1parse,
    GstBaseParseFrame * frame)
{
  GstByteWriter bw;
  GstBuffer *buffer;
  GstBuffer *frame_layer;
  gsize frame_layer_size;
  GstMemory *mem;
  gboolean ok;
  gboolean keyframe;
  guint8 sc_data[4];
  guint32 startcode;

  buffer = frame->buffer;
  keyframe = !(GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT));

  /* We need 8 bytes for frame-layer header */
  frame_layer_size = 8;
  if (vc1parse->profile == GST_VC1_PROFILE_ADVANCED) {
    if (!vc1parse->frame_layer_first_frame_sent) {
      /* First frame should contain sequence-header, entry-point and frame */
      frame_layer_size += 4 + gst_buffer_get_size (vc1parse->seq_hdr_buffer)
          + 4 + gst_buffer_get_size (vc1parse->entrypoint_buffer) + 4;
    } else if (keyframe) {
      /* Keyframe should contain entry point */
      frame_layer_size += 4 +
          gst_buffer_get_size (vc1parse->entrypoint_buffer) + 4;
    }
  }

  gst_byte_writer_init_with_size (&bw, frame_layer_size, TRUE);

  /* frame-layer header shall be serialized in little-endian byte order */
  ok = gst_byte_writer_put_uint24_le (&bw, gst_buffer_get_size (buffer));

  if (keyframe)
    ok &= gst_byte_writer_put_uint8 (&bw, 0x80);        /* keyframe */
  else
    ok &= gst_byte_writer_put_uint8 (&bw, 0x00);

  ok &= gst_byte_writer_put_uint32_le (&bw, GST_BUFFER_PTS (buffer));

  if (vc1parse->profile != GST_VC1_PROFILE_ADVANCED)
    goto headers_done;

  if (!vc1parse->frame_layer_first_frame_sent) {
    /* Write sequence-header start code, sequence-header entrypoint startcode
     * and entrypoint */
    ok &= gst_byte_writer_put_uint32_be (&bw, 0x0000010f);
    ok &= gst_byte_writer_put_buffer (&bw, vc1parse->seq_hdr_buffer, 0, -1);
    ok &= gst_byte_writer_put_uint32_be (&bw, 0x0000010e);
    ok &= gst_byte_writer_put_buffer (&bw, vc1parse->entrypoint_buffer, 0, -1);
  } else if (keyframe) {
    /* Write entrypoint startcode and entrypoint */
    ok &= gst_byte_writer_put_uint32_be (&bw, 0x0000010e);
    ok &= gst_byte_writer_put_buffer (&bw, vc1parse->entrypoint_buffer, 0, -1);
  }

  /* frame can begin with startcode, in this case, don't prepend it */
  if (gst_buffer_extract (buffer, 0, sc_data, 4) == 4) {
    startcode = GST_READ_UINT32_BE (sc_data);
    if (((startcode & 0xffffff00) == 0x00000100)) {
      /* Start code found */
      goto headers_done;
    }
  }

  ok &= gst_byte_writer_put_uint32_be (&bw, 0x0000010d);

headers_done:
  frame_layer = gst_byte_writer_reset_and_get_buffer (&bw);
  mem = gst_buffer_get_all_memory (frame_layer);
  gst_buffer_prepend_memory (buffer, mem);
  gst_buffer_unref (frame_layer);

  if (G_UNLIKELY (!ok)) {
    GST_ERROR_OBJECT (vc1parse, "failed to convert to frame layer");
    return GST_FLOW_ERROR;
  }

  vc1parse->frame_layer_first_frame_sent = TRUE;
  return GST_FLOW_OK;
}

static GstFlowReturn
gst_vc1_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
{
  GstVC1Parse *vc1parse = GST_VC1_PARSE (parse);
  GstFlowReturn ret = GST_FLOW_OK;

  if (!vc1parse->sent_codec_tag) {
    GstTagList *taglist;
    GstCaps *caps;

    /* codec tag */
    caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
    if (G_UNLIKELY (caps == NULL)) {
      if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (parse))) {
        GST_INFO_OBJECT (parse, "Src pad is flushing");
        return GST_FLOW_FLUSHING;
      } else {
        GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
        return GST_FLOW_NOT_NEGOTIATED;
      }
    }

    taglist = gst_tag_list_new_empty ();
    gst_pb_utils_add_codec_description_to_tag_list (taglist,
        GST_TAG_VIDEO_CODEC, caps);
    gst_caps_unref (caps);

    gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
    gst_tag_list_unref (taglist);

    /* also signals the end of first-frame processing */
    vc1parse->sent_codec_tag = TRUE;
  }

  /* Nothing to do here */
  if (vc1parse->input_stream_format == vc1parse->output_stream_format)
    return GST_FLOW_OK;

  switch (vc1parse->output_stream_format) {
    case VC1_STREAM_FORMAT_BDU:
      switch (vc1parse->input_stream_format) {
        case VC1_STREAM_FORMAT_BDU:
          g_assert_not_reached ();
          break;
        case VC1_STREAM_FORMAT_BDU_FRAME:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU:
          /* We just need to drop sequence-layer buffer */
          if (frame->flags & GST_BASE_PARSE_FRAME_FLAG_NO_FRAME) {
            ret = GST_BASE_PARSE_FLOW_DROPPED;
          }
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_ASF:
          ret = gst_vc1_parse_convert_asf_to_bdu (vc1parse, frame);
          break;
        case VC1_STREAM_FORMAT_FRAME_LAYER:
          goto conversion_not_supported;
          break;
        default:
          g_assert_not_reached ();
          break;
      }
      break;

    case VC1_STREAM_FORMAT_BDU_FRAME:
      switch (vc1parse->input_stream_format) {
        case VC1_STREAM_FORMAT_BDU:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_BDU_FRAME:
          g_assert_not_reached ();
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME:
          /* We just need to drop sequence-layer buffer */
          if (frame->flags & GST_BASE_PARSE_FRAME_FLAG_NO_FRAME) {
            ret = GST_BASE_PARSE_FLOW_DROPPED;
          }
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER:
        case VC1_STREAM_FORMAT_ASF:
        case VC1_STREAM_FORMAT_FRAME_LAYER:
          goto conversion_not_supported;
          break;
        default:
          g_assert_not_reached ();
          break;
      }
      break;

    case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU:
      switch (vc1parse->input_stream_format) {
        case VC1_STREAM_FORMAT_BDU:
          /* We just need to send the sequence-layer first */
          if (!vc1parse->seq_layer_sent) {
            ret = gst_vc1_parse_push_sequence_layer (vc1parse);
            if (ret != GST_FLOW_OK) {
              GST_ERROR_OBJECT (vc1parse, "push sequence layer failed");
              break;
            }
            vc1parse->seq_layer_sent = TRUE;
          }
          break;
        case VC1_STREAM_FORMAT_BDU_FRAME:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU:
          g_assert_not_reached ();
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_ASF:
          /* We just need to send the sequence-layer first */
          if (!vc1parse->seq_layer_sent) {
            ret = gst_vc1_parse_push_sequence_layer (vc1parse);
            if (ret != GST_FLOW_OK) {
              GST_ERROR_OBJECT (vc1parse, "push sequence layer failed");
              break;
            }
            vc1parse->seq_layer_sent = TRUE;
          }
          /* FIXME: We may only authorize this when header-format is set to
           * none and we should add the entrypoint for advanced profile. */
          ret = gst_vc1_parse_convert_asf_to_bdu (vc1parse, frame);
          break;
        case VC1_STREAM_FORMAT_FRAME_LAYER:
          goto conversion_not_supported;
          break;
        default:
          g_assert_not_reached ();
          break;
      }
      break;

    case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME:
      switch (vc1parse->input_stream_format) {
        case VC1_STREAM_FORMAT_BDU:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_BDU_FRAME:
          /* We just need to send the sequence-layer first */
          if (!vc1parse->seq_layer_sent) {
            ret = gst_vc1_parse_push_sequence_layer (vc1parse);
            if (ret != GST_FLOW_OK) {
              GST_ERROR_OBJECT (vc1parse, "push sequence layer failed");
              break;
            }
            vc1parse->seq_layer_sent = TRUE;
          }
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME:
          g_assert_not_reached ();
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER:
        case VC1_STREAM_FORMAT_ASF:
        case VC1_STREAM_FORMAT_FRAME_LAYER:
          goto conversion_not_supported;
          break;
        default:
          g_assert_not_reached ();
          break;
      }
      break;

    case VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME:
      if (vc1parse->profile != GST_VC1_PROFILE_SIMPLE &&
          vc1parse->profile != GST_VC1_PROFILE_MAIN) {
        GST_ERROR_OBJECT (vc1parse,
            "sequence-layer-raw-frame is only for simple/main profile");
        goto conversion_not_supported;
      }
      switch (vc1parse->input_stream_format) {
        case VC1_STREAM_FORMAT_BDU:
        case VC1_STREAM_FORMAT_BDU_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME:
          g_assert_not_reached ();
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER:
          goto conversion_not_supported;
        case VC1_STREAM_FORMAT_ASF:
          /* ASF contains raw frame for simple/main profile, so we just
           * have to send sequence-layer before frames */
          if (!vc1parse->seq_layer_sent) {
            ret = gst_vc1_parse_push_sequence_layer (vc1parse);
            if (ret != GST_FLOW_OK) {
              GST_ERROR_OBJECT (vc1parse, "push sequence layer failed");
              break;
            }
            vc1parse->seq_layer_sent = TRUE;
          }
          break;
        case VC1_STREAM_FORMAT_FRAME_LAYER:
          goto conversion_not_supported;
          break;
        default:
          g_assert_not_reached ();
          break;
      }
      break;

    case VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER:
      switch (vc1parse->input_stream_format) {
        case VC1_STREAM_FORMAT_BDU:
        case VC1_STREAM_FORMAT_BDU_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER:
          g_assert_not_reached ();
          break;
        case VC1_STREAM_FORMAT_ASF:
          /* Make sure we push the sequence layer */
          if (!vc1parse->seq_layer_sent) {
            ret = gst_vc1_parse_push_sequence_layer (vc1parse);
            if (ret != GST_FLOW_OK) {
              GST_ERROR_OBJECT (vc1parse, "push sequence layer failed");
              break;
            }
            vc1parse->seq_layer_sent = TRUE;
          }
          ret = gst_vc1_parse_convert_to_frame_layer (vc1parse, frame);
          break;
        case VC1_STREAM_FORMAT_FRAME_LAYER:
          /* We just need to send the sequence-layer first */
          if (!vc1parse->seq_layer_sent) {
            ret = gst_vc1_parse_push_sequence_layer (vc1parse);
            if (ret != GST_FLOW_OK) {
              GST_ERROR_OBJECT (vc1parse, "push sequence layer failed");
              break;
            }
            vc1parse->seq_layer_sent = TRUE;
          }
          break;
        default:
          g_assert_not_reached ();
          break;
      }
      break;

    case VC1_STREAM_FORMAT_ASF:
      switch (vc1parse->input_stream_format) {
        case VC1_STREAM_FORMAT_BDU:
        case VC1_STREAM_FORMAT_BDU_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_ASF:
          g_assert_not_reached ();
          break;
        case VC1_STREAM_FORMAT_FRAME_LAYER:
          goto conversion_not_supported;
          break;
        default:
          g_assert_not_reached ();
          break;
      }
      break;

    case VC1_STREAM_FORMAT_FRAME_LAYER:
      switch (vc1parse->input_stream_format) {
        case VC1_STREAM_FORMAT_BDU:
        case VC1_STREAM_FORMAT_BDU_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME:
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME:
          goto conversion_not_supported;
          break;
        case VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER:
          /* We just need to drop sequence-layer buffer */
          if (frame->flags & GST_BASE_PARSE_FRAME_FLAG_NO_FRAME) {
            ret = GST_BASE_PARSE_FLOW_DROPPED;
          }
          break;
        case VC1_STREAM_FORMAT_ASF:
          ret = gst_vc1_parse_convert_to_frame_layer (vc1parse, frame);
          break;
        case VC1_STREAM_FORMAT_FRAME_LAYER:
        default:
          g_assert_not_reached ();
          break;
      }
      break;

    default:
      g_assert_not_reached ();
      break;
  }

  return ret;

conversion_not_supported:
  GST_WARNING_OBJECT (vc1parse, "stream conversion not implemented yet");
  return GST_FLOW_NOT_NEGOTIATED;
}

/* SMPTE 421M Table 7 */
static const struct
{
  gint par_n, par_d;
} aspect_ratios[] = {
  {
  0, 0}, {
  1, 1}, {
  12, 11}, {
  10, 11}, {
  16, 11}, {
  40, 33}, {
  24, 11}, {
  20, 11}, {
  32, 11}, {
  80, 33}, {
  18, 11}, {
  15, 11}, {
  64, 33}, {
  160, 99}, {
  0, 0}, {
  0, 0}
};

/* SMPTE 421M Table 8 */
static const guint framerates_n[] = {
  0,
  24 * 1000,
  25 * 1000, 30 * 1000, 50 * 1000, 60 * 1000, 48 * 1000, 72 * 1000
};

/* SMPTE 421M Table 9 */
static const guint framerates_d[] = {
  0,
  1000,
  1001
};

static gboolean
gst_vc1_parse_handle_seq_hdr (GstVC1Parse * vc1parse,
    GstBuffer * buf, guint offset, guint size)
{
  GstVC1ParserResult pres;
  GstVC1Profile profile;
  GstMapInfo minfo;

  g_assert (gst_buffer_get_size (buf) >= offset + size);
  gst_buffer_replace (&vc1parse->seq_hdr_buffer, NULL);
  memset (&vc1parse->seq_hdr, 0, sizeof (vc1parse->seq_hdr));

  gst_buffer_map (buf, &minfo, GST_MAP_READ);
  pres =
      gst_vc1_parse_sequence_header (minfo.data + offset,
      size, &vc1parse->seq_hdr);
  gst_buffer_unmap (buf, &minfo);

  if (pres != GST_VC1_PARSER_OK) {
    GST_ERROR_OBJECT (vc1parse, "Invalid VC1 sequence header");
    return FALSE;
  }
  vc1parse->seq_hdr_buffer =
      gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, offset, size);
  profile = vc1parse->seq_hdr.profile;
  if (vc1parse->profile != profile) {
    vc1parse->update_caps = TRUE;
    vc1parse->profile = vc1parse->seq_hdr.profile;
  }

  /* Only update fps if not from caps */
  if (!vc1parse->fps_from_caps && profile != GST_VC1_PROFILE_ADVANCED) {
    gint fps;
    /* This is only an estimate but better than nothing */
    fps = vc1parse->seq_hdr.struct_c.framerate;
    if (fps != 0 && (vc1parse->fps_d == 0 ||
            gst_util_fraction_compare (fps, 1, vc1parse->fps_n,
                vc1parse->fps_d) != 0)) {
      vc1parse->update_caps = TRUE;
      vc1parse->fps_n = fps;
      vc1parse->fps_d = 1;
    }
  }

  if (profile == GST_VC1_PROFILE_ADVANCED) {
    GstVC1Level level;
    gint width, height;
    level = vc1parse->seq_hdr.advanced.level;
    if (vc1parse->level != level) {
      vc1parse->update_caps = TRUE;
      vc1parse->level = level;
    }

    width = vc1parse->seq_hdr.advanced.max_coded_width;
    height = vc1parse->seq_hdr.advanced.max_coded_height;
    if (vc1parse->width != width || vc1parse->height != height) {
      vc1parse->update_caps = TRUE;
      vc1parse->width = width;
      vc1parse->height = height;
    }

    /* Only update fps if not from caps */
    if (!vc1parse->fps_from_caps) {
      gint fps;
      /* This is only an estimate but better than nothing */
      fps = vc1parse->seq_hdr.advanced.framerate;
      if (fps != 0 && (vc1parse->fps_d == 0 ||
              gst_util_fraction_compare (fps, 1, vc1parse->fps_n,
                  vc1parse->fps_d) != 0)) {
        vc1parse->update_caps = TRUE;
        vc1parse->fps_n = fps;
        vc1parse->fps_d = 1;
      }
    }

    if (vc1parse->seq_hdr.advanced.display_ext) {
      /* Only update PAR if not from input caps */
      if (!vc1parse->par_from_caps
          && vc1parse->seq_hdr.advanced.aspect_ratio_flag) {
        gint par_n, par_d;
        if (vc1parse->seq_hdr.advanced.aspect_ratio == 15) {
          par_n = vc1parse->seq_hdr.advanced.aspect_horiz_size;
          par_d = vc1parse->seq_hdr.advanced.aspect_vert_size;
        } else {
          par_n = aspect_ratios[vc1parse->seq_hdr.advanced.aspect_ratio].par_n;
          par_d = aspect_ratios[vc1parse->seq_hdr.advanced.aspect_ratio].par_d;
        }

        if (par_n != 0 && par_d != 0 &&
            (vc1parse->par_d == 0
                || gst_util_fraction_compare (par_n, par_d,
                    vc1parse->par_n, vc1parse->par_d) != 0)) {
          vc1parse->update_caps = TRUE;
          vc1parse->par_n = par_n;
          vc1parse->par_d = par_d;
        }
      }

      /* Only update fps if not from caps, better value than above */
      if (!vc1parse->fps_from_caps && vc1parse->seq_hdr.advanced.framerate_flag) {
        gint fps_n = 0, fps_d = 0;
        if (!vc1parse->seq_hdr.advanced.framerateind) {
          if (vc1parse->seq_hdr.advanced.frameratenr > 0
              && vc1parse->seq_hdr.advanced.frameratenr < 8
              && vc1parse->seq_hdr.advanced.frameratedr > 0
              && vc1parse->seq_hdr.advanced.frameratedr < 3) {
            fps_n = framerates_n[vc1parse->seq_hdr.advanced.frameratenr];
            fps_d = framerates_d[vc1parse->seq_hdr.advanced.frameratedr];
          }
        } else {
          fps_n = vc1parse->seq_hdr.advanced.framerateexp + 1;
          fps_d = 32;
        }

        if (fps_n != 0 && fps_d != 0 &&
            (vc1parse->fps_d == 0
                || gst_util_fraction_compare (fps_n, fps_d,
                    vc1parse->fps_n, vc1parse->fps_d) != 0)) {
          vc1parse->update_caps = TRUE;
          vc1parse->fps_n = fps_n;
          vc1parse->fps_d = fps_d;
        }
      }
    }
  }

  return TRUE;
}

static gboolean
gst_vc1_parse_handle_seq_layer (GstVC1Parse * vc1parse,
    GstBuffer * buf, guint offset, guint size)
{
  GstVC1ParserResult pres;
  GstVC1Profile profile;
  GstVC1Level level;
  gint width, height;
  GstMapInfo minfo;

  g_assert (gst_buffer_get_size (buf) >= offset + size);

  gst_buffer_replace (&vc1parse->seq_layer_buffer, NULL);
  memset (&vc1parse->seq_layer, 0, sizeof (vc1parse->seq_layer));

  gst_buffer_map (buf, &minfo, GST_MAP_READ);
  pres =
      gst_vc1_parse_sequence_layer (minfo.data + offset,
      size, &vc1parse->seq_layer);
  gst_buffer_unmap (buf, &minfo);

  if (pres != GST_VC1_PARSER_OK) {
    GST_ERROR_OBJECT (vc1parse, "Invalid VC1 sequence layer");
    return FALSE;
  }
  vc1parse->seq_layer_buffer =
      gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, offset, size);
  profile = vc1parse->seq_layer.struct_c.profile;
  if (vc1parse->profile != profile) {
    vc1parse->update_caps = TRUE;
    vc1parse->profile = vc1parse->seq_layer.struct_c.profile;
  }

  width = vc1parse->seq_layer.struct_a.vert_size;
  height = vc1parse->seq_layer.struct_a.horiz_size;
  if (width > 0 && height > 0
      && (vc1parse->width != width || vc1parse->height != height)) {
    vc1parse->update_caps = TRUE;
    vc1parse->width = width;
    vc1parse->height = height;
  }

  level = vc1parse->seq_layer.struct_b.level;
  if (vc1parse->level != level) {
    vc1parse->update_caps = TRUE;
    vc1parse->level = level;
  }

  if (!vc1parse->fps_from_caps && profile != GST_VC1_PROFILE_ADVANCED) {
    gint fps;
    fps = vc1parse->seq_layer.struct_c.framerate;
    if (fps == 0 || fps == -1)
      fps = vc1parse->seq_layer.struct_b.framerate;
    if (fps != 0 && fps != -1 && (vc1parse->fps_d == 0 ||
            gst_util_fraction_compare (fps, 1, vc1parse->fps_n,
                vc1parse->fps_d) != 0)) {
      vc1parse->update_caps = TRUE;
      vc1parse->fps_n = fps;
      vc1parse->fps_d = 1;
    }
  }

  /* And now update the duration */
  if (vc1parse->seq_layer.numframes != 0 && vc1parse->seq_layer.numframes != -1)
    gst_base_parse_set_duration (GST_BASE_PARSE (vc1parse),
        GST_FORMAT_DEFAULT, vc1parse->seq_layer.numframes, 50);
  return TRUE;
}

static gboolean
gst_vc1_parse_handle_entrypoint (GstVC1Parse * vc1parse,
    GstBuffer * buf, guint offset, guint size)
{
  g_assert (gst_buffer_get_size (buf) >= offset + size);

  gst_buffer_replace (&vc1parse->entrypoint_buffer, NULL);
  vc1parse->entrypoint_buffer =
      gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, offset, size);

  return TRUE;
}

static void
gst_vc1_parse_update_stream_format_properties (GstVC1Parse * vc1parse)
{
  if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU
      || vc1parse->input_stream_format == VC1_STREAM_FORMAT_BDU_FRAME) {
    /* Need at least the 4 bytes start code */
    gst_base_parse_set_min_frame_size (GST_BASE_PARSE (vc1parse), 4);
    gst_base_parse_set_syncable (GST_BASE_PARSE (vc1parse), TRUE);
  } else
      if (vc1parse->input_stream_format ==
      VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU
      || vc1parse->input_stream_format ==
      VC1_STREAM_FORMAT_SEQUENCE_LAYER_BDU_FRAME) {
    /* Need at least the 36 bytes sequence layer */
    gst_base_parse_set_min_frame_size (GST_BASE_PARSE (vc1parse), 36);
    gst_base_parse_set_syncable (GST_BASE_PARSE (vc1parse), TRUE);
  } else
      if (vc1parse->input_stream_format ==
      VC1_STREAM_FORMAT_SEQUENCE_LAYER_RAW_FRAME
      || vc1parse->input_stream_format ==
      VC1_STREAM_FORMAT_SEQUENCE_LAYER_FRAME_LAYER) {
    /* Need at least the 36 bytes sequence layer */
    gst_base_parse_set_min_frame_size (GST_BASE_PARSE (vc1parse), 36);
    gst_base_parse_set_syncable (GST_BASE_PARSE (vc1parse), FALSE);
  } else if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_ASF) {
    vc1parse->input_stream_format = VC1_STREAM_FORMAT_ASF;
    /* Need something, assume this is already packetized */
    gst_base_parse_set_min_frame_size (GST_BASE_PARSE (vc1parse), 1);
    gst_base_parse_set_syncable (GST_BASE_PARSE (vc1parse), FALSE);
  } else if (vc1parse->input_stream_format == VC1_STREAM_FORMAT_FRAME_LAYER) {
    /* Need at least the frame layer header */
    gst_base_parse_set_min_frame_size (GST_BASE_PARSE (vc1parse), 8);
    gst_base_parse_set_syncable (GST_BASE_PARSE (vc1parse), FALSE);
  } else {
    g_assert_not_reached ();
  }
}

static gboolean
gst_vc1_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
{
  GstVC1Parse *vc1parse = GST_VC1_PARSE (parse);
  GstStructure *s;
  const GValue *value;
  GstBuffer *codec_data = NULL;
  const gchar *stream_format = NULL;
  const gchar *header_format = NULL;
  const gchar *profile = NULL;
  const gchar *format;

  GST_DEBUG_OBJECT (parse, "caps %" GST_PTR_FORMAT, caps);
  /* Parse the caps to get as much information as possible */
  s = gst_caps_get_structure (caps, 0);

  vc1parse->width = 0;
  gst_structure_get_int (s, "width", &vc1parse->width);
  vc1parse->height = 0;
  gst_structure_get_int (s, "height", &vc1parse->height);

  vc1parse->fps_n = vc1parse->fps_d = 0;
  vc1parse->fps_from_caps = FALSE;
  gst_structure_get_fraction (s, "framerate", &vc1parse->fps_n,
      &vc1parse->fps_d);
  if (vc1parse->fps_d != 0)
    vc1parse->fps_from_caps = TRUE;

  gst_structure_get_fraction (s, "pixel-aspect-ratio",
      &vc1parse->par_n, &vc1parse->par_d);
  if (vc1parse->par_n != 0 && vc1parse->par_d != 0)
    vc1parse->par_from_caps = TRUE;

  vc1parse->format = 0;
  format = gst_structure_get_string (s, "format");
  if (format && strcmp (format, "WVC1") == 0)
    vc1parse->format = GST_VC1_PARSE_FORMAT_WVC1;
  else
    vc1parse->format = GST_VC1_PARSE_FORMAT_WMV3;

  vc1parse->profile = -1;
  profile = gst_structure_get_string (s, "profile");
  if (profile && strcmp (profile, "simple"))
    vc1parse->profile = GST_VC1_PROFILE_SIMPLE;
  else if (profile && strcmp (profile, "main"))
    vc1parse->profile = GST_VC1_PROFILE_MAIN;
  else if (profile && strcmp (profile, "advanced"))
    vc1parse->profile = GST_VC1_PROFILE_ADVANCED;
  else if (vc1parse->format == GST_VC1_PARSE_FORMAT_WVC1)
    vc1parse->profile = GST_VC1_PROFILE_ADVANCED;
  else if (vc1parse->format == GST_VC1_PARSE_FORMAT_WMV3)
    vc1parse->profile = GST_VC1_PROFILE_MAIN;   /* or SIMPLE */

  vc1parse->level = -1;
  vc1parse->detecting_stream_format = FALSE;
  header_format = gst_structure_get_string (s, "header-format");
  stream_format = gst_structure_get_string (s, "stream-format");

  /* Now parse the codec_data */
  gst_buffer_replace (&vc1parse->seq_layer_buffer, NULL);
  gst_buffer_replace (&vc1parse->seq_hdr_buffer, NULL);
  gst_buffer_replace (&vc1parse->entrypoint_buffer, NULL);
  memset (&vc1parse->seq_layer, 0, sizeof (vc1parse->seq_layer));
  memset (&vc1parse->seq_hdr, 0, sizeof (vc1parse->seq_hdr));
  value = gst_structure_get_value (s, "codec_data");

  if (value != NULL) {
    gsize codec_data_size;
    GstMapInfo minfo;

    codec_data = gst_value_get_buffer (value);
    gst_buffer_map (codec_data, &minfo, GST_MAP_READ);
    codec_data_size = gst_buffer_get_size (codec_data);
    if ((codec_data_size == 4 || codec_data_size == 5)) {
      /* ASF, VC1/WMV3 simple/main profile
       * This is the sequence header without start codes
       */
      if (!gst_vc1_parse_handle_seq_hdr (vc1parse, codec_data,
              0, codec_data_size)) {
        gst_buffer_unmap (codec_data, &minfo);
        return FALSE;
      }
      if (header_format && strcmp (header_format, "asf") != 0)
        GST_WARNING_OBJECT (vc1parse,
            "Upstream claimed '%s' header format but 'asf' detected",
            header_format);
      vc1parse->input_header_format = VC1_HEADER_FORMAT_ASF;
    } else if (codec_data_size == 36 && minfo.data[3] == 0xc5) {
      /* Sequence Layer, SMPTE S421M-2006 Annex L.3 */
      if (!gst_vc1_parse_handle_seq_layer (vc1parse, codec_data, 0,
              codec_data_size)) {
        GST_ERROR_OBJECT (vc1parse, "Invalid VC1 sequence layer");
        gst_buffer_unmap (codec_data, &minfo);
        return FALSE;
      }

      if (header_format && strcmp (header_format, "sequence-layer") != 0)
        GST_WARNING_OBJECT (vc1parse,
            "Upstream claimed '%s' header format but 'sequence-layer' detected",
            header_format);
      vc1parse->input_header_format = VC1_HEADER_FORMAT_SEQUENCE_LAYER;
    } else {
      guint32 start_code;
      /* ASF, VC1 advanced profile
       * This should be the
       * 1) ASF binding byte
       * 2) Sequence Header with startcode
       * 3) EntryPoint Header with startcode
       */
      if (codec_data_size < 1 + 4 + 4 + 4 + 2) {
        GST_ERROR_OBJECT (vc1parse,
            "Too small for VC1 advanced profile ASF header");
        gst_buffer_unmap (codec_data, &minfo);
        return FALSE;
      }

      /* Some sanity checking */
      if ((minfo.data[0] & 0x01) != 0x01) {
        GST_ERROR_OBJECT (vc1parse,
            "Invalid binding byte for VC1 advanced profile ASF header");
        gst_buffer_unmap (codec_data, &minfo);
        return FALSE;
      }

      start_code = GST_READ_UINT32_BE (minfo.data + 1);
      if (start_code != 0x000010f) {
        GST_ERROR_OBJECT (vc1parse,
            "VC1 advanced profile ASF header does not start with SequenceHeader startcode");
        gst_buffer_unmap (codec_data, &minfo);
        return FALSE;
      }

      if (!gst_vc1_parse_handle_bdus (vc1parse, codec_data, 1,
              codec_data_size - 1)) {
        gst_buffer_unmap (codec_data, &minfo);
        return FALSE;
      }

      if (!vc1parse->seq_hdr_buffer || !vc1parse->entrypoint_buffer) {
        GST_ERROR_OBJECT (vc1parse,
            "Need sequence header and entrypoint header in the codec_data");
        gst_buffer_unmap (codec_data, &minfo);
        return FALSE;
      }

      if (header_format && strcmp (header_format, "asf") != 0)
        GST_WARNING_OBJECT (vc1parse,
            "Upstream claimed '%s' header format but 'asf' detected",
            header_format);

      vc1parse->input_header_format = VC1_HEADER_FORMAT_ASF;
    }
    gst_buffer_unmap (codec_data, &minfo);
  } else {
    vc1parse->input_header_format = VC1_HEADER_FORMAT_NONE;
    if (header_format && strcmp (header_format, "none") != 0)
      GST_WARNING_OBJECT (vc1parse,
          "Upstream claimed '%s' header format but 'none' detected",
          header_format);
  }

  /* If no stream-format was set we try to detect it */
  if (!stream_format) {
    vc1parse->detecting_stream_format = TRUE;
  } else {
    vc1parse->input_stream_format = stream_format_from_string (stream_format);
    gst_vc1_parse_update_stream_format_properties (vc1parse);
  }

  vc1parse->renegotiate = TRUE;
  vc1parse->update_caps = TRUE;
  return TRUE;
}
