Commit 3f8ee622 authored by Benjamin Schaaf's avatar Benjamin Schaaf
Browse files

Move thumbnail generation to processing pipeline

This ensures the thumbnail is properly created from the captured frame
instead of whatever the current preview is when the post-processing
finishes.
parent 21547ed2
......@@ -148,7 +148,7 @@ mp_main_set_preview(cairo_surface_t *image)
(GSourceFunc)set_preview, image, NULL);
}
static void
void
draw_surface_scaled_centered(cairo_t *cr, uint32_t dst_width, uint32_t dst_height,
cairo_surface_t *surface)
{
......@@ -168,35 +168,35 @@ draw_surface_scaled_centered(cairo_t *cr, uint32_t dst_width, uint32_t dst_heigh
cairo_restore(cr);
}
struct capture_completed_args {
cairo_surface_t *thumb;
char *fname;
};
static bool
capture_completed(const char *fname)
capture_completed(struct capture_completed_args *args)
{
strncpy(last_path, fname, 259);
// Create a thumbnail from the current surface
cairo_surface_t *thumb =
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 24, 24);
strncpy(last_path, args->fname, 259);
cairo_t *cr = cairo_create(thumb);
draw_surface_scaled_centered(cr, 24, 24, surface);
cairo_destroy(cr);
gtk_image_set_from_surface(GTK_IMAGE(thumb_last), thumb);
gtk_image_set_from_surface(GTK_IMAGE(thumb_last), args->thumb);
gtk_spinner_stop(GTK_SPINNER(process_spinner));
gtk_stack_set_visible_child(GTK_STACK(open_last_stack), thumb_last);
cairo_surface_destroy(thumb);
cairo_surface_destroy(args->thumb);
g_free(args->fname);
return false;
}
void
mp_main_capture_completed(const char *fname)
mp_main_capture_completed(cairo_surface_t *thumb, const char *fname)
{
gchar *name = g_strdup(fname);
struct capture_completed_args *args = malloc(sizeof(struct capture_completed_args));
args->thumb = thumb;
args->fname = g_strdup(fname);
g_main_context_invoke_full(g_main_context_default(), G_PRIORITY_DEFAULT_IDLE,
(GSourceFunc)capture_completed, name, g_free);
(GSourceFunc)capture_completed, args, free);
}
static void
......
......@@ -3,6 +3,8 @@
#include "camera_config.h"
#include "gtk/gtk.h"
#define MP_MAIN_THUMB_SIZE 24
struct mp_main_state {
const struct mp_camera_config *camera;
MPCameraMode mode;
......@@ -21,6 +23,9 @@ struct mp_main_state {
void mp_main_update_state(const struct mp_main_state *state);
void mp_main_set_preview(cairo_surface_t *image);
void mp_main_capture_completed(const char *fname);
void mp_main_capture_completed(cairo_surface_t *thumb, const char *fname);
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);
......@@ -128,7 +128,7 @@ mp_process_pipeline_stop()
mp_pipeline_free(pipeline);
}
static void
static cairo_surface_t *
process_image_for_preview(const MPImage *image)
{
uint32_t surface_width, surface_height, skip;
......@@ -147,7 +147,23 @@ process_image_for_preview(const MPImage *image)
camera->previewmatrix[0] == 0 ? NULL : camera->previewmatrix,
camera->blacklevel, skip);
// 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);
cairo_t *cr = cairo_create(thumb);
draw_surface_scaled_centered(
cr, MP_MAIN_THUMB_SIZE, MP_MAIN_THUMB_SIZE, surface);
cairo_destroy(cr);
}
// Pass processed preview to main
mp_main_set_preview(surface);
return thumb;
}
static void
......@@ -302,7 +318,7 @@ process_image_for_capture(const MPImage *image, int count)
}
static void
post_process_finished(GSubprocess *proc, GAsyncResult *res, gpointer user_data)
post_process_finished(GSubprocess *proc, GAsyncResult *res, cairo_surface_t *thumb)
{
char *stdout;
g_subprocess_communicate_utf8_finish(proc, res, &stdout, NULL, NULL);
......@@ -320,11 +336,11 @@ post_process_finished(GSubprocess *proc, GAsyncResult *res, gpointer user_data)
--path;
} while (path > stdout);
mp_main_capture_completed(path);
mp_main_capture_completed(thumb, path);
}
static void
process_capture_burst()
process_capture_burst(cairo_surface_t *thumb)
{
time_t rawtime;
time(&rawtime);
......@@ -357,7 +373,7 @@ process_capture_burst()
NULL,
NULL,
(GAsyncReadyCallback)post_process_finished,
NULL);
thumb);
}
static void
......@@ -365,7 +381,7 @@ process_image(MPPipeline *pipeline, const MPImage *image)
{
assert(image->width == mode.width && image->height == mode.height);
process_image_for_preview(image);
cairo_surface_t *thumb = process_image_for_preview(image);
if (captures_remaining > 0) {
int count = burst_length - captures_remaining;
......@@ -374,8 +390,13 @@ process_image(MPPipeline *pipeline, const MPImage *image)
process_image_for_capture(image, count);
if (captures_remaining == 0) {
process_capture_burst();
assert(thumb);
process_capture_burst(thumb);
} else {
assert(!thumb);
}
} else {
assert(!thumb);
}
free(image->data);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment