/* GStreamer
 *
 * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
 * Copyright (C) 2009 Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
 * Copyright (C) 2009 Nokia Corporation. All rights reserved.
 *   Contact: Stefan Kost <stefan.kost@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-flacparse
 * @see_also: flacdec, oggdemux, vorbisparse
 *
 * The flacparse element will parse the header packets of the FLAC
 * stream and put them as the streamheader in the caps. This is used in the
 * multifdsink case where you want to stream live FLAC streams to multiple
 * clients, each client has to receive the streamheaders first before they can
 * consume the FLAC packets.
 *
 * This element also makes sure that the buffers that it pushes out are properly
 * timestamped and that their offset and offset_end are set. The buffers that
 * flacparse outputs have all of the metadata that oggmux expects to receive,
 * which allows you to (for example) remux an ogg/flac or convert a native FLAC
 * format file to an ogg bitstream.
 *
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * gst-launch-1.0 -v filesrc location=sine.flac ! flacparse ! identity \
 *            ! oggmux ! filesink location=sine-remuxed.ogg
 * ]| This pipeline converts a native FLAC format file to an ogg bitstream.
 * It also illustrates that the streamheader is set in the caps, and that each
 * buffer has the timestamp, duration, offset, and offset_end set.
 * </refsect2>
 *
 */

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

#include "gstflacparse.h"

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

GST_DEBUG_CATEGORY_STATIC (flacparse_debug);
#define GST_CAT_DEFAULT flacparse_debug

/* CRC-8, poly = x^8 + x^2 + x^1 + x^0, init = 0 */
static const guint8 crc8_table[256] = {
  0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
  0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
  0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
  0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
  0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
  0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
  0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
  0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
  0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
  0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
  0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
  0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
  0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
  0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
  0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
  0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
  0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
  0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
  0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
  0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
  0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
  0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
  0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
  0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
  0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
  0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
  0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
  0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
  0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
  0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
  0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
  0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
};

static guint8
gst_flac_calculate_crc8 (const guint8 * data, guint length)
{
  guint8 crc = 0;

  while (length--) {
    crc = crc8_table[crc ^ *data];
    ++data;
  }

  return crc;
}

/* CRC-16, poly = x^16 + x^15 + x^2 + x^0, init = 0 */
static const guint16 crc16_table[256] = {
  0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011,
  0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022,
  0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072,
  0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041,
  0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2,
  0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1,
  0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1,
  0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082,
  0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192,
  0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1,
  0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1,
  0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2,
  0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151,
  0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162,
  0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132,
  0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101,
  0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312,
  0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321,
  0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371,
  0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342,
  0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1,
  0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2,
  0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2,
  0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381,
  0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291,
  0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2,
  0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2,
  0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1,
  0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252,
  0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261,
  0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231,
  0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202
};

static guint16
gst_flac_calculate_crc16 (const guint8 * data, guint length)
{
  guint16 crc = 0;

  while (length--) {
    crc = ((crc << 8) ^ crc16_table[(crc >> 8) ^ *data]) & 0xffff;
    data++;
  }

  return crc;
}

enum
{
  PROP_0,
  PROP_CHECK_FRAME_CHECKSUMS
};

#define DEFAULT_CHECK_FRAME_CHECKSUMS FALSE

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-flac, framed = (boolean) true, "
        "channels = (int) [ 1, 8 ], " "rate = (int) [ 1, 655350 ]")
    );

static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-flac")
    );

static GstBuffer *gst_flac_parse_generate_vorbiscomment (GstFlacParse *
    flacparse);

static inline void gst_flac_parse_reset_buffer_time_and_offset (GstBuffer *
    buffer);
static void gst_flac_parse_reset (GstFlacParse * parser);
static gboolean gst_flac_parse_handle_block_type (GstFlacParse * flacparse,
    guint type, GstBuffer * sbuffer);
static void gst_flac_parse_finalize (GObject * object);
static void gst_flac_parse_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_flac_parse_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_flac_parse_start (GstBaseParse * parse);
static gboolean gst_flac_parse_stop (GstBaseParse * parse);
static GstFlowReturn gst_flac_parse_handle_frame (GstBaseParse * parse,
    GstBaseParseFrame * frame, gint * skipsize);
static GstFlowReturn gst_flac_parse_parse_frame (GstBaseParse * parse,
    GstBaseParseFrame * frame, gint size);
static GstFlowReturn gst_flac_parse_pre_push_frame (GstBaseParse * parse,
    GstBaseParseFrame * frame);
static gboolean gst_flac_parse_convert (GstBaseParse * parse,
    GstFormat src_format, gint64 src_value, GstFormat dest_format,
    gint64 * dest_value);
static gboolean gst_flac_parse_src_event (GstBaseParse * parse,
    GstEvent * event);
static GstCaps *gst_flac_parse_get_sink_caps (GstBaseParse * parse,
    GstCaps * filter);
static gboolean gst_flac_parse_set_sink_caps (GstBaseParse * parse,
    GstCaps * caps);

#define gst_flac_parse_parent_class parent_class
G_DEFINE_TYPE (GstFlacParse, gst_flac_parse, GST_TYPE_BASE_PARSE);

