//---------------------------------------------------------------
  void
  Device1394::initDevice(int port)
  {
    MIRO_DBG(VIDEO, LL_DEBUG, "Device1394::initDevice()");

    handle_ = dc1394_create_handle(port);
    if (!handle_) {
      throw Miro::Exception("Device1394::initDevice: unable to create handle");
    }

    int num_nodes = raw1394_get_nodecount(handle_);
    int camera_count = 0;
    nodeid_t * camera_nodes = dc1394_get_camera_nodes(handle_, &camera_count, 1);

    MIRO_DBG_OSTR(VIDEO, LL_DEBUG,
		  "Device1394::initDevice: cameracount = " << camera_count);
    if (camera_count < 1)
      throw Miro::Exception("Device1394::initDevice: no camera found");

    p_camera_->node = camera_nodes[0];
    MIRO_DBG_OSTR(VIDEO, LL_DEBUG, 
		  "Device1394::initDevice: node = " << 
		  p_camera_->node << "/" << num_nodes);
    if (p_camera_->node == num_nodes - 1)
      throw Miro::Exception("Device1394::initDevice: camera is highest numbered node.");

    dc1394_stop_iso_transmission(handle_, p_camera_->node);

    if (dc1394_get_camera_feature_set(handle_, p_camera_->node, &features_) != DC1394_SUCCESS)
      throw Miro::Exception("Device1394::initDevice: unable to get camera features");
	
    if (Miro::Log::level() >= Miro::Log::LL_NOTICE)
      dc1394_print_feature_set(&features_);
  }
