/* GStreamer DCA parser
 * Copyright (C) 2010 Tim-Philipp Müller <tim centricular net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:element-dcaparse
 * @short_description: DCA (DTS Coherent Acoustics) parser
 * @see_also: #GstAmrParse, #GstAACParse, #GstAc3Parse
 *
 * This is a DCA (DTS Coherent Acoustics) parser.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 filesrc location=abc.dts ! dcaparse ! dtsdec ! audioresample ! audioconvert ! autoaudiosink
 * ]|
 * </refsect2>
 */

/* TODO:
 *  - should accept framed and unframed input (needs decodebin fixes first)
 *  - seeking in raw .dts files doesn't seem to work, but duration estimate ok
 *
 *  - if frames have 'odd' durations, the frame durations (plus timestamps)
 *    aren't adjusted up occasionally to make up for rounding error gaps.
 *    (e.g. if 512 samples per frame @ 48kHz = 10.666666667 ms/frame)
 */

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

#include <string.h>

#include "gstdcaparse.h"
#include <gst/base/base.h>
#include <gst/pbutils/pbutils.h>

GST_DEBUG_CATEGORY_STATIC (dca_parse_debug);
#define GST_CAT_DEFAULT dca_parse_debug

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-dts,"
        " framed = (boolean) true,"
        " channels = (int) [ 1, 8 ],"
        " rate = (int) [ 8000, 192000 ],"
        " depth = (int) { 14, 16 },"
        " endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, "
        " block-size = (int) [ 1, MAX], " " frame-size = (int) [ 1, MAX]"));

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-dts; " "audio/x-private1-dts"));

static void gst_dca_parse_finalize (GObject * object);

static gboolean gst_dca_parse_start (GstBaseParse * parse);
static gboolean gst_dca_parse_stop (GstBaseParse * parse);
static GstFlowReturn gst_dca_parse_handle_frame (GstBaseParse * parse,
    GstBaseParseFrame * frame, gint * skipsize);
static GstFlowReturn gst_dca_parse_pre_push_frame (GstBaseParse * parse,
    GstBaseParseFrame * frame);
static GstCaps *gst_dca_parse_get_sink_caps (GstBaseParse * parse,
    GstCaps * filter);
static gboolean gst_dca_parse_set_sink_caps (GstBaseParse * parse,
    GstCaps * caps);

#define gst_dca_parse_parent_class parent_class
G_DEFINE_TYPE (GstDcaParse, gst_dca_parse, GST_TYPE_BASE_PARSE);

static void
gst_dca_parse_class_init (GstDcaParseClass * klass)
{
  GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (dca_parse_debug, "dcaparse", 0,
      "DCA audio stream parser");

  object_class->finalize = gst_dca_parse_finalize;

  parse_class->start = GST_DEBUG_FUNCPTR (gst_dca_parse_start);
  parse_class->stop = GST_DEBUG_FUNCPTR (gst_dca_parse_stop);
  parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_dca_parse_handle_frame);
  parse_class->pre_push_frame =
      GST_DEBUG_FUNCPTR (gst_dca_parse_pre_push_frame);
  parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_dca_parse_get_sink_caps);
  parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_dca_parse_set_sink_caps);

  gst_element_class_add_static_pad_template (element_class, &sink_template);
  gst_element_class_add_static_pad_template (element_class, &src_template);

  gst_element_class_set_static_metadata (element_class,
      "DTS Coherent Acoustics audio stream parser", "Codec/Parser/Audio",
      "DCA parser", "Tim-Philipp Müller <tim centricular net>");
}

static void
gst_dca_parse_reset (GstDcaParse * dcaparse)
{
  dcaparse->channels = -1;
  dcaparse->rate = -1;
  dcaparse->depth = -1;
  dcaparse->endianness = -1;
  dcaparse->block_size = -1;
  dcaparse->frame_size = -1;
  dcaparse->last_sync = 0;
  dcaparse->sent_codec_tag = FALSE;
}