static void
gst_flac_parse_class_init (GstFlacParseClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GstBaseParseClass *baseparse_class = GST_BASE_PARSE_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (flacparse_debug, "flacparse", 0,
      "Flac parser element");

  gobject_class->finalize = gst_flac_parse_finalize;
  gobject_class->set_property = gst_flac_parse_set_property;
  gobject_class->get_property = gst_flac_parse_get_property;

  g_object_class_install_property (gobject_class, PROP_CHECK_FRAME_CHECKSUMS,
      g_param_spec_boolean ("check-frame-checksums", "Check Frame Checksums",
          "Check the overall checksums of every frame",
          DEFAULT_CHECK_FRAME_CHECKSUMS,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  baseparse_class->start = GST_DEBUG_FUNCPTR (gst_flac_parse_start);
  baseparse_class->stop = GST_DEBUG_FUNCPTR (gst_flac_parse_stop);
  baseparse_class->handle_frame =
      GST_DEBUG_FUNCPTR (gst_flac_parse_handle_frame);
  baseparse_class->pre_push_frame =
      GST_DEBUG_FUNCPTR (gst_flac_parse_pre_push_frame);
  baseparse_class->convert = GST_DEBUG_FUNCPTR (gst_flac_parse_convert);
  baseparse_class->src_event = GST_DEBUG_FUNCPTR (gst_flac_parse_src_event);
  baseparse_class->get_sink_caps =
      GST_DEBUG_FUNCPTR (gst_flac_parse_get_sink_caps);
  baseparse_class->set_sink_caps =
      GST_DEBUG_FUNCPTR (gst_flac_parse_set_sink_caps);

  gst_element_class_add_static_pad_template (element_class, &src_factory);
  gst_element_class_add_static_pad_template (element_class, &sink_factory);

  gst_element_class_set_static_metadata (element_class, "FLAC audio parser",
      "Codec/Parser/Audio",
      "Parses audio with the FLAC lossless audio codec",
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");
}

static void
gst_flac_parse_init (GstFlacParse * flacparse)
{
  flacparse->check_frame_checksums = DEFAULT_CHECK_FRAME_CHECKSUMS;
  GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (flacparse));
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (flacparse));
}

static void
gst_flac_parse_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstFlacParse *flacparse = GST_FLAC_PARSE (object);

  switch (prop_id) {
    case PROP_CHECK_FRAME_CHECKSUMS:
      flacparse->check_frame_checksums = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_flac_parse_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstFlacParse *flacparse = GST_FLAC_PARSE (object);

  switch (prop_id) {
    case PROP_CHECK_FRAME_CHECKSUMS:
      g_value_set_boolean (value, flacparse->check_frame_checksums);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_flac_parse_reset (GstFlacParse * parser)
{
  if (parser->tags) {
    gst_tag_list_unref (parser->tags);
    parser->tags = NULL;
  }
  if (parser->toc) {
    gst_toc_unref (parser->toc);
    parser->toc = NULL;
  }
  if (parser->seektable) {
    gst_buffer_unref (parser->seektable);
    parser->seektable = NULL;
  }

  g_list_foreach (parser->headers, (GFunc) gst_mini_object_unref, NULL);
  g_list_free (parser->headers);
  parser->headers = NULL;
}

static void
gst_flac_parse_finalize (GObject * object)
{
  GstFlacParse *flacparse = GST_FLAC_PARSE (object);

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

static gboolean
gst_flac_parse_start (GstBaseParse * parse)
{
  GstFlacParse *flacparse = GST_FLAC_PARSE (parse);

  flacparse->state = GST_FLAC_PARSE_STATE_INIT;
  flacparse->min_blocksize = 0;
  flacparse->max_blocksize = 0;
  flacparse->min_framesize = 0;
  flacparse->max_framesize = 0;

  flacparse->upstream_length = -1;

  flacparse->samplerate = 0;
  flacparse->channels = 0;
  flacparse->bps = 0;
  flacparse->total_samples = 0;

  flacparse->offset = GST_CLOCK_TIME_NONE;
  flacparse->blocking_strategy = 0;
  flacparse->block_size = 0;
  flacparse->sample_number = 0;
  flacparse->strategy_checked = FALSE;

  flacparse->sent_codec_tag = FALSE;

  /* "fLaC" marker */
  gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);

  /* inform baseclass we can come up with ts, based on counters in packets */
  gst_base_parse_set_has_timing_info (GST_BASE_PARSE_CAST (flacparse), TRUE);
  gst_base_parse_set_syncable (GST_BASE_PARSE_CAST (flacparse), TRUE);

  return TRUE;
}

static gboolean
gst_flac_parse_stop (GstBaseParse * parse)
{
  GstFlacParse *flacparse = GST_FLAC_PARSE (parse);

  gst_flac_parse_reset (flacparse);
  return TRUE;
}

static const guint8 sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 };

static const guint16 blocksize_table[16] = {
  0, 192, 576 << 0, 576 << 1, 576 << 2, 576 << 3, 0, 0,
  256 << 0, 256 << 1, 256 << 2, 256 << 3, 256 << 4, 256 << 5, 256 << 6,
  256 << 7,
};

static const guint32 sample_rate_table[16] = {
  0,
  88200, 176400, 192000,
  8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
  0, 0, 0, 0,
};

typedef enum
{
  FRAME_HEADER_VALID,
  FRAME_HEADER_INVALID,
  FRAME_HEADER_MORE_DATA
} FrameHeaderCheckReturn;

static FrameHeaderCheckReturn
gst_flac_parse_frame_header_is_valid (GstFlacParse * flacparse,
    const guint8 * data, guint size, gboolean set, guint16 * block_size_ret,
    gboolean * suspect)
{
  GstBitReader reader = GST_BIT_READER_INIT (data, size);
  guint8 blocking_strategy;
  guint16 block_size;
  guint32 samplerate = 0;
  guint64 sample_number;
  guint8 channels, bps;
  guint8 tmp = 0;
  guint8 actual_crc, expected_crc = 0;

  /* Skip 14 bit sync code */
  gst_bit_reader_skip_unchecked (&reader, 14);

  /* Must be 0 */
  if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
    goto error;

  /* 0 == fixed block size, 1 == variable block size */
  blocking_strategy = gst_bit_reader_get_bits_uint8_unchecked (&reader, 1);
  if (flacparse->force_variable_block_size)
    blocking_strategy = 1;

  /* block size index, calculation of the real blocksize below */
  block_size = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
  if (block_size == 0)
    goto error;

  /* sample rate index, calculation of the real samplerate below */
  samplerate = gst_bit_reader_get_bits_uint16_unchecked (&reader, 4);
  if (samplerate == 0x0f)
    goto error;

  /* channel assignment */
  channels = gst_bit_reader_get_bits_uint8_unchecked (&reader, 4);
  if (channels < 8) {
    channels++;
  } else if (channels <= 10) {
    channels = 2;
  } else if (channels > 10) {
    goto error;
  }
  if (flacparse->channels && flacparse->channels != channels)
    goto error;

  /* bits per sample */
  bps = gst_bit_reader_get_bits_uint8_unchecked (&reader, 3);
  if (bps == 0x03 || bps == 0x07) {
    goto error;
  } else if (bps == 0 && flacparse->bps == 0) {
    goto need_streaminfo;
  }
  bps = sample_size_table[bps];
  if (flacparse->bps && bps != flacparse->bps)
    goto error;

  /* reserved, must be 0 */
  if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) != 0)
    goto error;

  /* read "utf8" encoded sample/frame number */
  {
    gint len = 0;

    len = gst_bit_reader_get_bits_uint8_unchecked (&reader, 8);

    /* This is slightly faster than a loop */
    if (!(len & 0x80)) {
      sample_number = len;
      len = 0;
    } else if ((len & 0xc0) && !(len & 0x20)) {
      sample_number = len & 0x1f;
      len = 1;
    } else if ((len & 0xe0) && !(len & 0x10)) {
      sample_number = len & 0x0f;
      len = 2;
    } else if ((len & 0xf0) && !(len & 0x08)) {
      sample_number = len & 0x07;
      len = 3;
    } else if ((len & 0xf8) && !(len & 0x04)) {
      sample_number = len & 0x03;
      len = 4;
    } else if ((len & 0xfc) && !(len & 0x02)) {
      sample_number = len & 0x01;
      len = 5;
    } else if ((len & 0xfe) && !(len & 0x01)) {
      sample_number = len & 0x0;
      len = 6;
    } else {
      goto error;
    }

    if ((blocking_strategy == 0 && len > 5) ||
        (blocking_strategy == 1 && len > 6))
      goto error;

    while (len > 0) {
      if (!gst_bit_reader_get_bits_uint8 (&reader, &tmp, 8))
        goto need_more_data;

      if ((tmp & 0xc0) != 0x80)
        goto error;

      sample_number <<= 6;
      sample_number |= (tmp & 0x3f);
      len--;
    }
  }

  /* calculate real blocksize from the blocksize index */
  if (block_size == 6) {
    if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 8))
      goto need_more_data;
    block_size++;
  } else if (block_size == 7) {
    if (!gst_bit_reader_get_bits_uint16 (&reader, &block_size, 16))
      goto need_more_data;
    block_size++;
  } else {
    block_size = blocksize_table[block_size];
  }

  /* calculate the real samplerate from the samplerate index */
  if (samplerate == 0 && flacparse->samplerate == 0) {
    goto need_streaminfo;
  } else if (samplerate < 12) {
    samplerate = sample_rate_table[samplerate];
  } else if (samplerate == 12) {
    if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 8))
      goto need_more_data;
    samplerate *= 1000;
  } else if (samplerate == 13) {
    if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
      goto need_more_data;
  } else if (samplerate == 14) {
    if (!gst_bit_reader_get_bits_uint32 (&reader, &samplerate, 16))
      goto need_more_data;
    samplerate *= 10;
  }

  if (flacparse->samplerate && flacparse->samplerate != samplerate)
    goto error;

  /* check crc-8 for the header */
  if (!gst_bit_reader_get_bits_uint8 (&reader, &expected_crc, 8))
    goto need_more_data;

  actual_crc =
      gst_flac_calculate_crc8 (data,
      (gst_bit_reader_get_pos (&reader) / 8) - 1);
  if (actual_crc != expected_crc) {
    GST_DEBUG_OBJECT (flacparse,
        "Checksum mismatch. Header CRC was '%d' but frame has '%d'",
        expected_crc, actual_crc);
    goto error;
  }

  /* Sanity check sample number against blocking strategy, as it seems
     some files claim fixed block size but supply sample numbers,
     rather than block numbers. */
  if (blocking_strategy == 0 && flacparse->block_size != 0) {
    if (!flacparse->strategy_checked) {
      if (block_size == sample_number) {
        GST_WARNING_OBJECT (flacparse, "This file claims fixed block size, "
            "but seems to be lying: assuming variable block size");
        flacparse->force_variable_block_size = TRUE;
        blocking_strategy = 1;
      }
      flacparse->strategy_checked = TRUE;
    }
  }

  /* documentation says:
   * The "blocking strategy" bit must be the same throughout the entire stream. */
  if (flacparse->blocking_strategy != blocking_strategy) {
    if (flacparse->block_size != 0) {
      GST_WARNING_OBJECT (flacparse, "blocking strategy is not constant");
      if (suspect)
        *suspect = TRUE;
    }
  }

  /*
     The FLAC format documentation says:
     The "blocking strategy" bit determines how to calculate the sample number
     of the first sample in the frame. If the bit is 0 (fixed-blocksize), the
     frame header encodes the frame number as above, and the frame's starting
     sample number will be the frame number times the blocksize. If it is 1
     (variable-blocksize), the frame header encodes the frame's starting
     sample number itself. (In the case of a fixed-blocksize stream, only the
     last block may be shorter than the stream blocksize; its starting sample
     number will be calculated as the frame number times the previous frame's
     blocksize, or zero if it is the first frame).

     Therefore, when in fixed block size mode, we only update the block size
     the first time, then reuse that block size for subsequent calls.
     This will also fix a timestamp problem with the last block's timestamp
     being miscalculated by scaling the block number by a "wrong" block size.
   */
  if (blocking_strategy == 0) {
    if (flacparse->block_size != 0) {
      /* after first block */
      if (flacparse->block_size != block_size) {
        /* TODO: can we know we're on the last frame, to avoid warning ? */
        GST_WARNING_OBJECT (flacparse, "Block size is not constant");
        block_size = flacparse->block_size;
        if (suspect)
          *suspect = TRUE;
      }
    }
  }

  if (set) {
    flacparse->block_size = block_size;
    if (!flacparse->samplerate)
      flacparse->samplerate = samplerate;
    if (!flacparse->bps)
      flacparse->bps = bps;
    if (!flacparse->blocking_strategy)
      flacparse->blocking_strategy = blocking_strategy;
    if (!flacparse->channels)
      flacparse->channels = channels;
    if (!flacparse->sample_number)
      flacparse->sample_number = sample_number;

    GST_DEBUG_OBJECT (flacparse,
        "Parsed frame at offset %" G_GUINT64_FORMAT ":\n" "Block size: %u\n"
        "Sample/Frame number: %" G_GUINT64_FORMAT, flacparse->offset,
        flacparse->block_size, flacparse->sample_number);
  }

  if (block_size_ret)
    *block_size_ret = block_size;

  return FRAME_HEADER_VALID;

