OSDN Git Service

LinGui: fix race condition in audio settings
[handbrake-jp/handbrake-jp-git.git] / gtk / src / audiohandler.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  * audiohandler.c
4  * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
5  * 
6  * audiohandler.c is free software.
7  * 
8  * You may redistribute it and/or modify it under the terms of the
9  * GNU General Public License, as published by the Free Software
10  * Foundation; either version 2 of the License, or (at your option)
11  * any later version.
12  */
13
14 #include <gtk/gtk.h>
15 #include "hb.h"
16 #include "settings.h"
17 #include "hb-backend.h"
18 #include "values.h"
19 #include "callbacks.h"
20 #include "preview.h"
21 #include "audiohandler.h"
22
23 static void ghb_add_audio(signal_user_data_t *ud, GValue *settings);
24 static GValue* get_selected_asettings(signal_user_data_t *ud);
25
26 static gboolean block_updates = FALSE;
27
28 void
29 ghb_adjust_audio_rate_combos(signal_user_data_t *ud)
30 {
31         gint titleindex, track, acodec, select_acodec, mix;
32         hb_audio_config_t *aconfig;
33         GtkWidget *widget;
34         GValue *gval;
35         int mux;
36         gint bitrate;
37         gint sr = 48000;
38         
39         g_debug("ghb_adjust_audio_rate_combos ()");
40         mux = ghb_settings_combo_int(ud->settings, "FileFormat");
41         titleindex = ghb_settings_combo_int(ud->settings, "title");
42
43         widget = GHB_WIDGET(ud->builder, "AudioTrack");
44         gval = ghb_widget_value(widget);
45         track = ghb_lookup_combo_int("AudioTrack", gval);
46         ghb_value_free(gval);
47
48         widget = GHB_WIDGET(ud->builder, "AudioEncoder");
49         gval = ghb_widget_value(widget);
50         acodec = ghb_lookup_combo_int("AudioEncoder", gval);
51         ghb_value_free(gval);
52         widget = GHB_WIDGET(ud->builder, "AudioMixdown");
53         gval = ghb_widget_value(widget);
54         mix = ghb_lookup_combo_int("AudioMixdown", gval);
55         ghb_value_free(gval);
56
57         widget = GHB_WIDGET(ud->builder, "AudioBitrate");
58         gval = ghb_widget_value(widget);
59         bitrate = ghb_lookup_combo_int("AudioBitrate", gval);
60
61         widget = GHB_WIDGET(ud->builder, "AudioSamplerate");
62         gval = ghb_widget_value(widget);
63         sr = ghb_lookup_combo_int("AudioSamplerate", gval);
64
65         select_acodec = acodec;
66         if (mux == HB_MUX_MP4)
67         {
68                 select_acodec &= ~HB_ACODEC_DCA;
69         }
70         if ((select_acodec & HB_ACODEC_MASK) == 0)
71         {
72                 // Unsuported codec in this container.
73                 select_acodec |= HB_ACODEC_AC3;
74                 acodec = select_acodec;
75         }
76
77         aconfig = ghb_get_scan_audio_info(titleindex, track);
78         if (sr == 0)
79         {
80                 sr = aconfig ? aconfig->in.samplerate : 48000;
81         }
82         gboolean codec_defined_bitrate = FALSE;
83         if (ghb_audio_is_passthru (select_acodec))
84         {
85                 if (aconfig)
86                 {
87                         bitrate = aconfig->in.bitrate / 1000;
88
89                         // Set the values for bitrate and samplerate to the input rates
90                         if (aconfig->in.codec & select_acodec & HB_ACODEC_PASS_MASK)
91                         {
92                                 ghb_set_passthru_bitrate_opts (ud->builder, bitrate);
93                                 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(0));
94                                 select_acodec &= aconfig->in.codec | HB_ACODEC_PASS_FLAG;
95                                 codec_defined_bitrate = TRUE;
96                         }
97                         else
98                         {
99                                 select_acodec = ghb_select_audio_codec(ud->settings, aconfig, acodec);
100                                 if (acodec != HB_ACODEC_ANY)
101                                 {
102                                         ghb_ui_update(ud, "AudioEncoder", ghb_int64_value(select_acodec));
103                                 }
104
105                                 mix = ghb_get_best_mix( aconfig, select_acodec, mix);
106                                 bitrate = hb_get_default_audio_bitrate(select_acodec, sr, mix);
107                                 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix));
108                         }
109                         ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(0));
110                 }
111                 else
112                 {
113                         ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(0));
114                         ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(0));
115                         bitrate = 448;
116                         mix = ghb_get_best_mix( aconfig, select_acodec, 0);
117                 }
118                 ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_double_value(0));
119         }
120         else
121         {
122                 bitrate = hb_get_best_audio_bitrate(select_acodec, bitrate, sr, mix);
123         }
124         if (!codec_defined_bitrate)
125         {
126                 int low, high;
127                 hb_get_audio_bitrate_limits(select_acodec, sr, mix, &low, &high);
128                 ghb_set_default_bitrate_opts (ud->builder, low, high);
129         }
130         ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(bitrate));
131
132         ghb_settings_take_value(ud->settings, "AudioEncoderActual", 
133                                                         ghb_lookup_acodec_value(select_acodec));
134         GValue *asettings = get_selected_asettings(ud);
135         if (asettings)
136         {
137                 ghb_settings_take_value(asettings, "AudioEncoderActual", 
138                                                         ghb_lookup_acodec_value(select_acodec));
139         }
140         ghb_audio_list_refresh_selected(ud);
141         ghb_check_dependency(ud, NULL, "AudioEncoderActual");
142 }
143
144 static void
145 free_audio_hash_key_value(gpointer data)
146 {
147         g_free(data);
148 }
149
150 gchar*
151 ghb_get_user_audio_lang(signal_user_data_t *ud, gint titleindex, gint track)
152 {
153         GValue *audio_list, *asettings;
154         gchar *lang = NULL;
155
156         audio_list = ghb_settings_get_value(ud->settings, "audio_list");
157         if (ghb_array_len(audio_list) <= track)
158                 return NULL;
159         asettings = ghb_array_get_nth(audio_list, track);
160         track = ghb_settings_get_int(asettings, "AudioTrack");
161         lang = ghb_get_source_audio_lang(titleindex, track);
162         return lang;
163 }
164
165 void
166 ghb_set_pref_audio(gint titleindex, signal_user_data_t *ud)
167 {
168         gint fallback_acodec, track;
169         gchar *source_lang = NULL;
170         hb_audio_config_t *aconfig;
171         GHashTable *track_indices;
172         gint mux;
173
174         const GValue *pref_audio;
175         const GValue *audio, *drc;
176         gint acodec, bitrate, mix;
177         gdouble rate;
178         gint count, ii, list_count;
179         
180         g_debug("set_pref_audio");
181         mux = ghb_settings_combo_int(ud->settings, "FileFormat");
182         if (mux == HB_MUX_MP4)
183         {
184                 fallback_acodec = HB_ACODEC_FAAC;
185         }
186         else
187         {
188                 fallback_acodec = HB_ACODEC_LAME;
189         }
190         track_indices = g_hash_table_new_full(g_int_hash, g_int_equal, 
191                                                 free_audio_hash_key_value, free_audio_hash_key_value);
192         // Clear the audio list
193         ghb_clear_audio_list(ud);
194         // Find "best" audio based on audio preferences
195         if (!ghb_settings_get_boolean(ud->settings, "AudioDUB"))
196         {
197                 source_lang = ghb_get_source_audio_lang(titleindex, 0);
198         }
199         if (source_lang == NULL)
200                 source_lang = ghb_settings_get_string(ud->settings, "PreferredLanguage");
201
202         pref_audio = ghb_settings_get_value(ud->settings, "AudioList");
203
204         list_count = 0;
205         count = ghb_array_len(pref_audio);
206         for (ii = 0; ii < count; ii++)
207         {
208                 int select_acodec;
209
210                 audio = ghb_array_get_nth(pref_audio, ii);
211                 select_acodec = acodec = ghb_settings_combo_int(audio, "AudioEncoder");
212                 if (mux == HB_MUX_MP4)
213                 {
214                         select_acodec &= ~HB_ACODEC_DCA;
215                 }
216                 if ((select_acodec & HB_ACODEC_MASK) == 0)
217                 {
218                         // Unsuported codec in this container.
219                         select_acodec |= HB_ACODEC_AC3;
220                         acodec = select_acodec;
221                 }
222                 if ( ghb_audio_can_passthru( select_acodec ) )
223                 {
224                         fallback_acodec = HB_ACODEC_AC3;
225                 }
226                 bitrate = ghb_settings_combo_int(audio, "AudioBitrate");
227                 rate = ghb_settings_combo_double(audio, "AudioSamplerate");
228                 mix = ghb_settings_combo_int(audio, "AudioMixdown");
229                 drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
230                 // If there are multiple audios using the same codec, then
231                 // select sequential tracks for each.  The hash keeps track 
232                 // of the tracks used for each codec.
233                 track = ghb_find_audio_track(titleindex, source_lang, 
234                                                                 select_acodec, fallback_acodec, track_indices);
235                 // Check to see if:
236                 // 1. pref codec is passthru
237                 // 2. source codec is not passthru
238                 // 3. next pref is enabled
239                 aconfig = ghb_get_scan_audio_info(titleindex, track);
240                 if (aconfig && ghb_audio_is_passthru (acodec))
241                 {
242                         // HB_ACODEC_* are bit fields.  Treat acodec as mask
243                         if (!(aconfig->in.codec & select_acodec & HB_ACODEC_PASS_MASK))
244                         {
245                                 if (acodec != HB_ACODEC_ANY)
246                                         acodec = fallback_acodec;
247                                 // If we can't substitute the passthru with a suitable
248                                 // encoder and
249                                 // If there's more audio to process, or we've already
250                                 // placed one in the list, then we can skip this one
251                                 if (!(select_acodec & fallback_acodec) && 
252                                         ((ii + 1 < count) || (list_count != 0)))
253                                 {
254                                         // Skip this audio
255                                         acodec = 0;
256                                 }
257                                 else
258                                 {
259                                         int channels, min_rate, max_rate;
260                                         select_acodec = fallback_acodec;
261                                         mix = ghb_get_best_mix(aconfig, select_acodec, mix);
262                                         channels = HB_AMIXDOWN_GET_DISCRETE_CHANNEL_COUNT(mix);
263                                         bitrate = aconfig->in.bitrate / 1000;
264                                         min_rate = channels * 64;
265                                         max_rate = channels * 160;
266                                         if (bitrate < min_rate)
267                                                 bitrate = min_rate;
268                                         if (bitrate > max_rate)
269                                                 bitrate = max_rate;
270                                         rate = 0;
271                                 }
272                         }
273                         else
274                         {
275                                 select_acodec &= aconfig->in.codec | HB_ACODEC_PASS_FLAG;
276                         }
277                 }
278                 if (titleindex >= 0 && track < 0)
279                         acodec = 0;
280                 if (acodec != 0)
281                 {
282                         GValue *settings = ghb_dict_value_new();
283                         ghb_settings_set_int(settings, "AudioTrack", track);
284                         ghb_settings_set_string(settings, "AudioEncoder", 
285                                 ghb_lookup_combo_string("AudioEncoder", ghb_int_value(acodec)));
286                         ghb_settings_set_value(settings, "AudioEncoderActual", 
287                                                                         ghb_lookup_acodec_value(select_acodec));
288                         // This gets set autimatically if the codec is passthru
289                         ghb_settings_set_string(settings, "AudioBitrate",
290                                 ghb_lookup_combo_string("AudioBitrate", ghb_int_value(bitrate)));
291                         ghb_settings_set_string(settings, "AudioSamplerate",
292                                 ghb_lookup_combo_string("AudioSamplerate", ghb_int_value(rate)));
293                         mix = ghb_get_best_mix( aconfig, select_acodec, mix);
294                         ghb_settings_set_string(settings, "AudioMixdown",
295                                 ghb_lookup_combo_string("AudioMixdown", ghb_int_value(mix)));
296                         ghb_settings_set_value(settings, "AudioTrackDRCSlider", drc);
297                         ghb_add_audio(ud, settings);
298                         ghb_adjust_audio_rate_combos(ud);
299                 }
300         }
301         g_free(source_lang);
302         g_hash_table_destroy(track_indices);
303 }
304
305 static GValue*
306 get_selected_asettings(signal_user_data_t *ud)
307 {
308         GtkTreeView *treeview;
309         GtkTreePath *treepath;
310         GtkTreeSelection *selection;
311         GtkTreeModel *store;
312         GtkTreeIter iter;
313         gint *indices;
314         gint row;
315         GValue *asettings = NULL;
316         const GValue *audio_list;
317         
318         g_debug("get_selected_asettings ()");
319         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
320         selection = gtk_tree_view_get_selection (treeview);
321         if (gtk_tree_selection_get_selected(selection, &store, &iter))
322         {
323                 // Get the row number
324                 treepath = gtk_tree_model_get_path (store, &iter);
325                 indices = gtk_tree_path_get_indices (treepath);
326                 row = indices[0];
327                 gtk_tree_path_free(treepath);
328                 // find audio settings
329                 if (row < 0) return NULL;
330                 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
331                 if (row >= ghb_array_len(audio_list))
332                         return NULL;
333                 asettings = ghb_array_get_nth(audio_list, row);
334         }
335         return asettings;
336 }
337
338 void
339 ghb_audio_list_refresh_selected(signal_user_data_t *ud)
340 {
341         GtkTreeView *treeview;
342         GtkTreePath *treepath;
343         GtkTreeSelection *selection;
344         GtkTreeModel *store;
345         GtkTreeIter iter;
346         gint *indices;
347         gint row;
348         GValue *asettings = NULL;
349         const GValue *audio_list;
350         
351         g_debug("ghb_audio_list_refresh_selected ()");
352         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
353         selection = gtk_tree_view_get_selection (treeview);
354         if (gtk_tree_selection_get_selected(selection, &store, &iter))
355         {
356                 const gchar *track, *codec, *br, *sr, *mix;
357                 gchar *s_drc;
358                 gint itrack;
359                 gdouble drc;
360                 // Get the row number
361                 treepath = gtk_tree_model_get_path (store, &iter);
362                 indices = gtk_tree_path_get_indices (treepath);
363                 row = indices[0];
364                 gtk_tree_path_free(treepath);
365                 // find audio settings
366                 if (row < 0) return;
367                 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
368                 if (row >= ghb_array_len(audio_list))
369                         return;
370                 asettings = ghb_array_get_nth(audio_list, row);
371
372                 track = ghb_settings_combo_option(asettings, "AudioTrack");
373                 itrack = ghb_settings_combo_int(asettings, "AudioTrack");
374                 codec = ghb_settings_combo_option(asettings, "AudioEncoderActual");
375                 br = ghb_settings_combo_option(asettings, "AudioBitrate");
376                 sr = ghb_settings_combo_option(asettings, "AudioSamplerate");
377                 mix = ghb_settings_combo_option(asettings, "AudioMixdown");
378
379                 drc = ghb_settings_get_double(asettings, "AudioTrackDRCSlider");
380                 if (drc < 1.0)
381                         s_drc = g_strdup("Off");
382                 else
383                         s_drc = g_strdup_printf("%.1f", drc);
384
385                 gtk_list_store_set(GTK_LIST_STORE(store), &iter, 
386                         // These are displayed in list
387                         0, track,
388                         1, codec,
389                         2, br,
390                         3, sr,
391                         4, mix,
392                         5, s_drc,
393                         -1);
394                 g_free(s_drc);
395         }
396 }
397
398 G_MODULE_EXPORT void
399 audio_codec_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
400 {
401         static gint prev_acodec = 0;
402         gint acodec_code;
403         GValue *asettings, *gval;
404         
405         g_debug("audio_codec_changed_cb ()");
406         if (block_updates) return;
407
408         gval = ghb_widget_value(widget);
409         acodec_code = ghb_lookup_combo_int("AudioEncoder", gval);
410         ghb_value_free(gval);
411
412         asettings = get_selected_asettings(ud);
413         if (ghb_audio_is_passthru (prev_acodec) && 
414                 !ghb_audio_is_passthru (acodec_code))
415         {
416                 // Transition from passthru to not, put some audio settings back to 
417                 // pref settings
418                 gint titleindex;
419                 gint track;
420                 gint br, sr, mix_code;
421
422                 if (asettings != NULL)
423                 {
424                         br = ghb_settings_get_int(asettings, "AudioBitrate");
425                         sr = ghb_settings_combo_int(asettings, "AudioSamplerate");
426                         mix_code = ghb_settings_combo_int(asettings, "AudioMixdown");
427                 }
428                 else
429                 {
430                         br = 160;
431                         sr = 0;
432                         mix_code = 0;
433                 }
434
435                 titleindex = ghb_settings_combo_int(ud->settings, "title");
436                 track = ghb_settings_combo_int(ud->settings, "AudioTrack");
437                 if (sr)
438                 {
439                         sr = ghb_find_closest_audio_rate(sr);
440                 }
441                 ghb_ui_update(ud, "AudioSamplerate", ghb_int64_value(sr));
442
443                 hb_audio_config_t *aconfig;
444                 aconfig = ghb_get_scan_audio_info(titleindex, track);
445                 if (sr == 0)
446                 {
447                         sr = aconfig ? aconfig->in.samplerate : 48000;
448                 }
449                 mix_code = ghb_get_best_mix( aconfig, acodec_code, mix_code);
450                 br = hb_get_best_audio_bitrate(acodec_code, br, sr, mix_code);
451                 ghb_ui_update(ud, "AudioBitrate", ghb_int64_value(br));
452
453                 ghb_ui_update(ud, "AudioMixdown", ghb_int64_value(mix_code));
454         }
455         ghb_adjust_audio_rate_combos(ud);
456         ghb_grey_combo_options (ud->builder);
457         ghb_check_dependency(ud, widget, NULL);
458         prev_acodec = acodec_code;
459         if (asettings != NULL)
460         {
461                 ghb_widget_to_setting(asettings, widget);
462                 ghb_settings_set_value(asettings, "AudioEncoderActual", ghb_settings_get_value(ud->settings, "AudioEncoderActual"));
463                 ghb_audio_list_refresh_selected(ud);
464         }
465         ghb_update_destination_extension(ud);
466         ghb_live_reset(ud);
467 }
468
469 G_MODULE_EXPORT void
470 audio_track_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
471 {
472         GValue *asettings;
473
474         g_debug("audio_track_changed_cb ()");
475         if (block_updates) return;
476
477         ghb_adjust_audio_rate_combos(ud);
478         ghb_check_dependency(ud, widget, NULL);
479         ghb_grey_combo_options(ud->builder);
480         asettings = get_selected_asettings(ud);
481         if (asettings != NULL)
482         {
483                 const gchar *track;
484
485                 ghb_widget_to_setting(asettings, widget);
486                 ghb_audio_list_refresh_selected(ud);
487                 track = ghb_settings_combo_option(asettings, "AudioTrack");
488                 ghb_settings_set_string(asettings, "AudioTrackDescription", track);
489         }
490         ghb_live_reset(ud);
491 }
492
493 G_MODULE_EXPORT void
494 audio_mix_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
495 {
496         GValue *asettings;
497
498         g_debug("audio_mix_changed_cb ()");
499         if (block_updates) return;
500
501         ghb_adjust_audio_rate_combos(ud);
502         ghb_check_dependency(ud, widget, NULL);
503         asettings = get_selected_asettings(ud);
504         if (asettings != NULL)
505         {
506                 ghb_widget_to_setting(asettings, widget);
507                 ghb_audio_list_refresh_selected(ud);
508         }
509         ghb_live_reset(ud);
510 }
511
512 G_MODULE_EXPORT void
513 audio_widget_changed_cb(GtkWidget *widget, signal_user_data_t *ud)
514 {
515         GValue *asettings;
516
517         g_debug("audio_widget_changed_cb ()");
518         if (block_updates) return;
519
520         ghb_adjust_audio_rate_combos(ud);
521         ghb_check_dependency(ud, widget, NULL);
522         asettings = get_selected_asettings(ud);
523         if (asettings != NULL)
524         {
525                 ghb_widget_to_setting(asettings, widget);
526                 ghb_audio_list_refresh_selected(ud);
527         }
528         ghb_live_reset(ud);
529 }
530
531 G_MODULE_EXPORT void
532 drc_widget_changed_cb(GtkWidget *widget, gdouble val, signal_user_data_t *ud)
533 {
534         GValue *asettings;
535         GtkLabel *label;
536         gchar *drc;
537
538         g_debug("drc_widget_changed_cb ()");
539         if (block_updates) return;
540
541         label = GTK_LABEL(GHB_WIDGET(ud->builder, "drc_label"));
542         if (val < 1.0)
543                 drc = g_strdup_printf("Off");
544         else
545                 drc = g_strdup_printf("%.1f", val);
546         gtk_label_set_text(label, drc);
547         g_free(drc);
548         ghb_check_dependency(ud, widget, NULL);
549         asettings = get_selected_asettings(ud);
550         if (asettings != NULL)
551         {
552                 ghb_widget_to_setting(asettings, widget);
553                 ghb_audio_list_refresh_selected(ud);
554         }
555         ghb_live_reset(ud);
556 }
557
558 void
559 ghb_clear_audio_list(signal_user_data_t *ud)
560 {
561         GtkTreeView *treeview;
562         GtkListStore *store;
563         GValue *audio_list;
564         
565         g_debug("clear_audio_list ()");
566         audio_list = ghb_settings_get_value(ud->settings, "audio_list");
567         if (audio_list == NULL)
568         {
569                 audio_list = ghb_array_value_new(8);
570                 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
571         }
572         else
573                 ghb_array_value_reset(audio_list, 8);
574         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
575         store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
576         gtk_list_store_clear (store);
577 }
578
579 static void
580 add_to_audio_list(signal_user_data_t *ud, GValue *settings)
581 {
582         GtkTreeView *treeview;
583         GtkTreeIter iter;
584         GtkListStore *store;
585         GtkTreeSelection *selection;
586         const gchar *track, *codec, *br, *sr, *mix;
587         gchar *s_drc;
588         gint itrack;
589         gdouble drc;
590         
591         g_debug("add_to_audio_list ()");
592         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
593         selection = gtk_tree_view_get_selection (treeview);
594         store = GTK_LIST_STORE(gtk_tree_view_get_model(treeview));
595
596         track = ghb_settings_combo_option(settings, "AudioTrack");
597         itrack = ghb_settings_combo_int(settings, "AudioTrack");
598         codec = ghb_settings_combo_option(settings, "AudioEncoderActual");
599         br = ghb_settings_combo_option(settings, "AudioBitrate");
600         sr = ghb_settings_combo_option(settings, "AudioSamplerate");
601         mix = ghb_settings_combo_option(settings, "AudioMixdown");
602
603         drc = ghb_settings_get_double(settings, "AudioTrackDRCSlider");
604         if (drc < 1.0)
605                 s_drc = g_strdup("Off");
606         else
607                 s_drc = g_strdup_printf("%.1f", drc);
608
609         gtk_list_store_append(store, &iter);
610         gtk_list_store_set(store, &iter, 
611                 // These are displayed in list
612                 0, track,
613                 1, codec,
614                 2, br,
615                 3, sr,
616                 4, mix,
617                 5, s_drc,
618                 -1);
619         gtk_tree_selection_select_iter(selection, &iter);
620         g_free(s_drc);
621 }
622
623 G_MODULE_EXPORT void
624 audio_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
625 {
626         GtkTreeModel *store;
627         GtkTreeIter iter;
628         GtkWidget *widget;
629         
630         GtkTreePath *treepath;
631         gint *indices;
632         gint row;
633         GValue *asettings = NULL;
634
635         const GValue *audio_list;
636         g_debug("audio_list_selection_changed_cb ()");
637         if (gtk_tree_selection_get_selected(selection, &store, &iter))
638         {
639                 //const gchar *actual_codec, *track, *codec, *bitrate, *sample_rate, *mix;
640                 //gdouble drc;
641
642                 // Get the row number
643                 treepath = gtk_tree_model_get_path (store, &iter);
644                 indices = gtk_tree_path_get_indices (treepath);
645                 row = indices[0];
646                 gtk_tree_path_free(treepath);
647                 // find audio settings
648                 if (row < 0) return;
649                 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
650                 if (row >= ghb_array_len(audio_list))
651                         return;
652                 asettings = ghb_array_get_nth(audio_list, row);
653
654                 block_updates = TRUE;
655                 ghb_ui_update(ud, "AudioTrack", ghb_settings_get_value(asettings, "AudioTrack"));
656                 ghb_ui_update(ud, "AudioEncoder", ghb_settings_get_value(asettings, "AudioEncoder"));
657                 ghb_settings_set_value(ud->settings, "AudioEncoderActual", ghb_settings_get_value(asettings, "AudioEncoderActual"));
658                 ghb_check_dependency(ud, NULL, "AudioEncoderActual");
659                 ghb_ui_update(ud, "AudioBitrate", ghb_settings_get_value(asettings, "AudioBitrate"));
660                 ghb_ui_update(ud, "AudioSamplerate", ghb_settings_get_value(asettings, "AudioSamplerate"));
661                 ghb_ui_update(ud, "AudioMixdown", ghb_settings_get_value(asettings, "AudioMixdown"));
662                 ghb_ui_update(ud, "AudioTrackDRCSlider", ghb_settings_get_value(asettings, "AudioTrackDRCSlider"));
663                 block_updates = FALSE;
664                 widget = GHB_WIDGET (ud->builder, "audio_remove");
665                 gtk_widget_set_sensitive(widget, TRUE);
666         }
667         else
668         {
669                 widget = GHB_WIDGET (ud->builder, "audio_remove");
670                 gtk_widget_set_sensitive(widget, FALSE);
671         }
672 }
673
674 static void
675 ghb_add_audio(signal_user_data_t *ud, GValue *settings)
676 {
677         GValue *audio_list;
678         int count;
679         const gchar * track;
680
681         track = ghb_settings_combo_option(settings, "AudioTrack");
682         ghb_settings_set_string(settings, "AudioTrackDescription", track);
683
684         audio_list = ghb_settings_get_value(ud->settings, "audio_list");
685         if (audio_list == NULL)
686         {
687                 audio_list = ghb_array_value_new(8);
688                 ghb_settings_set_value(ud->settings, "audio_list", audio_list);
689         }
690         ghb_array_append(audio_list, settings);
691         add_to_audio_list(ud, settings);
692         count = ghb_array_len(audio_list);
693         if (count >= 99)
694         {
695                 GtkWidget * widget = GHB_WIDGET(ud->builder, "audio_add");
696                 gtk_widget_set_sensitive(widget, FALSE);
697         }
698         ghb_update_destination_extension(ud);
699 }
700
701 G_MODULE_EXPORT void
702 audio_add_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
703 {
704         // Add the current audio settings to the list.
705         GValue *asettings;
706         GtkWidget *widget;
707         
708         g_debug("audio_add_clicked_cb ()");
709         asettings = ghb_dict_value_new();
710         widget = GHB_WIDGET(ud->builder, "AudioTrack");
711         ghb_settings_take_value(asettings, "AudioTrack", ghb_widget_value(widget));
712         widget = GHB_WIDGET(ud->builder, "AudioEncoder");
713         ghb_settings_take_value(asettings, "AudioEncoder", ghb_widget_value(widget));
714         ghb_settings_set_value(asettings, "AudioEncoderActual", 
715                 ghb_settings_get_value(ud->settings, "AudioEncoderActual"));
716         widget = GHB_WIDGET(ud->builder, "AudioBitrate");
717         ghb_settings_take_value(asettings, "AudioBitrate", ghb_widget_value(widget));
718         widget = GHB_WIDGET(ud->builder, "AudioSamplerate");
719         ghb_settings_take_value(asettings, "AudioSamplerate", ghb_widget_value(widget));
720         widget = GHB_WIDGET(ud->builder, "AudioMixdown");
721         ghb_settings_take_value(asettings, "AudioMixdown", ghb_widget_value(widget));
722         widget = GHB_WIDGET(ud->builder, "AudioTrackDRCSlider");
723         ghb_settings_take_value(asettings, "AudioTrackDRCSlider", ghb_widget_value(widget));
724
725         ghb_add_audio(ud, asettings);
726 }
727
728 G_MODULE_EXPORT void
729 audio_remove_clicked_cb(GtkWidget *widget, signal_user_data_t *ud)
730 {
731         GtkTreeView *treeview;
732         GtkTreePath *treepath;
733         GtkTreeSelection *selection;
734         GtkTreeModel *store;
735         GtkTreeIter iter, nextIter;
736         gint *indices;
737         gint row;
738         GValue *audio_list;
739
740         g_debug("audio_remove_clicked_cb ()");
741         treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "audio_list"));
742         selection = gtk_tree_view_get_selection (treeview);
743         if (gtk_tree_selection_get_selected(selection, &store, &iter))
744         {
745                 nextIter = iter;
746                 if (!gtk_tree_model_iter_next(store, &nextIter))
747                 {
748                         nextIter = iter;
749                         if (gtk_tree_model_get_iter_first(store, &nextIter))
750                         {
751                                 gtk_tree_selection_select_iter (selection, &nextIter);
752                         }
753                 }
754                 else
755                 {
756                         gtk_tree_selection_select_iter (selection, &nextIter);
757                 }
758                 // Get the row number
759                 treepath = gtk_tree_model_get_path (store, &iter);
760                 indices = gtk_tree_path_get_indices (treepath);
761                 row = indices[0];
762                 gtk_tree_path_free(treepath);
763                 // Remove the selected item
764                 gtk_list_store_remove (GTK_LIST_STORE(store), &iter);
765                 // remove from audio settings list
766                 if (row < 0) return;
767                 widget = GHB_WIDGET (ud->builder, "audio_add");
768                 gtk_widget_set_sensitive(widget, TRUE);
769                 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
770                 if (row >= ghb_array_len(audio_list))
771                         return;
772                 GValue *old = ghb_array_get_nth(audio_list, row);
773                 ghb_value_free(old);
774                 ghb_array_remove(audio_list, row);
775         }
776 }
777
778 void
779 ghb_set_audio(signal_user_data_t *ud, GValue *settings)
780 {
781         gint acodec_code;
782
783         GValue *alist;
784         GValue *track, *audio, *acodec, *acodec_actual, *bitrate, *rate, *mix, *drc;
785         gint count, ii;
786         
787         g_debug("set_audio");
788         // Clear the audio list
789         ghb_clear_audio_list(ud);
790         alist = ghb_settings_get_value(settings, "audio_list");
791
792         count = ghb_array_len(alist);
793         for (ii = 0; ii < count; ii++)
794         {
795                 audio = ghb_array_get_nth(alist, ii);
796                 track = ghb_settings_get_value(audio, "AudioTrack");
797                 acodec = ghb_settings_get_value(audio, "AudioEncoder");
798                 acodec_actual = ghb_settings_get_value(audio, "AudioEncoderActual");
799                 bitrate = ghb_settings_get_value(audio, "AudioBitrate");
800                 rate = ghb_settings_get_value(audio, "AudioSamplerate");
801                 mix = ghb_settings_get_value(audio, "AudioMixdown");
802                 drc = ghb_settings_get_value(audio, "AudioTrackDRCSlider");
803                 acodec_code = ghb_lookup_combo_int("AudioEncoder", acodec);
804
805                 if (acodec_code != 0)
806                 {
807                         GValue *settings = ghb_dict_value_new();
808                         ghb_settings_set_value(settings, "AudioTrack", track);
809                         ghb_settings_set_value(settings, "AudioEncoder", acodec);
810                         ghb_settings_set_value(settings, "AudioEncoderActual", acodec_actual);
811
812                         // This gets set autimatically if the codec is passthru
813                         ghb_settings_set_value(settings, "AudioBitrate", bitrate);
814                         ghb_settings_set_value(settings, "AudioSamplerate", rate);
815                         ghb_settings_set_value(settings, "AudioMixdown", mix);
816                         ghb_settings_set_value(settings, "AudioTrackDRCSlider", drc);
817                         ghb_add_audio(ud, settings);
818                         ghb_adjust_audio_rate_combos(ud);
819                 }
820         }
821 }
822