static void
gst_dca_parse_init (GstDcaParse * dcaparse)
{
  gst_base_parse_set_min_frame_size (GST_BASE_PARSE (dcaparse),
      DCA_MIN_FRAMESIZE);
  gst_dca_parse_reset (dcaparse);
  dcaparse->baseparse_chainfunc =
      GST_BASE_PARSE_SINK_PAD (GST_BASE_PARSE (dcaparse))->chainfunc;

  GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (dcaparse));
  GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (dcaparse));
}

static void
gst_dca_parse_finalize (GObject * object)
{
  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static gboolean
gst_dca_parse_start (GstBaseParse * parse)
{
  GstDcaParse *dcaparse = GST_DCA_PARSE (parse);

  GST_DEBUG_OBJECT (parse, "starting");

  gst_dca_parse_reset (dcaparse);

  return TRUE;
}

static gboolean
gst_dca_parse_stop (GstBaseParse * parse)
{
  GST_DEBUG_OBJECT (parse, "stopping");

  return TRUE;
}

static gboolean
gst_dca_parse_parse_header (GstDcaParse * dcaparse,
    const GstByteReader * reader, guint * frame_size,
    guint * sample_rate, guint * channels, guint * depth,
    gint * endianness, guint * num_blocks, guint * samples_per_block,
    gboolean * terminator)
{
  static const int sample_rates[16] = { 0, 8000, 16000, 32000, 0, 0, 11025,
    22050, 44100, 0, 0, 12000, 24000, 48000, 96000, 192000
  };
  static const guint8 channels_table[16] = { 1, 2, 2, 2, 2, 3, 3, 4, 4, 5,
    6, 6, 6, 7, 8, 8
  };
  GstByteReader r = *reader;
  guint16 hdr[8];
  guint32 marker;
  guint chans, lfe, i;

  if (gst_byte_reader_get_remaining (&r) < (4 + sizeof (hdr)))
    return FALSE;

  marker = gst_byte_reader_peek_uint32_be_unchecked (&r);

  /* raw big endian or 14-bit big endian */
  if (marker == 0x7FFE8001 || marker == 0x1FFFE800) {
    for (i = 0; i < G_N_ELEMENTS (hdr); ++i)
      hdr[i] = gst_byte_reader_get_uint16_be_unchecked (&r);
  } else
    /* raw little endian or 14-bit little endian */
  if (marker == 0xFE7F0180 || marker == 0xFF1F00E8) {
    for (i = 0; i < G_N_ELEMENTS (hdr); ++i)
      hdr[i] = gst_byte_reader_get_uint16_le_unchecked (&r);
  } else {
    return FALSE;
  }

  GST_LOG_OBJECT (dcaparse, "dts sync marker 0x%08x at offset %u", marker,
      gst_byte_reader_get_pos (reader));

  /* 14-bit mode */
  if (marker == 0x1FFFE800 || marker == 0xFF1F00E8) {
    if ((hdr[2] & 0xFFF0) != 0x07F0)
      return FALSE;
    /* discard top 2 bits (2 void), shift in 2 */
    hdr[0] = (hdr[0] << 2) | ((hdr[1] >> 12) & 0x0003);
    /* discard top 4 bits (2 void, 2 shifted into hdr[0]), shift in 4 etc. */
    hdr[1] = (hdr[1] << 4) | ((hdr[2] >> 10) & 0x000F);
    hdr[2] = (hdr[2] << 6) | ((hdr[3] >> 8) & 0x003F);
    hdr[3] = (hdr[3] << 8) | ((hdr[4] >> 6) & 0x00FF);
    hdr[4] = (hdr[4] << 10) | ((hdr[5] >> 4) & 0x03FF);
    hdr[5] = (hdr[5] << 12) | ((hdr[6] >> 2) & 0x0FFF);
    hdr[6] = (hdr[6] << 14) | ((hdr[7] >> 0) & 0x3FFF);
    g_assert (hdr[0] == 0x7FFE && hdr[1] == 0x8001);
  }

  GST_LOG_OBJECT (dcaparse, "frame header: %04x%04x%04x%04x",
      hdr[2], hdr[3], hdr[4], hdr[5]);

  *terminator = (hdr[2] & 0x80) ? FALSE : TRUE;
  *samples_per_block = ((hdr[2] >> 10) & 0x1f) + 1;
  *num_blocks = ((hdr[2] >> 2) & 0x7F) + 1;
  *frame_size = (((hdr[2] & 0x03) << 12) | (hdr[3] >> 4)) + 1;
  chans = ((hdr[3] & 0x0F) << 2) | (hdr[4] >> 14);
  *sample_rate = sample_rates[(hdr[4] >> 10) & 0x0F];
  lfe = (hdr[5] >> 9) & 0x03;

  GST_TRACE_OBJECT (dcaparse, "frame size %u, num_blocks %u, rate %u, "
      "samples per block %u", *frame_size, *num_blocks, *sample_rate,
      *samples_per_block);

  if (*num_blocks < 6 || *frame_size < 96 || *sample_rate == 0)
    return FALSE;

  if (marker == 0x1FFFE800 || marker == 0xFF1F00E8)
    *frame_size = (*frame_size * 16) / 14;      /* FIXME: round up? */

  if (chans < G_N_ELEMENTS (channels_table))
    *channels = channels_table[chans] + ((lfe) ? 1 : 0);
  else
    return FALSE;

  if (depth)
    *depth = (marker == 0x1FFFE800 || marker == 0xFF1F00E8) ? 14 : 16;
  if (endianness)
    *endianness = (marker == 0xFE7F0180 || marker == 0xFF1F00E8) ?
        G_LITTLE_ENDIAN : G_BIG_ENDIAN;

  GST_TRACE_OBJECT (dcaparse, "frame size %u, channels %u, rate %u, "
      "num_blocks %u, samples_per_block %u", *frame_size, *channels,
      *sample_rate, *num_blocks, *samples_per_block);

  return TRUE;
}

static gint
gst_dca_parse_find_sync (GstDcaParse * dcaparse, GstByteReader * reader,
    gsize bufsize, guint32 * sync)
{
  guint32 best_sync = 0;
  guint best_offset = G_MAXUINT;
  gint off;

  /* FIXME: verify syncs via _parse_header() here already */

  /* Raw little endian */
  off = gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0xfe7f0180,
      0, bufsize);
  if (off >= 0 && off < best_offset) {
    best_offset = off;
    best_sync = 0xfe7f0180;
  }

  /* Raw big endian */
  off = gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x7ffe8001,
      0, bufsize);
  if (off >= 0 && off < best_offset) {
    best_offset = off;
    best_sync = 0x7ffe8001;
  }

  /* FIXME: check next 2 bytes as well for 14-bit formats (but then don't
   * forget to adjust the *skipsize= in _check_valid_frame() */

  /* 14-bit little endian  */
  off = gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0xff1f00e8,
      0, bufsize);
  if (off >= 0 && off < best_offset) {
    best_offset = off;
    best_sync = 0xff1f00e8;
  }

  /* 14-bit big endian  */
  off = gst_byte_reader_masked_scan_uint32 (reader, 0xffffffff, 0x1fffe800,
      0, bufsize);
  if (off >= 0 && off < best_offset) {
    best_offset = off;
    best_sync = 0x1fffe800;
  }

  if (best_offset == G_MAXUINT)
    return -1;

  *sync = best_sync;
  return best_offset;
}

