/*
 * dvbbasebin.c - 
 * Copyright (C) 2007 Alessandro Decina
 * Copyright (C) 2014 Samsung Electronics. All rights reserved.
 * 
 * Authors:
 *   Alessandro Decina <alessandro@nnva.org>
 *   Reynaldo H. Verdejo Pinochet <r.verdejo@sisa.samsung.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.
 */


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <string.h>
#include <gst/mpegts/mpegts.h>
#include "dvbbasebin.h"
#include "parsechannels.h"

GST_DEBUG_CATEGORY (dvb_base_bin_debug);
#define GST_CAT_DEFAULT dvb_base_bin_debug

static GstStaticPadTemplate src_template =
GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/mpegts, " "systemstream = (boolean) true ")
    );

static GstStaticPadTemplate program_template =
GST_STATIC_PAD_TEMPLATE ("program_%u", GST_PAD_SRC,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("video/mpegts, " "systemstream = (boolean) true ")
    );

enum
{
  /* FILL ME */
  SIGNAL_TUNING_START,
  SIGNAL_TUNING_DONE,
  SIGNAL_TUNING_FAIL,
  SIGNAL_TUNE,
  LAST_SIGNAL
};

enum
{
  ARG_0,
  PROP_ADAPTER,
  PROP_FRONTEND,
  PROP_DISEQC_SRC,
  PROP_FREQUENCY,
  PROP_POLARITY,
  PROP_SYMBOL_RATE,
  PROP_BANDWIDTH,
  PROP_CODE_RATE_HP,
  PROP_CODE_RATE_LP,
  PROP_GUARD,
  PROP_MODULATION,
  PROP_TRANS_MODE,
  PROP_HIERARCHY,
  PROP_INVERSION,
  PROP_PROGRAM_NUMBERS,
  PROP_STATS_REPORTING_INTERVAL,
  PROP_TUNING_TIMEOUT,
  PROP_DELSYS,
  PROP_PILOT,
  PROP_ROLLOFF,
  PROP_STREAM_ID,
  PROP_BANDWIDTH_HZ,
  PROP_ISDBT_LAYER_ENABLED,
  PROP_ISDBT_PARTIAL_RECEPTION,
  PROP_ISDBT_SOUND_BROADCASTING,
  PROP_ISDBT_SB_SUBCHANNEL_ID,
  PROP_ISDBT_SB_SEGMENT_IDX,
  PROP_ISDBT_SB_SEGMENT_COUNT,
  PROP_ISDBT_LAYERA_FEC,
  PROP_ISDBT_LAYERA_MODULATION,
  PROP_ISDBT_LAYERA_SEGMENT_COUNT,
  PROP_ISDBT_LAYERA_TIME_INTERLEAVING,
  PROP_ISDBT_LAYERB_FEC,
  PROP_ISDBT_LAYERB_MODULATION,
  PROP_ISDBT_LAYERB_SEGMENT_COUNT,
  PROP_ISDBT_LAYERB_TIME_INTERLEAVING,
  PROP_ISDBT_LAYERC_FEC,
  PROP_ISDBT_LAYERC_MODULATION,
  PROP_ISDBT_LAYERC_SEGMENT_COUNT,
  PROP_ISDBT_LAYERC_TIME_INTERLEAVING,
  PROP_LNB_SLOF,
  PROP_LNB_LOF1,
  PROP_LNB_LOF2,
  PROP_INTERLEAVING
};

typedef struct
{
  guint16 pid;
  guint usecount;
} DvbBaseBinStream;

typedef struct
{
  gint program_number;
  guint16 pmt_pid;
  guint16 pcr_pid;
  GstMpegtsSection *section;
  GstMpegtsSection *old_section;
  const GstMpegtsPMT *pmt;
  const GstMpegtsPMT *old_pmt;
  gboolean selected;
  gboolean pmt_active;
  gboolean active;
  GstPad *ghost;
} DvbBaseBinProgram;

static void dvb_base_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void dvb_base_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void dvb_base_bin_dispose (GObject * object);
static void dvb_base_bin_finalize (GObject * object);

static void dvb_base_bin_task (DvbBaseBin * basebin);

static GstStateChangeReturn dvb_base_bin_change_state (GstElement * element,
    GstStateChange transition);
static void dvb_base_bin_handle_message (GstBin * bin, GstMessage * message);
static void dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin,
    GstMpegtsSection * pat);
static void dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin,
    GstMpegtsSection * pmt);
static GstPad *dvb_base_bin_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
static void dvb_base_bin_release_pad (GstElement * element, GstPad * pad);
static void dvb_base_bin_rebuild_filter (DvbBaseBin * dvbbasebin);
static void
dvb_base_bin_deactivate_program (DvbBaseBin * dvbbasebin,
    DvbBaseBinProgram * program);

static void dvb_base_bin_uri_handler_init (gpointer g_iface,
    gpointer iface_data);

static void dvb_base_bin_program_destroy (gpointer data);

/* Proxy callbacks for dvbsrc signals */
static void tuning_start_signal_cb (GObject * object, DvbBaseBin * dvbbasebin);
static void tuning_done_signal_cb (GObject * object, DvbBaseBin * dvbbasebin);
static void tuning_fail_signal_cb (GObject * object, DvbBaseBin * dvbbasebin);

static void dvb_base_bin_do_tune (DvbBaseBin * dvbbasebin);

#define dvb_base_bin_parent_class parent_class
G_DEFINE_TYPE_EXTENDED (DvbBaseBin, dvb_base_bin, GST_TYPE_BIN,
    0,
    G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
        dvb_base_bin_uri_handler_init));


static void
dvb_base_bin_ref_stream (DvbBaseBinStream * stream)
{
  g_return_if_fail (stream != NULL);
  stream->usecount++;
}

