/*
 * GStreamer
 * Copyright (C) 2009 Sebastian Pölsterl <sebp@k-d-w.org>
 * Copyright (C) 2010 Andoni Morales Alastruey <ylatuya@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

/**
 * SECTION:element-teletextdec
 * @title: teletextdec
 *
 * Decode a stream of raw VBI packets containing teletext information to a RGBA
 * stream.
 *
 * ## Example launch line
 * |[
 * gst-launch-1.0 -v -m filesrc location=recording.mpeg ! tsdemux ! teletextdec ! videoconvert ! ximagesink
 * ]|
 *
 */

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

#include <gst/gst.h>
#include <gst/video/video.h>
#include <string.h>
#include <stdlib.h>

#include "gstteletextdec.h"

GST_DEBUG_CATEGORY_STATIC (gst_teletextdec_debug);
#define GST_CAT_DEFAULT gst_teletextdec_debug

#define parent_class gst_teletextdec_parent_class

#define SUBTITLES_PAGE 888
#define MAX_SLICES 32
#define DEFAULT_FONT_DESCRIPTION "verdana 12"
#define PANGO_TEMPLATE "<span font_desc=\"%s\" foreground=\"%s\"> %s \n</span>"

/* Filter signals and args */
enum
{
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_PAGENO,
  PROP_SUBNO,
  PROP_SUBTITLES_MODE,
  PROP_SUBS_TEMPLATE,
  PROP_FONT_DESCRIPTION
};

enum
{
  VBI_ERROR = -1,
  VBI_SUCCESS = 0,
  VBI_NEW_FRAME = 1
};

typedef enum
{
  DATA_UNIT_EBU_TELETEXT_NON_SUBTITLE = 0x02,
  DATA_UNIT_EBU_TELETEXT_SUBTITLE = 0x03,
  DATA_UNIT_EBU_TELETEXT_INVERTED = 0x0C,

  DATA_UNIT_ZVBI_WSS_CPR1204 = 0xB4,
  DATA_UNIT_ZVBI_CLOSED_CAPTION_525 = 0xB5,
  DATA_UNIT_ZVBI_MONOCHROME_SAMPLES_525 = 0xB6,

  DATA_UNIT_VPS = 0xC3,
  DATA_UNIT_WSS = 0xC4,
  DATA_UNIT_CLOSED_CAPTION = 0xC5,
  DATA_UNIT_MONOCHROME_SAMPLES = 0xC6,

  DATA_UNIT_STUFFING = 0xFF,
} data_unit_id;

typedef struct
{
  int pgno;
  int subno;
} page_info;

typedef enum
{
  SYSTEM_525 = 0,
  SYSTEM_625
} systems;

/*
 *  ETS 300 706 Table 30: Colour Map
 */
static const gchar *default_color_map[40] = {
  "#000000", "#FF0000", "#00FF00", "#FFFF00", "#0000FF",
  "#FF00FF", "#00FFFF", "#FFFFFF", "#000000", "#770000",
  "#007700", "#777700", "#000077", "#770077", "#007777",
  "#777777", "#FF0055", "#FF7700", "#00FF77", "#FFFFBB",
  "#00CCAA", "#550000", "#665522", "#CC7777", "#333333",
  "#FF7777", "#77FF77", "#FFFF77", "#7777FF", "#FF77FF",
  "#77FFFF", "#DDD0DD",

  /* Private colors */
  "#000000", "#FFAA99", "#44EE00", "#FFDD00", "#FFAA99",
  "#FF00FF", "#00FFFF", "#EEEEEE"
};

/* in RGBA mode, one character occupies 12 x 10 pixels. */
#define COLUMNS_TO_WIDTH(cols) ((cols) * 12)
#define ROWS_TO_HEIGHT(rows) ((rows) * 10)

static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-teletext;")
    );

static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS
    (GST_VIDEO_CAPS_MAKE ("RGBA") ";"
        "text/x-raw, format={utf-8,pango-markup} ;")
    );

G_DEFINE_TYPE (GstTeletextDec, gst_teletextdec, GST_TYPE_ELEMENT);

static void gst_teletextdec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_teletextdec_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_teletextdec_finalize (GObject * object);

static GstStateChangeReturn gst_teletextdec_change_state (GstElement *
    element, GstStateChange transition);

static GstFlowReturn gst_teletextdec_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static gboolean gst_teletextdec_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_teletextdec_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);

static void gst_teletextdec_event_handler (vbi_event * ev, void *user_data);

static GstFlowReturn gst_teletextdec_push_page (GstTeletextDec * teletext);
static GstFlowReturn gst_teletextdec_export_text_page (GstTeletextDec *
    teletext, vbi_page * page, GstBuffer ** buf);
