static GError * record_frames (UcaCamera *camera, Options *opts) { guint roi_width; guint roi_height; guint bits; guint pixel_size; gsize size; gint n_frames; guint n_allocated; GTimer *timer; UcaRingBuffer *buffer; GError *error = NULL; gdouble last_printed; g_object_get (G_OBJECT (camera), "roi-width", &roi_width, "roi-height", &roi_height, "sensor-bitdepth", &bits, NULL); pixel_size = get_bytes_per_pixel (bits); size = roi_width * roi_height * pixel_size; n_allocated = opts->n_frames > 0 ? opts->n_frames : 256; buffer = uca_ring_buffer_new (size, n_allocated); timer = g_timer_new(); g_print("Start recording: %ix%i at %i bits/pixel\n", roi_width, roi_height, bits); uca_camera_start_recording(camera, &error); if (error != NULL) return error; n_frames = 0; g_timer_start(timer); last_printed = 0.0; while (1) { gdouble elapsed; uca_camera_grab (camera, uca_ring_buffer_get_write_pointer (buffer), &error); uca_ring_buffer_write_advance (buffer); if (error != NULL) return error; n_frames++; elapsed = g_timer_elapsed (timer, NULL); if (n_frames == opts->n_frames || (opts->duration > 0.0 && elapsed >= opts->duration)) break; if (elapsed - last_printed >= 1.0) { g_print ("Recorded %i frames at %.2f frames/s\n", n_frames, n_frames / elapsed); last_printed = elapsed; } } g_print ("Stop recording: %3.2f frames/s\n", n_frames / g_timer_elapsed (timer, NULL)); uca_camera_stop_recording (camera, &error); #ifdef HAVE_LIBTIFF if (opts->write_tiff) write_tiff (buffer, opts, roi_width, roi_height, bits); else write_raw (buffer, opts); #else write_raw (buffer, opts); #endif g_object_unref (buffer); g_timer_destroy (timer); return error; }
/** * uca_camera_start_recording: * @camera: A #UcaCamera object * @error: Location to store a #UcaCameraError error or %NULL * * Initiate recording of frames. If UcaCamera:grab-asynchronous is %TRUE and a * #UcaCameraGrabFunc callback is set, frames are automatically transfered to * the client program, otherwise you must use uca_camera_grab(). */ void uca_camera_start_recording (UcaCamera *camera, GError **error) { UcaCameraClass *klass; UcaCameraPrivate *priv; GError *tmp_error = NULL; static GStaticMutex mutex = G_STATIC_MUTEX_INIT; g_return_if_fail (UCA_IS_CAMERA (camera)); klass = UCA_CAMERA_GET_CLASS (camera); g_return_if_fail (klass != NULL); g_return_if_fail (klass->start_recording != NULL); priv = camera->priv; g_static_mutex_lock (&mutex); if (priv->is_recording) { g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_RECORDING, "Camera is already recording"); goto start_recording_unlock; } if (priv->transfer_async && (camera->grab_func == NULL)) { g_set_error (error, UCA_CAMERA_ERROR, UCA_CAMERA_ERROR_NO_GRAB_FUNC, "No grab callback function set"); goto start_recording_unlock; } g_static_mutex_lock (&access_lock); (*klass->start_recording)(camera, &tmp_error); g_static_mutex_unlock (&access_lock); if (tmp_error == NULL) { priv->is_readout = FALSE; priv->is_recording = TRUE; priv->cancelling_recording = FALSE; /* TODO: we should depend on GLib 2.26 and use g_object_notify_by_pspec */ g_object_notify (G_OBJECT (camera), "is-recording"); } else g_propagate_error (error, tmp_error); if (priv->buffered) { guint width, height, bitdepth; guint pixel_size; g_object_get (camera, "roi-width", &width, "roi-height", &height, "sensor-bitdepth", &bitdepth, NULL); pixel_size = bitdepth <= 8 ? 1 : 2; priv->ring_buffer = uca_ring_buffer_new (width * height * pixel_size, priv->num_buffers); /* Let's read out the frames from another thread */ priv->read_thread = g_thread_new ("read-thread", (GThreadFunc) buffer_thread, camera); } start_recording_unlock: g_static_mutex_unlock (&mutex); }