static void
dvb_base_bin_unref_stream (DvbBaseBinStream * stream)
{
  g_return_if_fail (stream != NULL);
  g_return_if_fail (stream->usecount > 0);
  stream->usecount--;
}

static DvbBaseBinStream *
dvb_base_bin_add_stream (DvbBaseBin * dvbbasebin, guint16 pid)
{
  DvbBaseBinStream *stream;

  stream = g_new0 (DvbBaseBinStream, 1);
  stream->pid = pid;
  stream->usecount = 0;

  g_hash_table_insert (dvbbasebin->streams,
      GINT_TO_POINTER ((gint) pid), stream);

  return stream;
}

static DvbBaseBinStream *
dvb_base_bin_get_stream (DvbBaseBin * dvbbasebin, guint16 pid)
{
  return (DvbBaseBinStream *) g_hash_table_lookup (dvbbasebin->streams,
      GINT_TO_POINTER ((gint) pid));
}

static DvbBaseBinProgram *
dvb_base_bin_add_program (DvbBaseBin * dvbbasebin, gint program_number)
{
  DvbBaseBinProgram *program;

  program = g_new0 (DvbBaseBinProgram, 1);
  program->program_number = program_number;
  program->selected = FALSE;
  program->active = FALSE;
  program->pmt_pid = G_MAXUINT16;
  program->pcr_pid = G_MAXUINT16;
  program->pmt = NULL;
  program->old_pmt = NULL;

  g_hash_table_insert (dvbbasebin->programs,
      GINT_TO_POINTER (program_number), program);

  return program;
}

static DvbBaseBinProgram *
dvb_base_bin_get_program (DvbBaseBin * dvbbasebin, gint program_number)
{
  return (DvbBaseBinProgram *) g_hash_table_lookup (dvbbasebin->programs,
      GINT_TO_POINTER (program_number));
}


static guint dvb_base_bin_signals[LAST_SIGNAL] = { 0 };

static void
tuning_start_signal_cb (GObject * object, DvbBaseBin * dvbbasebin)
{
  g_signal_emit (dvbbasebin, dvb_base_bin_signals[SIGNAL_TUNING_START], 0);
}

static void
tuning_done_signal_cb (GObject * object, DvbBaseBin * dvbbasebin)
{
  g_signal_emit (dvbbasebin, dvb_base_bin_signals[SIGNAL_TUNING_DONE], 0);
}

static void
tuning_fail_signal_cb (GObject * object, DvbBaseBin * dvbbasebin)
{
  g_signal_emit (dvbbasebin, dvb_base_bin_signals[SIGNAL_TUNING_FAIL], 0);
}

static void
dvb_base_bin_do_tune (DvbBaseBin * dvbbasebin)
{
  g_signal_emit_by_name (dvbbasebin->dvbsrc, "tune", NULL);
}