static GstFlowReturn
gst_dca_parse_handle_frame (GstBaseParse * parse,
    GstBaseParseFrame * frame, gint * skipsize)
{
  GstDcaParse *dcaparse = GST_DCA_PARSE (parse);
  GstBuffer *buf = frame->buffer;
  GstByteReader r;
  gboolean parser_in_sync;
  gboolean terminator;
  guint32 sync = 0;
  guint size = 0, rate, chans, num_blocks, samples_per_block, depth;
  gint block_size;
  gint endianness;
  gint off = -1;
  GstMapInfo map;
  GstFlowReturn ret = GST_FLOW_EOS;
  gsize extra_size = 0;

  gst_buffer_map (buf, &map, GST_MAP_READ);

  if (G_UNLIKELY (map.size < 16)) {
    *skipsize = 1;
    goto cleanup;
  }

  parser_in_sync = !GST_BASE_PARSE_LOST_SYNC (parse);

  gst_byte_reader_init (&r, map.data, map.size);

  if (G_LIKELY (parser_in_sync && dcaparse->last_sync != 0)) {
    off = gst_byte_reader_masked_scan_uint32 (&r, 0xffffffff,
        dcaparse->last_sync, 0, map.size);
  }

  if (G_UNLIKELY (off < 0)) {
    off = gst_dca_parse_find_sync (dcaparse, &r, map.size, &sync);
  }

  /* didn't find anything that looks like a sync word, skip */
  if (off < 0) {
    *skipsize = map.size - 3;
    GST_DEBUG_OBJECT (dcaparse, "no sync, skipping %d bytes", *skipsize);
    goto cleanup;
  }

  GST_LOG_OBJECT (parse, "possible sync %08x at buffer offset %d", sync, off);

  /* possible frame header, but not at offset 0? skip bytes before sync */
  if (off > 0) {
    *skipsize = off;
    goto cleanup;
  }

  /* make sure the values in the frame header look sane */
  if (!gst_dca_parse_parse_header (dcaparse, &r, &size, &rate, &chans, &depth,
          &endianness, &num_blocks, &samples_per_block, &terminator)) {
    *skipsize = 4;
    goto cleanup;
  }

  GST_LOG_OBJECT (parse, "got frame, sync %08x, size %u, rate %d, channels %d",
      sync, size, rate, chans);

  dcaparse->last_sync = sync;

  /* FIXME: Don't look for a second syncword, there are streams out there
   * that consistently contain garbage between every frame so we never ever
   * find a second consecutive syncword.
   * See https://bugzilla.gnome.org/show_bug.cgi?id=738237
   */
#if 0
  parser_draining = GST_BASE_PARSE_DRAINING (parse);

  if (!parser_in_sync && !parser_draining) {
    /* check for second frame to be sure */
    GST_DEBUG_OBJECT (dcaparse, "resyncing; checking next frame syncword");
    if (map.size >= (size + 16)) {
      guint s2, r2, c2, n2, s3;
      gboolean t;

      GST_MEMDUMP ("buf", map.data, size + 16);
      gst_byte_reader_init (&r, map.data, map.size);
      gst_byte_reader_skip_unchecked (&r, size);

      if (!gst_dca_parse_parse_header (dcaparse, &r, &s2, &r2, &c2, NULL, NULL,
              &n2, &s3, &t)) {
        GST_DEBUG_OBJECT (dcaparse, "didn't find second syncword");
        *skipsize = 4;
        goto cleanup;
      }

      /* ok, got sync now, let's assume constant frame size */
      gst_base_parse_set_min_frame_size (parse, size);
    } else {
      /* wait for some more data */
      GST_LOG_OBJECT (dcaparse,
          "next sync out of reach (%" G_GSIZE_FORMAT " < %u)", map.size,
          size + 16);
      goto cleanup;
    }
  }
#endif

  /* found frame */
  ret = GST_FLOW_OK;

  /* metadata handling */
  block_size = num_blocks * samples_per_block;

  if (G_UNLIKELY (dcaparse->rate != rate || dcaparse->channels != chans
          || dcaparse->depth != depth || dcaparse->endianness != endianness
          || (!terminator && dcaparse->block_size != block_size)
          || (size != dcaparse->frame_size))) {
    GstCaps *caps;

    caps = gst_caps_new_simple ("audio/x-dts",
        "framed", G_TYPE_BOOLEAN, TRUE,
        "rate", G_TYPE_INT, rate, "channels", G_TYPE_INT, chans,
        "endianness", G_TYPE_INT, endianness, "depth", G_TYPE_INT, depth,
        "block-size", G_TYPE_INT, block_size, "frame-size", G_TYPE_INT, size,
        NULL);
    gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (parse), caps);
    gst_caps_unref (caps);

    dcaparse->rate = rate;
    dcaparse->channels = chans;
    dcaparse->depth = depth;
    dcaparse->endianness = endianness;
    dcaparse->block_size = block_size;
    dcaparse->frame_size = size;

    gst_base_parse_set_frame_rate (parse, rate, block_size, 0, 0);
  }

