Benjamin Schaaf 4 роки тому
батько
коміт
8ccf1451ed
4 змінених файлів з 40 додано та 105 видалено
  1. 2 0
      src/io_pipeline.c
  2. 5 30
      src/main.c
  3. 1 6
      src/main.h
  4. 32 69
      src/process_pipeline.c

+ 2 - 0
src/io_pipeline.c

@@ -311,6 +311,7 @@ capture(MPPipeline *pipeline, const void *data)
 				    V4L2_EXPOSURE_MANUAL);
 
 	// Change camera mode for capturing
+	mp_process_pipeline_sync();
 	mp_camera_stop_capture(info->camera);
 
 	mode = camera->capture_mode;
@@ -448,6 +449,7 @@ on_frame(MPBuffer buffer, void * _data)
 			}
 
 			// Go back to preview mode
+			mp_process_pipeline_sync();
 			mp_camera_stop_capture(info->camera);
 
 			mode = camera->preview_mode;

+ 5 - 30
src/main.c

@@ -182,34 +182,8 @@ mp_main_set_preview(MPProcessPipelineBuffer *buffer)
 				   (GSourceFunc)set_preview, buffer, NULL);
 }
 
-static void transform_centered(cairo_t *cr, uint32_t dst_width, uint32_t dst_height,
-	                       int src_width, int src_height)
-{
-	cairo_translate(cr, dst_width / 2, dst_height / 2);
-
-	double scale = MIN(dst_width / (double)src_width, dst_height / (double)src_height);
-	cairo_scale(cr, scale, scale);
-
-	cairo_translate(cr, -src_width / 2, -src_height / 2);
-}
-
-void
-draw_surface_scaled_centered(cairo_t *cr, uint32_t dst_width, uint32_t dst_height,
-			     cairo_surface_t *surface)
-{
-	cairo_save(cr);
-
-	int width = cairo_image_surface_get_width(surface);
-	int height = cairo_image_surface_get_height(surface);
-	transform_centered(cr, dst_width, dst_height, width, height);
-
-	cairo_set_source_surface(cr, surface, 0, 0);
-	cairo_paint(cr);
-	cairo_restore(cr);
-}
-
 struct capture_completed_args {
-	cairo_surface_t *thumb;
+	GdkTexture *thumb;
 	char *fname;
 };
 
@@ -218,19 +192,20 @@ capture_completed(struct capture_completed_args *args)
 {
 	strncpy(last_path, args->fname, 259);
 
-	// gtk_image_set_from_surface(GTK_IMAGE(thumb_last), args->thumb);
+	gtk_image_set_from_paintable(GTK_IMAGE(thumb_last),
+				     GDK_PAINTABLE(args->thumb));
 
 	gtk_spinner_stop(GTK_SPINNER(process_spinner));
 	gtk_stack_set_visible_child(GTK_STACK(open_last_stack), thumb_last);
 
-	cairo_surface_destroy(args->thumb);
+	g_object_unref(args->thumb);
 	g_free(args->fname);
 
 	return false;
 }
 
 void