static void
dvb_base_bin_class_init (DvbBaseBinClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;
  GstBinClass *bin_class;
  DvbBaseBinClass *dvbbasebin_class;
  GstElementFactory *dvbsrc_factory;
  GObjectClass *dvbsrc_class;
  typedef struct
  {
    guint prop_id;
    const gchar *prop_name;
  } ProxyedProperty;
  ProxyedProperty *walk;
  ProxyedProperty proxyed_properties[] = {
    {PROP_ADAPTER, "adapter"},
    {PROP_FRONTEND, "frontend"},
    {PROP_DISEQC_SRC, "diseqc-source"},
    {PROP_FREQUENCY, "frequency"},
    {PROP_POLARITY, "polarity"},
    {PROP_SYMBOL_RATE, "symbol-rate"},
#ifndef GST_REMOVE_DEPRECATED
    {PROP_BANDWIDTH, "bandwidth"},
#endif
    {PROP_CODE_RATE_HP, "code-rate-hp"},
    {PROP_CODE_RATE_LP, "code-rate-lp"},
    {PROP_GUARD, "guard"},
    {PROP_MODULATION, "modulation"},
    {PROP_TRANS_MODE, "trans-mode"},
    {PROP_HIERARCHY, "hierarchy"},
    {PROP_INVERSION, "inversion"},
    {PROP_STATS_REPORTING_INTERVAL, "stats-reporting-interval"},
    {PROP_TUNING_TIMEOUT, "tuning-timeout"},
    {PROP_DELSYS, "delsys"},
    {PROP_PILOT, "pilot"},
    {PROP_ROLLOFF, "rolloff"},
    {PROP_STREAM_ID, "stream-id"},
    {PROP_BANDWIDTH_HZ, "bandwidth-hz"},
    {PROP_ISDBT_LAYER_ENABLED, "isdbt-layer-enabled"},
    {PROP_ISDBT_PARTIAL_RECEPTION, "isdbt-partial-reception"},
    {PROP_ISDBT_SOUND_BROADCASTING, "isdbt-sound-broadcasting"},
    {PROP_ISDBT_SB_SUBCHANNEL_ID, "isdbt-sb-subchannel-id"},
    {PROP_ISDBT_SB_SEGMENT_IDX, "isdbt-sb-segment-idx"},
    {PROP_ISDBT_SB_SEGMENT_COUNT, "isdbt-sb-segment-count"},
    {PROP_ISDBT_LAYERA_FEC, "isdbt-layera-fec"},
    {PROP_ISDBT_LAYERA_MODULATION, "isdbt-layera-modulation"},
    {PROP_ISDBT_LAYERA_SEGMENT_COUNT, "isdbt-layera-segment-count"},
    {PROP_ISDBT_LAYERA_TIME_INTERLEAVING, "isdbt-layera-time-interleaving"},
    {PROP_ISDBT_LAYERB_FEC, "isdbt-layerb-fec"},
    {PROP_ISDBT_LAYERB_MODULATION, "isdbt-layerb-modulation"},
    {PROP_ISDBT_LAYERB_SEGMENT_COUNT, "isdbt-layerb-segment-count"},
    {PROP_ISDBT_LAYERB_TIME_INTERLEAVING, "isdbt-layerb-time-interleaving"},
    {PROP_ISDBT_LAYERC_FEC, "isdbt-layerc-fec"},
    {PROP_ISDBT_LAYERC_MODULATION, "isdbt-layerc-modulation"},
    {PROP_ISDBT_LAYERC_SEGMENT_COUNT, "isdbt-layerc-segment-count"},
    {PROP_ISDBT_LAYERC_TIME_INTERLEAVING, "isdbt-layerc-time-interleaving"},
    {PROP_LNB_SLOF, "lnb-slof"},
    {PROP_LNB_LOF1, "lnb-lof1"},
    {PROP_LNB_LOF2, "lnb-lof2"},
    {PROP_INTERLEAVING, "interleaving"},
    {0, NULL}
  };

  bin_class = GST_BIN_CLASS (klass);
  bin_class->handle_message = dvb_base_bin_handle_message;

  element_class = GST_ELEMENT_CLASS (klass);

  element_class->change_state = dvb_base_bin_change_state;
  element_class->request_new_pad = dvb_base_bin_request_new_pad;
  element_class->release_pad = dvb_base_bin_release_pad;

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&program_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&src_template));

  gst_element_class_set_static_metadata (element_class, "DVB bin",
      "Source/Bin/Video",
      "Access descramble and split DVB streams",
      "Alessandro Decina <alessandro@nnva.org>\n"
      "Reynaldo H. Verdejo Pinochet <r.verdejo@sisa.samsung.com>");

  gobject_class = G_OBJECT_CLASS (klass);
  gobject_class->set_property = dvb_base_bin_set_property;
  gobject_class->get_property = dvb_base_bin_get_property;
  gobject_class->dispose = dvb_base_bin_dispose;
  gobject_class->finalize = dvb_base_bin_finalize;

  dvbbasebin_class = (DvbBaseBinClass *) klass;
  dvbbasebin_class->do_tune = dvb_base_bin_do_tune;

  /* install dvbsrc properties */
  dvbsrc_factory = gst_element_factory_find ("dvbsrc");
  dvbsrc_class =
      g_type_class_ref (gst_element_factory_get_element_type (dvbsrc_factory));
  walk = proxyed_properties;
  while (walk->prop_name != NULL) {
    GParamSpec *pspec;
    GParamSpec *our_pspec;

    pspec = g_object_class_find_property (dvbsrc_class, walk->prop_name);
    if (pspec != NULL) {
      GType param_type = G_PARAM_SPEC_TYPE (pspec);

      if (param_type == G_TYPE_PARAM_INT) {
        GParamSpecInt *src_pspec = G_PARAM_SPEC_INT (pspec);

        our_pspec = g_param_spec_int (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            src_pspec->minimum, src_pspec->maximum, src_pspec->default_value,
            pspec->flags);
      } else if (param_type == G_TYPE_PARAM_UINT) {
        GParamSpecUInt *src_pspec = G_PARAM_SPEC_UINT (pspec);

        our_pspec = g_param_spec_uint (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            src_pspec->minimum, src_pspec->maximum, src_pspec->default_value,
            pspec->flags);
      } else if (param_type == G_TYPE_PARAM_UINT64) {
        GParamSpecUInt64 *src_pspec = G_PARAM_SPEC_UINT64 (pspec);

        our_pspec = g_param_spec_uint64 (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            src_pspec->minimum, src_pspec->maximum, src_pspec->default_value,
            pspec->flags);
      } else if (param_type == G_TYPE_PARAM_STRING) {
        GParamSpecString *src_pspec = G_PARAM_SPEC_STRING (pspec);

        our_pspec = g_param_spec_string (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            src_pspec->default_value, pspec->flags);
      } else if (param_type == G_TYPE_PARAM_ENUM) {
        GParamSpecEnum *src_pspec = G_PARAM_SPEC_ENUM (pspec);

        our_pspec = g_param_spec_enum (g_param_spec_get_name (pspec),
            g_param_spec_get_nick (pspec), g_param_spec_get_blurb (pspec),
            pspec->value_type, src_pspec->default_value, pspec->flags);
      } else {
        GST_ERROR ("Unsupported property type %s for property %s",
            g_type_name (param_type), g_param_spec_get_name (pspec));
        ++walk;
        continue;
      }

      g_object_class_install_property (gobject_class, walk->prop_id, our_pspec);
    } else {
      g_warning ("dvbsrc has no property named %s", walk->prop_name);
    }
    ++walk;
  }
  g_type_class_unref (dvbsrc_class);

  g_object_class_install_property (gobject_class, PROP_PROGRAM_NUMBERS,
      g_param_spec_string ("program-numbers",
          "Program Numbers",
          "Colon separated list of programs", "", G_PARAM_READWRITE));
  /**
   * DvbBaseBin::tuning-start:
   * @dvbbasebin: the element on which the signal is emitted
   *
   * Signal emited when the element first attempts to tune the
   * frontend tunner to a given frequency.
   */
  dvb_base_bin_signals[SIGNAL_TUNING_START] =
      g_signal_new ("tuning-start", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
  /**
   * DvbBaseBin::tuning-done:
   * @dvbbasebin: the element on which the signal is emitted
   *
   * Signal emited when the tunner has successfully got a lock on a signal.
   */
  dvb_base_bin_signals[SIGNAL_TUNING_DONE] =
      g_signal_new ("tuning-done", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
  /**
   * DvbBaseBin::tuning-fail:
   * @dvbbasebin: the element on which the signal is emitted
   *
   * Signal emited when the tunner failed to get a lock on the
   * signal.
   */
  dvb_base_bin_signals[SIGNAL_TUNING_FAIL] =
      g_signal_new ("tuning-fail", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);

  /**
   * DvbBaseBin::tune:
   * @dvbbasesink: the element on which the signal is emitted
   *
   * Signal emited from the application to the element, instructing it
   * to tune.
   */
  dvb_base_bin_signals[SIGNAL_TUNE] =
      g_signal_new ("tune", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
      G_STRUCT_OFFSET (DvbBaseBinClass, do_tune),
      NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}

static void
dvb_base_bin_reset (DvbBaseBin * dvbbasebin)
{
  if (dvbbasebin->hwcam) {
    cam_device_close (dvbbasebin->hwcam);
    cam_device_free (dvbbasebin->hwcam);
    dvbbasebin->hwcam = NULL;
  }
  dvbbasebin->trycam = TRUE;
}

static const gint16 initial_pids[] = { 0, 1, 0x10, 0x11, 0x12, 0x14, -1 };

static void
dvb_base_bin_init (DvbBaseBin * dvbbasebin)
{
  DvbBaseBinStream *stream;
  GstPad *ghost, *pad;
  int i;

  dvbbasebin->dvbsrc = gst_element_factory_make ("dvbsrc", NULL);
  dvbbasebin->buffer_queue = gst_element_factory_make ("queue", NULL);
  dvbbasebin->tsparse = gst_element_factory_make ("tsparse", NULL);

  g_object_set (dvbbasebin->buffer_queue, "max-size-buffers", 0,
      "max-size-bytes", 0, "max-size-time", (guint64) 0, NULL);

  gst_bin_add_many (GST_BIN (dvbbasebin), dvbbasebin->dvbsrc,
      dvbbasebin->buffer_queue, dvbbasebin->tsparse, NULL);

  gst_element_link_many (dvbbasebin->dvbsrc,
      dvbbasebin->buffer_queue, dvbbasebin->tsparse, NULL);

  /* Proxy dvbsrc signals */
  g_signal_connect (dvbbasebin->dvbsrc, "tuning-start",
      G_CALLBACK (tuning_start_signal_cb), dvbbasebin);
  g_signal_connect (dvbbasebin->dvbsrc, "tuning-done",
      G_CALLBACK (tuning_done_signal_cb), dvbbasebin);
  g_signal_connect (dvbbasebin->dvbsrc, "tuning-fail",
      G_CALLBACK (tuning_fail_signal_cb), dvbbasebin);

  /* Expose tsparse source pad */
  if (dvbbasebin->tsparse != NULL) {
    pad = gst_element_get_static_pad (dvbbasebin->tsparse, "src");
    ghost = gst_ghost_pad_new ("src", pad);
  } else {
    ghost = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC);
  }
  gst_element_add_pad (GST_ELEMENT (dvbbasebin), ghost);

  dvbbasebin->programs = g_hash_table_new_full (g_direct_hash, g_direct_equal,
      NULL, dvb_base_bin_program_destroy);
  dvbbasebin->streams = g_hash_table_new_full (g_direct_hash, g_direct_equal,
      NULL, g_free);

  dvbbasebin->pmtlist = NULL;
  dvbbasebin->pmtlist_changed = FALSE;

  dvbbasebin->disposed = FALSE;
  dvb_base_bin_reset (dvbbasebin);

  /* add PAT, CAT, NIT, SDT, EIT, TDT to pids filter for dvbsrc */
  i = 0;
  while (initial_pids[i] >= 0) {
    stream = dvb_base_bin_add_stream (dvbbasebin, (guint16) initial_pids[i]);
    dvb_base_bin_ref_stream (stream);
    i++;
  }
  dvb_base_bin_rebuild_filter (dvbbasebin);

  g_rec_mutex_init (&dvbbasebin->lock);
  dvbbasebin->task =
      gst_task_new ((GstTaskFunction) dvb_base_bin_task, dvbbasebin, NULL);
  gst_task_set_lock (dvbbasebin->task, &dvbbasebin->lock);
  dvbbasebin->poll = gst_poll_new_timer ();
}

static void
dvb_base_bin_dispose (GObject * object)
{
  DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object);

  if (!dvbbasebin->disposed) {
    /* remove mpegtsparse BEFORE dvbsrc, since the mpegtsparse::pad-removed
     * signal handler uses dvbsrc */
    dvb_base_bin_reset (dvbbasebin);
    if (dvbbasebin->tsparse != NULL)
      gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->tsparse);
    gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->dvbsrc);
    gst_bin_remove (GST_BIN (dvbbasebin), dvbbasebin->buffer_queue);
    dvbbasebin->disposed = TRUE;
  }

  if (G_OBJECT_CLASS (parent_class)->dispose)
    G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
