void set_frame_length(unsigned long size, int numCameras) { frame_length=size; dc1394_log_debug("Setting frame size to %ld kb",size/1024); frame_free=0; frame_buffer = malloc( size * numCameras); }
dc1394error_t dc1394_juju_capture_setup(platform_camera_t *craw, uint32_t num_dma_buffers, uint32_t flags) { struct fw_cdev_create_iso_context create; struct fw_cdev_start_iso start_iso; dc1394error_t err; dc1394video_frame_t proto; int i, j, retval; dc1394camera_t * camera = craw->camera; if (flags & DC1394_CAPTURE_FLAGS_DEFAULT) flags = DC1394_CAPTURE_FLAGS_CHANNEL_ALLOC | DC1394_CAPTURE_FLAGS_BANDWIDTH_ALLOC; craw->flags = flags; // if capture is already set, abort if (craw->capture_is_set>0) return DC1394_CAPTURE_IS_RUNNING; // if auto iso is requested, stop ISO (if necessary) if (flags & DC1394_CAPTURE_FLAGS_AUTO_ISO) { dc1394switch_t is_iso_on; dc1394_video_get_transmission(camera, &is_iso_on); if (is_iso_on == DC1394_ON) { err=dc1394_video_set_transmission(camera, DC1394_OFF); DC1394_ERR_RTN(err,"Could not stop ISO!"); } } if (capture_basic_setup(camera, &proto) != DC1394_SUCCESS) { dc1394_log_error("basic setup failed"); return DC1394_FAILURE; } if (flags & (DC1394_CAPTURE_FLAGS_CHANNEL_ALLOC | DC1394_CAPTURE_FLAGS_BANDWIDTH_ALLOC)) { uint64_t channels_allowed = 0; unsigned int bandwidth_units = 0; int channel; if (flags & DC1394_CAPTURE_FLAGS_CHANNEL_ALLOC) channels_allowed = 0xffff; if (flags & DC1394_CAPTURE_FLAGS_BANDWIDTH_ALLOC) dc1394_video_get_bandwidth_usage (camera, &bandwidth_units); err = juju_iso_allocate (craw, channels_allowed, bandwidth_units, &craw->capture_iso_resource); if (err == DC1394_SUCCESS) { channel = craw->capture_iso_resource->channel; } else if (err == DC1394_FUNCTION_NOT_SUPPORTED) { channel = craw->node_id & 0x3f; dc1394_log_warning ("iso allocation not available in this kernel, " "using channel %d...", channel); } else { dc1394_log_error ("juju: Failed to allocate iso resources"); return err; } if (dc1394_video_set_iso_channel (camera, channel) != DC1394_SUCCESS) return DC1394_NO_ISO_CHANNEL; } if (dc1394_video_get_iso_channel (camera, &craw->iso_channel) != DC1394_SUCCESS) return DC1394_FAILURE; dc1394_log_debug ("juju: Receiving from iso channel %d", craw->iso_channel); craw->iso_fd = open(craw->filename, O_RDWR); if (craw->iso_fd < 0) { dc1394_log_error("error opening file: %s", strerror (errno)); return DC1394_FAILURE; } create.type = FW_CDEV_ISO_CONTEXT_RECEIVE; create.header_size = craw->header_size; create.channel = craw->iso_channel; create.speed = SCODE_400; err = DC1394_IOCTL_FAILURE; if (ioctl(craw->iso_fd, FW_CDEV_IOC_CREATE_ISO_CONTEXT, &create) < 0) { dc1394_log_error("failed to create iso context"); goto error_fd; } craw->iso_handle = create.handle; craw->num_frames = num_dma_buffers; craw->current = -1; craw->buffer_size = proto.total_bytes * num_dma_buffers; craw->buffer = mmap(NULL, craw->buffer_size, PROT_READ | PROT_WRITE , MAP_SHARED, craw->iso_fd, 0); err = DC1394_IOCTL_FAILURE; if (craw->buffer == MAP_FAILED) goto error_fd; err = DC1394_MEMORY_ALLOCATION_FAILURE; craw->frames = malloc (num_dma_buffers * sizeof *craw->frames); if (craw->frames == NULL) goto error_mmap; for (i = 0; i < num_dma_buffers; i++) { err = init_frame(craw, i, &proto); if (err != DC1394_SUCCESS) { dc1394_log_error("error initing frames"); break; } } if (err != DC1394_SUCCESS) { for (j = 0; j < i; j++) release_frame(craw, j); goto error_mmap; } for (i = 0; i < num_dma_buffers; i++) { err = queue_frame(craw, i); if (err != DC1394_SUCCESS) { dc1394_log_error("error queuing"); goto error_frames; } } // starting from here we use the ISO channel so we set the flag in // the camera struct: craw->capture_is_set = 1; start_iso.cycle = -1; start_iso.tags = FW_CDEV_ISO_CONTEXT_MATCH_ALL_TAGS; start_iso.sync = 1; start_iso.handle = craw->iso_handle; retval = ioctl(craw->iso_fd, FW_CDEV_IOC_START_ISO, &start_iso); err = DC1394_IOCTL_FAILURE; if (retval < 0) { dc1394_log_error("error starting iso"); goto error_frames; } // if auto iso is requested, start ISO if (flags & DC1394_CAPTURE_FLAGS_AUTO_ISO) { err=dc1394_video_set_transmission(camera, DC1394_ON); DC1394_ERR_RTN(err,"Could not start ISO!"); craw->iso_auto_started=1; } return DC1394_SUCCESS; error_frames: for (i = 0; i < num_dma_buffers; i++) release_frame(craw, i); error_mmap: munmap(craw->buffer, craw->buffer_size); error_fd: close(craw->iso_fd); return err; }
dc1394error_t platform_capture_stop(platform_camera_t *craw) { dc1394camera_t * camera = craw->camera; int err; if (craw->capture_is_set>0) { // unlisten if (ioctl(craw->capture.dma_fd, VIDEO1394_IOC_UNLISTEN_CHANNEL, &(craw->iso_channel)) < 0) return DC1394_IOCTL_FAILURE; // release if (craw->capture.dma_ring_buffer) { munmap((void*)craw->capture.dma_ring_buffer,craw->capture.dma_buffer_size); } while (close(craw->capture.dma_fd) != 0) { dc1394_log_debug("waiting for dma_fd to close"); sleep (1); } craw->capture.dma_fd = -1; free (craw->capture.frames); craw->capture.frames = NULL; // this dma_device file is allocated by the strdup() function and can be freed here without problems. free(craw->capture.dma_device_file); craw->capture.dma_device_file=NULL; // capture is not set anymore craw->capture_is_set=0; // free ressources if they were allocated if (craw->allocated_channel >= 0) { if (dc1394_iso_release_channel (camera, craw->allocated_channel) != DC1394_SUCCESS) dc1394_log_warning("Warning: Could not free ISO channel"); } if (craw->allocated_bandwidth) { if (dc1394_iso_release_bandwidth (camera, craw->allocated_bandwidth) != DC1394_SUCCESS) dc1394_log_warning("Warning: Could not free bandwidth"); } craw->allocated_channel = -1; craw->allocated_bandwidth = 0; // stop ISO if it was started automatically if (craw->iso_auto_started>0) { err=dc1394_video_set_transmission(camera, DC1394_OFF); DC1394_ERR_RTN(err,"Could not stop ISO!"); craw->iso_auto_started=0; } // free the additional capture handle raw1394_destroy_handle(craw->capture.handle); } else { return DC1394_CAPTURE_IS_NOT_SET; } return DC1394_SUCCESS; }