/* GStreamer CDXA sync strippper / VCD parser
 * Copyright (C) 2004 Ronald Bultje <rbultje@ronald.bitfreak.net>
 * Copyright (C) 2008 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.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>

#include "gstvcdparse.h"

GST_DEBUG_CATEGORY_EXTERN (vcdparse_debug);
#define GST_CAT_DEFAULT vcdparse_debug

static gboolean gst_vcd_parse_sink_event (GstPad * pad, GstEvent * event);
static gboolean gst_vcd_parse_src_event (GstPad * pad, GstEvent * event);
static gboolean gst_vcd_parse_src_query (GstPad * pad, GstQuery * query);
static GstFlowReturn gst_vcd_parse_chain (GstPad * pad, GstBuffer * buf);
static GstStateChangeReturn gst_vcd_parse_change_state (GstElement * element,
    GstStateChange transition);

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

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/mpeg, systemstream = (boolean) TRUE")
    );

GST_BOILERPLATE (GstVcdParse, gst_vcd_parse, GstElement, GST_TYPE_ELEMENT);

static void
gst_vcd_parse_base_init (gpointer klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

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

  gst_element_class_set_static_metadata (element_class, "(S)VCD stream parser",
      "Codec/Parser", "Strip (S)VCD stream from its sync headers",
      "Tim-Philipp Müller <tim centricular net>, "
      "Ronald Bultje <rbultje@ronald.bitfreak.net>");
}

static void
gst_vcd_parse_class_init (GstVcdParseClass * klass)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  element_class->change_state = GST_DEBUG_FUNCPTR (gst_vcd_parse_change_state);
}

static void
gst_vcd_parse_init (GstVcdParse * vcd, GstVcdParseClass * klass)
{
  vcd->sinkpad = gst_pad_new_from_static_template (&sink_factory, "sink");
  gst_pad_set_chain_function (vcd->sinkpad,
      GST_DEBUG_FUNCPTR (gst_vcd_parse_chain));
  gst_pad_set_event_function (vcd->sinkpad,
      GST_DEBUG_FUNCPTR (gst_vcd_parse_sink_event));
  gst_element_add_pad (GST_ELEMENT (vcd), vcd->sinkpad);

  vcd->srcpad = gst_pad_new_from_static_template (&src_factory, "src");
  gst_pad_set_event_function (vcd->srcpad,
      GST_DEBUG_FUNCPTR (gst_vcd_parse_src_event));
  gst_pad_set_query_function (vcd->srcpad,
      GST_DEBUG_FUNCPTR (gst_vcd_parse_src_query));
  gst_pad_use_fixed_caps (vcd->srcpad);
  gst_pad_set_caps (vcd->srcpad,
      gst_static_pad_template_get_caps (&src_factory));
  gst_element_add_pad (GST_ELEMENT (vcd), vcd->srcpad);
}

/* These conversion functions assume there's no junk between sectors */

static gint64
gst_vcd_parse_get_out_offset (gint64 in_offset)
{
  gint64 out_offset, chunknum, rest;

  if (in_offset == -1)
    return -1;

  if (G_UNLIKELY (in_offset < -1)) {
    GST_WARNING ("unexpected/invalid in_offset %" G_GINT64_FORMAT, in_offset);
    return in_offset;
  }

  chunknum = in_offset / GST_CDXA_SECTOR_SIZE;
  rest = in_offset % GST_CDXA_SECTOR_SIZE;

  out_offset = chunknum * GST_CDXA_DATA_SIZE;
  if (rest > GST_CDXA_HEADER_SIZE) {
    if (rest >= GST_CDXA_HEADER_SIZE + GST_CDXA_DATA_SIZE)
      out_offset += GST_CDXA_DATA_SIZE;
    else
      out_offset += rest - GST_CDXA_HEADER_SIZE;
  }

  GST_LOG ("transformed in_offset %" G_GINT64_FORMAT " to out_offset %"
      G_GINT64_FORMAT, in_offset, out_offset);

  return out_offset;
}

