Exemple #1
0
static dc1394error_t
windows_capture_setup (platform_camera_t * craw, uint32_t num_dma_buffers, uint32_t flags)
{
    int i;

    free_resources(craw);

    ULARGE_INTEGER dma_buffer_size;
    const char * device_path = craw->device->device_path;
    t1394_GetHostDmaCapabilities (device_path, NULL, &dma_buffer_size);

    const dc1394video_frame_t * frame = &craw->capture.frames[0];
    int max_buffer_size = frame->total_bytes; //number of bytes needed
    int max_bytes = frame->packet_size / 2;

    PACQUISITION_BUFFER acquisition_buffer =
        dc1394BuildAcquisitonBuffer(max_buffer_size,
                                    (unsigned long)dma_buffer_size.QuadPart,
                                    max_bytes, 0);

    ISOCH_STREAM_PARAMS stream_params;
    if (acquisition_buffer) {
        stream_params.nMaxBufferSize = acquisition_buffer->subBuffers[0].ulSize;
        stream_params.nNumberOfBuffers = (num_dma_buffers * acquisition_buffer->nSubBuffers) + 1;

        // free the buffer: this wouldn't be necessary if this were merged into StartImageAcquisitionEx
        dc1394FreeAcquisitionBuffer(acquisition_buffer);
        acquisition_buffer = NULL;
    } else {
        dc1394_log_error("windows_capture_setup: failed to determine required buffer size and count!");
        return DC1394_FAILURE;
    }

    dc1394speed_t speed;
    if (dc1394_video_get_iso_speed(craw->camera, &speed) != DC1394_SUCCESS) {
        dc1394_log_error("windows_capture_setup: failed to get iso speed!");
        return DC1394_FAILURE;
    }

    uint32_t channel = -1;
    stream_params.fulSpeed = 1 << speed;
    stream_params.nChannel = channel;
    stream_params.nMaxBytesPerFrame = max_bytes;

    DWORD ret = t1394IsochSetupStream(craw->device->device_path,
                                      &stream_params);
    craw->allocated_channel = stream_params.nChannel;
    if (ret != ERROR_SUCCESS) {
        dc1394_log_error("windows_capture_setup: Error on IsochSetupStream: %d\n", ret);
        return DC1394_FAILURE;
    }

#if 1
    // allocate channel/bandwidth if requested
    if (flags & DC1394_CAPTURE_FLAGS_CHANNEL_ALLOC) {
        if (dc1394_iso_allocate_channel (craw->camera, 0, &craw->allocated_channel)
            != DC1394_SUCCESS) {
            return DC1394_FAILURE;
        }
        if (dc1394_video_set_iso_channel (craw->camera, craw->allocated_channel)
            != DC1394_SUCCESS) {
            return DC1394_FAILURE;
        }
    }
#endif
#if 1
    if (flags & DC1394_CAPTURE_FLAGS_BANDWIDTH_ALLOC) {
        unsigned int bandwidth_usage;
        if (dc1394_video_get_bandwidth_usage (craw->camera, &bandwidth_usage)
            != DC1394_SUCCESS) {
            return DC1394_FAILURE;
        }
        if (dc1394_iso_allocate_bandwidth (craw->camera, bandwidth_usage)
            != DC1394_SUCCESS) {
            return DC1394_FAILURE;
        }
        craw->allocated_bandwidth = bandwidth_usage;
    }
#endif

    /* QUEUE the buffers */
    for (i = 0; i < num_dma_buffers; ++i) {
        PACQUISITION_BUFFER buffer =
            dc1394BuildAcquisitonBuffer(max_buffer_size,
                                        dma_buffer_size.QuadPart, max_bytes, i);
        if(!buffer) {
            dc1394_log_error("windows_capture_setup: Error Allocating AcqBuffer %d\n", i);
            return DC1394_FAILURE;
        }

        // add it to our list of buffers
        if (i == 0) {
            craw->pLastBuffer = craw->pFirstBuffer = buffer;
            craw->pLastBuffer->pNextBuffer = craw->pCurrentBuffer = NULL;
        } else {
            craw->pFirstBuffer->pNextBuffer = buffer;
            craw->pFirstBuffer = buffer;
        }
    }

    // all done making buffers
    // open our long term device handle
    HANDLE device;
    if((device = OpenDevice(device_path, TRUE)) == INVALID_HANDLE_VALUE) {
        dc1394_log_error("windows_capture_setup error opening device (%s)\n", craw->device->device_path);
        return DC1394_FAILURE;
    }

    // all done making buffers
    // open our long term device handle
    PACQUISITION_BUFFER buffer;
    for (buffer = craw->pLastBuffer;
         buffer != NULL; buffer = buffer->pNextBuffer) {
        DWORD ret = dc1394AttachAcquisitionBuffer(device, buffer);
        if (ret != ERROR_SUCCESS) {
            dc1394_log_error("windows_capture_setup: Failed to attach buffer %u/%u", buffer->index, num_dma_buffers);
            return DC1394_FAILURE;
        }
    }

    // new: sleep a little while and verify that the buffers were
    // successfully attached this basically catches "Parameter is Incorrect"
    // here instead of confusing users at AcquireImageEx()
    // 50 ms is all it should take for completion routines to fire and
    // propagate in the kernel
    Sleep(50);

    for (buffer = craw->pLastBuffer;
         buffer != NULL; buffer = buffer->pNextBuffer) {
        DWORD dwBytesRet = 0;
        for (unsigned int bb = 0; bb < buffer->nSubBuffers; ++bb) {
            if (!GetOverlappedResult(device,
                                     &(buffer->subBuffers[bb].overLapped),
                                     &dwBytesRet, FALSE)) {
                if (GetLastError() != ERROR_IO_INCOMPLETE) {
                    dc1394_log_error("Buffer validation failed for buffer %u\n", buffer->index,bb);
                    return DC1394_FAILURE;
                }
                // else: this is the actual success case
            } else {
                dc1394_log_error("Buffer %u is unexpectedly ready during pre-listen validation\n", buffer->index, bb);
                return DC1394_FAILURE;
            }
        }
    }

    ret = t1394IsochListen(craw->device->device_path);
    if (ret != ERROR_SUCCESS) {
        dc1394_log_error("Error %08lx on IOCTL_ISOCH_LISTEN\n", ret);
        return DC1394_FAILURE;
    }

    // starting from here we use the ISO channel so we set the flag
    // in the camera struct:
    craw->capture_is_set = 1;

    for (i = 1; i < num_dma_buffers; ++i) {
        memcpy(&craw->capture.frames[i], frame, sizeof (dc1394video_frame_t));
    }
    craw->capture.frames_last_index = num_dma_buffers - 1;

    craw->device_acquisition = device;
    return DC1394_SUCCESS;
}
Exemple #2
0
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;
}
Exemple #3
0
dc1394error_t
platform_capture_setup(platform_camera_t *craw, uint32_t num_dma_buffers,
                     uint32_t flags)
{
    dc1394camera_t * camera = craw->camera;
    dc1394error_t err;

    if (flags & DC1394_CAPTURE_FLAGS_DEFAULT)
        flags = DC1394_CAPTURE_FLAGS_CHANNEL_ALLOC |
            DC1394_CAPTURE_FLAGS_BANDWIDTH_ALLOC;

    // if capture is already set, abort
    if (craw->capture_is_set>0)
        return DC1394_CAPTURE_IS_RUNNING;

    craw->capture.flags=flags;
    craw->allocated_channel = -1;

    // 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!");
        }
    }

    // allocate channel/bandwidth if requested
    if (flags & DC1394_CAPTURE_FLAGS_CHANNEL_ALLOC) {
        if (dc1394_iso_allocate_channel (camera, 0, &craw->allocated_channel)
            != DC1394_SUCCESS)
            goto fail;
        if (dc1394_video_set_iso_channel (camera, craw->allocated_channel)
            != DC1394_SUCCESS)
            goto fail;
    }
    if (flags & DC1394_CAPTURE_FLAGS_BANDWIDTH_ALLOC) {
        unsigned int bandwidth_usage;
        if (dc1394_video_get_bandwidth_usage (camera, &bandwidth_usage)
            != DC1394_SUCCESS)
            goto fail;
        if (dc1394_iso_allocate_bandwidth (camera, bandwidth_usage)
            != DC1394_SUCCESS)
            goto fail;
        craw->allocated_bandwidth = bandwidth_usage;
    }

    craw->capture.frames = malloc (num_dma_buffers * sizeof (dc1394video_frame_t));

    err=capture_basic_setup(camera, craw->capture.frames);
    if (err != DC1394_SUCCESS)
        goto fail;

    if (dc1394_video_get_iso_channel (camera, &craw->iso_channel)
        != DC1394_SUCCESS)
        goto fail;

    // the capture_is_set flag is set inside this function:
    err=capture_linux_setup (craw, num_dma_buffers);
    if (err != DC1394_SUCCESS)
        goto fail;

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

 fail:
    // free resources 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;

    free (craw->capture.frames);
    craw->capture.frames = NULL;
    dc1394_log_error ("Error: Failed to setup DMA capture");

    return DC1394_FAILURE;
}