need_streaminfo:
  GST_ERROR_OBJECT (flacparse, "Need STREAMINFO metadata. Bits per sample "
      "or sample rate not in frame header");
error:
  return FRAME_HEADER_INVALID;

need_more_data:
  return FRAME_HEADER_MORE_DATA;
}

static gboolean
gst_flac_parse_frame_is_valid (GstFlacParse * flacparse,
    const guint8 * data, gsize size, guint * ret)
{
  guint max, remaining;
  guint i, search_start, search_end;
  FrameHeaderCheckReturn header_ret;
  guint16 block_size;
  gboolean suspect_start = FALSE, suspect_end = FALSE;

  if (size < flacparse->min_framesize)
    goto need_more;

  header_ret =
      gst_flac_parse_frame_header_is_valid (flacparse, data, size, TRUE,
      &block_size, &suspect_start);
  if (header_ret == FRAME_HEADER_INVALID) {
    *ret = 0;
    return FALSE;
  }
  if (header_ret == FRAME_HEADER_MORE_DATA)
    goto need_more;

  /* mind unknown framesize */
  search_start = MAX (2, flacparse->min_framesize);
  if (flacparse->max_framesize)
    search_end = MIN (size, flacparse->max_framesize + 9 + 2);
  else
    search_end = size;
  search_end -= 2;

  remaining = size;

  for (i = search_start; i < search_end; i++, remaining--) {

    if ((GST_READ_UINT16_BE (data + i) & 0xfffe) != 0xfff8)
      continue;

    GST_LOG_OBJECT (flacparse, "possible frame end at offset %d", i);
    suspect_end = FALSE;
    header_ret =
        gst_flac_parse_frame_header_is_valid (flacparse, data + i,
        remaining, FALSE, NULL, &suspect_end);
    if (header_ret == FRAME_HEADER_VALID) {
      if (flacparse->check_frame_checksums || suspect_start || suspect_end) {
        guint16 actual_crc = gst_flac_calculate_crc16 (data, i - 2);
        guint16 expected_crc = GST_READ_UINT16_BE (data + i - 2);

        GST_LOG_OBJECT (flacparse,
            "Found possible frame (%d, %d). Checking for CRC match",
            suspect_start, suspect_end);
        if (actual_crc != expected_crc) {
          GST_DEBUG_OBJECT (flacparse,
              "Checksum mismatch. Header CRC was '%d' but frame has '%d'",
              expected_crc, actual_crc);
          continue;
        }
      }
      *ret = i;
      flacparse->block_size = block_size;
      return TRUE;
    } else if (header_ret == FRAME_HEADER_MORE_DATA) {
      goto need_more;
    }
  }

  /* For the last frame output everything to the end */
  if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
    if (flacparse->check_frame_checksums) {
      guint16 actual_crc = gst_flac_calculate_crc16 (data, size - 2);
      guint16 expected_crc = GST_READ_UINT16_BE (data + size - 2);

      if (actual_crc == expected_crc) {
        *ret = size;
        flacparse->block_size = block_size;
        return TRUE;
      }
    } else {
      *ret = size;
      flacparse->block_size = block_size;
      return TRUE;
    }
  }

  /* so we searched to expected end and found nothing,
   * give up on this frame (start) */
  if (flacparse->max_framesize && i > 2 * flacparse->max_framesize) {
    GST_LOG_OBJECT (flacparse,
        "could not determine valid frame end, discarding frame (start)");
    *ret = 1;
    return FALSE;
  }

need_more:
  max = flacparse->max_framesize + 16;
  if (max == 16)
    max = 1 << 24;
  *ret = MIN (size + 4096, max);
  return TRUE;
}