dvb_base_bin_finalize (GObject * object)
{
  DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object);

  g_hash_table_destroy (dvbbasebin->streams);
  g_hash_table_destroy (dvbbasebin->programs);
  g_list_free (dvbbasebin->pmtlist);

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

static void
dvb_base_bin_set_program_numbers (DvbBaseBin * dvbbasebin, const gchar * pn)
{
  gchar **strv, **walk;
  DvbBaseBinProgram *program;

  /* Split up and update programs */
  strv = g_strsplit (pn, ":", 0);

  for (walk = strv; *walk; walk++) {
    gint program_number = strtol (*walk, NULL, 0);

    program = dvb_base_bin_get_program (dvbbasebin, program_number);
    if (program == NULL) {
      program = dvb_base_bin_add_program (dvbbasebin, program_number);
      program->selected = TRUE;
    }
  }

  g_strfreev (strv);

  /* FIXME : Deactivate programs no longer selected */

  g_free (dvbbasebin->program_numbers);
  dvbbasebin->program_numbers = g_strdup (pn);

  if (0)
    dvb_base_bin_deactivate_program (dvbbasebin, NULL);
}

static void
dvb_base_bin_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object);

  switch (prop_id) {
    case PROP_ADAPTER:
    case PROP_DISEQC_SRC:
    case PROP_FRONTEND:
    case PROP_FREQUENCY:
    case PROP_POLARITY:
    case PROP_SYMBOL_RATE:
    case PROP_BANDWIDTH:
    case PROP_CODE_RATE_HP:
    case PROP_CODE_RATE_LP:
    case PROP_GUARD:
    case PROP_MODULATION:
    case PROP_TRANS_MODE:
    case PROP_HIERARCHY:
    case PROP_INVERSION:
    case PROP_STATS_REPORTING_INTERVAL:
    case PROP_TUNING_TIMEOUT:
    case PROP_DELSYS:
    case PROP_PILOT:
    case PROP_ROLLOFF:
    case PROP_STREAM_ID:
    case PROP_BANDWIDTH_HZ:
    case PROP_ISDBT_LAYER_ENABLED:
    case PROP_ISDBT_PARTIAL_RECEPTION:
    case PROP_ISDBT_SOUND_BROADCASTING:
    case PROP_ISDBT_SB_SUBCHANNEL_ID:
    case PROP_ISDBT_SB_SEGMENT_IDX:
    case PROP_ISDBT_SB_SEGMENT_COUNT:
    case PROP_ISDBT_LAYERA_FEC:
    case PROP_ISDBT_LAYERA_MODULATION:
    case PROP_ISDBT_LAYERA_SEGMENT_COUNT:
    case PROP_ISDBT_LAYERA_TIME_INTERLEAVING:
    case PROP_ISDBT_LAYERB_FEC:
    case PROP_ISDBT_LAYERB_MODULATION:
    case PROP_ISDBT_LAYERB_SEGMENT_COUNT:
    case PROP_ISDBT_LAYERB_TIME_INTERLEAVING:
    case PROP_ISDBT_LAYERC_FEC:
    case PROP_ISDBT_LAYERC_MODULATION:
    case PROP_ISDBT_LAYERC_SEGMENT_COUNT:
    case PROP_ISDBT_LAYERC_TIME_INTERLEAVING:
    case PROP_LNB_SLOF:
    case PROP_LNB_LOF1:
    case PROP_LNB_LOF2:
    case PROP_INTERLEAVING:
      /* FIXME: check if we can tune (state < PLAYING || program-numbers == "") */
      g_object_set_property (G_OBJECT (dvbbasebin->dvbsrc), pspec->name, value);
      break;
    case PROP_PROGRAM_NUMBERS:
      dvb_base_bin_set_program_numbers (dvbbasebin, g_value_get_string (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  }
}

static void
dvb_base_bin_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (object);

  switch (prop_id) {
    case PROP_ADAPTER:
    case PROP_FRONTEND:
    case PROP_DISEQC_SRC:
    case PROP_FREQUENCY:
    case PROP_POLARITY:
    case PROP_SYMBOL_RATE:
    case PROP_BANDWIDTH:
    case PROP_CODE_RATE_HP:
    case PROP_CODE_RATE_LP:
    case PROP_GUARD:
    case PROP_MODULATION:
    case PROP_TRANS_MODE:
    case PROP_HIERARCHY:
    case PROP_INVERSION:
    case PROP_STATS_REPORTING_INTERVAL:
    case PROP_TUNING_TIMEOUT:
    case PROP_DELSYS:
    case PROP_PILOT:
    case PROP_ROLLOFF:
    case PROP_STREAM_ID:
    case PROP_BANDWIDTH_HZ:
    case PROP_ISDBT_LAYER_ENABLED:
    case PROP_ISDBT_PARTIAL_RECEPTION:
    case PROP_ISDBT_SOUND_BROADCASTING:
    case PROP_ISDBT_SB_SUBCHANNEL_ID:
    case PROP_ISDBT_SB_SEGMENT_IDX:
    case PROP_ISDBT_SB_SEGMENT_COUNT:
    case PROP_ISDBT_LAYERA_FEC:
    case PROP_ISDBT_LAYERA_MODULATION:
    case PROP_ISDBT_LAYERA_SEGMENT_COUNT:
    case PROP_ISDBT_LAYERA_TIME_INTERLEAVING:
    case PROP_ISDBT_LAYERB_FEC:
    case PROP_ISDBT_LAYERB_MODULATION:
    case PROP_ISDBT_LAYERB_SEGMENT_COUNT:
    case PROP_ISDBT_LAYERB_TIME_INTERLEAVING:
    case PROP_ISDBT_LAYERC_FEC:
    case PROP_ISDBT_LAYERC_MODULATION:
    case PROP_ISDBT_LAYERC_SEGMENT_COUNT:
    case PROP_ISDBT_LAYERC_TIME_INTERLEAVING:
    case PROP_LNB_SLOF:
    case PROP_LNB_LOF1:
    case PROP_LNB_LOF2:
    case PROP_INTERLEAVING:
      g_object_get_property (G_OBJECT (dvbbasebin->dvbsrc), pspec->name, value);
      break;
    case PROP_PROGRAM_NUMBERS:
      g_value_set_string (value, dvbbasebin->program_numbers);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  }
}

