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:
34
main.c
34
main.c
@@ -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
7
main.h
@@ -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);
|
||||
|
Reference in New Issue
Block a user