static GstFlowReturn
gst_flac_parse_handle_frame (GstBaseParse * parse,
    GstBaseParseFrame * frame, gint * skipsize)
{
  GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
  GstBuffer *buffer = frame->buffer;
  GstMapInfo map;
  gboolean result = TRUE;
  GstFlowReturn ret = GST_FLOW_OK;
  guint framesize = 0;

  gst_buffer_map (buffer, &map, GST_MAP_READ);

  *skipsize = 1;

  if (G_UNLIKELY (map.size < 4)) {
    result = FALSE;
    goto cleanup;
  }

  if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
    if (memcmp (map.data, "fLaC", 4) == 0) {
      GST_DEBUG_OBJECT (flacparse, "fLaC marker found");
      framesize = 4;
      goto cleanup;
    }
    if (map.data[0] == 0xff && (map.data[1] >> 2) == 0x3e) {
      GST_DEBUG_OBJECT (flacparse, "Found headerless FLAC");
      /* Minimal size of a frame header */
      gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 9);
      flacparse->state = GST_FLAC_PARSE_STATE_GENERATE_HEADERS;
      *skipsize = 0;
      result = FALSE;
      goto cleanup;
    }
    GST_DEBUG_OBJECT (flacparse, "fLaC marker not found");
    result = FALSE;
    goto cleanup;
  }

  if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
    guint size = 4 + ((map.data[1] << 16) | (map.data[2] << 8) | (map.data[3]));

    GST_DEBUG_OBJECT (flacparse, "Found metadata block of size %u", size);
    framesize = size;
    gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), framesize);
    goto cleanup;
  }

  if ((GST_READ_UINT16_BE (map.data) & 0xfffe) == 0xfff8) {
    gboolean ret, is_first = !flacparse->strategy_checked;
    guint next;

    flacparse->offset = GST_BUFFER_OFFSET (buffer);
    flacparse->blocking_strategy = 0;
    flacparse->sample_number = 0;

    GST_DEBUG_OBJECT (flacparse, "Found sync code");
    ret = gst_flac_parse_frame_is_valid (flacparse, map.data, map.size, &next);
    if (ret) {
      if (is_first) {
        GST_INFO_OBJECT (flacparse, "First sample number is %" G_GUINT64_FORMAT,
            flacparse->sample_number);
        flacparse->first_sample_number = flacparse->sample_number;
      }
      framesize = next;
      goto cleanup;
    }

    /* If we're at EOS and the frame was not valid, drop it! */
    if (G_UNLIKELY (GST_BASE_PARSE_DRAINING (flacparse))) {
      GST_WARNING_OBJECT (flacparse, "EOS");
      result = FALSE;
      goto cleanup;
    }

    if (next == 0) {
    } else if (next > map.size) {
      GST_DEBUG_OBJECT (flacparse, "Requesting %u bytes", next);
      *skipsize = 0;
      gst_base_parse_set_min_frame_size (parse, next);
      result = FALSE;
      goto cleanup;
    } else {
      GST_ERROR_OBJECT (flacparse,
          "Giving up on invalid frame (%" G_GSIZE_FORMAT " bytes)", map.size);
      result = FALSE;
      goto cleanup;
    }
  } else {
    GstByteReader reader;
    gint off;

    gst_byte_reader_init (&reader, map.data, map.size);
    off =
        gst_byte_reader_masked_scan_uint32 (&reader, 0xfffc0000, 0xfff80000,
        0, map.size);

    if (off > 0) {
      GST_DEBUG_OBJECT (parse, "Possible sync at buffer offset %d", off);
      *skipsize = off;
      result = FALSE;
      goto cleanup;
    }

    GST_DEBUG_OBJECT (flacparse, "Sync code not found");
    *skipsize = map.size - 3;
    result = FALSE;
    goto cleanup;
  }

  result = FALSE;

cleanup:
  gst_buffer_unmap (buffer, &map);

  if (result)
    *skipsize = 0;

  if (result && framesize <= map.size) {
    ret = gst_flac_parse_parse_frame (parse, frame, framesize);
    if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
      frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
      ret = GST_FLOW_OK;
    }
    if (ret == GST_FLOW_OK)
      ret = gst_base_parse_finish_frame (parse, frame, framesize);
  }

  return ret;
}

static gboolean
gst_flac_parse_handle_streaminfo (GstFlacParse * flacparse, GstBuffer * buffer)
{
  GstBitReader reader;
  GstMapInfo map;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  gst_bit_reader_init (&reader, map.data, map.size);

  if (map.size != 4 + 34) {
    GST_ERROR_OBJECT (flacparse,
        "Invalid metablock size for STREAMINFO: %" G_GSIZE_FORMAT "", map.size);
    goto failure;
  }

  /* Skip metadata block header */
  if (!gst_bit_reader_skip (&reader, 32))
    goto error;

  if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->min_blocksize, 16))
    goto error;
  if (flacparse->min_blocksize < 16) {
    GST_WARNING_OBJECT (flacparse, "Invalid minimum block size: %u",
        flacparse->min_blocksize);
  }

  if (!gst_bit_reader_get_bits_uint16 (&reader, &flacparse->max_blocksize, 16))
    goto error;
  if (flacparse->max_blocksize < 16) {
    GST_WARNING_OBJECT (flacparse, "Invalid maximum block size: %u",
        flacparse->max_blocksize);
  }

  if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->min_framesize, 24))
    goto error;
  if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->max_framesize, 24))
    goto error;

  if (!gst_bit_reader_get_bits_uint32 (&reader, &flacparse->samplerate, 20))
    goto error;
  if (flacparse->samplerate == 0) {
    GST_ERROR_OBJECT (flacparse, "Invalid sample rate 0");
    goto failure;
  }

  if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->channels, 3))
    goto error;
  flacparse->channels++;
  if (flacparse->channels > 8) {
    GST_ERROR_OBJECT (flacparse, "Invalid number of channels %u",
        flacparse->channels);
    goto failure;
  }

  if (!gst_bit_reader_get_bits_uint8 (&reader, &flacparse->bps, 5))
    goto error;
  flacparse->bps++;

  if (!gst_bit_reader_get_bits_uint64 (&reader, &flacparse->total_samples, 36))
    goto error;
  if (flacparse->total_samples) {
    gst_base_parse_set_duration (GST_BASE_PARSE (flacparse),
        GST_FORMAT_DEFAULT, flacparse->total_samples, 0);
  }

  gst_buffer_unmap (buffer, &map);

  GST_DEBUG_OBJECT (flacparse, "STREAMINFO:\n"
      "\tmin/max blocksize: %u/%u,\n"
      "\tmin/max framesize: %u/%u,\n"
      "\tsamplerate: %u,\n"
      "\tchannels: %u,\n"
      "\tbits per sample: %u,\n"
      "\ttotal samples: %" G_GUINT64_FORMAT,
      flacparse->min_blocksize, flacparse->max_blocksize,
      flacparse->min_framesize, flacparse->max_framesize,
      flacparse->samplerate,
      flacparse->channels, flacparse->bps, flacparse->total_samples);

  return TRUE;

error:
  GST_ERROR_OBJECT (flacparse, "Failed to read data");
failure:
  gst_buffer_unmap (buffer, &map);
  return FALSE;
}

static gboolean
gst_flac_parse_handle_vorbiscomment (GstFlacParse * flacparse,
    GstBuffer * buffer)
{
  GstTagList *tags;
  GstMapInfo map;

  gst_buffer_map (buffer, &map, GST_MAP_READ);

  tags =
      gst_tag_list_from_vorbiscomment (map.data, map.size, map.data, 4, NULL);
  gst_buffer_unmap (buffer, &map);

  if (tags == NULL) {
    GST_ERROR_OBJECT (flacparse, "Invalid vorbiscomment block");
  } else if (gst_tag_list_is_empty (tags)) {
    gst_tag_list_unref (tags);
  } else if (flacparse->tags == NULL) {
    flacparse->tags = tags;
  } else {
    gst_tag_list_insert (flacparse->tags, tags, GST_TAG_MERGE_APPEND);
    gst_tag_list_unref (tags);
  }

  return TRUE;
}