static GstPad *
dvb_base_bin_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (element);
  GstPad *pad;
  GstPad *ghost;
  gchar *pad_name;

  GST_DEBUG_OBJECT (dvbbasebin, "New pad requested %s", GST_STR_NULL (name));

  if (dvbbasebin->tsparse == NULL)
    return NULL;

  if (name == NULL)
    name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);

  pad = gst_element_get_request_pad (dvbbasebin->tsparse, name);
  if (pad == NULL)
    return NULL;

  pad_name = gst_pad_get_name (pad);
  ghost = gst_ghost_pad_new (pad_name, pad);
  g_free (pad_name);
  gst_element_add_pad (element, ghost);

  return ghost;
}

static void
dvb_base_bin_release_pad (GstElement * element, GstPad * pad)
{
  GstGhostPad *ghost;
  GstPad *target;

  g_return_if_fail (GST_IS_DVB_BASE_BIN (element));

  ghost = GST_GHOST_PAD (pad);
  target = gst_ghost_pad_get_target (ghost);
  gst_element_release_request_pad (GST_ELEMENT (GST_DVB_BASE_BIN
          (element)->tsparse), target);
  gst_object_unref (target);

  gst_element_remove_pad (element, pad);
}

static void
dvb_base_bin_reset_pmtlist (DvbBaseBin * dvbbasebin)
{
  CamConditionalAccessPmtFlag flag;
  GList *walk;
  GstMpegtsPMT *pmt;

  walk = dvbbasebin->pmtlist;
  while (walk) {
    if (walk->prev == NULL) {
      if (walk->next == NULL)
        flag = CAM_CONDITIONAL_ACCESS_PMT_FLAG_ONLY;
      else
        flag = CAM_CONDITIONAL_ACCESS_PMT_FLAG_FIRST;
    } else {
      if (walk->next == NULL)
        flag = CAM_CONDITIONAL_ACCESS_PMT_FLAG_LAST;
      else
        flag = CAM_CONDITIONAL_ACCESS_PMT_FLAG_MORE;
    }

    pmt = (GstMpegtsPMT *) walk->data;
    cam_device_set_pmt (dvbbasebin->hwcam, pmt, flag);

    walk = walk->next;
  }

  dvbbasebin->pmtlist_changed = FALSE;
}