static gint64
gst_vcd_parse_get_in_offset (gint64 out_offset)
{
  gint64 in_offset, chunknum, rest;

  if (out_offset == -1)
    return -1;

  if (G_UNLIKELY (out_offset < -1)) {
    GST_WARNING ("unexpected/invalid out_offset %" G_GINT64_FORMAT, out_offset);
    return out_offset;
  }

  chunknum = out_offset / GST_CDXA_DATA_SIZE;
  rest = out_offset % GST_CDXA_DATA_SIZE;

  in_offset = chunknum * GST_CDXA_SECTOR_SIZE;
  if (rest > 0)
    in_offset += GST_CDXA_HEADER_SIZE + rest;

  GST_LOG ("transformed out_offset %" G_GINT64_FORMAT " to in_offset %"
      G_GINT64_FORMAT, out_offset, in_offset);

  return in_offset;
}

static gboolean
gst_vcd_parse_src_query (GstPad * pad, GstQuery * query)
{
  GstVcdParse *vcd = GST_VCD_PARSE (gst_pad_get_parent (pad));
  gboolean res = FALSE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:{
      GstFormat format;
      gint64 dur;

      /* first try upstream */
      if (!gst_pad_query_default (pad, query))
        break;

      /* we can only handle BYTES */
      gst_query_parse_duration (query, &format, &dur);
      if (format != GST_FORMAT_BYTES)
        break;

      gst_query_set_duration (query, GST_FORMAT_BYTES,
          gst_vcd_parse_get_out_offset (dur));

      res = TRUE;
      break;
    }
    case GST_QUERY_POSITION:{
      GstFormat format;
      gint64 pos;

      /* first try upstream */
      if (!gst_pad_query_default (pad, query))
        break;

      /* we can only handle BYTES */
      gst_query_parse_position (query, &format, &pos);
      if (format != GST_FORMAT_BYTES)
        break;

      gst_query_set_position (query, GST_FORMAT_BYTES,
          gst_vcd_parse_get_out_offset (pos));

      res = TRUE;
      break;
    }
    default:
      res = gst_pad_query_default (pad, query);
      break;
  }

  gst_object_unref (vcd);
  return res;
}

static gboolean
gst_vcd_parse_sink_event (GstPad * pad, GstEvent * event)
{
  GstVcdParse *vcd = GST_VCD_PARSE (gst_pad_get_parent (pad));
  gboolean res;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_NEWSEGMENT:{
      GstFormat format;
      gboolean update;
      gdouble rate, applied_rate;
      gint64 start, stop, position;

      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
          &format, &start, &stop, &position);

      if (format == GST_FORMAT_BYTES) {
        gst_event_unref (event);
        event = gst_event_new_new_segment_full (update, rate, applied_rate,
            GST_FORMAT_BYTES, gst_vcd_parse_get_out_offset (start),
            gst_vcd_parse_get_out_offset (stop), position);
      } else {
        GST_WARNING_OBJECT (vcd, "newsegment event in non-byte format");
      }
      res = gst_pad_event_default (pad, event);
      break;
    }
    case GST_EVENT_FLUSH_START:
      gst_adapter_clear (vcd->adapter);
      /* fall through */
    default:
      res = gst_pad_event_default (pad, event);
      break;
  }

  gst_object_unref (vcd);
  return res;
}

static gboolean
gst_vcd_parse_src_event (GstPad * pad, GstEvent * event)
{
  GstVcdParse *vcd = GST_VCD_PARSE (gst_pad_get_parent (pad));
  gboolean res;

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:{
      GstSeekType start_type, stop_type;
      GstSeekFlags flags;
      GstFormat format;
      gdouble rate;
      gint64 start, stop;

      gst_event_parse_seek (event, &rate, &format, &flags, &start_type,
          &start, &stop_type, &stop);

      if (format == GST_FORMAT_BYTES) {
        gst_event_unref (event);
        if (start_type != GST_SEEK_TYPE_NONE)
          start = gst_vcd_parse_get_in_offset (start);
        if (stop_type != GST_SEEK_TYPE_NONE)
          stop = gst_vcd_parse_get_in_offset (stop);
        event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, start_type,
            start, stop_type, stop);
      } else {
        GST_WARNING_OBJECT (vcd, "seek event in non-byte format");
      }
      res = gst_pad_event_default (pad, event);
      break;
    }
    default:
      res = gst_pad_event_default (pad, event);
      break;
  }

  gst_object_unref (vcd);
  return res;
}