static gboolean
gst_flac_parse_handle_cuesheet (GstFlacParse * flacparse, GstBuffer * buffer)
{
  GstByteReader reader;
  GstMapInfo map;
  guint i, j;
  guint8 n_tracks, track_num, index;
  guint64 offset;
  gint64 start, stop;
  gchar *id;
  gchar isrc[13];
  GstTagList *tags;
  GstToc *toc;
  GstTocEntry *cur_entry = NULL, *prev_entry = NULL;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  gst_byte_reader_init (&reader, map.data, map.size);

  toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);

  /* skip 4 bytes METADATA_BLOCK_HEADER */
  /* https://xiph.org/flac/format.html#metadata_block_header */
  if (!gst_byte_reader_skip (&reader, 4))
    goto error;

  /* skip 395 bytes from METADATA_BLOCK_CUESHEET */
  /* https://xiph.org/flac/format.html#metadata_block_cuesheet */
  if (!gst_byte_reader_skip (&reader, 395))
    goto error;

  if (!gst_byte_reader_get_uint8 (&reader, &n_tracks))
    goto error;

  /* CUESHEET_TRACK */
  /* https://xiph.org/flac/format.html#cuesheet_track */
  for (i = 0; i < n_tracks; i++) {
    if (!gst_byte_reader_get_uint64_be (&reader, &offset))
      goto error;
    if (!gst_byte_reader_get_uint8 (&reader, &track_num))
      goto error;

    if (gst_byte_reader_get_remaining (&reader) < 12)
      goto error;
    memcpy (isrc, map.data + gst_byte_reader_get_pos (&reader), 12);
    /* \0-terminate the string */
    isrc[12] = '\0';
    if (!gst_byte_reader_skip (&reader, 12))
      goto error;

    /* skip 14 bytes from CUESHEET_TRACK */
    if (!gst_byte_reader_skip (&reader, 14))
      goto error;
    if (!gst_byte_reader_get_uint8 (&reader, &index))
      goto error;
    /* add tracks in TOC */
    /* lead-out tack has number 170 or 255 */
    if (track_num != 170 && track_num != 255) {
      prev_entry = cur_entry;
      /* previous track stop time = current track start time */
      if (prev_entry != NULL) {
        gst_toc_entry_get_start_stop_times (prev_entry, &start, NULL);
        stop =
            gst_util_uint64_scale_round (offset, GST_SECOND,
            flacparse->samplerate);
        gst_toc_entry_set_start_stop_times (prev_entry, start, stop);
      }
      id = g_strdup_printf ("%08x", track_num);
      cur_entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_TRACK, id);
      g_free (id);
      start =
          gst_util_uint64_scale_round (offset, GST_SECOND,
          flacparse->samplerate);
      gst_toc_entry_set_start_stop_times (cur_entry, start, -1);
      /* add ISRC as tag in track */
      if (strlen (isrc) != 0) {
        tags = gst_tag_list_new_empty ();
        gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ISRC, isrc, NULL);
        gst_toc_entry_set_tags (cur_entry, tags);
      }
      gst_toc_append_entry (toc, cur_entry);
      /* CUESHEET_TRACK_INDEX */
      /* https://xiph.org/flac/format.html#cuesheet_track_index */
      for (j = 0; j < index; j++) {
        if (!gst_byte_reader_skip (&reader, 12))
          goto error;
      }
    } else {
      /* set stop time in last track */
      stop =
          gst_util_uint64_scale_round (offset, GST_SECOND,
          flacparse->samplerate);
      gst_toc_entry_set_start_stop_times (cur_entry, start, stop);
    }
  }

  /* send data as TOC */
  if (!flacparse->toc)
    flacparse->toc = toc;

  gst_buffer_unmap (buffer, &map);
  return TRUE;

error:
  GST_ERROR_OBJECT (flacparse, "Error reading data");
  gst_buffer_unmap (buffer, &map);
  return FALSE;
}

static gboolean
gst_flac_parse_handle_picture (GstFlacParse * flacparse, GstBuffer * buffer)
{
  GstByteReader reader;
  GstMapInfo map;
  guint32 img_len = 0, img_type = 0;
  guint32 img_mimetype_len = 0, img_description_len = 0;

  gst_buffer_map (buffer, &map, GST_MAP_READ);
  gst_byte_reader_init (&reader, map.data, map.size);

  if (!gst_byte_reader_skip (&reader, 4))
    goto error;

  if (!gst_byte_reader_get_uint32_be (&reader, &img_type))
    goto error;

  if (!gst_byte_reader_get_uint32_be (&reader, &img_mimetype_len))
    goto error;
  if (!gst_byte_reader_skip (&reader, img_mimetype_len))
    goto error;

  if (!gst_byte_reader_get_uint32_be (&reader, &img_description_len))
    goto error;
  if (!gst_byte_reader_skip (&reader, img_description_len))
    goto error;

  if (!gst_byte_reader_skip (&reader, 4 * 4))
    goto error;

  if (!gst_byte_reader_get_uint32_be (&reader, &img_len))
    goto error;

  if (gst_byte_reader_get_pos (&reader) + img_len > map.size)
    goto error;

  GST_INFO_OBJECT (flacparse, "Got image of %d bytes", img_len);

  if (img_len > 0) {
    if (flacparse->tags == NULL)
      flacparse->tags = gst_tag_list_new_empty ();

    gst_tag_list_add_id3_image (flacparse->tags,
        map.data + gst_byte_reader_get_pos (&reader), img_len, img_type);
  }

  gst_buffer_unmap (buffer, &map);
  return TRUE;

error:
  GST_ERROR_OBJECT (flacparse, "Error reading data");
  gst_buffer_unmap (buffer, &map);
  return FALSE;
}

static gboolean
gst_flac_parse_handle_seektable (GstFlacParse * flacparse, GstBuffer * buffer)
{

  GST_DEBUG_OBJECT (flacparse, "storing seektable");
  /* only store for now;
   * offset of the first frame is needed to get real info */
  if (flacparse->seektable)
    gst_buffer_unref (flacparse->seektable);
  flacparse->seektable = gst_buffer_ref (buffer);

  return TRUE;
}

static void
gst_flac_parse_process_seektable (GstFlacParse * flacparse, gint64 boffset)
{
  GstByteReader br;
  gint64 offset = 0, samples = 0;
  GstMapInfo map;

  GST_DEBUG_OBJECT (flacparse,
      "parsing seektable; base offset %" G_GINT64_FORMAT, boffset);

  if (boffset <= 0)
    goto exit;

  gst_buffer_map (flacparse->seektable, &map, GST_MAP_READ);
  gst_byte_reader_init (&br, map.data, map.size);

  /* skip header */
  if (!gst_byte_reader_skip (&br, 4))
    goto done;

  /* seekpoints */
  while (gst_byte_reader_get_remaining (&br)) {
    if (!gst_byte_reader_get_int64_be (&br, &samples))
      break;
    if (!gst_byte_reader_get_int64_be (&br, &offset))
      break;
    if (!gst_byte_reader_skip (&br, 2))
      break;

    GST_LOG_OBJECT (flacparse, "samples %" G_GINT64_FORMAT " -> offset %"
        G_GINT64_FORMAT, samples, offset);

    /* sanity check */
    if (G_LIKELY (offset > 0 && samples > 0)) {
      gst_base_parse_add_index_entry (GST_BASE_PARSE (flacparse),
          boffset + offset, gst_util_uint64_scale (samples, GST_SECOND,
              flacparse->samplerate), TRUE, FALSE);
    }
  }

done:
  gst_buffer_unmap (flacparse->seektable, &map);
exit:
  gst_buffer_unref (flacparse->seektable);
  flacparse->seektable = NULL;
}