static GstFlowReturn gst_teletextdec_export_rgba_page (GstTeletextDec *
    teletext, vbi_page * page, GstBuffer ** buf);
static GstFlowReturn gst_teletextdec_export_pango_page (GstTeletextDec *
    teletext, vbi_page * page, GstBuffer ** buf);

static void gst_teletextdec_process_telx_buffer (GstTeletextDec * teletext,
    GstBuffer * buf);
static gboolean gst_teletextdec_extract_data_units (GstTeletextDec *
    teletext, GstTeletextFrame * f, const guint8 * packet, guint * offset,
    gsize size);

static void gst_teletextdec_zvbi_init (GstTeletextDec * teletext);
static void gst_teletextdec_zvbi_clear (GstTeletextDec * teletext);
static void gst_teletextdec_reset_frame (GstTeletextDec * teletext);

/* initialize the gstteletext's class */
static void
gst_teletextdec_class_init (GstTeletextDecClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->set_property = gst_teletextdec_set_property;
  gobject_class->get_property = gst_teletextdec_get_property;
  gobject_class->finalize = gst_teletextdec_finalize;

  gstelement_class = GST_ELEMENT_CLASS (klass);
  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_teletextdec_change_state);

  g_object_class_install_property (gobject_class, PROP_PAGENO,
      g_param_spec_int ("page", "Page number",
          "Number of page that should displayed",
          100, 999, 100, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_SUBNO,
      g_param_spec_int ("subpage", "Sub-page number",
          "Number of sub-page that should displayed (-1 for all)",
          -1, 0x99, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_SUBTITLES_MODE,
      g_param_spec_boolean ("subtitles-mode", "Enable subtitles mode",
          "Enables subtitles mode for text output stripping the blank lines and "
          "the teletext state lines", FALSE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_SUBS_TEMPLATE,
      g_param_spec_string ("subtitles-template", "Subtitles output template",
          "Output template used to print each one of the subtitles lines",
          g_strescape ("%s\n", NULL),
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_FONT_DESCRIPTION,
      g_param_spec_string ("font-description", "Pango font description",
          "Font description used for the pango output.",
          DEFAULT_FONT_DESCRIPTION,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_static_metadata (gstelement_class,
      "Teletext decoder",
      "Decoder",
      "Decode a raw VBI stream containing teletext information to RGBA and text",
      "Sebastian Pölsterl <sebp@k-d-w.org>, "
      "Andoni Morales Alastruey <ylatuya@gmail.com>");

  gst_element_class_add_static_pad_template (gstelement_class, &src_template);
  gst_element_class_add_static_pad_template (gstelement_class, &sink_template);
}

/* initialize the new element
 * initialize instance structure
 */
static void
gst_teletextdec_init (GstTeletextDec * teletext)
{
  /* Create sink pad */
  teletext->sinkpad = gst_pad_new_from_static_template (&sink_template, "sink");
  gst_pad_set_chain_function (teletext->sinkpad,
      GST_DEBUG_FUNCPTR (gst_teletextdec_chain));
  gst_pad_set_event_function (teletext->sinkpad,
      GST_DEBUG_FUNCPTR (gst_teletextdec_sink_event));
  gst_element_add_pad (GST_ELEMENT (teletext), teletext->sinkpad);

  /* Create src pad */
  teletext->srcpad = gst_pad_new_from_static_template (&src_template, "src");
  gst_pad_set_event_function (teletext->srcpad,
      GST_DEBUG_FUNCPTR (gst_teletextdec_src_event));
  gst_element_add_pad (GST_ELEMENT (teletext), teletext->srcpad);

  teletext->segment = NULL;
  teletext->decoder = NULL;
  teletext->pageno = 0x100;
  teletext->subno = -1;
  teletext->subtitles_mode = FALSE;
  teletext->subtitles_template = g_strescape ("%s\n", NULL);
  teletext->font_description = g_strdup (DEFAULT_FONT_DESCRIPTION);

  teletext->in_timestamp = GST_CLOCK_TIME_NONE;
  teletext->in_duration = GST_CLOCK_TIME_NONE;

  teletext->rate_numerator = 0;
  teletext->rate_denominator = 1;

  teletext->queue = NULL;
  g_mutex_init (&teletext->queue_lock);

  gst_teletextdec_reset_frame (teletext);

  teletext->last_ts = 0;

  teletext->export_func = NULL;
  teletext->buf_pool = NULL;
}

static void
gst_teletextdec_finalize (GObject * object)
{
  GstTeletextDec *teletext = GST_TELETEXTDEC (object);

  g_mutex_clear (&teletext->queue_lock);

  g_free (teletext->frame);

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

static void
gst_teletextdec_zvbi_init (GstTeletextDec * teletext)
{
  g_return_if_fail (teletext != NULL);

  GST_LOG_OBJECT (teletext, "Initializing structures");

  teletext->decoder = vbi_decoder_new ();

  vbi_event_handler_register (teletext->decoder,
      VBI_EVENT_TTX_PAGE | VBI_EVENT_CAPTION,
      gst_teletextdec_event_handler, teletext);

  g_mutex_lock (&teletext->queue_lock);
  teletext->queue = g_queue_new ();
  g_mutex_unlock (&teletext->queue_lock);
}

static void
gst_teletextdec_zvbi_clear (GstTeletextDec * teletext)
{
  g_return_if_fail (teletext != NULL);

  GST_LOG_OBJECT (teletext, "Clearing structures");

  if (teletext->decoder != NULL) {
    vbi_decoder_delete (teletext->decoder);
    teletext->decoder = NULL;
  }
  if (teletext->frame != NULL) {
    if (teletext->frame->sliced_begin)
      g_free (teletext->frame->sliced_begin);
    g_free (teletext->frame);
    teletext->frame = NULL;
  }

  g_mutex_lock (&teletext->queue_lock);
  if (teletext->queue != NULL) {
    g_queue_free (teletext->queue);
    teletext->queue = NULL;
  }
  g_mutex_unlock (&teletext->queue_lock);

  teletext->in_timestamp = GST_CLOCK_TIME_NONE;
  teletext->in_duration = GST_CLOCK_TIME_NONE;
  teletext->pageno = 0x100;
  teletext->subno = -1;
  teletext->last_ts = 0;
}

static void
gst_teletextdec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstTeletextDec *teletext = GST_TELETEXTDEC (object);

  switch (prop_id) {
    case PROP_PAGENO:
      teletext->pageno = (gint) vbi_bin2bcd (g_value_get_int (value));
      break;
    case PROP_SUBNO:
      teletext->subno = g_value_get_int (value);
      break;
    case PROP_SUBTITLES_MODE:
      teletext->subtitles_mode = g_value_get_boolean (value);
      break;
    case PROP_SUBS_TEMPLATE:
      teletext->subtitles_template = g_value_dup_string (value);
      break;
    case PROP_FONT_DESCRIPTION:
      teletext->font_description = g_value_dup_string (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_teletextdec_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstTeletextDec *teletext = GST_TELETEXTDEC (object);

  switch (prop_id) {
    case PROP_PAGENO:
      g_value_set_int (value, (gint) vbi_bcd2dec (teletext->pageno));
      break;
    case PROP_SUBNO:
      g_value_set_int (value, teletext->subno);
      break;
    case PROP_SUBTITLES_MODE:
      g_value_set_boolean (value, teletext->subtitles_mode);
      break;
    case PROP_SUBS_TEMPLATE:
      g_value_set_string (value, teletext->subtitles_template);
      break;
    case PROP_FONT_DESCRIPTION:
      g_value_set_string (value, teletext->font_description);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_teletextdec_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean ret;
  GstTeletextDec *teletext = GST_TELETEXTDEC (parent);

  GST_DEBUG_OBJECT (teletext, "got event %s",
      gst_event_type_get_name (GST_EVENT_TYPE (event)));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEGMENT:
      /* maybe save and/or update the current segment (e.g. for output
       * clipping) or convert the event into one in a different format
       * (e.g. BYTES to TIME) or drop it and set a flag to send a newsegment
       * event in a different format later */
      if (NULL == teletext->export_func) {
        /* save the segment event and send it after sending caps. replace the
         * old event if present. */
        if (teletext->segment) {
          gst_event_unref (teletext->segment);
        }
        teletext->segment = event;
        ret = TRUE;
      } else {
        ret = gst_pad_push_event (teletext->srcpad, event);
      }
      break;
    case GST_EVENT_EOS:
      /* end-of-stream, we should close down all stream leftovers here */
      gst_teletextdec_zvbi_clear (teletext);
      ret = gst_pad_push_event (teletext->srcpad, event);
      break;
    case GST_EVENT_FLUSH_STOP:
      gst_teletextdec_zvbi_clear (teletext);
      gst_teletextdec_zvbi_init (teletext);
      ret = gst_pad_push_event (teletext->srcpad, event);
      break;
    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}

static gboolean
gst_teletextdec_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean ret;
  GstTeletextDec *teletext = GST_TELETEXTDEC (parent);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_RECONFIGURE:
      /* setting export_func to NULL will cause the element to renegotiate caps
       * before pushing a buffer. */
      teletext->export_func = NULL;
      ret = TRUE;
      break;

    default:
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }
  return ret;
}

static GstStateChangeReturn
gst_teletextdec_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstTeletextDec *teletext;

  teletext = GST_TELETEXTDEC (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_teletextdec_zvbi_init (teletext);
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret != GST_STATE_CHANGE_SUCCESS)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_teletextdec_zvbi_clear (teletext);
      break;
    default:
      break;
  }

  return ret;
}

static void
gst_teletextdec_reset_frame (GstTeletextDec * teletext)
{
  if (teletext->frame == NULL)
    teletext->frame = g_new0 (GstTeletextFrame, 1);
  if (teletext->frame->sliced_begin == NULL)
    teletext->frame->sliced_begin = g_new (vbi_sliced, MAX_SLICES);
  teletext->frame->current_slice = teletext->frame->sliced_begin;
  teletext->frame->sliced_end = teletext->frame->sliced_begin + MAX_SLICES;
  teletext->frame->last_field = 0;
  teletext->frame->last_field_line = 0;
  teletext->frame->last_frame_line = 0;
}

static void
gst_teletextdec_process_telx_buffer (GstTeletextDec * teletext, GstBuffer * buf)
{
  GstMapInfo buf_map;
  guint offset = 0;
  gint res;
  gst_buffer_map (buf, &buf_map, GST_MAP_READ);

  teletext->in_timestamp = GST_BUFFER_TIMESTAMP (buf);
  teletext->in_duration = GST_BUFFER_DURATION (buf);

  if (teletext->frame == NULL)
    gst_teletextdec_reset_frame (teletext);

  while (offset < buf_map.size) {
    res =
        gst_teletextdec_extract_data_units (teletext, teletext->frame,
        buf_map.data, &offset, buf_map.size);

    if (res == VBI_NEW_FRAME) {
      /* We have a new frame, it's time to feed the decoder */
      vbi_sliced *s;
      gint n_lines;

      n_lines = teletext->frame->current_slice - teletext->frame->sliced_begin;
      GST_LOG_OBJECT (teletext, "Completed frame, decoding new %d lines",
          n_lines);
      s = g_memdup (teletext->frame->sliced_begin,
          n_lines * sizeof (vbi_sliced));
      vbi_decode (teletext->decoder, s, n_lines, teletext->last_ts);
      /* From vbi_decode():
       * timestamp shall advance by 1/30 to 1/25 seconds whenever calling this
       * function. Failure to do so will be interpreted as frame dropping, which
       * starts a resynchronization cycle, eventually a channel switch may be assumed
       * which resets even more decoder state. So even if a frame did not contain
       * any useful data this function must be called, with lines set to zero.
       */
      teletext->last_ts += 0.04;

      g_free (s);
      gst_teletextdec_reset_frame (teletext);
    } else if (res == VBI_ERROR) {
      gst_teletextdec_reset_frame (teletext);
      goto beach;
    }
  }
beach:
  gst_buffer_unmap (buf, &buf_map);
  return;
}

static void
gst_teletextdec_event_handler (vbi_event * ev, void *user_data)
{
  page_info *pi;
  vbi_pgno pgno;
  vbi_subno subno;

  GstTeletextDec *teletext = GST_TELETEXTDEC (user_data);

  switch (ev->type) {
    case VBI_EVENT_TTX_PAGE:
      pgno = ev->ev.ttx_page.pgno;
      subno = ev->ev.ttx_page.subno;

      if (pgno != teletext->pageno
          || (teletext->subno != -1 && subno != teletext->subno))
        return;

      GST_DEBUG_OBJECT (teletext, "Received teletext page %03d.%02d",
          (gint) vbi_bcd2dec (pgno), (gint) vbi_bcd2dec (subno));

      pi = g_new (page_info, 1);
      pi->pgno = pgno;
      pi->subno = subno;

      g_mutex_lock (&teletext->queue_lock);
      g_queue_push_tail (teletext->queue, pi);
      g_mutex_unlock (&teletext->queue_lock);
      break;
    case VBI_EVENT_CAPTION:
      /* TODO: Handle subtitles in caption teletext pages */
      GST_DEBUG_OBJECT (teletext, "Received caption page. Not implemented");
      break;
    default:
      break;
  }
  return;
}

static void
gst_teletextdec_try_get_buffer_pool (GstTeletextDec * teletext, GstCaps * caps,
    gssize size)
{
  guint pool_bufsize, min_bufs, max_bufs;
  GstStructure *poolcfg;
  GstBufferPool *new_pool;
  GstQuery *alloc = gst_query_new_allocation (caps, TRUE);

  if (teletext->buf_pool) {
    /* this function is called only on a caps/size change, so it's practically
     * impossible that we'll be able to reuse the old pool. */
    gst_buffer_pool_set_active (teletext->buf_pool, FALSE);
    gst_object_unref (teletext->buf_pool);
  }

  if (!gst_pad_peer_query (teletext->srcpad, alloc)) {
    GST_DEBUG_OBJECT (teletext, "Failed to query peer pad for allocation "
        "parameters");
    teletext->buf_pool = NULL;
    goto beach;
  }

  if (gst_query_get_n_allocation_pools (alloc) > 0) {
    gst_query_parse_nth_allocation_pool (alloc, 0, &new_pool, &pool_bufsize,
        &min_bufs, &max_bufs);
  } else {
    new_pool = gst_buffer_pool_new ();
    max_bufs = 0;
    min_bufs = 1;
  }

  poolcfg = gst_buffer_pool_get_config (new_pool);
  gst_buffer_pool_config_set_params (poolcfg, gst_caps_copy (caps), size,
      min_bufs, max_bufs);
  if (!gst_buffer_pool_set_config (new_pool, poolcfg)) {
    GST_DEBUG_OBJECT (teletext, "Failed to configure the buffer pool");
    gst_object_unref (new_pool);
    teletext->buf_pool = NULL;
    goto beach;
  }
  if (!gst_buffer_pool_set_active (new_pool, TRUE)) {
    GST_DEBUG_OBJECT (teletext, "Failed to make the buffer pool active");
    gst_object_unref (new_pool);
    teletext->buf_pool = NULL;
    goto beach;
  }

  teletext->buf_pool = new_pool;

beach:
  gst_query_unref (alloc);
}

static gboolean
gst_teletextdec_negotiate_caps (GstTeletextDec * teletext, guint width,
    guint height)
{
  gboolean rv = FALSE;
  /* get the peer's caps filtered by our own ones. */
  GstCaps *ourcaps = gst_pad_query_caps (teletext->srcpad, NULL);
  GstCaps *peercaps = gst_pad_peer_query_caps (teletext->srcpad, ourcaps);
  GstStructure *caps_struct;
  const gchar *caps_name, *caps_fmt;

  gst_caps_unref (ourcaps);

  if (gst_caps_is_empty (peercaps)) {
    goto beach;
  }

  /* make them writable in case we need to fixate them (video/x-raw). */
  peercaps = gst_caps_make_writable (peercaps);
  caps_struct = gst_caps_get_structure (peercaps, 0);
  caps_name = gst_structure_get_name (caps_struct);
  caps_fmt = gst_structure_get_string (caps_struct, "format");

  if (!g_strcmp0 (caps_name, "video/x-raw")) {
    teletext->width = width;
    teletext->height = height;
    teletext->export_func = gst_teletextdec_export_rgba_page;
    gst_structure_set (caps_struct,
        "width", G_TYPE_INT, width,
        "height", G_TYPE_INT, height,
        "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
  } else if (!g_strcmp0 (caps_name, "text/x-raw") &&
      !g_strcmp0 (caps_fmt, "utf-8")) {
    teletext->export_func = gst_teletextdec_export_text_page;
  } else if (!g_strcmp0 (caps_name, "text/x-raw") &&
      !g_strcmp0 (caps_fmt, "pango-markup")) {
    teletext->export_func = gst_teletextdec_export_pango_page;
  } else {
    goto beach;
  }

  if (!gst_pad_push_event (teletext->srcpad, gst_event_new_caps (peercaps))) {
    goto beach;
  }

  /* try to get a bufferpool from the peer pad in case of RGBA output. */
  if (gst_teletextdec_export_rgba_page == teletext->export_func) {
    gst_teletextdec_try_get_buffer_pool (teletext, peercaps,
        width * height * sizeof (vbi_rgba));
  }

  /* we can happily return a success now. */
  rv = TRUE;

beach:
  gst_caps_unref (peercaps);
  return rv;
}

/* this function does the actual processing
 */
static GstFlowReturn
gst_teletextdec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstTeletextDec *teletext = GST_TELETEXTDEC (parent);
  GstFlowReturn ret = GST_FLOW_OK;

  teletext->in_timestamp = GST_BUFFER_TIMESTAMP (buf);
  teletext->in_duration = GST_BUFFER_DURATION (buf);

  gst_teletextdec_process_telx_buffer (teletext, buf);
  gst_buffer_unref (buf);

  g_mutex_lock (&teletext->queue_lock);
  if (!g_queue_is_empty (teletext->queue)) {
    ret = gst_teletextdec_push_page (teletext);
    if (ret != GST_FLOW_OK) {
      g_mutex_unlock (&teletext->queue_lock);
      goto error;
    }
  }
  g_mutex_unlock (&teletext->queue_lock);

  return ret;

/* ERRORS */
error:
  {
    if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_LINKED
        && ret != GST_FLOW_FLUSHING) {
      GST_ELEMENT_FLOW_ERROR (teletext, ret);
      return GST_FLOW_ERROR;
    }
    return ret;
  }
}

static GstFlowReturn
gst_teletextdec_push_page (GstTeletextDec * teletext)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GstBuffer *buf;
  vbi_page page;
  page_info *pi;
  gint pgno, subno;
  gboolean success;
  guint width, height;

  pi = g_queue_pop_head (teletext->queue);
  pgno = vbi_bcd2dec (pi->pgno);
  subno = vbi_bcd2dec (pi->subno);

  GST_INFO_OBJECT (teletext, "Fetching teletext page %03d.%02d", pgno, subno);

  success = vbi_fetch_vt_page (teletext->decoder, &page, pi->pgno, pi->subno,
      VBI_WST_LEVEL_3p5, 25, FALSE);
  g_free (pi);
  if (G_UNLIKELY (!success))
    goto fetch_page_failed;

  width = COLUMNS_TO_WIDTH (page.columns);
  height = ROWS_TO_HEIGHT (page.rows);

  /* if output_func is NULL, we need to (re-)negotiate. also, it is possible
   * (though unlikely) that we received a page of a different size. */
  if (G_UNLIKELY (NULL == teletext->export_func ||
          teletext->width != width || teletext->height != height)) {
    /* if negotiate_caps returns FALSE, that means we weren't able to
     * negotiate. */
    if (G_UNLIKELY (!gst_teletextdec_negotiate_caps (teletext, width, height))) {
      ret = GST_FLOW_NOT_NEGOTIATED;
      goto push_failed;
    }
    if (G_UNLIKELY (teletext->segment)) {
      gst_pad_push_event (teletext->srcpad, teletext->segment);
      teletext->segment = NULL;
    }
  }

  teletext->export_func (teletext, &page, &buf);
  vbi_unref_page (&page);

  GST_BUFFER_TIMESTAMP (buf) = teletext->in_timestamp;
  GST_BUFFER_DURATION (buf) = teletext->in_duration;

  GST_INFO_OBJECT (teletext, "Pushing buffer of size %" G_GSIZE_FORMAT,
      gst_buffer_get_size (buf));

  ret = gst_pad_push (teletext->srcpad, buf);
  if (ret != GST_FLOW_OK)
    goto push_failed;

  return GST_FLOW_OK;

fetch_page_failed:
  {
    GST_ELEMENT_ERROR (teletext, RESOURCE, READ, (NULL), (NULL));
    return GST_FLOW_ERROR;
  }

push_failed:
  {
    GST_ERROR_OBJECT (teletext, "Pushing buffer failed, reason %s",
        gst_flow_get_name (ret));
    return ret;
  }
}

static gchar **
gst_teletextdec_vbi_page_to_text_lines (guint start, guint stop, vbi_page *
    page)
{
  const guint lines_count = stop - start + 1;
  const guint line_length = page->columns;
  gchar **lines;
  guint i;

  /* allocate a new NULL-terminated array of strings */
  lines = (gchar **) g_malloc (sizeof (gchar *) * (lines_count + 1));
  lines[lines_count] = NULL;

  /* export each line in the range of the teletext page in text format */
  for (i = start; i <= stop; i++) {
    lines[i - start] = (gchar *) g_malloc (sizeof (gchar) * (line_length + 1));
    vbi_print_page_region (page, lines[i - start], line_length + 1, "UTF-8",
        TRUE, 0, 0, i, line_length, 1);
    /* Add the null character */
    lines[i - start][line_length] = '\0';
  }

  return lines;
}

static GstFlowReturn
gst_teletextdec_export_text_page (GstTeletextDec * teletext, vbi_page * page,
    GstBuffer ** buf)
{
  gchar *text;
  guint size;

  if (teletext->subtitles_mode) {
    gchar **lines;
    GString *subs;
    guint i;

    lines = gst_teletextdec_vbi_page_to_text_lines (1, 23, page);
    subs = g_string_new ("");
    /* Strip white spaces and squash blank lines */
    for (i = 0; i < 23; i++) {
      g_strstrip (lines[i]);
      if (g_strcmp0 (lines[i], ""))
        g_string_append_printf (subs, teletext->subtitles_template, lines[i]);
    }
    /* if the page is blank and doesn't contain any line of text, just add a
     * line break */
    if (!g_strcmp0 (subs->str, ""))
      g_string_append (subs, "\n");

    text = subs->str;
    size = subs->len + 1;
    g_string_free (subs, FALSE);
    g_strfreev (lines);
  } else {
    size = page->columns * page->rows;
    text = g_malloc (size);
    vbi_print_page (page, text, size, "UTF-8", FALSE, TRUE);
  }

  /* Allocate new buffer */
  *buf = gst_buffer_new_wrapped (text, size);

  return GST_FLOW_OK;
}

static GstFlowReturn
gst_teletextdec_export_rgba_page (GstTeletextDec * teletext, vbi_page * page,
    GstBuffer ** buf)
{
  guint size;
  GstBuffer *lbuf;
  GstMapInfo buf_map;

  size = teletext->width * teletext->height * sizeof (vbi_rgba);

  /* Allocate new buffer, using the negotiated pool if available. */
  if (teletext->buf_pool) {
    GstFlowReturn acquire_rv =
        gst_buffer_pool_acquire_buffer (teletext->buf_pool, &lbuf, NULL);
    if (acquire_rv != GST_FLOW_OK) {
      return acquire_rv;
    }
  } else {
    lbuf = gst_buffer_new_allocate (NULL, size, NULL);
    if (NULL == lbuf)
      return GST_FLOW_ERROR;
  }

  if (!gst_buffer_map (lbuf, &buf_map, GST_MAP_WRITE)) {
    gst_buffer_unref (lbuf);
    return GST_FLOW_ERROR;
  }

  vbi_draw_vt_page (page, VBI_PIXFMT_RGBA32_LE, buf_map.data, FALSE, TRUE);
  gst_buffer_unmap (lbuf, &buf_map);
  *buf = lbuf;

  return GST_FLOW_OK;
}

static GstFlowReturn
gst_teletextdec_export_pango_page (GstTeletextDec * teletext, vbi_page * page,
    GstBuffer ** buf)
{
  vbi_char *acp;
  const guint rows = page->rows;
  gchar **colors;
  gchar **lines;
  GString *subs;
  guint start, stop, k;
  gint i, j;

  colors = (gchar **) g_malloc (sizeof (gchar *) * (rows + 1));
  colors[rows] = NULL;

  /* parse all the lines and approximate it's foreground color using the first
   * non null character */
  for (acp = page->text, i = 0; i < page->rows; acp += page->columns, i++) {
    for (j = 0; j < page->columns; j++) {
      colors[i] = g_strdup (default_color_map[7]);
      if (acp[j].unicode != 0x20) {
        colors[i] = g_strdup (default_color_map[acp[j].foreground]);
        break;
      }
    }
  }

  /* get an array of strings with each line of the telext page */
  start = teletext->subtitles_mode ? 1 : 0;
  stop = teletext->subtitles_mode ? rows - 2 : rows - 1;
  lines = gst_teletextdec_vbi_page_to_text_lines (start, stop, page);

  /* format each line in pango markup */
  subs = g_string_new ("");
  for (k = start; k <= stop; k++) {
    g_string_append_printf (subs, PANGO_TEMPLATE,
        teletext->font_description, colors[k], lines[k - start]);
  }

  /* Allocate new buffer */
  *buf = gst_buffer_new_wrapped (subs->str, subs->len + 1);

  g_strfreev (lines);
  g_strfreev (colors);
  g_string_free (subs, FALSE);
  return GST_FLOW_OK;
}

/* Converts the line_offset / field_parity byte of a VBI data unit. */
static void
gst_teletextdec_lofp_to_line (guint * field, guint * field_line,
    guint * frame_line, guint lofp, systems system)
{
  guint line_offset;

  /* field_parity */
  *field = !(lofp & (1 << 5));

  line_offset = lofp & 31;

  if (line_offset > 0) {
    static const guint field_start[2][2] = {
      {0, 263},
      {0, 313},
    };

    *field_line = line_offset;
    *frame_line = field_start[system][*field] + line_offset;
  } else {
    *field_line = 0;
    *frame_line = 0;
  }
}

static int
gst_teletextdec_line_address (GstTeletextDec * teletext,
    GstTeletextFrame * frame, vbi_sliced ** spp, guint lofp, systems system)
{
  guint field;
  guint field_line;
  guint frame_line;

  if (G_UNLIKELY (frame->current_slice >= frame->sliced_end)) {
    GST_LOG_OBJECT (teletext, "Out of sliced VBI buffer space (%d lines).",
        (int) (frame->sliced_end - frame->sliced_begin));
    return VBI_ERROR;
  }

  gst_teletextdec_lofp_to_line (&field, &field_line, &frame_line, lofp, system);

  GST_LOG_OBJECT (teletext, "Line %u/%u=%u.", field, field_line, frame_line);

  if (frame_line != 0) {
    GST_LOG_OBJECT (teletext, "Last frame Line %u.", frame->last_frame_line);
    if (frame_line <= frame->last_frame_line) {
      GST_LOG_OBJECT (teletext, "New frame");
      return VBI_NEW_FRAME;
    }

    /* FIXME : This never happens, since lofp is a guint8 */
#if 0
    /* new segment flag */
    if (lofp < 0) {
      GST_LOG_OBJECT (teletext, "New frame");
      return VBI_NEW_FRAME;
    }
#endif

    frame->last_field = field;
    frame->last_field_line = field_line;
    frame->last_frame_line = frame_line;

    *spp = frame->current_slice++;
    (*spp)->line = frame_line;
  } else {
    /* Undefined line. */
    return VBI_ERROR;
  }

  return VBI_SUCCESS;
}

static gboolean
gst_teletextdec_extract_data_units (GstTeletextDec * teletext,
    GstTeletextFrame * f, const guint8 * packet, guint * offset, gsize size)
{
  const guint8 *data_unit;
  guint i;

  while (*offset < size) {
    vbi_sliced *s = NULL;
    gint data_unit_id, data_unit_length;

    data_unit = packet + *offset;
    data_unit_id = data_unit[0];
    data_unit_length = data_unit[1];
    GST_LOG_OBJECT (teletext, "vbi header %02x %02x %02x\n", data_unit[0],
        data_unit[1], data_unit[2]);

    switch (data_unit_id) {
      case DATA_UNIT_STUFFING:
      {
        *offset += 2 + data_unit_length;
        break;
      }

      case DATA_UNIT_EBU_TELETEXT_NON_SUBTITLE:
      case DATA_UNIT_EBU_TELETEXT_SUBTITLE:
      {
        gint res;

        if (G_UNLIKELY (data_unit_length != 1 + 1 + 42)) {
          /* Skip this data unit */
          GST_WARNING_OBJECT (teletext, "The data unit length is not 44 bytes");
          *offset += 2 + data_unit_length;
          break;
        }

        res =
            gst_teletextdec_line_address (teletext, f, &s, data_unit[2],
            SYSTEM_625);
        if (G_UNLIKELY (res == VBI_ERROR)) {
          /* Can't retrieve line address, skip this data unit */
          GST_WARNING_OBJECT (teletext,
              "Could not retrieve line address for this data unit");
          return VBI_ERROR;
        }
        if (G_UNLIKELY (f->last_field_line > 0
                && (f->last_field_line - 7 >= 23 - 7))) {
          GST_WARNING_OBJECT (teletext, "Bad line: %d", f->last_field_line - 7);
          return VBI_ERROR;
        }
        if (res == VBI_NEW_FRAME) {
          /* New frame */
          return VBI_NEW_FRAME;
        }
        s->id = VBI_SLICED_TELETEXT_B;
        for (i = 0; i < 42; i++)
          s->data[i] = vbi_rev8 (data_unit[4 + i]);
        *offset += 46;
        break;
      }

      case DATA_UNIT_ZVBI_WSS_CPR1204:
      case DATA_UNIT_ZVBI_CLOSED_CAPTION_525:
      case DATA_UNIT_ZVBI_MONOCHROME_SAMPLES_525:
      case DATA_UNIT_VPS:
      case DATA_UNIT_WSS:
      case DATA_UNIT_CLOSED_CAPTION:
      case DATA_UNIT_MONOCHROME_SAMPLES:
      {
        /*Not supported yet */
        *offset += 2 + data_unit_length;
        break;
      }

      default:
      {
        /* corrupted stream, increase the offset by one until we sync */
        GST_LOG_OBJECT (teletext, "Corrupted, increasing offset by one");
        *offset += 1;
        break;
      }
    }
  }
  return VBI_SUCCESS;
}

static gboolean
teletext_init (GstPlugin * teletext)
{
  GST_DEBUG_CATEGORY_INIT (gst_teletextdec_debug, "teletext", 0,
      "Teletext decoder");
  return gst_element_register (teletext, "teletextdec", GST_RANK_NONE,
      GST_TYPE_TELETEXTDEC);
}

GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
    GST_VERSION_MINOR,
    teletext,
    "Teletext plugin",
    teletext_init, VERSION, "LGPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)