cleanup:
  /* it is possible that DTS HD substream after DTS core */
  if (parse->flags & GST_BASE_PARSE_FLAG_DRAINING || map.size >= size + 9) {
    extra_size = 0;
    if (map.size >= size + 9) {
      const guint8 *next = map.data + size;
      /* Check for DTS_SYNCWORD_SUBSTREAM */
      if (next[0] == 0x64 && next[1] == 0x58 && next[2] == 0x20
          && next[3] == 0x25) {
        /* 7.4.1 Extension Substream Header */
        GstBitReader reader;
        gst_bit_reader_init (&reader, next + 4, 5);
        gst_bit_reader_skip (&reader, 8 + 2);   /* skip UserDefinedBits and nExtSSIndex) */
        if (gst_bit_reader_get_bits_uint8_unchecked (&reader, 1) == 0) {
          gst_bit_reader_skip (&reader, 8);
          extra_size =
              gst_bit_reader_get_bits_uint32_unchecked (&reader, 16) + 1;
        } else {
          gst_bit_reader_skip (&reader, 12);
          extra_size =
              gst_bit_reader_get_bits_uint32_unchecked (&reader, 20) + 1;
        }
      }
    }
    gst_buffer_unmap (buf, &map);
    if (ret == GST_FLOW_OK && size + extra_size <= map.size) {
      ret = gst_base_parse_finish_frame (parse, frame, size + extra_size);
    } else {
      ret = GST_FLOW_OK;
    }
  } else {
    gst_buffer_unmap (buf, &map);
  }

  return ret;
}

