/* 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];

  if (fcntl (READ_SOCKET (src), F_SETFL, O_NONBLOCK) < 0)
    GST_ERROR_OBJECT (src, "failed to make read socket non-blocking: %s",
        g_strerror (errno));
  if (fcntl (WRITE_SOCKET (src), F_SETFL, O_NONBLOCK) < 0)
    GST_ERROR_OBJECT (src, "failed to make write socket non-blocking: %s",
        g_strerror (errno));

  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;
}
