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.
This commit is contained in:
Benjamin Schaaf
2021-01-06 23:24:05 +11:00
parent 21547ed210
commit 3f8ee6227f
3 changed files with 51 additions and 25 deletions

34
main.c
View File

@@ -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);
strncpy(last_path, args->fname, 259);
// Create a thumbnail from the current surface
cairo_surface_t *thumb =
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 24, 24);
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

7
main.h
View File

@@ -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);

View File

@@ -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);