static void
_value_array_append_buffer (GValue * array_val, GstBuffer * buf)
{
  GValue value = { 0, };

  g_value_init (&value, GST_TYPE_BUFFER);
  /* copy buffer to avoid problems with circular refcounts */
  buf = gst_buffer_copy (buf);
  /* again, for good measure */
  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
  gst_value_set_buffer (&value, buf);
  gst_buffer_unref (buf);
  gst_value_array_append_value (array_val, &value);
  g_value_unset (&value);
}

static GstFlowReturn
gst_flac_parse_handle_headers (GstFlacParse * flacparse)
{
  GstBuffer *vorbiscomment = NULL;
  GstBuffer *streaminfo = NULL;
  GstBuffer *marker = NULL;
  GValue array = { 0, };
  GstCaps *caps;
  GList *l;
  GstFlowReturn res = GST_FLOW_OK;

  caps = gst_caps_new_simple ("audio/x-flac",
      "channels", G_TYPE_INT, flacparse->channels,
      "framed", G_TYPE_BOOLEAN, TRUE,
      "rate", G_TYPE_INT, flacparse->samplerate, NULL);

  if (!flacparse->headers)
    goto push_headers;

  for (l = flacparse->headers; l; l = l->next) {
    GstBuffer *header = l->data;
    GstMapInfo map;

    gst_buffer_map (header, &map, GST_MAP_READ);

    GST_BUFFER_FLAG_SET (header, GST_BUFFER_FLAG_HEADER);

    if (map.size == 4 && memcmp (map.data, "fLaC", 4) == 0) {
      marker = header;
    } else if (map.size > 1 && (map.data[0] & 0x7f) == 0) {
      streaminfo = header;
    } else if (map.size > 1 && (map.data[0] & 0x7f) == 4) {
      vorbiscomment = header;
    }

    gst_buffer_unmap (header, &map);
  }

  /* at least this one we can generate easily
   * to provide full headers downstream */
  if (vorbiscomment == NULL && streaminfo != NULL) {
    GST_DEBUG_OBJECT (flacparse,
        "missing vorbiscomment header; generating dummy");
    vorbiscomment = gst_flac_parse_generate_vorbiscomment (flacparse);
    flacparse->headers = g_list_insert (flacparse->headers, vorbiscomment,
        g_list_index (flacparse->headers, streaminfo) + 1);
  }

  if (marker == NULL || streaminfo == NULL || vorbiscomment == NULL) {
    GST_WARNING_OBJECT (flacparse,
        "missing header %p %p %p, muxing into container "
        "formats may be broken", marker, streaminfo, vorbiscomment);
    goto push_headers;
  }

  g_value_init (&array, GST_TYPE_ARRAY);

  /* add marker including STREAMINFO header */
  {
    GstBuffer *buf;
    guint16 num;
    GstMapInfo sinfomap, writemap;

    gst_buffer_map (streaminfo, &sinfomap, GST_MAP_READ);

    /* minus one for the marker that is merged with streaminfo here */
    num = g_list_length (flacparse->headers) - 1;

    buf = gst_buffer_new_and_alloc (13 + sinfomap.size);
    gst_buffer_map (buf, &writemap, GST_MAP_WRITE);

    writemap.data[0] = 0x7f;
    memcpy (writemap.data + 1, "FLAC", 4);
    writemap.data[5] = 0x01;    /* mapping version major */
    writemap.data[6] = 0x00;    /* mapping version minor */
    writemap.data[7] = (num & 0xFF00) >> 8;
    writemap.data[8] = (num & 0x00FF) >> 0;
    memcpy (writemap.data + 9, "fLaC", 4);
    memcpy (writemap.data + 13, sinfomap.data, sinfomap.size);
    _value_array_append_buffer (&array, buf);

    gst_buffer_unmap (streaminfo, &sinfomap);
    gst_buffer_unmap (buf, &writemap);
    gst_buffer_unref (buf);
  }

  /* add VORBISCOMMENT header */
  _value_array_append_buffer (&array, vorbiscomment);

  /* add other headers, if there are any */
  for (l = flacparse->headers; l; l = l->next) {
    if (GST_BUFFER_CAST (l->data) != marker &&
        GST_BUFFER_CAST (l->data) != streaminfo &&
        GST_BUFFER_CAST (l->data) != vorbiscomment) {
      _value_array_append_buffer (&array, GST_BUFFER_CAST (l->data));
    }
  }

  gst_structure_set_value (gst_caps_get_structure (caps, 0),
      "streamheader", &array);
  g_value_unset (&array);

push_headers:

  gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (GST_BASE_PARSE (flacparse)), caps);
  gst_caps_unref (caps);

  /* push header buffers; update caps, so when we push the first buffer the
   * negotiated caps will change to caps that include the streamheader field */
  while (flacparse->headers) {
    GstBuffer *buf = GST_BUFFER (flacparse->headers->data);
    GstBaseParseFrame frame;

    flacparse->headers =
        g_list_delete_link (flacparse->headers, flacparse->headers);
    buf = gst_buffer_make_writable (buf);

    /* init, set and give away frame */
    gst_base_parse_frame_init (&frame);
    frame.buffer = buf;
    frame.overhead = -1;
    res = gst_base_parse_push_frame (GST_BASE_PARSE (flacparse), &frame);
    gst_base_parse_frame_free (&frame);
    if (res != GST_FLOW_OK)
      break;
  }
  g_list_foreach (flacparse->headers, (GFunc) gst_mini_object_unref, NULL);
  g_list_free (flacparse->headers);
  flacparse->headers = NULL;

  return res;
}

/* empty vorbiscomment */
static GstBuffer *
gst_flac_parse_generate_vorbiscomment (GstFlacParse * flacparse)
{
  GstTagList *taglist = gst_tag_list_new_empty ();
  guchar header[4];
  guint size;
  GstBuffer *vorbiscomment;
  GstMapInfo map;

  header[0] = 0x84;             /* is_last = 1; type = 4; */

  vorbiscomment =
      gst_tag_list_to_vorbiscomment_buffer (taglist, header,
      sizeof (header), NULL);
  gst_tag_list_unref (taglist);

  gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);

  /* Get rid of framing bit */
  if (map.data[map.size - 1] == 1) {
    GstBuffer *sub;

    sub =
        gst_buffer_copy_region (vorbiscomment, GST_BUFFER_COPY_ALL, 0,
        map.size - 1);
    gst_buffer_unmap (vorbiscomment, &map);
    gst_buffer_unref (vorbiscomment);
    vorbiscomment = sub;
    gst_buffer_map (vorbiscomment, &map, GST_MAP_WRITE);
  }

  size = map.size - 4;
  map.data[1] = ((size & 0xFF0000) >> 16);
  map.data[2] = ((size & 0x00FF00) >> 8);
  map.data[3] = (size & 0x0000FF);
  gst_buffer_unmap (vorbiscomment, &map);
  gst_flac_parse_reset_buffer_time_and_offset (vorbiscomment);

  return vorbiscomment;
}

