/* 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);

#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);

  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;
    goto cleanup;
  }

  if ((GST_READ_UINT16_BE (map.data) & 0xfffe) == 0xfff8) {
    gboolean ret;
    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) {
      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;

  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;
    }

    /* 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 */
    if (flacparse->blocking_strategy == 0) {
      GST_BUFFER_PTS (buffer) =
          gst_util_uint64_scale (flacparse->sample_number,
          flacparse->block_size * GST_SECOND, flacparse->samplerate);
      GST_BUFFER_OFFSET_END (buffer) =
          flacparse->sample_number * flacparse->block_size +
          flacparse->block_size;
    } else {
      GST_BUFFER_PTS (buffer) =
          gst_util_uint64_scale (flacparse->sample_number, GST_SECOND,
          flacparse->samplerate);
      GST_BUFFER_OFFSET_END (buffer) =
          flacparse->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;
}