Example #2
0
int discoverAVC( int* port, octlet_t guid )
{
	rom1394_directory rom_dir;
	raw1394handle_t handle;
	int device = -1;
	int i, j = 0;
	int m = raw1394_get_num_ports();

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

	for ( ; j < m && device == -1; j++ )
	{
		handle = raw1394_open( j );
		for ( i = 0; i < raw1394_get_nodecount( handle ); ++i )
		{
			if ( guid != 0 )
			{
				/* select explicitly by GUID */
				if ( guid == rom1394_get_guid( handle, i ) )
				{
					device = i;
					*port = j;
					break;
				}
			}
			else
			{
				/* select first AV/C Tape Reccorder Player node */
				if ( rom1394_get_directory( handle, i, &rom_dir ) < 0 )
				{
					fprintf( stderr, "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 ) )
				{
					device = i;
					*port = j;
					break;
				}
			}
		}
		raw1394_close( handle );
	}

	return device;
}
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;
    }
}
/*
 * 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;
}
Example #5
0
bool linuxfwCamera::findCamera() {
	
	// get the number of ports
	raw1394handle_t phandle = raw1394_new_handle();
	
	if (phandle==NULL) {
		printf( "no firewire ports found\n");
		return false;
	}
	
	struct raw1394_portinfo pinf;
	int ports = raw1394_get_port_info(phandle, &pinf, 0);
	dc1394_destroy_handle(phandle);
	
	//printf("firewire ports: %d\n",ports);
	if (ports<1) {
		printf("no firewire ports found\n");
		return false;
	}
	// open ohci and asign handle to it
	for (int i=0;i<ports;i++)  {
		//printf("trying port %d\n",i);
		handle = dc1394_create_handle(i);
	
		// get the camera nodes and describe them as we find them
		numNodes = raw1394_get_nodecount(handle);
		camera_nodes = dc1394_get_camera_nodes(handle,&numCameras,0);
		//fflush(stdout);
	
		//printf("found %d cameras\n",numCameras);
		if (numCameras<1) {
			dc1394_destroy_handle(handle);
			continue;
		} else {
			cameraID = 0;
			return true;
		}
	}
	
	fprintf( stderr, "no firewire camera found\n");
	return false;
}
Example #6
0
static GValueArray *
gst_1394_get_guid_array (void)
{
  GValueArray *result = NULL;
  raw1394handle_t handle = NULL;
  int num_ports = 0;
  int port = 0;
  int num_nodes = 0;
  int node = 0;
  rom1394_directory directory;
  GValue value = { 0, };

  handle = raw1394_new_handle ();

  if (handle == NULL)
    return NULL;

  num_ports = raw1394_get_port_info (handle, NULL, 0);
  for (port = 0; port < num_ports; port++) {
    if (raw1394_set_port (handle, port) >= 0) {
      num_nodes = raw1394_get_nodecount (handle);
      for (node = 0; node < num_nodes; node++) {
        rom1394_get_directory (handle, node, &directory);
        if (rom1394_get_node_type (&directory) == ROM1394_NODE_TYPE_AVC &&
            avc1394_check_subunit_type (handle, node,
                AVC1394_SUBUNIT_TYPE_VCR)) {
          if (result == NULL)
            result = g_value_array_new (3);     /* looks like a sensible default */
          g_value_init (&value, G_TYPE_UINT64);
          g_value_set_uint64 (&value, rom1394_get_guid (handle, node));
          g_value_array_append (result, &value);
          g_value_unset (&value);
        }
      }
    }
  }

  return result;
}
Example #7
0
void AVC1394Control::initialize()
{
	int i;

	current_command = COMMAND_NONE;
	device = -1;

	device_lock = new Mutex("AVC1394Control::device_lock");

#ifdef RAW1394_V_0_8
	handle = raw1394_get_handle();
#else
	handle = raw1394_new_handle();
#endif
//printf("AVC1394Control::initialize(): 1\n");
	if(!handle)
	{
//printf("AVC1394Control::initialize(): 2\n");
		if(!errno)
		{
//printf("AVC1394Control::initialize(): 3\n");
			fprintf(stderr, "AVC1394Control::initialize(): Not Compatable!\n");
		} 
		else 
		{
//printf("AVC1394Control::initialize(): 4\n");
			fprintf(stderr, "AVC1394Control::initialize(): couldn't get handle\n");
		}
		return;
	}

	if(raw1394_set_port(handle, 0) < 0) {
//printf("AVC1394Control::initialize(): 5\n");
		perror("AVC1394Control::initialize(): couldn't set port");
//		raw1394_destroy_handle(handle);
		return;
	}

	for(i = 0; i < raw1394_get_nodecount(handle); i++)
	{
		if(rom1394_get_directory(handle, i, &rom_dir) < 0)
		{
//printf("AVC1394Control::initialize(): 6\n");
			fprintf(stderr, "AVC1394Control::initialize(): node %d\n", i);
//			raw1394_destroy_handle(handle);
			return;
		}
		
		if((rom1394_get_node_type(&rom_dir) == ROM1394_NODE_TYPE_AVC) &&
			avc1394_check_subunit_type(handle, i, AVC1394_SUBUNIT_TYPE_VCR))
		{
//printf("AVC1394Control::initialize(): 7\n");
			device = i;
			break;
		}
	}

	if(device == -1)
	{
//printf("AVC1394Control::initialize(): 8\n");
		fprintf(stderr, "AVC1394Control::initialize(): No AV/C Devices\n");
//		raw1394_destroy_handle(handle);
		return;
	}

}
bool FirewirePort::ScanNodes(void)
{
    int node, board;  // loop counters

    // Clear any existing Node2Board
    memset(Node2Board, BoardIO::MAX_BOARDS, sizeof(Node2Board));

    // Get base node id (zero out 6 lsb)
    baseNodeId = raw1394_get_local_id(handle) & 0xFFC0;
    outStr << "ScanNodes: base node id = " << std::hex << baseNodeId << std::endl;

    // iterate through all the nodes and find out their boardId
    int numNodes = raw1394_get_nodecount(handle);
    NumOfNodes_ = numNodes - 1;

    outStr << "ScanNodes: building node map for " << numNodes << " nodes:" << std::endl;
    IsAllBoardsBroadcastCapable_ = true;
    // Iterate through all connected nodes (except for last one, which is the PC).
    for (node = 0; node < numNodes-1; node++){
        quadlet_t data;
        if (raw1394_read(handle, baseNodeId+node, 4, 4, &data)) {
            outStr << "ScanNodes: unable to read from node " << node << std::endl;
            return false;
        }
        data = bswap_32(data);
        if ((data != 0xC0FFEE) && (data != QLA1_String)) {
            outStr << "Node " << node << " is not a QLA board" << std::endl;
            continue;
        }
        // Now, read firmware version
        unsigned long fver = 0;
        if (data == QLA1_String) {
            if (raw1394_read(handle, baseNodeId+node, 7, 4, &data)) {
                outStr << "ScanNodes: unable to read firmware version from node "
                       << node << std::endl;
                return false;
            }
            data = bswap_32(data);
            fver = data;
        }
        if (raw1394_read(handle, baseNodeId+node, 0, 4, &data)) {
            outStr << "ScanNodes: unable to read status from node " << node << std::endl;
            return false;
        }
        data = bswap_32(data);
        // board_id is bits 27-24, BOARD_ID_MASK = 0x0f000000
        board = (data & BOARD_ID_MASK) >> 24;
        outStr << "  Node " << node << ", BoardId = " << board
               << ", Firmware Version = " << fver << std::endl;
        if (Node2Board[node] < BoardIO::MAX_BOARDS)
            outStr << "    Duplicate entry, previous value = "
                   << static_cast<int>(Node2Board[node]) << std::endl;
        Node2Board[node] = board;
        FirmwareVersion[board] = fver;

        // check firmware version
        // FirmwareVersion >= 4, broadcast capable
        if (fver < 4) IsAllBoardsBroadcastCapable_ = false;
    }

    // Use broadcast by default if all firmware are bc capable
    if (IsAllBoardsBroadcastCapable_) {
        Protocol_ = FirewirePort::PROTOCOL_SEQ_R_BC_W;
        outStr << "ScanNodes: all nodes broadcast capable" << std::endl;
    }

    // update Board2Node
    for (board = 0; board < BoardIO::MAX_BOARDS; board++) {
        Board2Node[board] = MAX_NODES;
        for (node = 0; node < numNodes-1; node++) {
            if (Node2Board[node] == board) {
                if (Board2Node[board] < MAX_NODES)
                    outStr << "Warning: GetNodeId detected duplicate board id for " << board << std::endl;
                Board2Node[board] = node;
            }
        }
    }

    return true;
}
int CameraDcam::findCameraByGuid(void)
{
   /*-----------------------------------------------------------------------
    *  get the camera nodes and describe them as we find them
    * Number of available ports is known globally.
    *-----------------------------------------------------------------------*/
    //as the root node is not determined statically we may reset the bus in order to make a camera become
    //NOT a root node.
    //Uses generally the first camera found on bus.

    int portNum,resetNum, numNodes, foundCamerasOnBus;
    int resetBus = 1;
    nodeid_t * camera_nodes = NULL;

    for (resetNum=0; resetNum < MAX_RESETS && resetBus == 1; resetNum++)
    {
        resetBus = 0;
        foundCamerasOnBus = 0;
        for (portNum=0; portNum < firewireNumPorts; portNum++)
        {
            porthandle[portNum] = dc1394_create_handle(portNum);//handle for portNum
            if (porthandle[portNum]==NULL)
            {
                GDOS_WARNING("error: Unable to aquire handle for port %i.\n", portNum);
            }

            //each port can have multiple cameras attached.
            numNodes = 0;
            camera_nodes = dc1394_get_camera_nodes(porthandle[portNum], &numNodes, 0); //last parameter defines if output is given.

            //if any camera is found on this port...
            if (numNodes > 0)
            {
                GDOS_DBG_INFO("found %i cameras to port %i.\n",numNodes, portNum);
                //try to put them all at their position.
                int k;
                 for (k = 0; k < numNodes; k++)
                 {
                    //try to get camera guid
                    dc1394_camerainfo info;
                    if (dc1394_get_camera_info(porthandle[portNum], camera_nodes[k], &info) == DC1394_SUCCESS)
                    {
                        //test if camera node is root, if so reset bus...
                        if (camera_nodes[k] == raw1394_get_nodecount(porthandle[portNum])-1)
                        {
                            //reset and retry if root
                            GDOS_WARNING("error: camera found as root node - resetting.\n");
                            raw1394_reset_bus(porthandle[portNum]);
                            int node_pos = 0;
                            for (node_pos=0; node_pos < 10; node_pos++)
                                resetBus = 1;
                                foundCamerasOnBus = foundCamerasOnBus - k; //no -1 as the array stqarts with 0
                        }
                        GDOS_DBG_INFO("found camera with guid:%x \n", info.euid_64);
                        //put camera in the global variable
                        if ((cameraGuid == 0) || (cameraGuid == (int) info.euid_64))
                        {
                            GDOS_DBG_INFO("using camera node:%i with guid:%x \n",camera_nodes[k],  info.euid_64);
                            camera_node = camera_nodes[k];
                            dc1394CameraPortNo = portNum;
                        }
                        foundCamerasOnBus = foundCamerasOnBus + 1;
                    }//if camera_info
                }//for numCameras
            }//if numCamera > 0
            else {
               GDOS_ERROR("No cameras found! (%d nodes on the bus)\n"
               "  - could be you need to try a different 1394 device (modify code to fix)\n",
               numNodes );
            }
        }//for firewireNumPorts
    }//for MAXRESETS

    GDOS_DBG_INFO("bus init complete found %i cameras.\n",foundCamerasOnBus);
    if (resetNum == MAX_RESETS-1)
        return FW_ERROR;
    return DC1394_SUCCESS;
}
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;
}
Example #11
0
int cpi_enumerate_devices( unicap_device_t *device, int index )
{
    raw1394handle_t raw1394handle;
    int numcards;
    struct raw1394_portinfo portinfo[16];
    int current_index = 0;
    int card = 0;

    /* 	TRACE( "dcam_enumerate_devices ( i = %d ) \n", index ); */

    raw1394handle = raw1394_new_handle();
    if( !raw1394handle )
    {
        if( !errno )
        {
            TRACE( "dcam: no kernel support\n" );
            return STATUS_NO_DEVICE;
        }
        else
        {
            TRACE( "dcam: can' t get handle\n" );
            return STATUS_NO_DEVICE;
        }
    }

    numcards = raw1394_get_port_info( raw1394handle, portinfo, 16 );
    if( !numcards )
    {
        TRACE( "dcam: no 1394 cards!\n" );

        raw1394_destroy_handle( raw1394handle );
        return STATUS_NO_DEVICE;
    }
    else if( numcards < 0 )
    {
        raw1394_destroy_handle( raw1394handle );
        return STATUS_NO_DEVICE;
    }

    raw1394_destroy_handle( raw1394handle );

    // go through all present cards, search for cameras
    for( card = 0; card < numcards; card++ )
    {
        int nodecount;
        int node = 0;
        if( ( raw1394handle = raw1394_new_handle_on_port( card ) ) == 0 )
        {
            return STATUS_NO_DEVICE;
        }

        raw1394_set_userdata( raw1394handle, 0 );

        TRACE( "dcam: probing card %d\n", card );

        nodecount = raw1394_get_nodecount( raw1394handle );
        for( node = 0; node < nodecount; node++ )
        {
            int unit_directory_count;
            int directory;

            TRACE( "dcam: probing node %d\n", node );

            // shortcut since most devices only have 1 unit directory
            if( _dcam_is_compatible( raw1394handle, node, 0 ) )
            {
                if( index == current_index )
                {
                    unicap_status_t status;
                    status = _dcam_get_device_info( raw1394handle, node, 0, device );
                    if( status == STATUS_SUCCESS )
                    {
                        TRACE( "found dcam\n" );
                        // got the device with the index we want
                        raw1394_destroy_handle( raw1394handle );
                        return status;
                    }
                    else
                    {
                        TRACE( "can not get device info!\n" );
                    }
                }
                current_index++;
                continue;
            }

            unit_directory_count = _dcam_get_directory_count( raw1394handle, node );
            if( unit_directory_count <= 1 )
            {
                TRACE( "directory count <= 1 for node: %d\n", node );
                continue; // try next device
            }

            // scan through all directories of this device
            for( directory = 1; directory < unit_directory_count; directory++ )
            {
                if( _dcam_is_compatible( raw1394handle, node, directory ) )
                {
                    if( index == current_index )
                    {
                        unicap_status_t status;
                        status = _dcam_get_device_info( raw1394handle, node, directory, device );
                        if( status == STATUS_SUCCESS )
                        {
                            // got the device with the index we want
                            raw1394_destroy_handle( raw1394handle );
                            return status;
                        }
                    }
                    current_index++;
                }
            }// for( directory..
        }// for( node..
        raw1394_destroy_handle( raw1394handle );
    }// for( card..

    return STATUS_NO_DEVICE;
}
Example #12
0
int dc1394Init(int cam, int width, int height, int max_frames, int trigger_mode, int shutter, int gain, int trig_on, int iso_speed, int frame_rate)
{
  int numNodes;
  nodeid_t * camera_nodes;
  int numCameras;

  if (first) {
    bzero(Cams, sizeof(Cams));
    first = 0;
  }
    printf("now is the time\n");
  if ((cam < 0) || (cam >= MAX_CAMERAS)) {
    fprintf(stderr, "Camera out of range, cam = %d must be between 0 and %d\n", cam, MAX_CAMERAS);
    return 0;
  }

  /* clean up any active daq */
  if (Cams[cam].thread_id != 0) {
    void *status;
    pthread_cancel(Cams[cam].thread_id);
    pthread_join(Cams[cam].thread_id, &status);
    Cams[cam].thread_id = 0;
  }

  /* now find the camera choke if not there or not correct */
  Cams[cam].handle = dc1394_create_handle(0);
  if (Cams[cam].handle==NULL)
  {
    fprintf( stderr, "Unable to aquire a raw1394 handle\n\n"
             "Please check \n"
	     "  - if the kernel modules `ieee1394',`raw1394' and `ohci1394' are loaded \n"
	     "  - if you have read/write access to /dev/raw1394\n\n");
    return(0);
  }

  /*-----------------------------------------------------------------------
   *  get the camera nodes and describe them as we find them
   *-----------------------------------------------------------------------*/
  numNodes = raw1394_get_nodecount(Cams[cam].handle);
  camera_nodes = dc1394_get_camera_nodes(Cams[cam].handle,&numCameras,1);
  if (numCameras<1)
  {
    fprintf( stderr, "no cameras found :(\n");
    dc1394_destroy_handle(Cams[cam].handle);
    Cams[cam].handle = 0;
    return(0);
  }

  /*-----------------------------------------------------------------------
   *  to prevent the iso-transfer bug from raw1394 system, check if
   *  camera is highest node. For details see 
   *  http://linux1394.sourceforge.net/faq.html#DCbusmgmt
   *  and
   *  http://sourceforge.net/tracker/index.php?func=detail&aid=435107&group_id=8157&atid=108157
   *-----------------------------------------------------------------------*/
  if( camera_nodes[0] == numNodes-1)
  {
    fprintf( stderr, "\n"
             "Sorry, your camera is the highest numbered node\n"
             "of the bus, and has therefore become the root node.\n"
             "The root node is responsible for maintaining \n"
             "the timing of isochronous transactions on the IEEE \n"
             "1394 bus.  However, if the root node is not cycle master \n"
             "capable (it doesn't have to be), then isochronous \n"
             "transactions will not work.  The host controller card is \n"
             "cycle master capable, however, most cameras are not.\n"
             "\n"
             "The quick solution is to add the parameter \n"
             "attempt_root=1 when loading the OHCI driver as a \n"
             "module.  So please do (as root):\n"
             "\n"
             "   rmmod ohci1394\n"
             "   insmod ohci1394 attempt_root=1\n"
             "\n"
             "for more information see the FAQ at \n"
             "http://linux1394.sourceforge.net/faq.html#DCbusmgmt\n"
             "\n");
    dc1394_destroy_handle(Cams[cam].handle);
    dc1394_free_camera_nodes(camera_nodes);
    return(0);
  }
  
  /*-----------------------------------------------------------------------
   *  setup capture
   *-----------------------------------------------------------------------*/
   if (dc1394_dma_setup_capture(Cams[cam].handle,camera_nodes[0],
                           0, /* channel */ 
                           FORMAT_VGA_NONCOMPRESSED,
                           MODE_640x480_MONO,
                           SPEED_400,
                           FRAMERATE_30,
				3, /* frames */
			    1,
			    "/dev/video1394/0", 
                           &Cams[cam].camera)!=DC1394_SUCCESS) 
 {
    fprintf( stderr,"unable to setup camera-\n"
             "check line %d of %s to make sure\n"
             "that the video mode,framerate and format are\n"
             "supported by your camera\n",
             __LINE__,__FILE__);
    dc1394_dma_release_camera(Cams[cam].handle,&Cams[cam].camera);
    Cams[cam].dma_active = 0;
    dc1394_destroy_handle(Cams[cam].handle);
    Cams[cam].handle = 0;
    dc1394_free_camera_nodes(camera_nodes);
    return(0);
  }
  dc1394_free_camera_nodes(camera_nodes);
  
  /* set trigger mode */
  if( dc1394_set_trigger_mode(Cams[cam].handle, Cams[cam].camera.node, trigger_mode)
      != DC1394_SUCCESS)
  {
    fprintf( stderr, "unable to set camera trigger mode\n");
    /*    
    dc1394_dma_release_camera(Cams[cam].handle,&Cams[cam].camera);
    Cams[cam].dma_active = 0;
    dc1394_destroy_handle(Cams[cam].handle);
    Cams[cam].handle = 0;
    return(0);
    */
  }

  /* eventually the same for the shutter and gain */

  if (dc1394_set_trigger_on_off(Cams[cam].handle, Cams[cam].camera.node,
				trig_on) != DC1394_SUCCESS)
    {
      fprintf(stderr, "unable to set trigger on to %d\n", trig_on);
    }


  /*-----------------------------------------------------------------------
   *  have the camera start sending us data
   *-----------------------------------------------------------------------*/
  if (dc1394_start_iso_transmission(Cams[cam].handle,Cams[cam].camera.node) !=DC1394_SUCCESS) 
  {
    fprintf( stderr, "unable to start camera iso transmission\n");
    dc1394_dma_release_camera(Cams[cam].handle,&Cams[cam].camera);
    Cams[cam].dma_active = 0;
    dc1394_destroy_handle(Cams[cam].handle);
    Cams[cam].handle = 0;
    return(0);
  }
  Cams[cam].running = 1;

  /* make room for the answers and write down all of the knobs for later use */
  if ( (width != Cams[cam].width) ||
       (height != Cams[cam].height) ||
       (max_frames != Cams[cam].max_frames) ){
    if (Cams[cam].frames != NULL)
      free(Cams[cam].frames);
    Cams[cam].frames = (unsigned char *)malloc(width*height*max_frames);
    if (Cams[cam].frames == NULL) {
      fprintf(stderr, "Could not allocate memory for %d frames (%d x %d)\n", max_frames, width, height);
      dc1394_dma_release_camera(Cams[cam].handle,&Cams[cam].camera);
      Cams[cam].dma_active = 0;
      dc1394_destroy_handle(Cams[cam].handle);
      Cams[cam].handle = 0;
      Cams[cam].max_frames = 0;
      return(0);
    }
    Cams[cam].times = (double *)malloc(max_frames * sizeof(double));
    if (Cams[cam].times == NULL) {
      fprintf(stderr, "Could not allocate memory for %d times\n", max_frames);
      dc1394_dma_release_camera(Cams[cam].handle,&Cams[cam].camera);
      free( Cams[cam].frames );
      Cams[cam].dma_active = 0;
      dc1394_destroy_handle(Cams[cam].handle);
      Cams[cam].handle = 0;
      Cams[cam].max_frames = 0;
     return(0);
    }

    Cams[cam].width = width;
    Cams[cam].height = height;
    Cams[cam].max_frames = max_frames;
  }
  Cams[cam].next_frame = 0;
  Cams[cam].trigger_mode = trigger_mode;
  Cams[cam].shutter = shutter;
  Cams[cam].gain = gain;
  if (pthread_create(&Cams[cam].thread_id,  NULL, AcquireFrames, (void *)cam) != 0) {
      fprintf(stderr, "Could not create thread to handle camera daq\n");
      dc1394_stop_iso_transmission(Cams[cam].handle,Cams[cam].camera.node);
      Cams[cam].running = 0;
      dc1394_dma_release_camera(Cams[cam].handle,&Cams[cam].camera);
      Cams[cam].dma_active = 0;
      dc1394_destroy_handle(Cams[cam].handle);
      Cams[cam].handle = 0;
      return(0);
  }
  return(1);
}