static gboolean
gst_flac_parse_generate_headers (GstFlacParse * flacparse)
{
  GstBuffer *marker, *streaminfo;
  GstMapInfo map;

  marker = gst_buffer_new_and_alloc (4);
  gst_buffer_map (marker, &map, GST_MAP_WRITE);
  memcpy (map.data, "fLaC", 4);
  gst_buffer_unmap (marker, &map);
  gst_flac_parse_reset_buffer_time_and_offset (marker);
  flacparse->headers = g_list_append (flacparse->headers, marker);

  streaminfo = gst_buffer_new_and_alloc (4 + 34);
  gst_buffer_map (streaminfo, &map, GST_MAP_WRITE);
  memset (map.data, 0, 4 + 34);

  /* metadata block header */
  map.data[0] = 0x00;           /* is_last = 0; type = 0; */
  map.data[1] = 0x00;           /* length = 34; */
  map.data[2] = 0x00;
  map.data[3] = 0x22;

  /* streaminfo */

  map.data[4] = (flacparse->block_size >> 8) & 0xff;    /* min blocksize = blocksize; */
  map.data[5] = (flacparse->block_size) & 0xff;
  map.data[6] = (flacparse->block_size >> 8) & 0xff;    /* max blocksize = blocksize; */
  map.data[7] = (flacparse->block_size) & 0xff;

  map.data[8] = 0x00;           /* min framesize = 0; */
  map.data[9] = 0x00;
  map.data[10] = 0x00;
  map.data[11] = 0x00;          /* max framesize = 0; */
  map.data[12] = 0x00;
  map.data[13] = 0x00;

  map.data[14] = (flacparse->samplerate >> 12) & 0xff;
  map.data[15] = (flacparse->samplerate >> 4) & 0xff;
  map.data[16] = (flacparse->samplerate >> 0) & 0xf0;

  map.data[16] |= (flacparse->channels - 1) << 1;

  map.data[16] |= ((flacparse->bps - 1) >> 4) & 0x01;
  map.data[17] = (((flacparse->bps - 1)) & 0x0f) << 4;

  {
    gint64 duration;

    if (gst_pad_peer_query_duration (GST_BASE_PARSE_SINK_PAD (flacparse),
            GST_FORMAT_TIME, &duration) && duration != -1) {
      duration = GST_CLOCK_TIME_TO_FRAMES (duration, flacparse->samplerate);

      map.data[17] |= (duration >> 32) & 0xff;
      map.data[18] |= (duration >> 24) & 0xff;
      map.data[19] |= (duration >> 16) & 0xff;
      map.data[20] |= (duration >> 8) & 0xff;
      map.data[21] |= (duration >> 0) & 0xff;
    }
  }
  /* MD5 = 0; */

  gst_buffer_unmap (streaminfo, &map);
  gst_flac_parse_reset_buffer_time_and_offset (streaminfo);
  flacparse->headers = g_list_append (flacparse->headers, streaminfo);

  flacparse->headers = g_list_append (flacparse->headers,
      gst_flac_parse_generate_vorbiscomment (flacparse));

  return TRUE;
}

static inline void
gst_flac_parse_reset_buffer_time_and_offset (GstBuffer * buffer)
{
  GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
  GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
  GST_BUFFER_OFFSET (buffer) = 0;
  GST_BUFFER_OFFSET_END (buffer) = 0;
}

/* Type 127 is invalid for a metadata block header & should
 * be discarded _before_ calling this function */
static gboolean
gst_flac_parse_handle_block_type (GstFlacParse * flacparse, guint type,
    GstBuffer * sbuffer)
{
  gboolean ret = TRUE;

  switch (type) {
    case 0:                    /* STREAMINFO */
      GST_INFO_OBJECT (flacparse, "STREAMINFO header");
      ret = gst_flac_parse_handle_streaminfo (flacparse, sbuffer);
      break;
    case 3:                    /* SEEKTABLE */
      GST_INFO_OBJECT (flacparse, "SEEKTABLE header");
      ret = gst_flac_parse_handle_seektable (flacparse, sbuffer);
      break;
    case 4:                    /* VORBIS_COMMENT */
      GST_INFO_OBJECT (flacparse, "VORBISCOMMENT header");
      ret = gst_flac_parse_handle_vorbiscomment (flacparse, sbuffer);
      break;
    case 5:                    /* CUESHEET */
      GST_INFO_OBJECT (flacparse, "CUESHEET header");
      ret = gst_flac_parse_handle_cuesheet (flacparse, sbuffer);
      break;
    case 6:                    /* PICTURE */
      GST_INFO_OBJECT (flacparse, "PICTURE header");
      ret = gst_flac_parse_handle_picture (flacparse, sbuffer);
      break;
    case 1:                    /* PADDING */
      GST_INFO_OBJECT (flacparse, "PADDING header");
      break;
    case 2:                    /* APPLICATION */
      GST_INFO_OBJECT (flacparse, "APPLICATION header");
      break;
    default:                   /* RESERVED */
      GST_INFO_OBJECT (flacparse, "Unhandled metadata header type '%u'", type);
      GST_FIXME_OBJECT (flacparse, "FLAC version might not be fully supported");
      break;
  }

  return ret;
}

static GstFlowReturn
gst_flac_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
    gint size)
{
  GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
  GstBuffer *buffer = frame->buffer, *sbuffer;
  GstMapInfo map;
  GstFlowReturn res = GST_FLOW_ERROR;
  guint64 relative_sample_number;

  gst_buffer_map (buffer, &map, GST_MAP_READ);

  if (flacparse->state == GST_FLAC_PARSE_STATE_INIT) {
    sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);
    gst_flac_parse_reset_buffer_time_and_offset (sbuffer);

    /* 32 bits metadata block */
    gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
    flacparse->state = GST_FLAC_PARSE_STATE_HEADERS;

    flacparse->headers = g_list_append (flacparse->headers, sbuffer);

    res = GST_BASE_PARSE_FLOW_DROPPED;
  } else if (flacparse->state == GST_FLAC_PARSE_STATE_HEADERS) {
    gboolean is_last = map.data[0] >> 7;
    guint type = (map.data[0] & 0x7F);

    if (type == 127) {
      GST_WARNING_OBJECT (flacparse, "Invalid metadata block type 127");
      res = GST_BASE_PARSE_FLOW_DROPPED;
      goto cleanup;
    }

    GST_DEBUG_OBJECT (flacparse, "Handling metadata block of type %u", type);

    sbuffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, size);

    if (gst_flac_parse_handle_block_type (flacparse, type, sbuffer)) {
      gst_flac_parse_reset_buffer_time_and_offset (sbuffer);
      flacparse->headers = g_list_append (flacparse->headers, sbuffer);
    } else {
      GST_WARNING_OBJECT (parse, "failed to parse header of type %u", type);
      GST_MEMDUMP_OBJECT (parse, "bad header data", map.data, size);

      gst_buffer_unref (sbuffer);

      /* error out unless we have a STREAMINFO header */
      if (flacparse->samplerate == 0 || flacparse->bps == 0)
        goto header_parsing_error;

      /* .. in which case just stop header parsing and try to find audio */
      is_last = TRUE;
    }

    if (is_last) {
      res = gst_flac_parse_handle_headers (flacparse);

      /* Minimal size of a frame header */
      gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
              flacparse->min_framesize));
      flacparse->state = GST_FLAC_PARSE_STATE_DATA;

      if (res != GST_FLOW_OK)
        goto cleanup;
    } else {
      /* Header length */
      gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), 4);
    }

    /* DROPPED because we pushed already or will push all headers manually */
    res = GST_BASE_PARSE_FLOW_DROPPED;
  } else {
    if (flacparse->offset != GST_BUFFER_OFFSET (buffer)) {
      FrameHeaderCheckReturn ret;

      flacparse->offset = GST_BUFFER_OFFSET (buffer);
      ret =
          gst_flac_parse_frame_header_is_valid (flacparse,
          map.data, map.size, TRUE, NULL, NULL);
      if (ret != FRAME_HEADER_VALID) {
        GST_ERROR_OBJECT (flacparse,
            "Baseclass didn't provide a complete frame");
        goto cleanup;
      }
    }

    if (flacparse->block_size == 0) {
      GST_ERROR_OBJECT (flacparse, "Unparsed frame");
      goto cleanup;
    }

    if (flacparse->seektable)
      gst_flac_parse_process_seektable (flacparse, GST_BUFFER_OFFSET (buffer));

    if (flacparse->state == GST_FLAC_PARSE_STATE_GENERATE_HEADERS) {
      if (flacparse->blocking_strategy == 1) {
        GST_WARNING_OBJECT (flacparse,
            "Generating headers for variable blocksize streams not supported");

        res = gst_flac_parse_handle_headers (flacparse);
      } else {
        GST_DEBUG_OBJECT (flacparse, "Generating headers");

        if (!gst_flac_parse_generate_headers (flacparse))
          goto cleanup;

        res = gst_flac_parse_handle_headers (flacparse);
      }
      flacparse->state = GST_FLAC_PARSE_STATE_DATA;
      if (res != GST_FLOW_OK)
        goto cleanup;
    }

    /* also cater for oggmux metadata */
    relative_sample_number =
        flacparse->sample_number - flacparse->first_sample_number;
    if (flacparse->blocking_strategy == 0) {
      GST_BUFFER_PTS (buffer) =
          gst_util_uint64_scale (relative_sample_number,
          flacparse->block_size * GST_SECOND, flacparse->samplerate);
      GST_BUFFER_OFFSET_END (buffer) =
          relative_sample_number * flacparse->block_size +
          flacparse->block_size;
    } else {
      GST_BUFFER_PTS (buffer) =
          gst_util_uint64_scale (relative_sample_number, GST_SECOND,
          flacparse->samplerate);
      GST_BUFFER_OFFSET_END (buffer) =
          relative_sample_number + flacparse->block_size;
    }

    GST_BUFFER_DTS (buffer) = GST_BUFFER_PTS (buffer);
    GST_BUFFER_OFFSET (buffer) =
        gst_util_uint64_scale (GST_BUFFER_OFFSET_END (buffer), GST_SECOND,
        flacparse->samplerate);
    GST_BUFFER_DURATION (buffer) =
        GST_BUFFER_OFFSET (buffer) - GST_BUFFER_PTS (buffer);

    /* To simplify, we just assume that it's a fixed size header and ignore
     * subframe headers. The first could lead us to be off by 88 bits and
     * the second even less, so the total inaccuracy is negligible. */
    frame->overhead = 7;

    /* Minimal size of a frame header */
    gst_base_parse_set_min_frame_size (GST_BASE_PARSE (flacparse), MAX (9,
            flacparse->min_framesize));

    flacparse->offset = -1;
    flacparse->blocking_strategy = 0;
    flacparse->sample_number = 0;
    res = GST_FLOW_OK;
  }

