4 #include <glib/gstdio.h>
8 static GValue *defaults;
17 static value_map_t subtitle_xlat[] =
23 { "Abkhazian", "abk" },
24 { "Afrikaans", "afr" },
26 { "Albanian", "sqi" },
29 { "Aragonese", "arg" },
30 { "Armenian", "hye" },
31 { "Assamese", "asm" },
35 { "Azerbaijani", "aze" },
39 { "Belarusian", "bel" },
45 { "Bulgarian", "bul" },
48 { "Chamorro", "cha" },
51 { "Church Slavic", "chu" },
54 { "Corsican", "cos" },
60 { "Dzongkha", "dzo" },
62 { "Esperanto", "epo" },
63 { "Estonian", "est" },
69 { "Western Frisian", "fry" },
71 { "Georgian", "kat" },
73 { "Gaelic (Scots)", "gla" },
75 { "Galician", "glg" },
77 { "Greek, Modern", "ell" },
79 { "Gujarati", "guj" },
85 { "Hiri Motu", "hmo" },
86 { "Hungarian", "hun" },
88 { "Icelandic", "isl" },
90 { "Sichuan Yi", "iii" },
91 { "Inuktitut", "iku" },
92 { "Interlingue", "ile" },
93 { "Interlingua", "ina" },
94 { "Indonesian", "ind" },
97 { "Javanese", "jav" },
98 { "Japanese", "jpn" },
99 { "Kalaallisut", "kal" },
100 { "Kannada", "kan" },
101 { "Kashmiri", "kas" },
104 { "Central Khmer", "khm" },
106 { "Kinyarwanda", "kin" },
107 { "Kirghiz", "kir" },
111 { "Kuanyama", "kua" },
112 { "Kurdish", "kur" },
115 { "Latvian", "lav" },
116 { "Limburgan", "lim" },
117 { "Lingala", "lin" },
118 { "Lithuanian", "lit" },
119 { "Luxembourgish", "ltz" },
120 { "Luba-Katanga", "lub" },
122 { "Macedonian", "mkd" },
123 { "Marshallese", "mah" },
124 { "Malayalam", "mal" },
126 { "Marathi", "mar" },
128 { "Malagasy", "mlg" },
129 { "Maltese", "mlt" },
130 { "Moldavian", "mol" },
131 { "Mongolian", "mon" },
134 { "Ndebele, South", "nbl" },
135 { "Ndebele, North", "nde" },
138 { "Norwegian Nynorsk", "nno" },
139 { "Norwegian Bokmål", "nob" },
140 { "Norwegian", "nor" },
141 { "Chichewa; Nyanja", "nya" },
142 { "Occitan", "oci" },
146 { "Ossetian", "oss" },
147 { "Panjabi", "pan" },
148 { "Persian", "fas" },
151 { "Portuguese", "por" },
153 { "Quechua", "que" },
154 { "Romansh", "roh" },
155 { "Romanian", "ron" },
157 { "Russian", "rus" },
159 { "Sanskrit", "san" },
160 { "Serbian", "srp" },
161 { "Croatian", "hrv" },
162 { "Sinhala", "sin" },
164 { "Slovenian", "slv" },
165 { "Northern Sami", "sme" },
170 { "Sotho, Southern", "sot" },
171 { "Spanish", "spa" },
172 { "Sardinian", "srd" },
174 { "Sundanese", "sun" },
175 { "Swahili", "swa" },
176 { "Swedish", "swe" },
177 { "Tahitian", "tah" },
182 { "Tagalog", "tgl" },
184 { "Tibetan", "bod" },
185 { "Tigrinya", "tir" },
189 { "Turkmen", "tuk" },
190 { "Turkish", "tur" },
193 { "Ukrainian", "ukr" },
197 { "Vietnamese", "vie" },
198 { "Volapük", "vol" },
200 { "Walloon", "wln" },
203 { "Yiddish", "yid" },
210 static value_map_t vcodec_xlat[] =
212 {"MPEG-4 (FFmpeg)", "ffmpeg"},
213 {"MPEG-4 (XviD)", "ffmpeg"},
214 {"H.264 (x264)", "x264"},
215 {"VP3 (Theora)", "theora"},
219 value_map_t container_xlat[] =
229 value_map_t framerate_xlat[] =
231 {"Same as source", "source"},
236 {"23.976", "23.976"},
243 value_map_t deint_xlat[] =
252 value_map_t denoise_xlat[] =
261 static value_map_t acodec_xlat[] =
263 {"AAC (faac)", "faac"},
264 {"AC3 Passthru", "ac3"},
265 {"MP3 (lame)", "lame"},
266 {"Vorbis (vorbis)", "vorbis"},
270 value_map_t samplerate_xlat[] =
281 value_map_t mix_xlat[] =
284 {"Stereo", "stereo"},
285 {"Dolby Surround", "dpl1"},
286 {"Dolby Pro Logic II", "dpl2"},
287 {"6-channel discrete", "6ch"},
288 {"AC3 Passthru", "none"},
297 value_map_t *value_map;
302 key_map_t key_map[] =
304 {"Audio1Bitrate", NULL, NULL, FALSE, FALSE},
305 {"Audio1Encoder", NULL, NULL, FALSE, FALSE},
306 {"Audio1Mixdown", NULL, NULL, FALSE, FALSE},
307 {"Audio1Samplerate", NULL, NULL, FALSE, FALSE},
308 {"Audio1Track", NULL, NULL, FALSE, FALSE},
309 {"Audio1TrackDescription", NULL, NULL, FALSE, FALSE},
310 {"Audio1TrackDRCSlider", NULL, NULL, FALSE, FALSE},
311 {"Audio2Bitrate", NULL, NULL, FALSE, FALSE},
312 {"Audio2Encoder", NULL, NULL, FALSE, FALSE},
313 {"Audio2Mixdown", NULL, NULL, FALSE, FALSE},
314 {"Audio2Samplerate", NULL, NULL, FALSE, FALSE},
315 {"Audio2Track", NULL, NULL, FALSE, FALSE},
316 {"Audio2TrackDescription", NULL, NULL, FALSE, FALSE},
317 {"Audio2TrackDRCSlider", NULL, NULL, FALSE, FALSE},
318 {"ChapterMarkers", NULL, NULL, TRUE, FALSE},
319 {"Default", NULL, NULL, TRUE, FALSE},
320 {"FileFormat", NULL, NULL, TRUE, FALSE},
321 {"Folder", NULL, NULL, TRUE, FALSE},
322 {"Mp4HttpOptimize", NULL, NULL, TRUE, FALSE},
323 {"Mp4iPodCompatible", NULL, NULL, TRUE, FALSE},
324 {"Mp4LargeFile", NULL, NULL, TRUE, FALSE},
325 {"PictureAutoCrop", NULL, NULL, TRUE, FALSE},
326 {"PictureBottomCrop", NULL, NULL, TRUE, FALSE},
327 {"PictureDeblock", NULL, NULL, TRUE, FALSE},
328 {"PictureDecomb", NULL, NULL, TRUE, FALSE},
329 {"PictureDeinterlace", NULL, NULL, TRUE, FALSE},
330 {"PictureDenoise", NULL, NULL, TRUE, FALSE},
331 {"PictureDetelecine", NULL, NULL, TRUE, FALSE},
332 {"PictureHeight", NULL, NULL, TRUE, FALSE},
333 {"PictureKeepRatio", NULL, NULL, TRUE, FALSE},
334 {"PictureLeftCrop", NULL, NULL, TRUE, FALSE},
335 {"PicturePAR", NULL, NULL, TRUE, FALSE},
336 {"PictureRightCrop", NULL, NULL, TRUE, FALSE},
337 {"PictureTopCrop", NULL, NULL, TRUE, FALSE},
338 {"PictureWidth", NULL, NULL, TRUE, FALSE},
339 {"PresetDescription", NULL, NULL, TRUE, FALSE},
340 {"PresetName", NULL, NULL, TRUE, FALSE},
341 {"Subtitles", NULL, NULL, TRUE, FALSE},
342 {"SubtitlesForced", NULL, NULL, TRUE, FALSE},
343 {"Type", NULL, NULL, TRUE, FALSE},
344 {"UsesMaxPictureSettings", NULL, NULL, TRUE, FALSE},
345 {"UsesPictureFilters", NULL, NULL, TRUE, FALSE},
346 {"UsesPictureSettings", NULL, NULL, TRUE, FALSE},
347 {"VFR", NULL, NULL, FALSE, TRUE},
348 {"VideoAvgBitrate", NULL, NULL, TRUE, FALSE},
349 {"VideoEncoder", NULL, NULL, TRUE, FALSE},
350 {"VideoFramerate", NULL, NULL, TRUE, FALSE},
351 {"VideoGrayScale", NULL, NULL, TRUE, FALSE},
352 {"VideoQualitySlider", NULL, NULL, TRUE, FALSE},
353 {"VideoQualityType", NULL, NULL, TRUE, FALSE},
354 {"VideoTargetSize", NULL, NULL, TRUE, FALSE},
355 {"VideoTwoPass", NULL, NULL, TRUE, FALSE},
356 {"VideoTurboTwoPass", NULL, NULL, TRUE, FALSE},
357 {"x264Option", NULL, NULL, TRUE, FALSE},
362 key_xlat(key_map_t *key_map, const gchar *mac_key)
366 for (ii = 0; key_map[ii].mac_key; ii++)
368 if (strcmp(mac_key, key_map[ii].mac_key) == 0)
370 if (key_map[ii].ignore)
375 g_warning("Unrecognized key: (%s)", mac_key);
386 GValue *gval, *def_val;
387 const gchar *lin_key;
388 if (key_map[key_index].same)
389 lin_key = key_map[key_index].mac_key;
391 lin_key = key_map[key_index].lin_key;
392 value_map_t *value_map = key_map[key_index].value_map;
394 def_val = ghb_dict_lookup(defaults, lin_key);
403 str = ghb_value_string(mac_val);
404 for (ii = 0; value_map[ii].mac_val; ii++)
406 if (strcmp(str, value_map[ii].mac_val) == 0)
408 sval = ghb_string_value_new(value_map[ii].lin_val);
410 gval = ghb_value_new(G_VALUE_TYPE(def_val));
411 if (!g_value_transform(sval, gval))
413 g_warning("1 can't transform");
414 ghb_value_free(gval);
415 ghb_value_free(sval);
418 ghb_value_free(sval);
422 g_warning("Can't map value: (%s)", str);
427 gval = ghb_value_new(G_VALUE_TYPE(def_val));
428 if (!g_value_transform(mac_val, gval))
430 g_warning("2 can't transform");
431 ghb_value_free(gval);
439 g_warning("Bad key: (%s)", lin_key);
445 key_map_t audio_key_map[] =
447 {"Audio1Bitrate", "AudioBitrate", NULL, FALSE, FALSE},
448 {"Audio1Encoder", "AudioEncoder", NULL, FALSE, FALSE},
449 {"Audio1Mixdown", "AudioMixdown", NULL, FALSE},
450 {"Audio1Samplerate", "AudioSamplerate", NULL, FALSE, FALSE},
451 {"Audio1Track", "AudioTrack", NULL, FALSE, FALSE},
452 {"Audio1TrackDescription", "AudioTrackDescription", NULL, FALSE, FALSE},
453 {"Audio1TrackDRCSlider", "AudioTrackDRCSlider", NULL, FALSE, FALSE},
454 {"Audio2Bitrate", "AudioBitrate", NULL, FALSE, FALSE},
455 {"Audio2Encoder", "AudioEncoder", NULL, FALSE, FALSE},
456 {"Audio2Mixdown", "AudioMixdown", NULL, FALSE, FALSE},
457 {"Audio2Samplerate", "AudioSamplerate", NULL, FALSE, FALSE},
458 {"Audio2Track", "AudioTrack", NULL, FALSE, FALSE},
459 {"Audio2TrackDescription", "AudioTrackDescription", NULL, FALSE, FALSE},
460 {"Audio2TrackDRCSlider", "AudioTrackDRCSlider", NULL, FALSE, FALSE},
465 hard_value_xlat(GValue *lin_dict, const gchar *mac_key, GValue *mac_val)
469 GValue *audio_defaults;
471 audio_defaults = ghb_array_get_nth(
472 ghb_dict_lookup(defaults, "AudioList"), 0);
473 key_index = key_xlat(audio_key_map, mac_key);
476 gint audio_index, count, ii;
477 GValue *alist, *adict, *val;
478 const gchar *lin_key;
480 if (audio_key_map[key_index].same)
481 lin_key = audio_key_map[key_index].mac_key;
483 lin_key = audio_key_map[key_index].lin_key;
484 audio_index = mac_key[5] - '1';
485 alist = ghb_dict_lookup(lin_dict, "AudioList");
488 alist = ghb_array_value_new(8);
489 ghb_dict_insert(lin_dict, "AudioList", alist);
491 count = ghb_array_len(alist);
492 for (ii = count; ii <= audio_index; ii++)
494 adict = ghb_value_dup(audio_defaults);
495 ghb_array_append(alist, adict);
497 adict = ghb_array_get_nth(alist, audio_index);
498 val = value_xlat(audio_defaults, audio_key_map, key_index, mac_val);
501 ghb_dict_insert(adict, g_strdup(lin_key), val);
508 parse_preset_dict(GValue *mac_dict, GValue *lin_dict)
512 GValue *mac_val, *val;
514 ghb_dict_iter_init(&iter, mac_dict);
515 // middle (void*) cast prevents gcc warning "defreferencing type-punned
516 // pointer will break strict-aliasing rules"
517 while (g_hash_table_iter_next(
518 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&mac_val))
522 key_index = key_xlat(key_map, key);
524 { // The simple translations
525 const gchar *lin_key;
527 if (key_map[key_index].same)
528 lin_key = key_map[key_index].mac_key;
530 lin_key = key_map[key_index].lin_key;
533 val = value_xlat(defaults, key_map, key_index, mac_val);
536 ghb_dict_insert(lin_dict, g_strdup(lin_key), val);
541 hard_value_xlat(lin_dict, key, mac_val);
548 parse_preset_array(GValue *mac_array, GValue *lin_array)
551 GValue *mac_dict, *lin_dict, *gval;
553 count = ghb_array_len(mac_array);
554 for (ii = 0; ii < count; ii++)
556 mac_dict = ghb_array_get_nth(mac_array, ii);
558 // Only process builtin types
559 if (ghb_value_int(ghb_dict_lookup(mac_dict, "Type")) != 0)
562 lin_dict = ghb_dict_value_new();
563 ghb_array_append(lin_array, lin_dict);
564 gval = ghb_dict_lookup(mac_dict, "PresetName");
567 ghb_dict_insert(lin_dict, g_strdup("PresetName"),
568 ghb_value_dup(gval));
570 gval = ghb_dict_lookup(mac_dict, "PresetDescription");
573 ghb_dict_insert(lin_dict, g_strdup("PresetDescription"),
574 ghb_value_dup(gval));
576 gval = ghb_dict_lookup(mac_dict, "Folder");
577 if (gval && ghb_value_boolean(gval))
581 mval = ghb_dict_lookup(mac_dict, "ChildrenArray");
582 lval = ghb_array_value_new(32);
583 ghb_dict_insert(lin_dict, g_strdup("ChildrenArray"), lval);
584 ghb_dict_insert(lin_dict, g_strdup("Folder"),
585 ghb_boolean_value_new(TRUE));
586 ghb_dict_insert(lin_dict, g_strdup("Type"),
587 ghb_int_value_new(0));
588 parse_preset_array(mval, lval);
592 ghb_dict_insert(lin_dict, g_strdup("Type"),
593 ghb_int_value_new(0));
594 parse_preset_dict(mac_dict, lin_dict);
600 xlat(GValue *mac, GValue *lin)
602 return parse_preset_array(mac, lin);
606 main(gint argc, gchar *argv[])
608 GValue *mac_plist, *lin_plist;
613 fprintf(stderr, "Usage: <mac plist> <lin plist>\n");
618 ghb_register_transforms();
619 internal = ghb_plist_parse_file("internal_defaults.xml");
620 defaults = ghb_dict_lookup(internal, "Presets");
621 mac_plist = ghb_plist_parse_file(argv[1]);
622 lin_plist = ghb_array_value_new(32);
623 xlat(mac_plist, lin_plist);
624 ghb_plist_write_file(argv[2], lin_plist);