static void
dvb_base_bin_init_cam (DvbBaseBin * dvbbasebin)
{
  gint adapter;
  gchar *ca_file;

  g_object_get (dvbbasebin->dvbsrc, "adapter", &adapter, NULL);
  /* TODO: handle multiple cams */
  ca_file = g_strdup_printf ("/dev/dvb/adapter%d/ca0", adapter);
  if (g_file_test (ca_file, G_FILE_TEST_EXISTS)) {
    dvbbasebin->hwcam = cam_device_new ();
    /* device_open() can block up to 5s ! */
    if (!cam_device_open (dvbbasebin->hwcam, ca_file)) {
      GST_ERROR_OBJECT (dvbbasebin, "could not open %s", ca_file);
      cam_device_free (dvbbasebin->hwcam);
      dvbbasebin->hwcam = NULL;
    }
  }

  dvbbasebin->trycam = FALSE;

  g_free (ca_file);
}

static GstStateChangeReturn
dvb_base_bin_change_state (GstElement * element, GstStateChange transition)
{
  DvbBaseBin *dvbbasebin;
  GstStateChangeReturn ret;

  dvbbasebin = GST_DVB_BASE_BIN (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (dvbbasebin->tsparse == NULL) {
        GST_ELEMENT_ERROR (dvbbasebin, CORE, MISSING_PLUGIN, (NULL),
            ("No 'tsparse' element, check your GStreamer installation."));
        return GST_STATE_CHANGE_FAILURE;
      }
      break;
    default:
      break;
  }

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

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_poll_set_flushing (dvbbasebin->poll, FALSE);
      g_rec_mutex_lock (&dvbbasebin->lock);
      gst_task_start (dvbbasebin->task);
      g_rec_mutex_unlock (&dvbbasebin->lock);
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_poll_set_flushing (dvbbasebin->poll, TRUE);
      g_rec_mutex_lock (&dvbbasebin->lock);
      gst_task_stop (dvbbasebin->task);
      g_rec_mutex_unlock (&dvbbasebin->lock);
      dvb_base_bin_reset (dvbbasebin);
      break;
    default:
      break;
  }

  return ret;
}

static void
foreach_stream_build_filter (gpointer key, gpointer value, gpointer user_data)
{
  DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (user_data);
  DvbBaseBinStream *stream = (DvbBaseBinStream *) value;
  gchar *tmp, *pid;

  GST_DEBUG ("stream %d usecount %d", stream->pid, stream->usecount);

  if (stream->usecount > 0) {
    /* TODO: use g_strjoinv FTW */
    tmp = dvbbasebin->filter;
    pid = g_strdup_printf ("%d", stream->pid);
    dvbbasebin->filter = g_strjoin (":", pid, dvbbasebin->filter, NULL);

    g_free (pid);
    g_free (tmp);
  }
}

static void
dvb_base_bin_rebuild_filter (DvbBaseBin * dvbbasebin)
{
  g_hash_table_foreach (dvbbasebin->streams,
      foreach_stream_build_filter, dvbbasebin);

  if (dvbbasebin->filter == NULL)
    /* fix dvbsrc to handle NULL filter */
    dvbbasebin->filter = g_strdup ("");

  GST_INFO_OBJECT (dvbbasebin, "rebuilt filter %s", dvbbasebin->filter);

  /* FIXME: find a way to not add unwanted pids controlled by app */
  g_object_set (dvbbasebin->dvbsrc, "pids", dvbbasebin->filter, NULL);
  g_free (dvbbasebin->filter);
  dvbbasebin->filter = NULL;
}