/* -1 = no sync (discard buffer),
 * otherwise offset indicates sync point in buffer */
static gint
gst_vcd_parse_sync (const guint8 * data, guint size)
{
  const guint8 sync_marker[12] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00
  };
  guint off = 0;

  while (size >= 12) {
    if (memcmp (data, sync_marker, 12) == 0)
      return off;

    --size;
    ++data;
    ++off;
  }
  return -1;
}

static GstFlowReturn
gst_vcd_parse_chain (GstPad * pad, GstBuffer * buf)
{
  GstVcdParse *vcd = GST_VCD_PARSE (GST_PAD_PARENT (pad));
  GstFlowReturn flow = GST_FLOW_OK;

  gst_adapter_push (vcd->adapter, buf);
  buf = NULL;

  while (gst_adapter_available (vcd->adapter) >= GST_CDXA_SECTOR_SIZE) {
    const guint8 *data;
    guint8 header[4 + 8];
    gint sync_offset;

    /* find sync (we could peek any size though really) */
    data = gst_adapter_peek (vcd->adapter, GST_CDXA_SECTOR_SIZE);
    sync_offset = gst_vcd_parse_sync (data, GST_CDXA_SECTOR_SIZE);
    GST_LOG_OBJECT (vcd, "sync offset = %d", sync_offset);

    if (sync_offset < 0) {
      gst_adapter_flush (vcd->adapter, GST_CDXA_SECTOR_SIZE - 12);
      continue;                 /* try again */
    }

    gst_adapter_flush (vcd->adapter, sync_offset);

    if (gst_adapter_available (vcd->adapter) < GST_CDXA_SECTOR_SIZE) {
      GST_LOG_OBJECT (vcd, "not enough data in adapter, waiting for more");
      break;
    }

    GST_LOG_OBJECT (vcd, "have full sector");

    /* have one sector: a sector is 2352 bytes long and is composed of:
     *
     * +-------------------------------------------------------+
     * !  sync    !  header ! subheader ! data ...   ! edc     !
     * ! 12 bytes ! 4 bytes ! 8 bytes   ! 2324 bytes ! 4 bytes !
     * +-------------------------------------------------------+
     * 
     * We strip the data out of it and send it to the srcpad.
     * 
     * sync       : 00 FF FF FF FF FF FF FF FF FF FF 00
     * header     : hour minute second mode
     * sub-header : track channel sub_mode coding repeat (4 bytes)
     * edc        : checksum
     */

    /* Skip CDXA header and edc footer, only keep data in the middle */
    gst_adapter_copy (vcd->adapter, header, 12, sizeof (header));
    gst_adapter_flush (vcd->adapter, GST_CDXA_HEADER_SIZE);
    buf = gst_adapter_take_buffer (vcd->adapter, GST_CDXA_DATA_SIZE);
    gst_adapter_flush (vcd->adapter, 4);

    /* we could probably do something clever to keep track of buffer offsets */
    buf = gst_buffer_make_metadata_writable (buf);
    GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
    GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
    gst_buffer_set_caps (buf, GST_PAD_CAPS (vcd->srcpad));

    flow = gst_pad_push (vcd->srcpad, buf);
    buf = NULL;

    if (G_UNLIKELY (flow != GST_FLOW_OK)) {
      GST_DEBUG_OBJECT (vcd, "flow: %s", gst_flow_get_name (flow));
      break;
    }
  }

  return flow;
}

static GstStateChangeReturn
gst_vcd_parse_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn res = GST_STATE_CHANGE_SUCCESS;
  GstVcdParse *vcd = GST_VCD_PARSE (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      vcd->adapter = gst_adapter_new ();
      break;
    default:
      break;
  }

  res = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
    case GST_STATE_CHANGE_READY_TO_NULL:
      if (vcd->adapter) {
        g_object_unref (vcd->adapter);
        vcd->adapter = NULL;
      }
      break;
    default:
      break;
  }

  return res;
}
