/* GStreamer
 * Copyright (C) <2008> Edward Hervey <bilboed@bilboed.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */
/**
 * SECTION:element-hdv1394src
 *
 * Read MPEG-TS data from firewire port.
 *
 * <refsect2>
 * <title>Example launch line</title>
 * |[
 * gst-launch-1.0 hdv1394src ! queue ! decodebin name=d ! queue ! xvimagesink d. ! queue ! alsasink
 * ]| captures from the firewire port and plays the streams.
 * |[
 * gst-launch-1.0 hdv1394src ! queue ! filesink location=mydump.ts
 * ]| capture to a disk file
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <unistd.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>

#include <libavc1394/avc1394.h>
#include <libavc1394/avc1394_vcr.h>
#include <libavc1394/rom1394.h>
#include <libraw1394/raw1394.h>
#include <libiec61883/iec61883.h>

#include <gst/gst.h>

#include "gsthdv1394src.h"
#include "gst1394probe.h"


#define CONTROL_STOP            'S'     /* stop the select call */
#define CONTROL_SOCKETS(src)   src->control_sock
#define WRITE_SOCKET(src)      src->control_sock[1]
#define READ_SOCKET(src)       src->control_sock[0]

#define SEND_COMMAND(src, command)          \
G_STMT_START {                              \
  int G_GNUC_UNUSED _res; unsigned char c; c = command;   \
  _res = write (WRITE_SOCKET(src), &c, 1);  \
} G_STMT_END

#define READ_COMMAND(src, command, res)        \
G_STMT_START {                                 \
  res = read(READ_SOCKET(src), &command, 1);   \
} G_STMT_END


GST_DEBUG_CATEGORY_STATIC (hdv1394src_debug);
#define GST_CAT_DEFAULT (hdv1394src_debug)

#define DEFAULT_PORT    -1
#define DEFAULT_CHANNEL   63
#define DEFAULT_USE_AVC   TRUE
#define DEFAULT_GUID    0

enum
{
  PROP_0,
  PROP_PORT,
  PROP_CHANNEL,
  PROP_USE_AVC,
  PROP_GUID,
  PROP_DEVICE_NAME
};

static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS
    ("video/mpegts,systemstream=(boolean)true,packetsize=(int)188")
    );

static void gst_hdv1394src_uri_handler_init (gpointer g_iface,
    gpointer iface_data);

static void gst_hdv1394src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_hdv1394src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_hdv1394src_dispose (GObject * object);

static gboolean gst_hdv1394src_start (GstBaseSrc * bsrc);
static gboolean gst_hdv1394src_stop (GstBaseSrc * bsrc);
static gboolean gst_hdv1394src_unlock (GstBaseSrc * bsrc);

static GstFlowReturn gst_hdv1394src_create (GstPushSrc * psrc,
    GstBuffer ** buf);

static void gst_hdv1394src_update_device_name (GstHDV1394Src * src);

#define gst_hdv1394src_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstHDV1394Src, gst_hdv1394src, GST_TYPE_PUSH_SRC,
    G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER,
        gst_hdv1394src_uri_handler_init));