static void
dvb_base_bin_remove_pmt_streams (DvbBaseBin * dvbbasebin,
    const GstMpegtsPMT * pmt)
{
  gint i;
  DvbBaseBinStream *stream;

  for (i = 0; i < pmt->streams->len; i++) {
    GstMpegtsPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i);

    stream = dvb_base_bin_get_stream (dvbbasebin, pmtstream->pid);
    if (stream == NULL) {
      GST_WARNING_OBJECT (dvbbasebin, "removing unknown stream %d ??",
          pmtstream->pid);
      continue;
    }

    dvb_base_bin_unref_stream (stream);
  }
}

static void
dvb_base_bin_add_pmt_streams (DvbBaseBin * dvbbasebin, const GstMpegtsPMT * pmt)
{
  DvbBaseBinStream *stream;
  gint i;

  for (i = 0; i < pmt->streams->len; i++) {
    GstMpegtsPMTStream *pmtstream = g_ptr_array_index (pmt->streams, i);

    GST_DEBUG ("filtering stream %d stream_type %d", pmtstream->pid,
        pmtstream->stream_type);

    stream = dvb_base_bin_get_stream (dvbbasebin, pmtstream->pid);
    if (stream == NULL)
      stream = dvb_base_bin_add_stream (dvbbasebin, pmtstream->pid);
    dvb_base_bin_ref_stream (stream);
  }
}

static void
dvb_base_bin_activate_program (DvbBaseBin * dvbbasebin,
    DvbBaseBinProgram * program)
{
  DvbBaseBinStream *stream;

  if (program->old_pmt) {
    dvb_base_bin_remove_pmt_streams (dvbbasebin, program->old_pmt);
    dvbbasebin->pmtlist = g_list_remove (dvbbasebin->pmtlist, program->old_pmt);
  }

  /* activate the PMT and PCR streams. If the PCR stream is in the PMT its
   * usecount will be incremented by 2 here and decremented by 2 when the
   * program is deactivated */
  if (!program->pmt_active) {
    stream = dvb_base_bin_get_stream (dvbbasebin, program->pmt_pid);
    if (stream == NULL)
      stream = dvb_base_bin_add_stream (dvbbasebin, program->pmt_pid);
    dvb_base_bin_ref_stream (stream);
    program->pmt_active = TRUE;
  }

  if (program->pmt) {
    guint16 old_pcr_pid;

    old_pcr_pid = program->pcr_pid;
    program->pcr_pid = program->pmt->pcr_pid;
    if (old_pcr_pid != G_MAXUINT16 && old_pcr_pid != program->pcr_pid) {
      dvb_base_bin_unref_stream (dvb_base_bin_get_stream (dvbbasebin,
              old_pcr_pid));
    }

    stream = dvb_base_bin_get_stream (dvbbasebin, program->pcr_pid);
    if (stream == NULL)
      stream = dvb_base_bin_add_stream (dvbbasebin, program->pcr_pid);
    dvb_base_bin_ref_stream (stream);

    dvb_base_bin_add_pmt_streams (dvbbasebin, program->pmt);
    dvbbasebin->pmtlist =
        g_list_append (dvbbasebin->pmtlist, (gpointer) program->pmt);
    dvbbasebin->pmtlist_changed = TRUE;
    program->active = TRUE;
  }

  dvb_base_bin_rebuild_filter (dvbbasebin);
}

static void
dvb_base_bin_deactivate_program (DvbBaseBin * dvbbasebin,
    DvbBaseBinProgram * program)
{
  DvbBaseBinStream *stream;

  stream = dvb_base_bin_get_stream (dvbbasebin, program->pmt_pid);
  if (stream != NULL) {
    dvb_base_bin_unref_stream (stream);
  }

  stream = dvb_base_bin_get_stream (dvbbasebin, program->pcr_pid);
  if (stream != NULL) {
    dvb_base_bin_unref_stream (stream);
  }

  if (program->pmt) {
    dvb_base_bin_remove_pmt_streams (dvbbasebin, program->pmt);
    dvbbasebin->pmtlist = g_list_remove (dvbbasebin->pmtlist, program->pmt);
    dvbbasebin->pmtlist_changed = TRUE;
  }

  dvb_base_bin_rebuild_filter (dvbbasebin);
  program->pmt_active = FALSE;
  program->active = FALSE;
}

static void
dvb_base_bin_handle_message (GstBin * bin, GstMessage * message)
{
  DvbBaseBin *dvbbasebin;

  dvbbasebin = GST_DVB_BASE_BIN (bin);

  /* note: message->src might be a GstPad, so use element cast w/o typecheck */
  if (GST_ELEMENT_CAST (message->src) == dvbbasebin->tsparse) {
    GstMpegtsSection *section = gst_message_parse_mpegts_section (message);

    if (section) {
      switch (GST_MPEGTS_SECTION_TYPE (section)) {
        case GST_MPEGTS_SECTION_PAT:
          dvb_base_bin_pat_info_cb (dvbbasebin, section);
          break;
        case GST_MPEGTS_SECTION_PMT:
          dvb_base_bin_pmt_info_cb (dvbbasebin, section);
          break;
        default:
          break;
      }
      gst_mpegts_section_unref (section);
    }
  }

  /* chain up */
  GST_BIN_CLASS (parent_class)->handle_message (bin, message);
}