cleanup:
  gst_buffer_unmap (buffer, &map);
  return res;

header_parsing_error:
  GST_ELEMENT_ERROR (flacparse, STREAM, DECODE, (NULL),
      ("Failed to parse headers"));
  goto cleanup;
}

static GstFlowReturn
gst_flac_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
{
  GstFlacParse *flacparse = GST_FLAC_PARSE (parse);

  if (!flacparse->sent_codec_tag) {
    GstCaps *caps;

    if (flacparse->tags == NULL)
      flacparse->tags = gst_tag_list_new_empty ();

    /* 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;
      }
      GST_INFO_OBJECT (parse, "Src pad is not negotiated!");
      return GST_FLOW_NOT_NEGOTIATED;
    }
    gst_pb_utils_add_codec_description_to_tag_list (flacparse->tags,
        GST_TAG_AUDIO_CODEC, caps);
    gst_caps_unref (caps);

    /* Announce our pending tags */
    gst_base_parse_merge_tags (parse, flacparse->tags, GST_TAG_MERGE_REPLACE);

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

  /* Push toc */
  if (flacparse->toc) {
    gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (flacparse),
        gst_event_new_toc (flacparse->toc, FALSE));
  }

  frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP;

  return GST_FLOW_OK;
}

static gboolean
gst_flac_parse_convert (GstBaseParse * parse,
    GstFormat src_format, gint64 src_value, GstFormat dest_format,
    gint64 * dest_value)
{
  GstFlacParse *flacparse = GST_FLAC_PARSE (parse);

  if (flacparse->samplerate > 0) {
    if (src_format == GST_FORMAT_DEFAULT && dest_format == GST_FORMAT_TIME) {
      if (src_value != -1)
        *dest_value =
            gst_util_uint64_scale (src_value, GST_SECOND,
            flacparse->samplerate);
      else
        *dest_value = -1;
      return TRUE;
    } else if (src_format == GST_FORMAT_TIME &&
        dest_format == GST_FORMAT_DEFAULT) {
      if (src_value != -1)
        *dest_value =
            gst_util_uint64_scale (src_value, flacparse->samplerate,
            GST_SECOND);
      else
        *dest_value = -1;
      return TRUE;
    }
  }

  return GST_BASE_PARSE_CLASS (parent_class)->convert (parse, src_format,
      src_value, dest_format, dest_value);
}

static gboolean
gst_flac_parse_src_event (GstBaseParse * parse, GstEvent * event)
{
  GstFlacParse *flacparse = GST_FLAC_PARSE (parse);
  gboolean res = FALSE;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_TOC_SELECT:
    {
      GstTocEntry *entry = NULL;
      GstEvent *seek_event;
      GstToc *toc = NULL;
      gint64 start_pos;
      gchar *uid = NULL;

      /* FIXME: some locking would be good */
      if (flacparse->toc)
        toc = gst_toc_ref (flacparse->toc);

      if (toc != NULL) {
        gst_event_parse_toc_select (event, &uid);
        if (uid != NULL) {
          entry = gst_toc_find_entry (toc, uid);
          if (entry != NULL) {
            gst_toc_entry_get_start_stop_times (entry, &start_pos, NULL);

            /* FIXME: use segment rate here instead? */
            seek_event = gst_event_new_seek (1.0,
                GST_FORMAT_TIME,
                GST_SEEK_FLAG_FLUSH,
                GST_SEEK_TYPE_SET, start_pos, GST_SEEK_TYPE_NONE, -1);

            res =
                GST_BASE_PARSE_CLASS (parent_class)->src_event (parse,
                seek_event);

          } else {
            GST_WARNING_OBJECT (parse, "no TOC entry with given UID: %s", uid);
          }
          g_free (uid);
        }
        gst_toc_unref (toc);
      } else {
        GST_DEBUG_OBJECT (flacparse, "no TOC to select");
      }
      gst_event_unref (event);
      break;
    }
    default:
      res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
      break;
  }
  return res;
}

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, "framed");
  }
}

static GstCaps *
gst_flac_parse_get_sink_caps (GstBaseParse * parse, GstCaps * filter)
{
  GstCaps *peercaps, *templ;
  GstCaps *res;

  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 framed field */
    peercaps = gst_caps_make_writable (peercaps);
    remove_fields (peercaps);

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

  if (filter) {
    GstCaps *intersection;

    intersection =
        gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (res);
    res = intersection;
  }

  return res;
}

static gboolean
gst_flac_parse_set_sink_caps (GstBaseParse * parse, GstCaps * caps)
{
  /* If caps are changing, drain any pending frames we have so that afterwards
   * we can potentially accept a new stream that is starting with the FLAC
   * headers again. If headers appear in the middle of the stream we can't
   * detect them
   */
  gst_base_parse_drain (parse);
  return TRUE;
}