static void
gst_hdv1394src_class_init (GstHDV1394SrcClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSrcClass *gstbasesrc_class;
  GstPushSrcClass *gstpushsrc_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbasesrc_class = (GstBaseSrcClass *) klass;
  gstpushsrc_class = (GstPushSrcClass *) klass;

  gobject_class->set_property = gst_hdv1394src_set_property;
  gobject_class->get_property = gst_hdv1394src_get_property;
  gobject_class->dispose = gst_hdv1394src_dispose;

  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_PORT,
      g_param_spec_int ("port", "Port", "Port number (-1 automatic)",
          -1, 16, DEFAULT_PORT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_CHANNEL,
      g_param_spec_int ("channel", "Channel", "Channel number for listening",
          0, 64, DEFAULT_CHANNEL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_USE_AVC,
      g_param_spec_boolean ("use-avc", "Use AV/C", "Use AV/C VTR control",
          DEFAULT_USE_AVC, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_GUID,
      g_param_spec_uint64 ("guid", "GUID",
          "select one of multiple DV devices by its GUID. use a hexadecimal "
          "like 0xhhhhhhhhhhhhhhhh. (0 = no guid)", 0, G_MAXUINT64,
          DEFAULT_GUID, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  /**
   * GstHDV1394Src:device-name:
   *
   * Descriptive name of the currently opened device
   */
  g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_DEVICE_NAME,
      g_param_spec_string ("device-name", "device name",
          "user-friendly name of the device", "Default",
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  gstbasesrc_class->negotiate = NULL;
  gstbasesrc_class->start = gst_hdv1394src_start;
  gstbasesrc_class->stop = gst_hdv1394src_stop;
  gstbasesrc_class->unlock = gst_hdv1394src_unlock;

  gstpushsrc_class->create = gst_hdv1394src_create;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&src_factory));

  gst_element_class_set_static_metadata (gstelement_class,
      "Firewire (1394) HDV video source", "Source/Video",
      "Source for MPEG-TS video data from firewire port",
      "Edward Hervey <bilboed@bilboed.com>");

  GST_DEBUG_CATEGORY_INIT (hdv1394src_debug, "hdv1394src", 0,
      "MPEG-TS firewire source");
}

static void
gst_hdv1394src_init (GstHDV1394Src * dv1394src)
{
  GstPad *srcpad = GST_BASE_SRC_PAD (dv1394src);

  gst_base_src_set_live (GST_BASE_SRC (dv1394src), TRUE);
  gst_pad_use_fixed_caps (srcpad);

  dv1394src->port = DEFAULT_PORT;
  dv1394src->channel = DEFAULT_CHANNEL;

  dv1394src->use_avc = DEFAULT_USE_AVC;
  dv1394src->guid = DEFAULT_GUID;
  dv1394src->uri = g_strdup_printf ("hdv://%d", dv1394src->port);
  dv1394src->device_name = g_strdup_printf ("Default");

  READ_SOCKET (dv1394src) = -1;
  WRITE_SOCKET (dv1394src) = -1;

  dv1394src->frame_sequence = 0;
}

static void
gst_hdv1394src_dispose (GObject * object)
{
  GstHDV1394Src *src = GST_HDV1394SRC (object);

  g_free (src->uri);
  src->uri = NULL;

  g_free (src->device_name);
  src->device_name = NULL;

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

static void
gst_hdv1394src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstHDV1394Src *filter = GST_HDV1394SRC (object);

  switch (prop_id) {
    case PROP_PORT:
      filter->port = g_value_get_int (value);
      g_free (filter->uri);
      filter->uri = g_strdup_printf ("hdv://%d", filter->port);
      break;
    case PROP_CHANNEL:
      filter->channel = g_value_get_int (value);
      break;
    case PROP_USE_AVC:
      filter->use_avc = g_value_get_boolean (value);
      break;
    case PROP_GUID:
      filter->guid = g_value_get_uint64 (value);
      gst_hdv1394src_update_device_name (filter);
      break;
    default:
      break;
  }
}

static void
gst_hdv1394src_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstHDV1394Src *filter = GST_HDV1394SRC (object);

  switch (prop_id) {
    case PROP_PORT:
      g_value_set_int (value, filter->port);
      break;
    case PROP_CHANNEL:
      g_value_set_int (value, filter->channel);
      break;
    case PROP_USE_AVC:
      g_value_set_boolean (value, filter->use_avc);
      break;
    case PROP_GUID:
      g_value_set_uint64 (value, filter->guid);
      break;
    case PROP_DEVICE_NAME:
      g_value_set_string (value, filter->device_name);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstHDV1394Src *
gst_hdv1394src_from_raw1394handle (raw1394handle_t handle)
{
  iec61883_mpeg2_t mpeg2 = (iec61883_mpeg2_t) raw1394_get_userdata (handle);
  return GST_HDV1394SRC (iec61883_mpeg2_get_callback_data (mpeg2));
}

/* Within one loop iteration (which may call _receive() many times), it seems
 * as though '*data' will always be different.
 *
 * We can therefore assume that any '*data' given to us will stay allocated until
 * the next loop iteration.
 */

static int
gst_hdv1394src_iec61883_receive (unsigned char *data, int len,
    unsigned int dropped, void *cbdata)
{
  GstHDV1394Src *dv1394src = GST_HDV1394SRC (cbdata);

  GST_LOG ("data:%p, len:%d, dropped:%d", data, len, dropped);

  /* error out if we don't have enough room ! */
  if (G_UNLIKELY (dv1394src->outoffset > (2048 * 188 - len)))
    return -1;

  if (G_LIKELY (len == IEC61883_MPEG2_TSP_SIZE)) {
    memcpy ((guint8 *) dv1394src->outdata + dv1394src->outoffset, data, len);
    dv1394src->outoffset += len;
  }
  dv1394src->frame_sequence++;
  return 0;
}

/*
 * When an ieee1394 bus reset happens, usually a device has been removed
 * or added.  We send a message on the message bus with the node count 
 * and whether the capture device used in this element connected, disconnected 
 * or was unchanged
 * Message structure:
 * nodecount - integer with number of nodes on bus
 * current-device-change - integer (1 if device connected, 0 if no change to
 *                         current device status, -1 if device disconnected)
 */
static int
gst_hdv1394src_bus_reset (raw1394handle_t handle, unsigned int generation)
{
  GstHDV1394Src *src;
  gint nodecount;
  GstMessage *message;
  GstStructure *structure;
  gint current_device_change;
  gint i;

  src = gst_hdv1394src_from_raw1394handle (handle);

  GST_INFO_OBJECT (src, "have bus reset");

  /* update generation - told to do so by docs */
  raw1394_update_generation (handle, generation);
  nodecount = raw1394_get_nodecount (handle);
  /* allocate memory for portinfo */

  /* current_device_change is -1 if camera disconnected, 0 if other device
   * connected or 1 if camera has now connected */
  current_device_change = -1;
  for (i = 0; i < nodecount; i++) {
    if (src->guid == rom1394_get_guid (handle, i)) {
      /* Camera is with us */
      GST_DEBUG ("Camera is with us");
      if (!src->connected) {
        current_device_change = 1;
        src->connected = TRUE;
      } else
        current_device_change = 0;
    }
  }
  if (src->connected && current_device_change == -1) {
    GST_DEBUG ("Camera has disconnected");
    src->connected = FALSE;
  } else if (!src->connected && current_device_change == -1) {
    GST_DEBUG ("Camera is still not with us");
    current_device_change = 0;
  }

  structure = gst_structure_new ("ieee1394-bus-reset", "nodecount", G_TYPE_INT,
      nodecount, "current-device-change", G_TYPE_INT, current_device_change,
      NULL);
  message = gst_message_new_element (GST_OBJECT (src), structure);
  gst_element_post_message (GST_ELEMENT (src), message);

  return 0;
}

static GstFlowReturn
gst_hdv1394src_create (GstPushSrc * psrc, GstBuffer ** buf)
{
  GstHDV1394Src *dv1394src = GST_HDV1394SRC (psrc);
  struct pollfd pollfds[2];

  pollfds[0].fd = raw1394_get_fd (dv1394src->handle);
  pollfds[0].events = POLLIN | POLLERR | POLLHUP | POLLPRI;
  pollfds[1].fd = READ_SOCKET (dv1394src);
  pollfds[1].events = POLLIN | POLLERR | POLLHUP | POLLPRI;

  /* allocate a 2048 samples buffer */
  dv1394src->outdata = g_malloc (2048 * 188);
  dv1394src->outoffset = 0;

  GST_DEBUG ("Create...");

  while (TRUE) {
    int res = poll (pollfds, 2, -1);

    GST_LOG ("res:%d", res);

    if (G_UNLIKELY (res < 0)) {
      if (errno == EAGAIN || errno == EINTR)
        continue;
      else
        goto error_while_polling;
    }

    if (G_UNLIKELY (pollfds[1].revents)) {
      char command;

      if (pollfds[1].revents & POLLIN)
        READ_COMMAND (dv1394src, command, res);

      goto told_to_stop;
    } else if (G_LIKELY (pollfds[0].revents & POLLIN)) {
      int pt;

      pt = dv1394src->frame_sequence;
      /* shouldn't block in theory */
      GST_LOG ("Iterating ! (%d)", dv1394src->frame_sequence);
      raw1394_loop_iterate (dv1394src->handle);
      GST_LOG ("After iteration : %d (diff:%d)",
          dv1394src->frame_sequence, dv1394src->frame_sequence - pt);
      if (dv1394src->outoffset)
        break;
    }
  }

  g_assert (dv1394src->outoffset);

  GST_LOG ("We have some frames (%u bytes)", (guint) dv1394src->outoffset);

  /* Create the buffer */
  *buf = gst_buffer_new_wrapped (dv1394src->outdata, dv1394src->outoffset);
  dv1394src->outdata = NULL;
  dv1394src->outoffset = 0;

  return GST_FLOW_OK;

error_while_polling:
  {
    GST_ELEMENT_ERROR (dv1394src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
    return GST_FLOW_EOS;
  }
told_to_stop:
  {
    GST_DEBUG_OBJECT (dv1394src, "told to stop, shutting down");
    return GST_FLOW_FLUSHING;
  }
}

static int
gst_hdv1394src_discover_avc_node (GstHDV1394Src * src)
{
  int node = -1;
  int i, j = 0;
  int m = src->num_ports;

  if (src->port >= 0) {
    /* search on explicit port */
    j = src->port;
    m = j + 1;
  }

  /* loop over all our ports */
  for (; j < m && node == -1; j++) {
    raw1394handle_t handle;
    struct raw1394_portinfo pinf[16];

    /* open the port */
    handle = raw1394_new_handle ();
    if (!handle) {
      GST_WARNING ("raw1394 - failed to get handle: %s.\n", strerror (errno));
      continue;
    }
    if (raw1394_get_port_info (handle, pinf, 16) < 0) {
      GST_WARNING ("raw1394 - failed to get port info: %s.\n",
          strerror (errno));
      goto next;
    }

    /* tell raw1394 which host adapter to use */
    if (raw1394_set_port (handle, j) < 0) {
      GST_WARNING ("raw1394 - failed to set set port: %s.\n", strerror (errno));
      goto next;
    }

    /* now loop over all the nodes */
    for (i = 0; i < raw1394_get_nodecount (handle); i++) {
      /* are we looking for an explicit GUID ? */
      if (src->guid != 0) {
        if (src->guid == rom1394_get_guid (handle, i)) {
          node = i;
          src->port = j;
          g_free (src->uri);
          src->uri = g_strdup_printf ("dv://%d", src->port);
          break;
        }
      } else {
        rom1394_directory rom_dir;

        /* select first AV/C Tape Recorder Player node */
        if (rom1394_get_directory (handle, i, &rom_dir) < 0) {
          GST_WARNING ("error reading config rom directory for node %d\n", i);
          continue;
        }
        if ((rom1394_get_node_type (&rom_dir) == ROM1394_NODE_TYPE_AVC) &&
            avc1394_check_subunit_type (handle, i, AVC1394_SUBUNIT_TYPE_VCR)) {
          node = i;
          src->port = j;
          src->guid = rom1394_get_guid (handle, i);
          g_free (src->uri);
          src->uri = g_strdup_printf ("dv://%d", src->port);
          g_free (src->device_name);
          src->device_name = g_strdup (rom_dir.label);
          break;
        }
        rom1394_free_directory (&rom_dir);
      }
    }
  next:
    raw1394_destroy_handle (handle);
  }
  return node;
}

static gboolean
gst_hdv1394src_start (GstBaseSrc * bsrc)
{
  GstHDV1394Src *src = GST_HDV1394SRC (bsrc);
  int control_sock[2];

  src->connected = FALSE;

  if (socketpair (PF_UNIX, SOCK_STREAM, 0, control_sock) < 0)
    goto socket_pair;

  READ_SOCKET (src) = control_sock[0];
  WRITE_SOCKET (src) = control_sock[1];

  fcntl (READ_SOCKET (src), F_SETFL, O_NONBLOCK);
  fcntl (WRITE_SOCKET (src), F_SETFL, O_NONBLOCK);

  src->handle = raw1394_new_handle ();

  if (!src->handle) {
    if (errno == EACCES)
      goto permission_denied;
    else if (errno == ENOENT)
      goto not_found;
    else
      goto no_handle;
  }

  src->num_ports = raw1394_get_port_info (src->handle, src->pinfo, 16);

  if (src->num_ports == 0)
    goto no_ports;

  if (src->use_avc || src->port == -1)
    src->avc_node = gst_hdv1394src_discover_avc_node (src);

  /* lets destroy handle and create one on port
     this is more reliable than setting port on
     the existing handle */
  raw1394_destroy_handle (src->handle);
  src->handle = raw1394_new_handle_on_port (src->port);
  if (!src->handle)
    goto cannot_set_port;

  raw1394_set_userdata (src->handle, src);
  raw1394_set_bus_reset_handler (src->handle, gst_hdv1394src_bus_reset);

  {
    nodeid_t m_node = (src->avc_node | 0xffc0);
    int m_channel = -1;
    int m_bandwidth = 0;
    int m_outputPort = -1;
    int m_inputPort = -1;

    m_channel = iec61883_cmp_connect (src->handle, m_node, &m_outputPort,
        raw1394_get_local_id (src->handle), &m_inputPort, &m_bandwidth);

    if (m_channel >= 0) {
      src->channel = m_channel;
    }
  }


  if ((src->iec61883mpeg2 =
          iec61883_mpeg2_recv_init (src->handle,
              gst_hdv1394src_iec61883_receive, src)) == NULL)
    goto cannot_initialise_dv;

#if 0
  raw1394_set_iso_handler (src->handle, src->channel,
      gst_hdv1394src_iso_receive);
#endif

  GST_DEBUG_OBJECT (src, "successfully opened up 1394 connection");
  src->connected = TRUE;

  if (iec61883_mpeg2_recv_start (src->iec61883mpeg2, src->channel) != 0)
    goto cannot_start;
#if 0
  if (raw1394_start_iso_rcv (src->handle, src->channel) < 0)
    goto cannot_start;
#endif

  if (src->use_avc) {
    raw1394handle_t avc_handle = raw1394_new_handle_on_port (src->port);

    GST_LOG ("We have an avc_handle");

    /* start the VCR */
    if (avc_handle) {
      if (!avc1394_vcr_is_recording (avc_handle, src->avc_node)
          && avc1394_vcr_is_playing (avc_handle, src->avc_node)
          != AVC1394_VCR_OPERAND_PLAY_FORWARD) {
        GST_LOG ("Calling avc1394_vcr_play()");
        avc1394_vcr_play (avc_handle, src->avc_node);
      }
      raw1394_destroy_handle (avc_handle);
    } else {
      GST_WARNING_OBJECT (src, "Starting VCR via avc1394 failed: %s",
          g_strerror (errno));
    }
  }

  return TRUE;

socket_pair:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE, (NULL),
        GST_ERROR_SYSTEM);
    return FALSE;
  }
permission_denied:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM);
    return FALSE;
  }
not_found:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), GST_ERROR_SYSTEM);
    return FALSE;
  }