static void
dvb_base_bin_pat_info_cb (DvbBaseBin * dvbbasebin, GstMpegtsSection * section)
{
  GPtrArray *pat;
  DvbBaseBinProgram *program;
  DvbBaseBinStream *stream;
  guint old_pmt_pid;
  gint i;
  gboolean rebuild_filter = FALSE;

  if (!(pat = gst_mpegts_section_get_pat (section))) {
    GST_WARNING_OBJECT (dvbbasebin, "got invalid PAT");
    return;
  }

  for (i = 0; i < pat->len; i++) {
    GstMpegtsPatProgram *patp = g_ptr_array_index (pat, i);

    program = dvb_base_bin_get_program (dvbbasebin, patp->program_number);
    if (program == NULL)
      program = dvb_base_bin_add_program (dvbbasebin, patp->program_number);

    old_pmt_pid = program->pmt_pid;
    program->pmt_pid = patp->network_or_program_map_PID;

    if (program->selected) {
      /* PAT update */
      if (old_pmt_pid != G_MAXUINT16 && old_pmt_pid != program->pmt_pid) {
        dvb_base_bin_unref_stream (dvb_base_bin_get_stream (dvbbasebin,
                old_pmt_pid));
      }

      stream = dvb_base_bin_get_stream (dvbbasebin, program->pmt_pid);
      if (stream == NULL)
        stream = dvb_base_bin_add_stream (dvbbasebin, program->pmt_pid);

      dvb_base_bin_ref_stream (stream);

      rebuild_filter = TRUE;
    }
  }

  if (rebuild_filter)
    dvb_base_bin_rebuild_filter (dvbbasebin);
}

static void
dvb_base_bin_pmt_info_cb (DvbBaseBin * dvbbasebin, GstMpegtsSection * section)
{
  const GstMpegtsPMT *pmt;
  DvbBaseBinProgram *program;
  guint program_number;

  pmt = gst_mpegts_section_get_pmt (section);
  if (G_UNLIKELY (pmt == NULL)) {
    GST_WARNING_OBJECT (dvbbasebin, "Received invalid PMT");
    return;
  }

  program_number = section->subtable_extension;

  program = dvb_base_bin_get_program (dvbbasebin, program_number);
  if (program == NULL) {
    GST_WARNING ("got PMT for program %d but program not in PAT",
        program_number);
    program = dvb_base_bin_add_program (dvbbasebin, program_number);
  }

  program->old_pmt = program->pmt;
  program->old_section = program->section;
  program->pmt = pmt;
  program->section = gst_mpegts_section_ref (section);

  /* activate the program if it's selected and either it's not active or its pmt
   * changed */
  if (program->selected && (!program->active || program->old_pmt != NULL))
    dvb_base_bin_activate_program (dvbbasebin, program);

  if (program->old_pmt) {
    gst_mpegts_section_unref (program->old_section);
    program->old_pmt = NULL;
  }
}

static guint
dvb_base_bin_uri_get_type (GType type)
{
  return GST_URI_SRC;
}

static const gchar *const *
dvb_base_bin_uri_get_protocols (GType type)
{
  static const gchar *protocols[] = { "dvb", NULL };

  return protocols;
}

static gchar *
dvb_base_bin_uri_get_uri (GstURIHandler * handler)
{
  return g_strdup ("dvb://");
}

static gboolean
dvb_base_bin_uri_set_uri (GstURIHandler * handler, const gchar * uri,
    GError ** error)
{
  DvbBaseBin *dvbbasebin = GST_DVB_BASE_BIN (handler);
  GError *err = NULL;
  gchar *location;

  location = gst_uri_get_location (uri);

  if (location == NULL)
    goto no_location;

  if (!set_properties_for_channel (GST_ELEMENT (dvbbasebin), location, &err))
    goto set_properties_failed;

  /* FIXME: here is where we parse channels.conf */

  g_free (location);
  return TRUE;
/* ERRORS */
post_error_and_exit:
  {
    gst_element_message_full (GST_ELEMENT (dvbbasebin), GST_MESSAGE_ERROR,
        err->domain, err->code, g_strdup (err->message), NULL, __FILE__,
        GST_FUNCTION, __LINE__);
    g_propagate_error (error, err);
    return FALSE;
  }
no_location:
  {
    g_set_error (&err, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
        "No details to DVB URI");
    goto post_error_and_exit;
  }
set_properties_failed:
  {
    g_free (location);
    goto post_error_and_exit;
  }
}

static void
dvb_base_bin_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;

  iface->get_type = dvb_base_bin_uri_get_type;
  iface->get_protocols = dvb_base_bin_uri_get_protocols;
  iface->get_uri = dvb_base_bin_uri_get_uri;
  iface->set_uri = dvb_base_bin_uri_set_uri;
}

gboolean
gst_dvb_base_bin_plugin_init (GstPlugin * plugin)
{
  GST_DEBUG_CATEGORY_INIT (dvb_base_bin_debug, "dvbbasebin", 0, "DVB bin");

  cam_init ();

  return gst_element_register (plugin, "dvbbasebin",
      GST_RANK_NONE, GST_TYPE_DVB_BASE_BIN);
}

static void
dvb_base_bin_program_destroy (gpointer data)
{
  DvbBaseBinProgram *program;

  program = (DvbBaseBinProgram *) data;

  if (program->pmt) {
    program->pmt = NULL;
    gst_mpegts_section_unref (program->section);
  }

  g_free (program);
}

static void
dvb_base_bin_task (DvbBaseBin * basebin)
{
  gint pollres;

  GST_DEBUG_OBJECT (basebin, "In task");

  /* If we haven't tried to open the cam, try now */
  if (G_UNLIKELY (basebin->trycam))
    dvb_base_bin_init_cam (basebin);

  /* poll with timeout */
  pollres = gst_poll_wait (basebin->poll, GST_SECOND / 4);

  if (G_UNLIKELY (pollres == -1)) {
    gst_task_stop (basebin->task);
    return;
  }
  if (basebin->hwcam) {
    cam_device_poll (basebin->hwcam);

    if (basebin->pmtlist_changed) {
      if (cam_device_ready (basebin->hwcam)) {
        GST_DEBUG_OBJECT (basebin, "pmt list changed");
        dvb_base_bin_reset_pmtlist (basebin);
      } else {
        GST_DEBUG_OBJECT (basebin, "pmt list changed but CAM not ready");
      }
    }
  }
}