-mp_main_capture_completed(cairo_surface_t *thumb, const char *fname)
+mp_main_capture_completed(GdkTexture *thumb, const char *fname)
 {
 	struct capture_completed_args *args = malloc(sizeof(struct capture_completed_args));
 	args->thumb = thumb;

+ 1 - 6
src/main.h

@@ -5,8 +5,6 @@
 #include "process_pipeline.h"
 #include "gtk/gtk.h"
 
-#define MP_MAIN_THUMB_SIZE 24
-
 struct mp_main_state {
 	const struct mp_camera_config *camera;
 	MPCameraMode mode;
@@ -28,11 +26,8 @@ struct mp_main_state {
 void mp_main_update_state(const struct mp_main_state *state);
 
 void mp_main_set_preview(MPProcessPipelineBuffer *buffer);
-void mp_main_capture_completed(cairo_surface_t *thumb, const char *fname);
+void mp_main_capture_completed(GdkTexture *thumb, const char *fname);
 
 void mp_main_set_zbar_result(MPZBarScanResult *result);
 
 int remap(int value, int input_min, int input_max, int output_min, int output_max);
-
-void draw_surface_scaled_centered(cairo_t *cr, uint32_t dst_width, uint32_t dst_height,
-			          cairo_surface_t *surface);

+ 32 - 69
src/process_pipeline.c

@@ -40,6 +40,9 @@ static int captures_remaining = 0;
 static int preview_width;
 static int preview_height;
 
+static int output_buffer_width = -1;
+static int output_buffer_height = -1;
+
 // static bool gain_is_manual;
 static int gain;
 static int gain_max;
@@ -252,7 +255,7 @@ mp_process_pipeline_init_gl(GdkSurface *surface)
 	mp_pipeline_invoke(pipeline, (MPPipelineCallback) init_gl, &surface, sizeof(GdkSurface *));
 }
 
-static cairo_surface_t *
+static GdkTexture *
 process_image_for_preview(const uint8_t *image)
 {
 #ifdef PROFILE_DEBAYER
@@ -300,55 +303,6 @@ process_image_for_preview(const uint8_t *image)
 	printf("%fms\n", (float)(t2 - t1) / CLOCKS_PER_SEC * 1000);
 #endif
 
-	// {
-	// 	glBindTexture(GL_TEXTURE_2D, textures[1]);
-	// 	EGLImage egl_image = eglCreateImage(egl_display, egl_context, EGL_GL_TEXTURE_2D, (EGLClientBuffer)(size_t)textures[1], NULL);
-
-	// 	// Make sure it's in the expected format
-	// 	int fourcc;
-	// 	eglExportDMABUFImageQueryMESA(egl_display, egl_image, &fourcc, NULL, NULL);
-	// 	assert(fourcc == DRM_FORMAT_ABGR8888);
-
-
-	// 	int dmabuf_fd;
-	// 	int stride, offset;
-	// 	eglExportDMABUFImageMESA(egl_display, egl_image, &dmabuf_fd, &stride, &offset);
-
-	// 	int fsize = lseek(dmabuf_fd, 0, SEEK_END);
-	// 	printf("SIZE %d STRIDE %d OFFSET %d SIZE %d:%d\n", fsize, stride, offset, preview_width, preview_height);
-
-	// 	size_t size = stride * preview_height;
-	// 	uint32_t *data = mmap(NULL, fsize, PROT_READ, MAP_SHARED, dmabuf_fd, 0);
-	// 	assert(data != MAP_FAILED);
-
-	// 	int pixel_stride = stride / 4;
-
-	// 	for (size_t y = 0; y < preview_height; ++y) {
-	// 		for (size_t x = 0; x < preview_width; ++x) {
-	// 			uint32_t p = data[x + y * pixel_stride];
-	// 			pixels[x + y * preview_width] = p;
-	// 		// 	uint16_t p = data[x + y * stride];
-	// 		// 	uint32_t r = (p & 0b11111);
-	// 		// 	uint32_t g = ((p >> 5) & 0b11111);
-	// 		// 	uint32_t b = ((p >> 10) & 0b11111);
-	// 		// 	pixels[x + y * preview_width] = (r << 16) | (g << 8) | b;
-	// 		}
-	// 		// memcpy(pixels + preview_width * y, data + stride * y, preview_width * sizeof(uint32_t));
-	// 	}
-
-	// 	{
-	// 		FILE *f = fopen("test.raw", "w");
-	// 		fwrite(data, fsize, 1, f);
-	// 		fclose(f);
-	// 	}
-
-	// 	// memcpy(pixels, data, size);
-	// 	munmap(data, size);
-	// 	close(dmabuf_fd);
-	// }
-	// glReadPixels(0, 0, preview_width, preview_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
-	// check_gl();
-
 #ifdef RENDERDOC
 	if(rdoc_api) rdoc_api->EndFrameCapture(NULL, NULL);
 #endif
@@ -357,20 +311,33 @@ process_image_for_preview(const uint8_t *image)
 	mp_main_set_preview(output_buffer);
 
 	// Create a thumbnail from the preview for the last capture
-	cairo_surface_t *thumb = NULL;
-	// if (captures_remaining == 1) {
-	// 	printf("Making thumbnail\n");
-	// 	thumb = cairo_image_surface_create(
-	// 		CAIRO_FORMAT_ARGB32, MP_MAIN_THUMB_SIZE, MP_MAIN_THUMB_SIZE);
+	GdkTexture *thumb = NULL;
+	if (captures_remaining == 1) {
+		printf("Making thumbnail\n");
 
-	// 	cairo_t *cr = cairo_create(thumb);
-	// 	draw_surface_scaled_centered(
-	// 		cr, MP_MAIN_THUMB_SIZE, MP_MAIN_THUMB_SIZE, surface);
-	// 	cairo_destroy(cr);
-	// }
+		size_t size = output_buffer_width * output_buffer_height * sizeof(uint32_t);
 
-	// Pass processed preview to main and zbar
-	// mp_zbar_pipeline_process_image(cairo_surface_reference(surface));
+		uint32_t *data = g_malloc_n(size, 1);
+
+		glReadPixels(0, 0, output_buffer_width, output_buffer_height, GL_RGBA, GL_UNSIGNED_BYTE, data);
+		check_gl();
+
+		// Flip vertically
+		for (size_t y = 0; y < output_buffer_height / 2; ++y) {
+			for (size_t x = 0; x < output_buffer_width; ++x) {
+				uint32_t tmp = data[(output_buffer_height - y - 1) * output_buffer_width + x];
+				data[(output_buffer_height - y - 1) * output_buffer_width + x] = data[y * output_buffer_width + x];
+				data[y * output_buffer_width + x] = tmp;
+			}
+		}
+
+		thumb = gdk_memory_texture_new(
+			output_buffer_width,
+			output_buffer_height,
+			GDK_MEMORY_R8G8B8A8,
+			g_bytes_new_take(data, size),
+			output_buffer_width * sizeof(uint32_t));
+	}
 
 	return thumb;
 }
@@ -527,7 +494,7 @@ process_image_for_capture(const uint8_t *image, int count)
 }
 
 static void
-post_process_finished(GSubprocess *proc, GAsyncResult *res, cairo_surface_t *thumb)
+post_process_finished(GSubprocess *proc, GAsyncResult *res, GdkTexture *thumb)
 {
 	char *stdout;
 	g_subprocess_communicate_utf8_finish(proc, res, &stdout, NULL, NULL);
@@ -550,7 +517,7 @@ post_process_finished(GSubprocess *proc, GAsyncResult *res, cairo_surface_t *thu
 }
 
 static void
-process_capture_burst(cairo_surface_t *thumb)
+process_capture_burst(GdkTexture *thumb)
 {
 	time_t rawtime;
 	time(&rawtime);
@@ -615,7 +582,7 @@ process_image(MPPipeline *pipeline, const MPBuffer *buffer)
 	MPZBarImage *zbar_image = mp_zbar_image_new(image, mode.pixel_format, mode.width, mode.height, camera->rotate, camera->mirrored);
 	mp_zbar_pipeline_process_image(mp_zbar_image_ref(zbar_image));
 
-	cairo_surface_t *thumb = process_image_for_preview(image);
+	GdkTexture *thumb = process_image_for_preview(image);
 
 	if (captures_remaining > 0) {
 		int count = burst_length - captures_remaining;
@@ -646,7 +613,6 @@ mp_process_pipeline_process_image(MPBuffer buffer)
 {
 	// If we haven't processed the previous frame yet, drop this one
 	if (frames_received != frames_processed && !is_capturing) {
-		printf("Dropped frame at capture\n");
 		mp_io_pipeline_release_buffer(buffer.index);
 		return;
 	}
@@ -682,9 +648,6 @@ mp_process_pipeline_capture()
 	mp_pipeline_invoke(pipeline, capture, NULL, 0);
 }
 
-static int output_buffer_width = -1;
-static int output_buffer_height = -1;
-
 static void
 on_output_changed()
 {