no_handle:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
        ("can't get raw1394 handle (%s)", g_strerror (errno)));
    return FALSE;
  }
no_ports:
  {
    raw1394_destroy_handle (src->handle);
    src->handle = NULL;
    GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
        ("no ports available for raw1394"));
    return FALSE;
  }
cannot_set_port:
  {
    GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, (NULL),
        ("can't set 1394 port %d", src->port));
    return FALSE;
  }
cannot_start:
  {
    raw1394_destroy_handle (src->handle);
    src->handle = NULL;
    iec61883_mpeg2_close (src->iec61883mpeg2);
    src->iec61883mpeg2 = NULL;
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
        ("can't start 1394 iso receive"));
    return FALSE;
  }
cannot_initialise_dv:
  {
    raw1394_destroy_handle (src->handle);
    src->handle = NULL;
    GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
        ("can't initialise iec61883 hdv"));
    return FALSE;
  }
}

static gboolean
gst_hdv1394src_stop (GstBaseSrc * bsrc)
{
  GstHDV1394Src *src = GST_HDV1394SRC (bsrc);

  close (READ_SOCKET (src));
  close (WRITE_SOCKET (src));
  READ_SOCKET (src) = -1;
  WRITE_SOCKET (src) = -1;

  iec61883_mpeg2_close (src->iec61883mpeg2);
#if 0
  raw1394_stop_iso_rcv (src->handle, src->channel);
#endif

  if (src->use_avc) {
    raw1394handle_t avc_handle = raw1394_new_handle_on_port (src->port);

    /* pause and stop the VCR */
    if (avc_handle) {
      if (!avc1394_vcr_is_recording (avc_handle, src->avc_node)
          && (avc1394_vcr_is_playing (avc_handle, src->avc_node)
              != AVC1394_VCR_OPERAND_PLAY_FORWARD_PAUSE))
        avc1394_vcr_pause (avc_handle, src->avc_node);
      avc1394_vcr_stop (avc_handle, src->avc_node);
      raw1394_destroy_handle (avc_handle);
    } else {
      GST_WARNING_OBJECT (src, "Starting VCR via avc1394 failed: %s",
          g_strerror (errno));
    }
  }

  raw1394_destroy_handle (src->handle);

  return TRUE;
}