/*
 * MPEG-PS private1 streams add a 2 bytes "Audio Substream Headers" for each
 * buffer (not each frame) with the offset of the next frame's start.
 * These 2 bytes can be dropped safely as they do not include any timing
 * information, only the offset to the start of the next frame.
 * See gstac3parse.c for a more detailed description.
 * */

static GstFlowReturn
gst_dca_parse_chain_priv (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstDcaParse *dcaparse = GST_DCA_PARSE (parent);
  GstFlowReturn ret;
  GstBuffer *newbuf;
  gsize size;

  size = gst_buffer_get_size (buffer);
  if (size >= 2) {
    newbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 2, size - 2);
    gst_buffer_unref (buffer);
    ret = dcaparse->baseparse_chainfunc (pad, parent, newbuf);
  } else {
    gst_buffer_unref (buffer);
    ret = GST_FLOW_OK;
  }

  return ret;
}

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_dca_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_dca_parse_set_sink_caps (GstBaseParse * parse, GstCaps * caps)
{
  GstStructure *s;
  GstDcaParse *dcaparse = GST_DCA_PARSE (parse);

  s = gst_caps_get_structure (caps, 0);
  if (gst_structure_has_name (s, "audio/x-private1-dts")) {
    gst_pad_set_chain_function (parse->sinkpad, gst_dca_parse_chain_priv);
  } else {
    gst_pad_set_chain_function (parse->sinkpad, dcaparse->baseparse_chainfunc);
  }
  return TRUE;
}

static GstFlowReturn
gst_dca_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
{
  GstDcaParse *dcaparse = GST_DCA_PARSE (parse);

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

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

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

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

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

  return GST_FLOW_OK;
}
