atomes 1.1.14
atomes: an atomic scale modeling tool box
Loading...
Searching...
No Matches
w_encode.c
Go to the documentation of this file.
1/* This file is part of the 'atomes' software
2
3'atomes' is free software: you can redistribute it and/or modify it under the terms
4of the GNU Affero General Public License as published by the Free Software Foundation,
5either version 3 of the License, or (at your option) any later version.
6
7'atomes' is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9See the GNU General Public License for more details.
10
11You should have received a copy of the GNU Affero General Public License along with 'atomes'.
12If not, see <https://www.gnu.org/licenses/>
13
14Copyright (C) 2022-2024 by CNRS and University of Strasbourg */
15
22/*
23* This file: 'w_encode.c'
24*
25* Contains:
26*
27
28 - The functions to create the encoding (image/video) window
29
30*
31* List of functions:
32
33 void clean_animation (glwin * view);
34 void set_encoding_widget_sensitivity (gboolean video, int sensitivity);
35 void window_encode (glwin * view, gboolean video);
36
37 G_MODULE_EXPORT void set_video_frames (GtkEntry * res, gpointer data);
38 G_MODULE_EXPORT void set_video_extra_frames (GtkEntry * res, gpointer data);
39 G_MODULE_EXPORT void set_video_res (GtkEntry * res, gpointer data);
40 G_MODULE_EXPORT void set_video_codec (GtkComboBox *ComboBoxGtk);
41 G_MODULE_EXPORT void set_video_opengl_spin (GtkSpinButton * res, gpointer data);
42 G_MODULE_EXPORT void set_video_bitrate (GtkEntry * res, gpointer data);
43 G_MODULE_EXPORT void set_image_format (GtkComboBox * box, gpointer data);
44 G_MODULE_EXPORT void run_window_encode (GtkDialog * win ,gint response_id, gpointer data);
45
46*/
47
48#include "global.h"
49#include "interface.h"
50#include "glview.h"
51#include "movie.h"
52
53int video_res[2];
59
60extern char * codec_name[VIDEO_CODECS];
61extern char * image_name[IMAGE_FORMATS];
62extern gboolean spin (gpointer data);
63
72G_MODULE_EXPORT void set_video_frames (GtkEntry * res, gpointer data)
73{
74 const gchar * n;
75 int frs;
76 n = entry_get_text (res);
77 frs = atof(n);
78 if (frs > 0)
79 {
80 framesec = frs;
81 }
83}
84
93G_MODULE_EXPORT void set_video_extra_frames (GtkEntry * res, gpointer data)
94{
95 const gchar * n;
96 int exf;
97 n = entry_get_text (res);
98 exf = atof(n);
99 if (exf >= 0)
100 {
101 extraframes = exf;
102 }
104}
105
114G_MODULE_EXPORT void set_video_res (GtkEntry * res, gpointer data)
115{
116 const gchar * n;
117 int vres;
118 int id = GPOINTER_TO_INT(data);
119 n = entry_get_text (res);
120 vres = atof(n);
121 if (vres > 0)
122 {
123 video_res[id] = vres;
124 }
126}
127
135G_MODULE_EXPORT void set_video_codec (GtkComboBox *ComboBoxGtk)
136{
137 codec = gtk_combo_box_get_active (ComboBoxGtk);
138}
139
148G_MODULE_EXPORT void set_video_opengl_spin (GtkSpinButton * res, gpointer data)
149{
150 qual = gtk_spin_button_get_value_as_int(res);
151 if (qual == 0 || (qual > 1 && qual <= 1000))
152 {
154 }
155 update_entry_int (GTK_ENTRY(res), oglquality);
156}
157
166G_MODULE_EXPORT void set_video_bitrate (GtkEntry * res, gpointer data)
167{
168 const gchar * n;
169 int bit;
170 n = entry_get_text (res);
171 bit = atof(n);
172 if (bit > 0)
173 {
174 bitrate = bit;
175 }
177}
178
187{
188 int i;
189 snapshot * shot = view -> anim -> first;
190 snapshot * del;
191 for (i=0; i < view -> anim -> frames-1; i++)
192 {
193 del = shot;
194 shot = shot -> next;
195 g_free (del);
196 }
197 view -> anim -> first = view -> anim -> last = shot;
198 view -> anim -> frames = 0;
199 for (i=0; i<5; i++)
200 {
201 if (view -> anim -> last -> img -> i_rings[i] != NULL)
202 {
203 g_free (view -> anim -> last -> img -> i_rings[i]);
204 view -> anim -> last -> img -> i_rings[i] = NULL;
205 }
206 }
207}
208
209GtkWidget * resf;
210GtkWidget * rese;
211GtkWidget * resb;
212GtkWidget * res[2];
213GtkWidget * cod;
214
223void set_encoding_widget_sensitivity (gboolean video, int sensitivity)
224{
225 if (video)
226 {
227 widget_set_sensitive (resf, sensitivity);
228 widget_set_sensitive (rese, sensitivity);
229 widget_set_sensitive (resb, sensitivity);
230 }
231 widget_set_sensitive (res[0], sensitivity);
232 widget_set_sensitive (res[1], sensitivity);
233 widget_set_sensitive (cod, sensitivity);
234}
235
236GtkWidget * form;
237
246G_MODULE_EXPORT void set_image_format (GtkComboBox * box, gpointer data)
247{
248 codec = gtk_combo_box_get_active (box);
249 switch (codec)
250 {
251 case 0:
252 gtk_image_set_from_file (GTK_IMAGE(form), PACKAGE_PNG);
253 break;
254 case 1:
255 gtk_image_set_from_file (GTK_IMAGE(form), PACKAGE_JPG);
256 break;
257 case 2:
258 gtk_image_set_from_file (GTK_IMAGE(form), PACKAGE_TIFF);
259 break;
260 case 3:
261 gtk_image_set_from_file (GTK_IMAGE(form), PACKAGE_BMP);
262 break;
263 }
264}
265
266GtkWidget * encoding_pb;
268
278G_MODULE_EXPORT void run_window_encode (GtkDialog * win , gint response_id, gpointer data)
279{
280 glwin * view = (glwin *)data;
281 if (response_id == GTK_RESPONSE_APPLY)
282 {
284 video_options * vopts = g_malloc0(sizeof*vopts);
285 vopts -> proj = view -> proj;
286 vopts -> oglquality = oglquality;
287 vopts -> video_res = duplicate_int (2, video_res);
288 vopts -> codec = codec;
289 if (encode_video)
290 {
291 vopts -> framesec = framesec;
292 vopts -> extraframes = extraframes;
293 vopts -> bitrate = bitrate;
294 save_movie (view, vopts);
295 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(encoding_pb), 0.0);
296 }
297 else
298 {
299 render_image (view, vopts);
300 }
301 g_free (vopts -> video_res);
302 g_free (vopts);
304 }
305 else
306 {
308 }
309}
310
319void window_encode (glwin * view, gboolean video)
320{
321 gchar * str;
322 int i;
323 if (video)
324 {
325 str = g_strdup_printf ("%s - movie encoding", prepare_for_title(get_project_by_id(view -> proj) -> name));
326 }
327 else
328 {
329 str = g_strdup_printf ("%s - image rendering", prepare_for_title(get_project_by_id(view -> proj) -> name));
330 }
331 GtkWidget * win = dialog_cancel_apply (str, view -> win, FALSE);
332 g_free (str);
333 GtkWidget * vbox = dialog_get_content_area (win);
334 GtkWidget * hbox;
335 if (video)
336 {
337 gtk_widget_set_size_request (vbox, -1, 420);
338 // Frames
339 hbox = create_hbox (0);
340 gtk_widget_set_size_request (hbox, 300, -1);
341 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, hbox, FALSE, FALSE, 10);
342 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, markup_label("Frames recorded:", 350, -1, 0.0, 0.5), FALSE, FALSE, 0);
343 str = g_strdup_printf ("<b>%d</b>", view -> anim -> frames);
344 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, markup_label(str, -1, -1, 0.0, 0.5), FALSE, FALSE, 0);
345 g_free (str);
346
347 // Frames per second
348 hbox = create_hbox (0);
349 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, hbox, FALSE, FALSE, 0);
350 gtk_widget_set_size_request (hbox, 300, -1);
351 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, markup_label("Frames per seconds:", 350, -1, 0.0, 0.5), FALSE, FALSE, 0);
352 resf = create_entry (G_CALLBACK(set_video_frames), 100, 10, FALSE, NULL);
353 framesec = 24;
354 update_entry_int (GTK_ENTRY(resf), framesec);
355 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, resf, FALSE, FALSE, 0);
356
357 // Extra frames
358 hbox = create_hbox (0);
359 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, hbox, FALSE, FALSE, 10);
360 gtk_widget_set_size_request (hbox, 300, -1);
361 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, markup_label("Extra frames every (frames):", 350, -1, 0.0, 0.5), FALSE, FALSE, 0);
362 rese = create_entry (G_CALLBACK(set_video_extra_frames), 100, 10, FALSE, NULL);
363 extraframes = 10;
364 update_entry_int (GTK_ENTRY(rese), extraframes);
365 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, rese, FALSE, FALSE, 0);
366 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, markup_label("Movie resolution (in pixels):", -1, -1, 0.0, 0.5), FALSE, FALSE, 0);
367 }
368 else
369 {
370 gtk_widget_set_size_request (vbox, -1, 230);
371 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, markup_label("Image resolution (in pixels):", -1, -1, 0.0, 0.5), FALSE, FALSE, 10);
372 }
373 hbox = create_hbox (0);
374 gtk_widget_set_size_request (hbox, 300, -1);
375 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, hbox, FALSE, FALSE, (video) ? 10 : 0);
376 gchar * ax[2]={"x: ", "y: "};
377 for (i=0; i<2; i++)
378 {
379 video_res[i] = view -> pixels[i];
380 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, markup_label(ax[i], 100, -1, 0.5, 0.5), FALSE, FALSE, 0);
381 res[i] = create_entry (G_CALLBACK(set_video_res), 100, 10, FALSE, (gpointer)GINT_TO_POINTER(i));
382 update_entry_int (GTK_ENTRY(res[i]), video_res[i]);
383 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, res[i], FALSE, FALSE, 0);
384 }
385
386 cod = create_combo ();
387 hbox = create_hbox (0);
388 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, hbox, FALSE, FALSE, video ? 0 : 10);
389 gtk_widget_set_size_request (hbox, 300, -1);
390 if (video)
391 {
392 // Codec
393 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, markup_label("Video codec:", 300, -1, 0.0, 0.5), FALSE, FALSE, 0);
394 for (i=0; i<VIDEO_CODECS; i++) combo_text_append (cod, codec_name[i]);
395 g_signal_connect (G_OBJECT(cod), "changed", G_CALLBACK(set_video_codec), NULL);
396 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, cod, FALSE, FALSE, 0);
397 }
398 else
399 {
400 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, markup_label("Image format:", 150, -1, 0.0, 0.5), FALSE, FALSE, 0);
401 GtkWidget * fixed = gtk_fixed_new ();
402 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, fixed, TRUE, TRUE, 0);
403 for (i=0; i<IMAGE_FORMATS; i++) combo_text_append (cod, image_name[i]);
404 gtk_fixed_put (GTK_FIXED(fixed), cod, -1, 10);
405 g_signal_connect (G_OBJECT(cod), "changed", G_CALLBACK(set_image_format), NULL);
406 form = gtk_image_new ();
407 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, form, TRUE, TRUE, 0);
408 }
409 codec = 0;
410 gtk_combo_box_set_active (GTK_COMBO_BOX(cod), codec);
411
412 if (! video) set_image_format (GTK_COMBO_BOX(cod), NULL);
413
414 if (video)
415 {
416 // Overall video Quality
417 hbox = create_hbox (0);
418 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, hbox, FALSE, FALSE, 10);
419 gtk_widget_set_size_request (hbox, 300, -1);
420 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, markup_label("Video quality (bitrate in kb/s):", 350, -1, 0.0, 0.5), FALSE, FALSE, 0);
421 resb = create_entry (G_CALLBACK(set_video_bitrate), 100, 10, FALSE, NULL);
422 bitrate = 5000;
423 update_entry_int (GTK_ENTRY(resb), bitrate);
424 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, resb, FALSE, FALSE, 0);
425 }
426 // Overall OpenGL Quality
427 hbox = create_hbox (0);
428 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, hbox, FALSE, FALSE, 0);
429 gtk_widget_set_size_request (hbox, 300, -1);
430 if (video)
431 {
432 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, markup_label("OpenGL quality [0-1000] (0= recorded quality):", -1, -1, 0.0, 0.5), FALSE, FALSE, 0);
433 }
434 else
435 {
436 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, markup_label("OpenGL quality [0-1000] (0= on-screen quality):", -1, -1, 0.0, 0.5), FALSE, FALSE, 0);
437 }
438 oglquality = 0;
439 add_box_child_start (GTK_ORIENTATION_HORIZONTAL, hbox, spin_button (G_CALLBACK(set_video_opengl_spin), 0, 0, 1000, 1, 0, 100, NULL), FALSE, FALSE, 20);
440 if (video)
441 {
442 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, markup_label("Progress: ", -1, -1, 0.0, 0.5), FALSE, FALSE, 10);
443 encoding_pb = gtk_progress_bar_new ();
444 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(encoding_pb), 0.0);
445 add_box_child_start (GTK_ORIENTATION_VERTICAL, vbox, encoding_pb, FALSE, FALSE, 0);
446 }
447 show_the_widgets (win);
448
449 if (view -> spin[0] || view -> spin[1])
450 {
451 for (i=0; i<2; i++)
452 {
453 view -> spin[i+2] = view -> spin[i];
454 view -> spin_speed[i+2] = view -> spin_speed[i];
455 view -> spin[i] = FALSE;
456 }
457 }
458 gboolean old_play, old_stop;
459 old_play = view -> play;
460 old_stop = view -> stop;
461 view -> play = FALSE;
462 view -> stop = TRUE;
463 encode_video = video;
464 run_this_gtk_dialog (win, G_CALLBACK(run_window_encode), view);
465 clean_animation (view);
466 update (view);
467 if (view -> spin[2] || view -> spin[3])
468 {
469 for (i=0; i<2; i++)
470 {
471 view -> spin[i] = view -> spin[i+2];
472 view -> spin_speed[i] = view -> spin_speed[i+2];
473 g_timeout_add (REFRESH, (GSourceFunc) spin, & view -> colorp[0][i]);
474 view -> spin[i+2] = FALSE;
475 view -> spin_speed[i+2] = 0;
476 }
477 }
478 view -> play = old_play;
479 view -> stop = old_stop;
480}
color colorp[64]
double ax
Definition curve.c:70
int * duplicate_int(int num, int *old_val)
copy a list of int
Definition global.c:572
Global variable declarations Global convenience function declarations Global data structure defin...
GtkWidget * dialog_cancel_apply(gchar *title, GtkWidget *parent, gboolean resiz)
create a dialog modal offering a choice to apply something or not
Definition gtk-misc.c:541
void run_this_gtk_dialog(GtkWidget *dial, GCallback handler, gpointer data)
run a GTK (3 and 4) basic GtkDialog
Definition gtk-misc.c:472
GtkWidget * create_entry(GCallback handler, int dim, int cdim, gboolean key_release, gpointer data)
Create a GtkEntry.
Definition gtk-misc.c:1294
project * proj
const gchar * entry_get_text(GtkEntry *entry)
get the text in a GtkEntry
Definition gtk-misc.c:577
void update_entry_int(GtkEntry *entry, int intval)
update the content of a GtkEntry as int
Definition gtk-misc.c:594
GtkWidget * spin_button(GCallback handler, double value, double start, double end, double step, int digits, int dim, gpointer data)
create a spin button
Definition gtk-misc.c:1752
GtkWidget * create_combo()
create a GtkCombox widget, note deprecated in GTK4
Definition gtk-misc.c:903
GtkWidget * dialog_get_content_area(GtkWidget *widg)
prepare GtkWidget to insert content in a GtkDialog window
Definition gtk-misc.c:805
GtkWidget * markup_label(gchar *text, int dimx, int dimy, float ax, float ay)
Definition gtk-misc.c:1565
void add_box_child_start(int orientation, GtkWidget *widg, GtkWidget *child, gboolean expand, gboolean fill, int padding)
Add a GtkWidget in a GtkBox at the initial position.
Definition gtk-misc.c:279
void widget_set_sensitive(GtkWidget *widg, gboolean sensitive)
Set sensitivity for a GtkWidget, ensuring it is a GtkWidget.
Definition gtk-misc.c:186
void destroy_this_dialog(GtkDialog *dialog)
destroy a GtkDialog
Definition gtk-misc.c:2041
GtkWidget * create_hbox(int spacing)
create a GtkBox with horizontal orientation
Definition gtk-misc.c:793
void combo_text_append(GtkWidget *combo, gchar *text)
append text in GtkComboBox widget
Definition gtk-misc.c:880
gchar * prepare_for_title(gchar *init)
prepare a string for a window title, getting rid of all markup
Definition tools.c:71
void show_the_widgets(GtkWidget *widg)
show GtkWidget
Definition gtk-misc.c:169
project * get_project_by_id(int p)
get project pointer using id number
Definition project.c:120
void update(glwin *view)
update the rendering of the OpenGL window
Definition glview.c:439
Variable declarations related to the OpenGL window Function declarations related to the OpenGL wind...
#define REFRESH
Refresh time for spinning the OpenGL window in milliseconds.
Definition glview.h:130
int qual
Definition ogl_draw.c:67
void render_image(glwin *view, video_options *iopts)
render an image from the OpenGL window - prepare the dialog
Definition image.c:164
Messaging function declarations.
void save_movie(glwin *view, video_options *vopts)
saving a movie - prepare the dialog
Definition movie.c:1291
Data structure declarations for movie encoding Function declarations for movie encoding.
#define VIDEO_CODECS
Definition movie.h:36
#define IMAGE_FORMATS
Definition movie.h:37
Definition glwin.h:875
GtkWidget * form
Definition w_encode.c:236
void set_encoding_widget_sensitivity(gboolean video, int sensitivity)
Adjust the sensitivity for the widgets of the encoding window.
Definition w_encode.c:223
void window_encode(glwin *view, gboolean video)
encoding a movie - creating the dialog
Definition w_encode.c:319
int oglquality
Definition w_encode.c:57
G_MODULE_EXPORT void set_video_codec(GtkComboBox *ComboBoxGtk)
change video codec
Definition w_encode.c:135
GtkWidget * cod
Definition w_encode.c:213
GtkWidget * res[2]
Definition w_encode.c:212
G_MODULE_EXPORT void set_video_bitrate(GtkEntry *res, gpointer data)
set video bitrate entry callback
Definition w_encode.c:166
G_MODULE_EXPORT void run_window_encode(GtkDialog *win, gint response_id, gpointer data)
encoding a movie - running the dialog
Definition w_encode.c:278
int codec
Definition w_encode.c:56
int extraframes
Definition w_encode.c:55
void clean_animation(glwin *view)
clean saved animation data
Definition w_encode.c:186
int video_res[2]
Definition w_encode.c:53
G_MODULE_EXPORT void set_video_frames(GtkEntry *res, gpointer data)
set number of frames
Definition w_encode.c:72
GtkWidget * rese
Definition w_encode.c:210
gboolean spin(gpointer data)
spin
Definition w_spiner.c:56
char * codec_name[VIDEO_CODECS]
Definition movie.c:90
int bitrate
Definition w_encode.c:58
G_MODULE_EXPORT void set_video_extra_frames(GtkEntry *res, gpointer data)
set video extra frames
Definition w_encode.c:93
char * image_name[IMAGE_FORMATS]
Definition image.c:57
gboolean encode_video
Definition w_encode.c:267
G_MODULE_EXPORT void set_video_opengl_spin(GtkSpinButton *res, gpointer data)
set encoding OpenGL quality callback - spin
Definition w_encode.c:148
G_MODULE_EXPORT void set_video_res(GtkEntry *res, gpointer data)
set video / image resolution
Definition w_encode.c:114
G_MODULE_EXPORT void set_image_format(GtkComboBox *box, gpointer data)
selecting the image format
Definition w_encode.c:246
int framesec
Definition w_encode.c:54
GtkWidget * resb
Definition w_encode.c:211
GtkWidget * resf
Definition w_encode.c:209
GtkWidget * encoding_pb
Definition w_encode.c:266
GtkWidget * hbox
Definition workspace.c:71
GtkWidget * img
Definition workspace.c:70
GtkWidget * vbox
Definition workspace.c:72