static gboolean
gst_hdv1394src_unlock (GstBaseSrc * bsrc)
{
  GstHDV1394Src *src = GST_HDV1394SRC (bsrc);

  SEND_COMMAND (src, CONTROL_STOP);

  return TRUE;
}

static void
gst_hdv1394src_update_device_name (GstHDV1394Src * src)
{
  raw1394handle_t handle;
  gint portcount, port, nodecount, node;
  rom1394_directory directory;

  g_free (src->device_name);
  src->device_name = NULL;

  GST_LOG_OBJECT (src, "updating device name for current GUID");

  handle = raw1394_new_handle ();

  if (handle == NULL)
    goto gethandle_failed;

  portcount = raw1394_get_port_info (handle, NULL, 0);
  for (port = 0; port < portcount; port++) {
    if (raw1394_set_port (handle, port) >= 0) {
      nodecount = raw1394_get_nodecount (handle);
      for (node = 0; node < nodecount; node++) {
        if (src->guid == rom1394_get_guid (handle, node)) {
          if (rom1394_get_directory (handle, node, &directory) >= 0) {
            g_free (src->device_name);
            src->device_name = g_strdup (directory.label);
            rom1394_free_directory (&directory);
            goto done;
          } else {
            GST_WARNING ("error reading rom directory for node %d", node);
          }
        }
      }
    }
  }

  src->device_name = g_strdup ("Unknown");      /* FIXME: translate? */

done:

  raw1394_destroy_handle (handle);
  return;

/* ERRORS */
gethandle_failed:
  {
    GST_WARNING ("failed to get raw1394 handle: %s", g_strerror (errno));
    src->device_name = g_strdup ("Unknown");    /* FIXME: translate? */
    return;
  }
}

