16 #include <unicap/unicap.h>
18 static boolean lives_wait_user_buffer(lives_vdev_t *ldev, unicap_data_buffer_t **buff,
double timeout) {
20 unicap_status_t status;
25 status = unicap_poll_buffer(ldev->handle, &ncount);
28 if (status != STATUS_SUCCESS) lives_printerr(
"Unicap poll failed with status %d\n", status);
32 if (!SUCCESS(unicap_wait_buffer(ldev->handle, buff)))
return FALSE;
44 static boolean lives_wait_system_buffer(lives_vdev_t *ldev,
double timeout) {
49 if (ldev->buffer_ready != 0) {
63 static void new_frame_cb(unicap_event_t event, unicap_handle_t handle,
64 unicap_data_buffer_t *buffer,
void *usr_data) {
65 lives_vdev_t *ldev = (lives_vdev_t *)usr_data;
67 ldev->buffer_ready = 0;
71 if (ldev->buffer_ready != 1) {
72 lives_memcpy(ldev->buffer1.data, buffer->data, ldev->buffer1.buffer_size);
73 ldev->buffer_ready = 1;
75 lives_memcpy(ldev->buffer2.data, buffer->data, ldev->buffer2.buffer_size);
76 ldev->buffer_ready = 2;
82 lives_vdev_t *ldev = (lives_vdev_t *)sfile->
ext_src;
83 unicap_data_buffer_t *returned_buffer = NULL;
85 void *odata = ldev->buffer1.data;
89 weed_set_int_value(layer, WEED_LEAF_WIDTH, sfile->
hsize /
91 weed_set_int_value(layer, WEED_LEAF_HEIGHT, sfile->
vsize);
92 weed_set_int_value(layer, WEED_LEAF_CURRENT_PALETTE, ldev->current_palette);
93 weed_set_int_value(layer, WEED_LEAF_YUV_SUBSPACE, WEED_YUV_SUBSPACE_YCBCR);
94 weed_set_int_value(layer, WEED_LEAF_YUV_SAMPLING, WEED_YUV_SAMPLING_DEFAULT);
95 weed_set_int_value(layer, WEED_LEAF_YUV_CLAMPING, ldev->YUV_clamping);
99 if (ldev->buffer_type == UNICAP_BUFFER_TYPE_USER) {
101 ldev->buffer1.data = (
unsigned char *)weed_get_voidptr_value(layer, WEED_LEAF_PIXEL_DATA, &
error);
104 unicap_queue_buffer(ldev->handle, &ldev->buffer1);
106 if (!lives_wait_user_buffer(ldev, &returned_buffer, timeoutsecs)) {
108 lives_printerr(
"Failed to wait for user buffer!\n");
109 unicap_stop_capture(ldev->handle);
110 unicap_dequeue_buffer(ldev->handle, &returned_buffer);
111 unicap_start_capture(ldev->handle);
113 ldev->buffer1.data = (
unsigned char *)odata;
118 if (!lives_wait_system_buffer(ldev, timeoutsecs)) {
120 lives_printerr(
"Failed to wait for system buffer!\n");
123 if (ldev->buffer_ready == 1) returned_buffer = &ldev->buffer1;
124 else returned_buffer = &ldev->buffer2;
127 pixel_data = weed_get_voidptr_array(layer, WEED_LEAF_PIXEL_DATA, &
error);
130 boolean contig =
FALSE;
134 if (ldev->buffer_type == UNICAP_BUFFER_TYPE_SYSTEM) {
135 int rowstride = weed_get_int_value(layer, WEED_LEAF_ROWSTRIDES, &
error);
136 size_t bsize = rowstride * sfile->
vsize;
137 if (bsize > returned_buffer->buffer_size) {
139 lives_printerr(
"Warning - returned buffer size too small !\n");
141 bsize = returned_buffer->buffer_size;
143 lives_memcpy(pixel_data[0], returned_buffer->data, bsize);
158 ldev->buffer1.data = (
unsigned char *)odata;
164 static unicap_format_t *lvdev_get_best_format(
const unicap_format_t *formats,
165 lives_vdev_t *ldev,
int palette,
int width,
int height) {
176 unicap_format_t *format;
178 int bestp = WEED_PALETTE_END;
179 int bestw = 0, besth = 0;
183 for (format_count = 0;
184 SUCCESS(unicap_enumerate_formats(ldev->handle, NULL, (unicap_format_t *)&formats[format_count], format_count))
185 && (format_count < MAX_FORMATS); format_count++) {
186 format = (unicap_format_t *)&formats[format_count];
191 cpal = fourccp_to_weedp(format->fourcc, format->bpp, NULL, NULL, NULL, NULL);
196 unicap_set_format(ldev->handle, format);
197 lives_printerr(
"Unusable palette with fourcc 0x%x bpp=%d, size=%dx%d buf=%d\n", format->fourcc, format->bpp,
199 format->size.height, (
int)format->buffer_size);
218 if (width >= format->min_size.width && height >= format->min_size.height) {
219 if (format->h_stepping > 0 && format->v_stepping > 0) {
221 lives_printerr(
"Can set any size with step %d and %d; min %d x %d, max %d x %d\n",
222 format->h_stepping, format->v_stepping,
223 format->min_size.width, format->min_size.height, format->max_size.width, format->max_size.height);
226 format->size.width = (int)(((
double)width + (
double)format->h_stepping / 2.)
227 / (double)format->h_stepping) * format->h_stepping;
229 format->size.height = (int)(((
double)height + (double)format->v_stepping / 2.)
230 / (double)format->v_stepping) * format->v_stepping;
232 if (format->size.width > format->max_size.width) format->size.width = format->max_size.width;
233 if (format->size.height > format->max_size.height) format->size.height = format->max_size.height;
235 if (format->size.width > bestw || format->size.height > besth) {
236 bestw = format->size.width;
237 besth = format->size.height;
244 lives_printerr(
"Checking %d array sizes\n", format->size_count);
247 if (format->size_count == 0) {
250 if ((format->size.width > bestw || format->size.height > besth) && (bestw < width || besth < height)) {
252 bestw = format->size.width;
253 besth = format->size.height;
256 lives_printerr(
"Size is best so far\n");
263 for (i = 0; i < format->size_count; i++) {
265 lives_printerr(
"entry %d:%d x %d\n", i, format->sizes[i].width, format->sizes[i].height);
267 if (format->sizes[i].width > bestw && format->sizes[i].height > besth &&
268 (bestw < width || besth < height)) {
270 bestw = format->size.width = format->sizes[i].width;
271 besth = format->size.height = format->sizes[i].height;
274 lives_printerr(
"Size is best so far\n");
281 if (bestw < format->min_size.width || besth < format->min_size.height)
continue;
282 bestw = format->size.width = format->min_size.width;
283 besth = format->size.height = format->min_size.height;
289 if (f > -1)
return (unicap_format_t *)(&formats[f]);
296 static boolean open_vdev_inner(unicap_device_t *device) {
298 lives_vdev_t *ldev = (lives_vdev_t *)
lives_malloc(
sizeof(lives_vdev_t));
299 unicap_format_t formats[MAX_FORMATS];
300 unicap_format_t *format;
303 unicap_open(&ldev->handle, device);
312 unicap_lock_stream(ldev->handle);
318 unicap_unlock_stream(ldev->handle);
319 unicap_close(ldev->handle);
324 if (!(format->buffer_types & UNICAP_BUFFER_TYPE_USER)) {
326 format->buffer_type = UNICAP_BUFFER_TYPE_SYSTEM;
329 unicap_register_callback(ldev->handle, UNICAP_EVENT_NEW_FRAME, (unicap_callback_t) new_frame_cb,
332 }
else format->buffer_type = UNICAP_BUFFER_TYPE_USER;
334 ldev->buffer_type = format->buffer_type;
337 ldev->current_palette = fourccp_to_weedp(format->fourcc, format->bpp, (
int *)&
cfile->interlace,
338 &ldev->YUV_sampling, &ldev->YUV_subspace, &ldev->YUV_clamping);
341 lives_printerr(
"\nUsing palette with fourcc 0x%x, translated as %s\n", format->fourcc,
345 if (!SUCCESS(unicap_set_format(ldev->handle, format))) {
347 unicap_unlock_stream(ldev->handle);
348 unicap_close(ldev->handle);
353 g_print(
"ALLX %ld %d %d %d %d\n", format->buffer_size, format->size.width, format->size.height,
358 ldev->current_palette) /
360 int wwidth = format->size.width, awidth;
361 int wheight = format->size.height, aheight;
364 lives_printerr(
"Unicap buffer size is wrong, resetting it.\n");
368 unicap_get_format(ldev->handle, format);
369 awidth = format->size.width;
370 aheight = format->size.height;
373 lives_printerr(
"Wanted frame size %d x %d, got %d x %d\n", wwidth, wheight, awidth, aheight);
380 cfile->hsize = format->size.width;
381 cfile->vsize = format->size.height;
383 cfile->ext_src = ldev;
386 ldev->buffer1.data = (
unsigned char *)
lives_malloc(format->buffer_size);
387 ldev->buffer1.buffer_size = format->buffer_size;
389 ldev->buffer2.data = (
unsigned char *)
lives_malloc(format->buffer_size);
390 ldev->buffer2.buffer_size = format->buffer_size;
392 ldev->buffer_ready = 0;
395 cfile->bpp = format->bpp;
397 unicap_start_capture(ldev->handle);
400 if (ldev->current_palette == WEED_PALETTE_A8) {
401 ldev->current_palette = WEED_PALETTE_YUV444P;
402 ldev->is_really_grey =
TRUE;
403 }
else ldev->is_really_grey =
FALSE;
409 void lives_vdev_free(lives_vdev_t *ldev) {
411 unicap_stop_capture(ldev->handle);
412 unicap_unlock_stream(ldev->handle);
413 unicap_close(ldev->handle);
414 if (ldev->buffer1.data)
lives_free(ldev->buffer1.data);
415 if (ldev->buffer2.data)
lives_free(ldev->buffer2.data);
419 boolean on_open_vdev_activate(LiVESMenuItem *menuitem, livespointer user_data) {
420 unicap_device_t devices[MAX_DEVICES];
422 LiVESList *devlist = NULL;
424 LiVESWidget *card_dialog;
436 int status = STATUS_SUCCESS;
442 status = unicap_reenumerate_devices(&dev_count);
444 if (dev_count == 0) {
450 for (i = 0; SUCCESS(status) && (dev_count < MAX_DEVICES); i++) {
451 status = unicap_enumerate_devices(NULL, &devices[i], i);
452 if (!SUCCESS(status)) {
453 if (i == 0)
LIVES_INFO(
"Unicap failed to get any devices");
458 for (i = 0; i < dev_count; i++) {
459 if (!unicap_is_stream_locked(&devices[i])) {
460 devlist = lives_list_prepend(devlist, devices[i].identifier);
473 lives_list_free(devlist);
474 if (response == LIVES_RESPONSE_CANCEL) {
479 char *device = (
char *)user_data;
480 for (i = 0; i < dev_count; i++) {
481 if (!strcmp(device, devices[i].device)) {
488 for (i = dev_count - 1; i >= 0; i--) {
489 if (!unicap_is_stream_locked(&devices[i])) {
498 if (*devices[devno].device) fname = lives_strdup(devices[devno].device);
499 else fname = lives_strdup(devices[devno].identifier);
511 g_print(
"checking formats for %s\n", fname);
513 if (!open_vdev_inner(&devices[devno])) {
514 d_print(
_(
"Unable to open device %s\n"), fname);
527 lives_snprintf(
cfile->type, 40,
"%s", fname);
529 d_print(
_(
"Opened device %s\n"), devices[devno].identifier);