/*** GSTURIHANDLER INTERFACE *************************************************/

static GstURIType
gst_hdv1394src_uri_get_type (GType type)
{
  return GST_URI_SRC;
}

static const gchar *const *
gst_hdv1394src_uri_get_protocols (GType type)
{
  static const gchar *protocols[] = { (char *) "hdv", NULL };

  return protocols;
}

static gchar *
gst_hdv1394src_uri_get_uri (GstURIHandler * handler)
{
  GstHDV1394Src *gst_hdv1394src = GST_HDV1394SRC (handler);

  return gst_hdv1394src->uri;
}

static gboolean
gst_hdv1394src_uri_set_uri (GstURIHandler * handler, const gchar * uri,
    GError ** error)
{
  gchar *protocol, *location;
  gboolean ret = TRUE;
  GstHDV1394Src *gst_hdv1394src = GST_HDV1394SRC (handler);

  protocol = gst_uri_get_protocol (uri);
  if (strcmp (protocol, "hdv") != 0) {
    g_free (protocol);
    g_set_error (error, GST_URI_ERROR, GST_URI_ERROR_BAD_URI,
        "Invalid HDV URI");
    return FALSE;
  }
  g_free (protocol);

  location = gst_uri_get_location (uri);
  if (location && *location != '\0')
    gst_hdv1394src->port = strtol (location, NULL, 10);
  else
    gst_hdv1394src->port = DEFAULT_PORT;
  g_free (location);
  g_free (gst_hdv1394src->uri);
  gst_hdv1394src->uri = g_strdup_printf ("hdv://%d", gst_hdv1394src->port);

  return ret;
}

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

  iface->get_type = gst_hdv1394src_uri_get_type;
  iface->get_protocols = gst_hdv1394src_uri_get_protocols;
  iface->get_uri = gst_hdv1394src_uri_get_uri;
  iface->set_uri = gst_hdv1394src_uri_set_uri;
}
