summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-05-21 12:51:43 +0100
committerCarl Hetherington <cth@carlh.net>2013-05-21 12:51:43 +0100
commitdc6713f19bb9084aac18eabe399b14ca1ac26df9 (patch)
tree8c6591d7dbc10c54c672869dd4ec8bb64aeb8c39 /src/lib
parent83742c7e6edcf958e0820abc77c029f4ada4880f (diff)
parent47e6b6725168213f2a7db24c2965cfa173f755b4 (diff)
Merge master.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/ab_transcoder.cc2
-rw-r--r--src/lib/film.cc9
-rw-r--r--src/lib/format.cc32
-rw-r--r--src/lib/po/es_ES.po62
-rw-r--r--src/lib/po/fr_FR.po133
-rw-r--r--src/lib/po/it_IT.po62
-rw-r--r--src/lib/po/sv_SE.po62
-rw-r--r--src/lib/sndfile_decoder.cc4
-rw-r--r--src/lib/stack.cpp463
-rw-r--r--src/lib/stack.hpp60
-rw-r--r--src/lib/util.cc26
-rw-r--r--src/lib/wscript8
12 files changed, 742 insertions, 181 deletions
diff --git a/src/lib/ab_transcoder.cc b/src/lib/ab_transcoder.cc
index d8f13dae4..c42f0d241 100644
--- a/src/lib/ab_transcoder.cc
+++ b/src/lib/ab_transcoder.cc
@@ -62,7 +62,7 @@ ABTranscoder::ABTranscoder (
_db = decoder_factory (_film_b, o);
shared_ptr<AudioStream> st = _film_a->audio_stream();
- if (st) {
+ if (st && st->sample_rate()) {
_matcher.reset (new Matcher (_film_a->log(), st->sample_rate(), _film_a->source_frame_rate()));
}
_delay_line.reset (new DelayLine (_film_a->log(), _film_a->audio_delay() / 1000.0f));
diff --git a/src/lib/film.cc b/src/lib/film.cc
index 0ca374604..81c7de77f 100644
--- a/src/lib/film.cc
+++ b/src/lib/film.cc
@@ -987,14 +987,7 @@ Film::set_content (string c)
}
/* Default format */
- switch (content_type()) {
- case STILL:
- set_format (Format::from_id ("var-185"));
- break;
- case VIDEO:
- set_format (Format::from_id ("185"));
- break;
- }
+ set_format (Config::instance()->default_format ());
/* Still image DCPs must use external audio */
if (content_type() == STILL) {
diff --git a/src/lib/format.cc b/src/lib/format.cc
index 8c3d0d8ad..78e200847 100644
--- a/src/lib/format.cc
+++ b/src/lib/format.cc
@@ -72,59 +72,63 @@ Format::setup_formats ()
{
/// TRANSLATORS: these are film picture aspect ratios; "Academy" means 1.37, "Flat" 1.85 and "Scope" 2.39.
_formats.push_back (
- new FixedFormat (1.19, libdcp::Size (1285, 1080), N_("119"), _("1.19"), N_("F")
+ new FixedFormat (1.19, libdcp::Size (1285, 1080), "119", _("1.19"), "F"
));
_formats.push_back (
- new FixedFormat (4.0 / 3.0, libdcp::Size (1436, 1080), N_("133"), _("4:3"), N_("F")
+ new FixedFormat (4.0 / 3.0, libdcp::Size (1436, 1080), "133", _("4:3"), "F"
));
_formats.push_back (
- new FixedFormat (1.38, libdcp::Size (1485, 1080), N_("138"), _("1.375"), N_("F")
+ new FixedFormat (1.38, libdcp::Size (1485, 1080), "138", _("1.375"), "F"
));
_formats.push_back (
- new FixedFormat (4.0 / 3.0, libdcp::Size (1998, 1080), N_("133-in-flat"), _("4:3 within Flat"), N_("F")
+ new FixedFormat (4.0 / 3.0, libdcp::Size (1998, 1080), "133-in-flat", _("4:3 within Flat"), "F"
));
_formats.push_back (
- new FixedFormat (1.37, libdcp::Size (1480, 1080), N_("137"), _("Academy"), N_("F")
+ new FixedFormat (1.37, libdcp::Size (1480, 1080), "137", _("Academy"), "F"
));
_formats.push_back (
- new FixedFormat (1.66, libdcp::Size (1793, 1080), N_("166"), _("1.66"), N_("F")
+ new FixedFormat (1.66, libdcp::Size (1793, 1080), "166", _("1.66"), "F"
));
_formats.push_back (
- new FixedFormat (1.66, libdcp::Size (1998, 1080), N_("166-in-flat"), _("1.66 within Flat"), N_("F")
+ new FixedFormat (1.66, libdcp::Size (1998, 1080), "166-in-flat", _("1.66 within Flat"), "F"
));
_formats.push_back (
- new FixedFormat (1.78, libdcp::Size (1998, 1080), N_("178-in-flat"), _("16:9 within Flat"), N_("F")
+ new FixedFormat (1.78, libdcp::Size (1998, 1080), "178-in-flat", _("16:9 within Flat"), "F"
));
_formats.push_back (
- new FixedFormat (1.78, libdcp::Size (1920, 1080), N_("178"), _("16:9"), N_("F")
+ new FixedFormat (1.78, libdcp::Size (1920, 1080), "178", _("16:9"), "F"
));
_formats.push_back (
- new FixedFormat (1.85, libdcp::Size (1998, 1080), N_("185"), _("Flat"), N_("F")
+ new FixedFormat (1.85, libdcp::Size (1998, 1080), "185", _("Flat"), "F"
));
_formats.push_back (
- new FixedFormat (1.78, libdcp::Size (2048, 858), N_("178-in-scope"), _("16:9 within Scope"), N_("S")
+ new FixedFormat (1.78, libdcp::Size (2048, 858), "178-in-scope", _("16:9 within Scope"), "S"
));
_formats.push_back (
- new FixedFormat (2.39, libdcp::Size (2048, 858), N_("239"), _("Scope"), N_("S")
+ new FixedFormat (2.39, libdcp::Size (2048, 858), "239", _("Scope"), "S"
+ ));
+
+ _formats.push_back (
+ new FixedFormat (1.896, libdcp::Size (2048, 1080), "full-frame", _("Full frame"), "C"
));
_formats.push_back (
- new VariableFormat (libdcp::Size (1998, 1080), N_("var-185"), _("Flat without stretch"), N_("F")
+ new VariableFormat (libdcp::Size (1998, 1080), "var-185", _("Flat without stretch"), "F"
));
_formats.push_back (
- new VariableFormat (libdcp::Size (2048, 858), N_("var-239"), _("Scope without stretch"), N_("S")
+ new VariableFormat (libdcp::Size (2048, 858), "var-239", _("Scope without stretch"), "S"
));
}
diff --git a/src/lib/po/es_ES.po b/src/lib/po/es_ES.po
index 1608f3b0c..944505007 100644
--- a/src/lib/po/es_ES.po
+++ b/src/lib/po/es_ES.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: LIBDVDOMATIC\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-04-22 15:06+0100\n"
+"POT-Creation-Date: 2013-05-09 09:51+0100\n"
"PO-Revision-Date: 2013-04-02 19:10-0500\n"
"Last-Translator: Manuel AC <manuel.acevedo@civantos.>\n"
"Language-Team: Manuel AC <manuel.acevedo@civantos.com>\n"
@@ -74,7 +74,7 @@ msgstr "Academy"
msgid "Advertisement"
msgstr "Publicidad"
-#: src/lib/job.cc:72
+#: src/lib/job.cc:73
msgid "An error occurred whilst handling the file %1."
msgstr "Ha ocurrido un error con el fichero %1."
@@ -94,7 +94,7 @@ msgstr "Bicúbico"
msgid "Bilinear"
msgstr "Bilineal"
-#: src/lib/job.cc:306
+#: src/lib/job.cc:318
msgid "Cancelled"
msgstr ""
@@ -107,7 +107,7 @@ msgid "Cannot resample audio as libswresample is not present"
msgstr ""
"No se puede redimensionar el sonido porque no se encuentra libswresample"
-#: src/lib/util.cc:932
+#: src/lib/util.cc:960
msgid "Centre"
msgstr ""
@@ -139,16 +139,16 @@ msgstr "No se pudo escribir el fichero remoto (%1)"
msgid "Cubic interpolating deinterlacer"
msgstr "Desentrelazado por interpolación cúbica"
-#: src/lib/util.cc:1007
+#: src/lib/util.cc:1035
msgid "DCP and source have the same rate.\n"
msgstr "La fuente y el DCP tienen la misma velocidad.\n"
-#: src/lib/util.cc:1017
+#: src/lib/util.cc:1045
#, fuzzy
msgid "DCP will run at %1%% of the source speed.\n"
msgstr "El DCP se reproducirá al %1%% de la velocidad de la fuente.\n"
-#: src/lib/util.cc:1010
+#: src/lib/util.cc:1038
msgid "DCP will use every other frame of the source.\n"
msgstr "El DCP usará fotogramas alternos de la fuente.\n"
@@ -171,11 +171,11 @@ msgstr "Deringing filter"
msgid "Dolby CP750"
msgstr "Dolby CP750"
-#: src/lib/util.cc:1012
+#: src/lib/util.cc:1040
msgid "Each source frame will be doubled in the DCP.\n"
msgstr "Se doblará cada fotograma de la fuente en el DCP.\n"
-#: src/lib/job.cc:304
+#: src/lib/job.cc:316
msgid "Error (%1)"
msgstr "Error (%1)"
@@ -247,7 +247,7 @@ msgstr "Horizontal deblocking filter"
msgid "Horizontal deblocking filter A"
msgstr "Horizontal deblocking filter A"
-#: src/lib/job.cc:96 src/lib/job.cc:105
+#: src/lib/job.cc:97 src/lib/job.cc:106
msgid ""
"It is not known what caused this error. The best idea is to report the "
"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
@@ -263,15 +263,15 @@ msgstr "Kernel deinterlacer"
msgid "Lanczos"
msgstr "Lanczos"
-#: src/lib/util.cc:930
+#: src/lib/util.cc:958
msgid "Left"
msgstr ""
-#: src/lib/util.cc:934
+#: src/lib/util.cc:962
msgid "Left surround"
msgstr ""
-#: src/lib/util.cc:933
+#: src/lib/util.cc:961
msgid "Lfe (sub)"
msgstr ""
@@ -301,7 +301,7 @@ msgstr "Motion compensating deinterlacer"
msgid "Noise reduction"
msgstr "Reducción de ruido"
-#: src/lib/job.cc:302
+#: src/lib/job.cc:314
msgid "OK (ran for %1)"
msgstr "OK (ejecución %1)"
@@ -321,15 +321,15 @@ msgstr "Anuncio de servicio público"
msgid "Rating"
msgstr "Clasificación"
-#: src/lib/util.cc:500
+#: src/lib/util.cc:513
msgid "Rec 709"
msgstr "Rec 709"
-#: src/lib/util.cc:931
+#: src/lib/util.cc:959
msgid "Right"
msgstr ""
-#: src/lib/util.cc:935
+#: src/lib/util.cc:963
msgid "Right surround"
msgstr ""
@@ -373,7 +373,7 @@ msgstr "Temporal noise reducer"
msgid "Test"
msgstr "Test"
-#: src/lib/job.cc:78
+#: src/lib/job.cc:79
msgid ""
"The drive that the film is stored on is low in disc space. Free some more "
"space and try again."
@@ -393,7 +393,7 @@ msgstr "Codificar %1"
msgid "Transitional"
msgstr "Transitional"
-#: src/lib/job.cc:104
+#: src/lib/job.cc:105
msgid "Unknown error"
msgstr "Error desconocido"
@@ -429,7 +429,7 @@ msgstr "Yet Another Deinterlacing Filter"
msgid "cannot contain slashes"
msgstr "no puede contener barras"
-#: src/lib/util.cc:541
+#: src/lib/util.cc:554
msgid "connect timed out"
msgstr "tiempo de conexión agotado"
@@ -470,7 +470,7 @@ msgstr "no se pudo encontrar decodificador de subtítutlos"
msgid "could not find video decoder"
msgstr "no se pudo encontrar decodificador de vídeo"
-#: src/lib/sndfile_decoder.cc:72
+#: src/lib/sndfile_decoder.cc:67
msgid "could not open external audio file for reading"
msgstr "no se pudo leer el fichero externo de audio"
@@ -505,11 +505,11 @@ msgstr "no se pudo abrir la sesión SSH"
msgid "could not write to file %1 (%2)"
msgstr "No se pudo escribir el fichero remoto (%1)"
-#: src/lib/sndfile_decoder.cc:94
+#: src/lib/sndfile_decoder.cc:89
msgid "external audio files have differing lengths"
msgstr "los ficheros externos de sonido tienen duraciones diferentes"
-#: src/lib/sndfile_decoder.cc:76
+#: src/lib/sndfile_decoder.cc:71
msgid "external audio files must be mono"
msgstr "los ficheros externos de sonido deben ser mono"
@@ -521,23 +521,23 @@ msgstr "formato"
msgid "frames per second"
msgstr "fotogramas por segundo"
-#: src/lib/util.cc:115
+#: src/lib/util.cc:128
msgid "hour"
msgstr "hora"
-#: src/lib/util.cc:112 src/lib/util.cc:117
+#: src/lib/util.cc:125 src/lib/util.cc:130
msgid "hours"
msgstr "horas"
-#: src/lib/util.cc:122
+#: src/lib/util.cc:135
msgid "minute"
msgstr "minuto"
-#: src/lib/util.cc:124
+#: src/lib/util.cc:137
msgid "minutes"
msgstr "minutos"
-#: src/lib/util.cc:684
+#: src/lib/util.cc:697
msgid "missing key %1 in key-value set"
msgstr "falta la clave %1 en el par clave-valor"
@@ -563,15 +563,15 @@ msgstr "todavía no se soportan subtítulos que no son en mapas de bits"
#. / TRANSLATORS: remaining here follows an amount of time that is remaining
#. / on an operation.
-#: src/lib/job.cc:299
+#: src/lib/job.cc:311
msgid "remaining"
msgstr "pendiente"
-#: src/lib/util.cc:498
+#: src/lib/util.cc:511
msgid "sRGB"
msgstr "sRGB"
-#: src/lib/util.cc:127
+#: src/lib/util.cc:140
msgid "seconds"
msgstr "segundos"
diff --git a/src/lib/po/fr_FR.po b/src/lib/po/fr_FR.po
index d1123d84b..a6a72598f 100644
--- a/src/lib/po/fr_FR.po
+++ b/src/lib/po/fr_FR.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: DVD-o-matic FRENCH\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-04-22 15:06+0100\n"
-"PO-Revision-Date: 2013-03-20 00:39+0100\n"
-"Last-Translator: FreeDCP.net <freedcp.net@gmail.com>\n"
+"POT-Creation-Date: 2013-05-09 09:51+0100\n"
+"PO-Revision-Date: 2013-05-10 14:33+0100\n"
+"Last-Translator: \n"
"Language-Team: \n"
"Language: \n"
"MIME-Version: 1.0\n"
@@ -55,7 +55,7 @@ msgstr "Débruitage 3D"
#: src/lib/format.cc:79
msgid "4:3"
-msgstr ""
+msgstr "4:3"
#: src/lib/format.cc:87
msgid "4:3 within Flat"
@@ -73,7 +73,7 @@ msgstr "Academy"
msgid "Advertisement"
msgstr "Advertisement"
-#: src/lib/job.cc:72
+#: src/lib/job.cc:73
msgid "An error occurred whilst handling the file %1."
msgstr "Une erreur s'est produite lors du traitement du fichier %1."
@@ -93,21 +93,21 @@ msgstr "Bicubique"
msgid "Bilinear"
msgstr "Bilinéaire"
-#: src/lib/job.cc:306
+#: src/lib/job.cc:318
msgid "Cancelled"
-msgstr ""
+msgstr "Annulé"
#: src/lib/exceptions.cc:60
msgid "Cannot handle pixel format %1 during %2"
-msgstr ""
+msgstr "Format du pixel %1 non géré par %2"
#: src/lib/encoder.cc:101
msgid "Cannot resample audio as libswresample is not present"
msgstr "Ré-échantillonnage du son impossible : libswresample est absent"
-#: src/lib/util.cc:932
+#: src/lib/util.cc:960
msgid "Centre"
-msgstr ""
+msgstr "Centre"
#: src/lib/scp_dcp_job.cc:109
msgid "Copy DCP to TMS"
@@ -137,27 +137,37 @@ msgstr "Écriture vers fichier distant (%1) impossible"
msgid "Cubic interpolating deinterlacer"
msgstr "Désentrelacement cubique interpolé"
-#: src/lib/util.cc:1007
+#: src/lib/util.cc:1035
msgid "DCP and source have the same rate.\n"
msgstr "Le DCP et la source ont les mêmes cadences.\n"
-#: src/lib/util.cc:1017
+#: src/lib/util.cc:1045
#, fuzzy
msgid "DCP will run at %1%% of the source speed.\n"
msgstr "La cadence du DCP sera %1%% par rapport à la source.\n"
-#: src/lib/util.cc:1010
+#: src/lib/util.cc:1038
msgid "DCP will use every other frame of the source.\n"
msgstr "Le DCP utilisera une image sur deux de la source.\n"
-#: src/lib/filter.cc:68 src/lib/filter.cc:69 src/lib/filter.cc:70
-#: src/lib/filter.cc:71 src/lib/filter.cc:72 src/lib/filter.cc:73
+#: src/lib/filter.cc:68
+#: src/lib/filter.cc:69
+#: src/lib/filter.cc:70
+#: src/lib/filter.cc:71
+#: src/lib/filter.cc:72
+#: src/lib/filter.cc:73
msgid "De-blocking"
msgstr "De-bloc"
-#: src/lib/filter.cc:75 src/lib/filter.cc:76 src/lib/filter.cc:77
-#: src/lib/filter.cc:78 src/lib/filter.cc:79 src/lib/filter.cc:80
-#: src/lib/filter.cc:81 src/lib/filter.cc:82 src/lib/filter.cc:83
+#: src/lib/filter.cc:75
+#: src/lib/filter.cc:76
+#: src/lib/filter.cc:77
+#: src/lib/filter.cc:78
+#: src/lib/filter.cc:79
+#: src/lib/filter.cc:80
+#: src/lib/filter.cc:81
+#: src/lib/filter.cc:82
+#: src/lib/filter.cc:83
msgid "De-interlacing"
msgstr "Désentrelacement"
@@ -169,11 +179,11 @@ msgstr "Filtre anti bourdonnement"
msgid "Dolby CP750"
msgstr "Dolby CP750"
-#: src/lib/util.cc:1012
+#: src/lib/util.cc:1040
msgid "Each source frame will be doubled in the DCP.\n"
msgstr "Chaque image source sera dupliquée dans le DCP.\n"
-#: src/lib/job.cc:304
+#: src/lib/job.cc:316
msgid "Error (%1)"
msgstr "Erreur (%1)"
@@ -245,13 +255,10 @@ msgstr "Filtre dé-bloc horizontal"
msgid "Horizontal deblocking filter A"
msgstr "Filtre dé-bloc horizontal"
-#: src/lib/job.cc:96 src/lib/job.cc:105
-msgid ""
-"It is not known what caused this error. The best idea is to report the "
-"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
-msgstr ""
-"Erreur indéterminée. Merci de rapporter le problème à la liste DVD-o-matic "
-"(dvdomatic@carlh.net)"
+#: src/lib/job.cc:97
+#: src/lib/job.cc:106
+msgid "It is not known what caused this error. The best idea is to report the problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
+msgstr "Erreur indéterminée. Merci de rapporter le problème à la liste DVD-o-matic (dvdomatic@carlh.net)"
#: src/lib/filter.cc:82
msgid "Kernel deinterlacer"
@@ -261,15 +268,15 @@ msgstr "Désentrelaceur noyau"
msgid "Lanczos"
msgstr "Lanczos"
-#: src/lib/util.cc:930
+#: src/lib/util.cc:958
msgid "Left"
msgstr "Gauche"
-#: src/lib/util.cc:934
+#: src/lib/util.cc:962
msgid "Left surround"
msgstr "Arrière gauche"
-#: src/lib/util.cc:933
+#: src/lib/util.cc:961
msgid "Lfe (sub)"
msgstr "Basses fréquences"
@@ -285,8 +292,11 @@ msgstr "Désentrelaceur linéaire interpolé"
msgid "Median deinterlacer"
msgstr "Désentrelaceur médian"
-#: src/lib/filter.cc:74 src/lib/filter.cc:85 src/lib/filter.cc:86
-#: src/lib/filter.cc:87 src/lib/filter.cc:90
+#: src/lib/filter.cc:74
+#: src/lib/filter.cc:85
+#: src/lib/filter.cc:86
+#: src/lib/filter.cc:87
+#: src/lib/filter.cc:90
msgid "Misc"
msgstr "Divers"
@@ -294,12 +304,14 @@ msgstr "Divers"
msgid "Motion compensating deinterlacer"
msgstr "Désentrelaceur par compensation de mouvement"
-#: src/lib/filter.cc:84 src/lib/filter.cc:88 src/lib/filter.cc:89
+#: src/lib/filter.cc:84
+#: src/lib/filter.cc:88
+#: src/lib/filter.cc:89
#: src/lib/filter.cc:91
msgid "Noise reduction"
msgstr "Réduction de bruit"
-#: src/lib/job.cc:302
+#: src/lib/job.cc:314
msgid "OK (ran for %1)"
msgstr "OK (processus %1)"
@@ -319,15 +331,15 @@ msgstr "Public Service Announcement"
msgid "Rating"
msgstr "Classification"
-#: src/lib/util.cc:500
+#: src/lib/util.cc:513
msgid "Rec 709"
msgstr "Rec 709"
-#: src/lib/util.cc:931
+#: src/lib/util.cc:959
msgid "Right"
msgstr "Droite"
-#: src/lib/util.cc:935
+#: src/lib/util.cc:963
msgid "Right surround"
msgstr "Arrière droite"
@@ -371,13 +383,9 @@ msgstr "Réduction de bruit temporel"
msgid "Test"
msgstr "Test"
-#: src/lib/job.cc:78
-msgid ""
-"The drive that the film is stored on is low in disc space. Free some more "
-"space and try again."
-msgstr ""
-"Le disque contenant le film est plein. Libérez de l'espace et essayez à "
-"nouveau."
+#: src/lib/job.cc:79
+msgid "The drive that the film is stored on is low in disc space. Free some more space and try again."
+msgstr "Le disque contenant le film est plein. Libérez de l'espace et essayez à nouveau."
#: src/lib/dcp_content_type.cc:46
msgid "Trailer"
@@ -391,7 +399,7 @@ msgstr "Transcodage %1"
msgid "Transitional"
msgstr "Transitional"
-#: src/lib/job.cc:104
+#: src/lib/job.cc:105
msgid "Unknown error"
msgstr "Erreur inconnue"
@@ -427,7 +435,7 @@ msgstr "Un autre filtre de désentrelacement"
msgid "cannot contain slashes"
msgstr "slash interdit"
-#: src/lib/util.cc:541
+#: src/lib/util.cc:554
msgid "connect timed out"
msgstr "temps de connexion expiré"
@@ -467,7 +475,7 @@ msgstr "décodeur de sous-titre introuvable"
msgid "could not find video decoder"
msgstr "décodeur vidéo introuvable"
-#: src/lib/sndfile_decoder.cc:72
+#: src/lib/sndfile_decoder.cc:67
msgid "could not open external audio file for reading"
msgstr "lecture du fichier audio externe impossible"
@@ -481,9 +489,10 @@ msgstr "lecture du fichier impossible"
#: src/lib/exceptions.cc:44
msgid "could not read from file %1 (%2)"
-msgstr "Création du dossier distant %1 impossible (%2)"
+msgstr "création du dossier distant %1 impossible (%2)"
-#: src/lib/encoder.cc:137 src/lib/encoder.cc:314
+#: src/lib/encoder.cc:137
+#: src/lib/encoder.cc:314
msgid "could not run sample-rate converter"
msgstr "conversion de la fréquence d'échantillonnage impossible"
@@ -499,11 +508,11 @@ msgstr "démarrage de session SSH impossible"
msgid "could not write to file %1 (%2)"
msgstr "Écriture vers fichier distant (%1) impossible (%2)"
-#: src/lib/sndfile_decoder.cc:94
+#: src/lib/sndfile_decoder.cc:89
msgid "external audio files have differing lengths"
msgstr "Les fichiers audio externes ont des durées différentes"
-#: src/lib/sndfile_decoder.cc:76
+#: src/lib/sndfile_decoder.cc:71
msgid "external audio files must be mono"
msgstr "les fichiers audio externes doivent être en mono"
@@ -515,35 +524,37 @@ msgstr "format"
msgid "frames per second"
msgstr "images par seconde"
-#: src/lib/util.cc:115
+#: src/lib/util.cc:128
msgid "hour"
msgstr "heure"
-#: src/lib/util.cc:112 src/lib/util.cc:117
+#: src/lib/util.cc:125
+#: src/lib/util.cc:130
msgid "hours"
msgstr "heures"
-#: src/lib/util.cc:122
+#: src/lib/util.cc:135
msgid "minute"
msgstr "minute"
-#: src/lib/util.cc:124
+#: src/lib/util.cc:137
msgid "minutes"
msgstr "minutes"
-#: src/lib/util.cc:684
+#: src/lib/util.cc:697
msgid "missing key %1 in key-value set"
msgstr "clé %1 non sélectionnée"
#: src/lib/exceptions.cc:54
msgid "missing required setting %1"
-msgstr ""
+msgstr "paramètre %1 manquant"
#: src/lib/subtitle.cc:52
msgid "multi-part subtitles not yet supported"
msgstr "sous-titres en plusieurs parties non supportés"
-#: src/lib/film.cc:296 src/lib/film.cc:341
+#: src/lib/film.cc:296
+#: src/lib/film.cc:341
msgid "name"
msgstr "nom"
@@ -557,15 +568,15 @@ msgstr "sous-titres non-bitmap non supportés actuellement"
#. / TRANSLATORS: remaining here follows an amount of time that is remaining
#. / on an operation.
-#: src/lib/job.cc:299
+#: src/lib/job.cc:311
msgid "remaining"
msgstr "restant"
-#: src/lib/util.cc:498
+#: src/lib/util.cc:511
msgid "sRGB"
msgstr "sRGB"
-#: src/lib/util.cc:127
+#: src/lib/util.cc:140
msgid "seconds"
msgstr "secondes"
diff --git a/src/lib/po/it_IT.po b/src/lib/po/it_IT.po
index a3d35dec9..6a7486d82 100644
--- a/src/lib/po/it_IT.po
+++ b/src/lib/po/it_IT.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: IT VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-04-22 15:06+0100\n"
+"POT-Creation-Date: 2013-05-09 09:51+0100\n"
"PO-Revision-Date: 2013-04-28 10:26+0100\n"
"Last-Translator: Maci <macibro@gmail.com>\n"
"Language-Team: \n"
@@ -73,7 +73,7 @@ msgstr "Academy"
msgid "Advertisement"
msgstr "Pubblicità"
-#: src/lib/job.cc:72
+#: src/lib/job.cc:73
msgid "An error occurred whilst handling the file %1."
msgstr "Errore durante l'elaborazione del file %1."
@@ -93,7 +93,7 @@ msgstr "Bicubica"
msgid "Bilinear"
msgstr "Bilineare"
-#: src/lib/job.cc:306
+#: src/lib/job.cc:318
msgid "Cancelled"
msgstr "Cancellato"
@@ -105,7 +105,7 @@ msgstr "Non posso gestire il formato di pixel %1 durante %2"
msgid "Cannot resample audio as libswresample is not present"
msgstr "Non posso ricampionare l'audio perchè libswresample non è presente"
-#: src/lib/util.cc:932
+#: src/lib/util.cc:960
msgid "Centre"
msgstr "Centro"
@@ -137,15 +137,15 @@ msgstr "Non posso scrivere il file remoto (%1)"
msgid "Cubic interpolating deinterlacer"
msgstr "Deinterlacciatore cubico interpolato"
-#: src/lib/util.cc:1007
+#: src/lib/util.cc:1035
msgid "DCP and source have the same rate.\n"
msgstr "Il DCP e il sorgente hanno la stessa frequenza.\n"
-#: src/lib/util.cc:1017
+#: src/lib/util.cc:1045
msgid "DCP will run at %1%% of the source speed.\n"
msgstr "Il DCP andrà al %1%% della velocità del sorgente.\n"
-#: src/lib/util.cc:1010
+#: src/lib/util.cc:1038
msgid "DCP will use every other frame of the source.\n"
msgstr "Il DCP userà ogni altro fotogramma del sorgente.\n"
@@ -168,11 +168,11 @@ msgstr "Filtro deringing"
msgid "Dolby CP750"
msgstr "Dolby CP750"
-#: src/lib/util.cc:1012
+#: src/lib/util.cc:1040
msgid "Each source frame will be doubled in the DCP.\n"
msgstr "Ogni fotogramma del sorgente sarà raddoppiato nel DCP.\n"
-#: src/lib/job.cc:304
+#: src/lib/job.cc:316
msgid "Error (%1)"
msgstr "Errore (%1)"
@@ -244,7 +244,7 @@ msgstr "Filtro sblocco orizzontale"
msgid "Horizontal deblocking filter A"
msgstr "Filtro A sblocco orizzontale"
-#: src/lib/job.cc:96 src/lib/job.cc:105
+#: src/lib/job.cc:97 src/lib/job.cc:106
msgid ""
"It is not known what caused this error. The best idea is to report the "
"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
@@ -260,15 +260,15 @@ msgstr "Deinterlacciatore Kernel"
msgid "Lanczos"
msgstr "Lanczos"
-#: src/lib/util.cc:930
+#: src/lib/util.cc:958
msgid "Left"
msgstr "Sinistro"
-#: src/lib/util.cc:934
+#: src/lib/util.cc:962
msgid "Left surround"
msgstr "Surround sinistro"
-#: src/lib/util.cc:933
+#: src/lib/util.cc:961
msgid "Lfe (sub)"
msgstr "Lfe(sub)"
@@ -298,7 +298,7 @@ msgstr "Dinterlacciatore compensativo di movimento"
msgid "Noise reduction"
msgstr "Riduzione del rumore"
-#: src/lib/job.cc:302
+#: src/lib/job.cc:314
msgid "OK (ran for %1)"
msgstr "OK (eseguito in %1)"
@@ -318,15 +318,15 @@ msgstr "Annuncio di pubblico servizio"
msgid "Rating"
msgstr "Punteggio"
-#: src/lib/util.cc:500
+#: src/lib/util.cc:513
msgid "Rec 709"
msgstr "Rec 709"
-#: src/lib/util.cc:931
+#: src/lib/util.cc:959
msgid "Right"
msgstr "Destro"
-#: src/lib/util.cc:935
+#: src/lib/util.cc:963
msgid "Right surround"
msgstr "Surround destro"
@@ -370,7 +370,7 @@ msgstr "Riduttore temporale di rumore"
msgid "Test"
msgstr "Prova"
-#: src/lib/job.cc:78
+#: src/lib/job.cc:79
msgid ""
"The drive that the film is stored on is low in disc space. Free some more "
"space and try again."
@@ -390,7 +390,7 @@ msgstr "Transcodifica %1"
msgid "Transitional"
msgstr "Di transizione"
-#: src/lib/job.cc:104
+#: src/lib/job.cc:105
msgid "Unknown error"
msgstr "Errore sconosciuto"
@@ -426,7 +426,7 @@ msgstr "Altro filtro di deinterlacciamento"
msgid "cannot contain slashes"
msgstr "non può contenere barre"
-#: src/lib/util.cc:541
+#: src/lib/util.cc:554
msgid "connect timed out"
msgstr "connessione scaduta"
@@ -466,7 +466,7 @@ msgstr "non riesco a trovare il decoder dei sottotitoli"
msgid "could not find video decoder"
msgstr "non riesco a trovare il decoder video"
-#: src/lib/sndfile_decoder.cc:72
+#: src/lib/sndfile_decoder.cc:67
msgid "could not open external audio file for reading"
msgstr "non riesco ad aprire il file dell'audio esterno per leggerlo"
@@ -498,11 +498,11 @@ msgstr "non posso avviare la sessione SSH"
msgid "could not write to file %1 (%2)"
msgstr "non posso scrivere il file (%1)"
-#: src/lib/sndfile_decoder.cc:94
+#: src/lib/sndfile_decoder.cc:89
msgid "external audio files have differing lengths"
msgstr "i files dell'audio esterno hanno durata diversa"
-#: src/lib/sndfile_decoder.cc:76
+#: src/lib/sndfile_decoder.cc:71
msgid "external audio files must be mono"
msgstr "i files dell'audio esterno devono essere mono"
@@ -514,23 +514,23 @@ msgstr "formato"
msgid "frames per second"
msgstr "fotogrammi al secondo"
-#: src/lib/util.cc:115
+#: src/lib/util.cc:128
msgid "hour"
msgstr "ora"
-#: src/lib/util.cc:112 src/lib/util.cc:117
+#: src/lib/util.cc:125 src/lib/util.cc:130
msgid "hours"
msgstr "ore"
-#: src/lib/util.cc:122
+#: src/lib/util.cc:135
msgid "minute"
msgstr "minuto"
-#: src/lib/util.cc:124
+#: src/lib/util.cc:137
msgid "minutes"
msgstr "minuti"
-#: src/lib/util.cc:684
+#: src/lib/util.cc:697
msgid "missing key %1 in key-value set"
msgstr "persa la chiave %1 tra i valori chiave"
@@ -556,15 +556,15 @@ msgstr "sottotitoli non-bitmap non ancora supportati"
#. / TRANSLATORS: remaining here follows an amount of time that is remaining
#. / on an operation.
-#: src/lib/job.cc:299
+#: src/lib/job.cc:311
msgid "remaining"
msgstr "restano"
-#: src/lib/util.cc:498
+#: src/lib/util.cc:511
msgid "sRGB"
msgstr "sRGB"
-#: src/lib/util.cc:127
+#: src/lib/util.cc:140
msgid "seconds"
msgstr "secondi"
diff --git a/src/lib/po/sv_SE.po b/src/lib/po/sv_SE.po
index 11aeff987..58d336ef8 100644
--- a/src/lib/po/sv_SE.po
+++ b/src/lib/po/sv_SE.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: DVD-o-matic\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2013-04-22 15:06+0100\n"
+"POT-Creation-Date: 2013-05-09 09:51+0100\n"
"PO-Revision-Date: 2013-04-10 15:35+0100\n"
"Last-Translator: Adam Klotblixt <adam.klotblixt@gmail.com>\n"
"Language-Team: \n"
@@ -73,7 +73,7 @@ msgstr "Academy"
msgid "Advertisement"
msgstr "Reklam"
-#: src/lib/job.cc:72
+#: src/lib/job.cc:73
msgid "An error occurred whilst handling the file %1."
msgstr "Ett fel inträffade vid hantering av filen %1"
@@ -93,7 +93,7 @@ msgstr "Bikubisk"
msgid "Bilinear"
msgstr "Bilinjär"
-#: src/lib/job.cc:306
+#: src/lib/job.cc:318
msgid "Cancelled"
msgstr "Avbruten"
@@ -106,7 +106,7 @@ msgid "Cannot resample audio as libswresample is not present"
msgstr ""
"Kan inte omsampla ljudet eftersom libswresample inte finns tillgängligt"
-#: src/lib/util.cc:932
+#: src/lib/util.cc:960
msgid "Centre"
msgstr "Mitt"
@@ -138,15 +138,15 @@ msgstr "Kunde inte skriva till fjärrfil (%1)"
msgid "Cubic interpolating deinterlacer"
msgstr "Kubiskt interpolerande avflätare"
-#: src/lib/util.cc:1007
+#: src/lib/util.cc:1035
msgid "DCP and source have the same rate.\n"
msgstr "DCP och källa har samma bildfrekvens.\n"
-#: src/lib/util.cc:1017
+#: src/lib/util.cc:1045
msgid "DCP will run at %1%% of the source speed.\n"
msgstr "DCP kommer att köras på %1%% av källans hastighet.\n"
-#: src/lib/util.cc:1010
+#: src/lib/util.cc:1038
msgid "DCP will use every other frame of the source.\n"
msgstr "DCP kommer att använda varannan bild från källan.\n"
@@ -169,11 +169,11 @@ msgstr "Avringningsfilter"
msgid "Dolby CP750"
msgstr "Dolby CP750"
-#: src/lib/util.cc:1012
+#: src/lib/util.cc:1040
msgid "Each source frame will be doubled in the DCP.\n"
msgstr "Varje bild från källan kommer att användas två gånger i DCPn.\n"
-#: src/lib/job.cc:304
+#: src/lib/job.cc:316
msgid "Error (%1)"
msgstr "Fel (%1)"
@@ -245,7 +245,7 @@ msgstr "Filter för horisontal kantighetsutjämning"
msgid "Horizontal deblocking filter A"
msgstr "Filter för horisontal kantighetsutjämning A"
-#: src/lib/job.cc:96 src/lib/job.cc:105
+#: src/lib/job.cc:97 src/lib/job.cc:106
msgid ""
"It is not known what caused this error. The best idea is to report the "
"problem to the DVD-o-matic mailing list (dvdomatic@carlh.net)"
@@ -261,15 +261,15 @@ msgstr "Kernel-avflätare"
msgid "Lanczos"
msgstr "Lanczos"
-#: src/lib/util.cc:930
+#: src/lib/util.cc:958
msgid "Left"
msgstr "Vänster"
-#: src/lib/util.cc:934
+#: src/lib/util.cc:962
msgid "Left surround"
msgstr "Vänster surround"
-#: src/lib/util.cc:933
+#: src/lib/util.cc:961
msgid "Lfe (sub)"
msgstr "Lfe (sub)"
@@ -299,7 +299,7 @@ msgstr "Rörelsekompenserande avflätare"
msgid "Noise reduction"
msgstr "Brusreducering"
-#: src/lib/job.cc:302
+#: src/lib/job.cc:314
msgid "OK (ran for %1)"
msgstr "OK (kördes %1)"
@@ -319,15 +319,15 @@ msgstr "Offentligt Servicemeddelande"
msgid "Rating"
msgstr "Klassificeringsklipp"
-#: src/lib/util.cc:500
+#: src/lib/util.cc:513
msgid "Rec 709"
msgstr "Rec 709"
-#: src/lib/util.cc:931
+#: src/lib/util.cc:959
msgid "Right"
msgstr "Höger"
-#: src/lib/util.cc:935
+#: src/lib/util.cc:963
msgid "Right surround"
msgstr "Höger surround"
@@ -371,7 +371,7 @@ msgstr "Temporal brusreducering"
msgid "Test"
msgstr "Test"
-#: src/lib/job.cc:78
+#: src/lib/job.cc:79
msgid ""
"The drive that the film is stored on is low in disc space. Free some more "
"space and try again."
@@ -391,7 +391,7 @@ msgstr "Konvertera %1"
msgid "Transitional"
msgstr "Övergångsklipp"
-#: src/lib/job.cc:104
+#: src/lib/job.cc:105
msgid "Unknown error"
msgstr "Okänt fel"
@@ -431,7 +431,7 @@ msgid "cannot contain slashes"
msgstr "får inte innehålla snedstreck"
# Svengelska
-#: src/lib/util.cc:541
+#: src/lib/util.cc:554
#, fuzzy
msgid "connect timed out"
msgstr "uppkopplingen tajmade ur"
@@ -472,7 +472,7 @@ msgstr "kunde inte hitta undertext-avkodare"
msgid "could not find video decoder"
msgstr "kunde inte hitta video-avkodare"
-#: src/lib/sndfile_decoder.cc:72
+#: src/lib/sndfile_decoder.cc:67
msgid "could not open external audio file for reading"
msgstr "kunde inte öppna extern audio-fil för läsning"
@@ -504,11 +504,11 @@ msgstr "kunde inte starta SSH-session"
msgid "could not write to file %1 (%2)"
msgstr "kunde inte skriva till fil %1 (%2)"
-#: src/lib/sndfile_decoder.cc:94
+#: src/lib/sndfile_decoder.cc:89
msgid "external audio files have differing lengths"
msgstr "externa audio-filer har olika längder"
-#: src/lib/sndfile_decoder.cc:76
+#: src/lib/sndfile_decoder.cc:71
msgid "external audio files must be mono"
msgstr "externa audio-filer måste vara mono"
@@ -520,23 +520,23 @@ msgstr "format"
msgid "frames per second"
msgstr "bilder per sekund"
-#: src/lib/util.cc:115
+#: src/lib/util.cc:128
msgid "hour"
msgstr "timme"
-#: src/lib/util.cc:112 src/lib/util.cc:117
+#: src/lib/util.cc:125 src/lib/util.cc:130
msgid "hours"
msgstr "timmar"
-#: src/lib/util.cc:122
+#: src/lib/util.cc:135
msgid "minute"
msgstr "minut"
-#: src/lib/util.cc:124
+#: src/lib/util.cc:137
msgid "minutes"
msgstr "minuter"
-#: src/lib/util.cc:684
+#: src/lib/util.cc:697
msgid "missing key %1 in key-value set"
msgstr "saknad nyckel %1 i nyckel-värde grupp"
@@ -562,15 +562,15 @@ msgstr "icke-rastergrafiska undertexter stöds inte ännu"
#. / TRANSLATORS: remaining here follows an amount of time that is remaining
#. / on an operation.
-#: src/lib/job.cc:299
+#: src/lib/job.cc:311
msgid "remaining"
msgstr "återstående tid"
-#: src/lib/util.cc:498
+#: src/lib/util.cc:511
msgid "sRGB"
msgstr "sRGB"
-#: src/lib/util.cc:127
+#: src/lib/util.cc:140
msgid "seconds"
msgstr "sekunder"
diff --git a/src/lib/sndfile_decoder.cc b/src/lib/sndfile_decoder.cc
index fdaf2eeaa..7e9e67d0f 100644
--- a/src/lib/sndfile_decoder.cc
+++ b/src/lib/sndfile_decoder.cc
@@ -96,6 +96,10 @@ SndfileDecoder::SndfileDecoder (shared_ptr<Film> f, DecodeOptions o)
bool
SndfileDecoder::pass ()
{
+ if (_audio_streams.empty ()) {
+ return true;
+ }
+
/* Do things in half second blocks as I think there may be limits
to what FFmpeg (and in particular the resampler) can cope with.
*/
diff --git a/src/lib/stack.cpp b/src/lib/stack.cpp
new file mode 100644
index 000000000..20a5c5be7
--- /dev/null
+++ b/src/lib/stack.cpp
@@ -0,0 +1,463 @@
+/** -*- c-basic-offset: 4; default-tab-width: 4; indent-tabs-mode: nil; -*- */
+
+// Copyright 2007 Edd Dawson.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#include <cassert>
+#include <cstring>
+#include <cstdlib>
+#include <iomanip>
+#include <ostream>
+#include <stdexcept>
+#include <sstream>
+
+#include "stack.hpp"
+
+#if defined(_WIN32)
+# include <windows.h>
+# include <imagehlp.h>
+
+# if defined(__MINGW32__)
+# define PACKAGE 1
+# define PACKAGE_VERSION 1
+# include <bfd.h> // link against libbfd and libiberty
+# include <psapi.h> // link against psapi
+# include <cxxabi.h>
+# endif
+
+#elif defined(__GNUC__)
+# include <dlfcn.h>
+# include <cxxabi.h>
+#endif
+
+namespace
+{
+ const char * const unknown_function = "[unknown function]";
+ const char * const unknown_module = "[unknown module]";
+
+#if defined(__GNUC__)
+ std::string demangle(const char *name)
+ {
+ if (!name)
+ return unknown_function;
+
+ int status = 0;
+ char *d = 0;
+ std::string ret = name;
+ try
+ {
+ if ((d = abi::__cxa_demangle(name, 0, 0, &status)))
+ ret = d;
+ }
+ catch (const std::bad_alloc &) { }
+
+ std::free(d);
+ return ret;
+ }
+#endif
+
+#if defined(_WIN32)
+
+ // Derive from this to disallow copying of your class.
+ // c.f. boost::noncopyable
+ class uncopyable
+ {
+ protected:
+ uncopyable() { }
+
+ private:
+ uncopyable(const uncopyable &);
+ uncopyable &operator= (const uncopyable &);
+ };
+
+#if defined(__MINGW32__)
+
+ // Provides a means to translate a program counter offset in to the name of the corresponding function.
+ class bfd_context : uncopyable
+ {
+ private:
+ struct find_data
+ {
+ std::string func;
+ unsigned int line;
+ asymbol **symbol_table;
+ bfd_vma counter;
+ };
+
+ public:
+ bfd_context() :
+ abfd_(0),
+ sec_(0),
+ symbol_table_(0)
+ {
+ char procname[MAX_PATH];
+ GetModuleFileNameA(NULL, procname, sizeof procname);
+
+ bfd_init();
+ abfd_ = bfd_openr(procname, 0);
+ if (!abfd_)
+ throw std::runtime_error("Failed to parse object data for the executable");
+
+ char **formats = 0;
+ bool b1 = bfd_check_format(abfd_, bfd_object);
+ bool b2 = bfd_check_format_matches(abfd_, bfd_object, &formats);
+ bool b3 = bfd_get_file_flags(abfd_) & HAS_SYMS;
+
+ if (!(b1 && b2 && b3))
+ {
+ bfd_close(abfd_);
+ free(formats);
+ throw std::runtime_error("Failed to parse object data for the executable");
+ }
+ free(formats);
+
+ // Load symbol table
+ unsigned dummy = 0;
+ if (bfd_read_minisymbols(abfd_, FALSE, reinterpret_cast<void **>(&symbol_table_), &dummy) == 0 &&
+ bfd_read_minisymbols(abfd_, TRUE, reinterpret_cast<void **>(&symbol_table_), &dummy) < 0)
+ {
+ free(symbol_table_);
+ bfd_close(abfd_);
+ throw std::runtime_error("Failed to parse object data for the executable");
+ }
+ }
+
+ ~bfd_context()
+ {
+ free(symbol_table_);
+ bfd_close(abfd_);
+ }
+
+ std::pair<std::string, unsigned int> get_function_name_and_line(DWORD offset)
+ {
+ find_data data;
+ data.symbol_table = symbol_table_;
+ data.counter = offset;
+
+ bfd_map_over_sections(abfd_, &find_function_name_in_section, &data);
+
+ return std::make_pair(data.func, data.line);
+ }
+
+ private:
+ static void find_function_name_in_section(bfd *abfd, asection *sec, void *opaque_data)
+ {
+ assert(sec);
+ assert(opaque_data);
+ find_data &data = *static_cast<find_data *>(opaque_data);
+
+ if (!data.func.empty()) return; // already found it
+
+ if (!(bfd_get_section_flags(abfd, sec) & SEC_ALLOC)) return;
+
+ bfd_vma vma = bfd_get_section_vma(abfd, sec);
+ if (data.counter < vma || vma + bfd_get_section_size(sec) <= data.counter) return;
+
+ const char *func = 0;
+ const char *file = 0;
+ unsigned line = 0;
+
+ if (bfd_find_nearest_line(abfd, sec, data.symbol_table, data.counter - vma, &file, &func, &line) && func) {
+ data.func = demangle(func);
+ data.line = line;
+ }
+ }
+
+ private:
+ bfd *abfd_;
+ asection *sec_;
+ asymbol **symbol_table_;
+ };
+
+#endif // __MINGW32__
+
+ // g++ spouts warnings if you use {0} to initialize PODs. So we use this instead:
+ const struct
+ {
+ template<typename POD>
+ operator POD () const { POD p; std::memset(&p, 0, sizeof p); return p; }
+ }
+ empty_pod = { };
+
+ // Wraps a FARPROC. Implicitly convertible to any kind of pointer-to-function.
+ // Avoids having reinterpret casts all over the place.
+ struct auto_cast_function_ptr
+ {
+ auto_cast_function_ptr(FARPROC f) : fptr_(f) { }
+
+ template<typename FuncPtr>
+ operator FuncPtr() const { return reinterpret_cast<FuncPtr>(fptr_); }
+
+ FARPROC fptr_;
+ };
+
+ // A wrapper around a DLL. Can dynamically get function pointers with the function() function!
+ class windows_dll : uncopyable
+ {
+ public:
+ explicit windows_dll(const std::string &libname) :
+ name_(libname),
+ lib_(LoadLibraryA(name_.c_str()))
+ {
+ if (!lib_) throw std::runtime_error("Failed to load dll " + name_);
+ }
+
+ ~windows_dll() { FreeLibrary(lib_); }
+
+ const std::string &name() const { return name_; }
+
+ auto_cast_function_ptr function(const char *func_name) const
+ {
+ FARPROC proc = GetProcAddress(lib_, func_name);
+ if (!proc) throw std::runtime_error(std::string("failed to load function ") + func_name + " from library " + name_);
+
+ return proc;
+ }
+
+ private:
+ std::string name_;
+ HMODULE lib_;
+ };
+
+ // An object that makes sure debugging symbols are available
+ class symbol_context : uncopyable
+ {
+ public:
+ symbol_context()
+ {
+ if (!SymInitialize(GetCurrentProcess(), 0, TRUE))
+ throw std::runtime_error("Failed to initialize symbol context");
+ }
+ ~symbol_context() { SymCleanup(GetCurrentProcess()); }
+ };
+
+ // A simple Windows mutex class. Use a lock object to lock the mutex for the duration of a scope.
+ class mutex : uncopyable
+ {
+ public:
+ mutex() { InitializeCriticalSection(&cs_); }
+ ~mutex() { DeleteCriticalSection(&cs_); }
+
+ private:
+ friend class lock;
+ void lock() { EnterCriticalSection(&cs_); }
+ void unlock() { LeaveCriticalSection(&cs_); }
+
+ CRITICAL_SECTION cs_;
+ }
+ g_fill_frames_mtx;
+
+ // A lock for the mutex
+ class lock : uncopyable
+ {
+ public:
+ lock(mutex &m) : m_(m) { m.lock(); }
+ ~lock() { m_.unlock(); }
+ private:
+ mutex &m_;
+ };
+
+
+ void fill_frames(std::list<dbg::stack_frame> &frames, dbg::stack::depth_type limit)
+ {
+ lock lk(g_fill_frames_mtx);
+
+ symbol_context sc;
+#ifdef __MINGW32__
+ bfd_context bfdc;
+#endif
+
+ STACKFRAME frame = empty_pod;
+ CONTEXT context = empty_pod;
+ context.ContextFlags = CONTEXT_FULL;
+
+ windows_dll kernel32("kernel32.dll");
+ void (WINAPI *RtlCaptureContext_)(CONTEXT*) = kernel32.function("RtlCaptureContext");
+
+ RtlCaptureContext_(&context);
+
+#if defined(_M_AMD64)
+ frame.AddrPC.Offset = context.Rip;
+ frame.AddrPC.Mode = AddrModeFlat;
+ frame.AddrStack.Offset = context.Rsp;
+ frame.AddrStack.Mode = AddrModeFlat;
+ frame.AddrFrame.Offset = context.Rbp;
+ frame.AddrFrame.Mode = AddrModeFlat;
+#else
+ frame.AddrPC.Offset = context.Eip;
+ frame.AddrPC.Mode = AddrModeFlat;
+ frame.AddrStack.Offset = context.Esp;
+ frame.AddrStack.Mode = AddrModeFlat;
+ frame.AddrFrame.Offset = context.Ebp;
+ frame.AddrFrame.Mode = AddrModeFlat;
+#endif
+
+ HANDLE process = GetCurrentProcess();
+ HANDLE thread = GetCurrentThread();
+
+ bool skip = true;
+ bool has_limit = limit != 0;
+ char symbol_buffer[sizeof(IMAGEHLP_SYMBOL) + 255];
+ char module_name_raw[MAX_PATH];
+
+#if defined(_M_AMD64)
+ const DWORD machine = IMAGE_FILE_MACHINE_AMD64;
+#else
+ const DWORD machine = IMAGE_FILE_MACHINE_I386;
+#endif
+
+ while(StackWalk(machine, process, thread, &frame, &context, 0, SymFunctionTableAccess, SymGetModuleBase, 0))
+ {
+ if (skip)
+ {
+ skip = false;
+ continue;
+ }
+
+ if (has_limit && limit-- == 0) break;
+
+ IMAGEHLP_SYMBOL *symbol = reinterpret_cast<IMAGEHLP_SYMBOL *>(symbol_buffer);
+ symbol->SizeOfStruct = (sizeof *symbol) + 255;
+ symbol->MaxNameLength = 254;
+
+#if defined(_WIN64)
+ DWORD64 module_base = SymGetModuleBase(process, frame.AddrPC.Offset);
+#else
+ DWORD module_base = SymGetModuleBase(process, frame.AddrPC.Offset);
+#endif
+ std::string module_name = unknown_module;
+ if (module_base && GetModuleFileNameA(reinterpret_cast<HINSTANCE>(module_base), module_name_raw, MAX_PATH))
+ module_name = module_name_raw;
+
+#if defined(__MINGW32__)
+ std::pair<std::string, unsigned int> func_and_line = bfdc.get_function_name_and_line(frame.AddrPC.Offset);
+
+ if (func_and_line.first.empty())
+ {
+#if defined(_WIN64)
+ DWORD64 dummy = 0;
+#else
+ DWORD dummy = 0;
+#endif
+ BOOL got_symbol = SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol);
+ func_and_line.first = got_symbol ? symbol->Name : unknown_function;
+ }
+#else
+ DWORD dummy = 0;
+ BOOL got_symbol = SymGetSymFromAddr(process, frame.AddrPC.Offset, &dummy, symbol);
+ std::string func = got_symbol ? symbol->Name : unknown_function;
+#endif
+
+ dbg::stack_frame f(reinterpret_cast<const void *>(frame.AddrPC.Offset), func_and_line.first, func_and_line.second, module_name);
+ frames.push_back(f);
+ }
+ }
+#elif defined(__GNUC__)
+# if defined(__i386__) || defined(__amd64__)
+
+ void fill_frames(std::list<dbg::stack_frame> &frames, dbg::stack::depth_type limit)
+ {
+ // Based on code found at:
+ // http://www.tlug.org.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV
+
+ Dl_info info;
+ void **frame = static_cast<void **>(__builtin_frame_address(0));
+ void **bp = static_cast<void **>(*frame);
+ void *ip = frame[1];
+
+ bool has_limit = limit != 0;
+ bool skip = true;
+
+ while(bp && ip && dladdr(ip, &info))
+ {
+ if (skip)
+ skip = false;
+ else
+ {
+ if (has_limit && limit-- == 0) break;
+ frames.push_back(dbg::stack_frame(ip, demangle(info.dli_sname), info.dli_fname));
+
+ if(info.dli_sname && !std::strcmp(info.dli_sname, "main")) break;
+ }
+
+ ip = bp[1];
+ bp = static_cast<void**>(bp[0]);
+ }
+ }
+
+# elif defined(__ppc__)
+
+ void fill_frames(std::list<dbg::stack_frame> &frames, dbg::stack::depth_type limit)
+ {
+ // Based on code found at:
+ // http://www.informit.com/articles/article.aspx?p=606582&seqNum=4&rl=1
+
+ void *ip = __builtin_return_address(0);
+ void **frame = static_cast<void **>(__builtin_frame_address(1));
+ bool has_limit = limit != 0;
+ Dl_info info;
+
+ do
+ {
+ if (has_limit && limit-- == 0) break;
+
+ if (dladdr(ip, &info))
+ frames.push_back(dbg::stack_frame(ip, demangle(info.dli_sname), info.dli_fname));
+
+ if (frame && (frame = static_cast<void**>(*frame))) ip = *(frame + 2);
+ }
+ while (frame && ip);
+ }
+
+# else
+ // GNU, but not x86, x64 nor PPC
+# error "Sorry but dbg::stack is not supported on this architecture"
+# endif
+#else
+ // Unsupported compiler
+# error "Sorry but dbg::stack is not supported on this compiler"
+#endif
+
+} // close anonymous namespace
+
+
+
+namespace dbg
+{
+ stack_frame::stack_frame(const void *instruction, const std::string &function, unsigned int line, const std::string &module) :
+ instruction(instruction),
+ function(function),
+ line(line),
+ module(module)
+ {
+ }
+
+ std::ostream &operator<< (std::ostream &out, const stack_frame &frame)
+ {
+ return out << frame.instruction << ": " << frame.function << ":" << frame.line << " in " << frame.module;
+ }
+
+ stack::stack(depth_type limit)
+ {
+ fill_frames(frames_, limit);
+ }
+
+ stack::const_iterator stack::begin() const
+ {
+ return frames_.begin();
+ }
+
+ stack::const_iterator stack::end() const
+ {
+ return frames_.end();
+ }
+
+ stack::depth_type stack::depth() const
+ {
+ return frames_.size();
+ }
+
+} // close namespace dbg
+
diff --git a/src/lib/stack.hpp b/src/lib/stack.hpp
new file mode 100644
index 000000000..2b622d020
--- /dev/null
+++ b/src/lib/stack.hpp
@@ -0,0 +1,60 @@
+/** -*- c-basic-offset: 4; default-tab-width: 4; indent-tabs-mode: nil; -*- */
+
+// Copyright 2007 Edd Dawson.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef STACK_HPP_0022_01092007
+#define STACK_HPP_0022_01092007
+
+#include <string>
+#include <list>
+#include <iosfwd>
+
+namespace dbg
+{
+ //! stack_frame objects are collected by a stack object. They contain information about the instruction pointer,
+ //! the name of the corresponding function and the "module" (executable or library) in which the function resides.
+ struct stack_frame
+ {
+ stack_frame(const void *instruction, const std::string &function, unsigned int line, const std::string &module);
+
+ const void *instruction;
+ std::string function;
+ unsigned int line;
+ std::string module;
+ };
+
+ //! Allows you to write a stack_frame object to an std::ostream
+ std::ostream &operator<< (std::ostream &out, const stack_frame &frame);
+
+ //! Instantiate a dbg::stack object to collect information about the current call stack. Once created, a stack object
+ //! may be freely copied about and will continue to contain the information about the scope in which collection occurred.
+ class stack
+ {
+ public:
+ typedef std::list<stack_frame>::size_type depth_type;
+ typedef std::list<stack_frame>::const_iterator const_iterator;
+
+ //! Collect information about the current call stack. Information on the most recent frames will be collected
+ //! up to the specified limit. 0 means unlimited.
+ //! An std::runtime_error may be thrown on failure.
+ stack(depth_type limit = 0);
+
+ //! Returns an iterator referring to the "top" stack frame
+ const_iterator begin() const;
+
+ //! Returns an iterator referring to one past the "bottom" stack frame
+ const_iterator end() const;
+
+ //! Returns the number of frames collected
+ depth_type depth() const;
+
+ private:
+ std::list<stack_frame> frames_;
+ };
+
+} // close namespace dbg
+
+#endif // STACK_HPP_0022_01092007
diff --git a/src/lib/util.cc b/src/lib/util.cc
index be078a95f..2f8be6edd 100644
--- a/src/lib/util.cc
+++ b/src/lib/util.cc
@@ -39,6 +39,7 @@
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
#include <boost/filesystem.hpp>
+#include <glib.h>
#include <openjpeg.h>
#include <openssl/md5.h>
#include <magick/MagickCore.h>
@@ -60,6 +61,9 @@ extern "C" {
#include "filter.h"
#include "sound_processor.h"
#include "config.h"
+#ifdef DVDOMATIC_WINDOWS
+#include "stack.hpp"
+#endif
#include "i18n.h"
@@ -75,12 +79,14 @@ using std::min;
using std::max;
using std::multimap;
using std::pair;
+using std::ofstream;
using boost::shared_ptr;
using boost::lexical_cast;
using boost::optional;
using libdcp::Size;
boost::thread::id ui_thread;
+boost::filesystem::path backtrace_file;
/** Convert some number of seconds to a string representation
* in hours, minutes and seconds.
@@ -242,12 +248,28 @@ seconds (struct timeval t)
return t.tv_sec + (double (t.tv_usec) / 1e6);
}
+#ifdef DVDOMATIC_WINDOWS
+LONG WINAPI exception_handler(struct _EXCEPTION_POINTERS *)
+{
+ dbg::stack s;
+ ofstream f (backtrace_file.string().c_str());
+ std::copy(s.begin(), s.end(), std::ostream_iterator<dbg::stack_frame>(f, "\n"));
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
/** Call the required functions to set up DVD-o-matic's static arrays, etc.
* Must be called from the UI thread, if there is one.
*/
void
dvdomatic_setup ()
{
+#ifdef DVDOMATIC_WINDOWS
+ backtrace_file /= g_get_user_config_dir ();
+ backtrace_file /= "backtrace.txt";
+ SetUnhandledExceptionFilter(exception_handler);
+#endif
+
avfilter_register_all ();
Format::setup_formats ();
@@ -1054,8 +1076,8 @@ LocaleGuard::LocaleGuard ()
if (old) {
_old = strdup (old);
- if (strcmp (_old, "POSIX")) {
- setlocale (LC_NUMERIC, "POSIX");
+ if (strcmp (_old, "C")) {
+ setlocale (LC_NUMERIC, "C");
}
}
}
diff --git a/src/lib/wscript b/src/lib/wscript
index 51b103afd..253a496d1 100644
--- a/src/lib/wscript
+++ b/src/lib/wscript
@@ -66,9 +66,13 @@ def build(bld):
BOOST_FILESYSTEM BOOST_THREAD BOOST_DATETIME BOOST_SIGNALS2
SNDFILE OPENJPEG POSTPROC TIFF MAGICK SSH DCP GLIB LZMA
"""
+
+ obj.source = sources + ' version.cc'
+
if bld.env.TARGET_WINDOWS:
- obj.uselib += ' WINSOCK2'
- obj.source = sources + " version.cc"
+ obj.uselib += ' WINSOCK2 BFD DBGHELP IBERTY'
+ obj.source += ' stack.cpp'
+
obj.target = 'dvdomatic'
i18n.po_to_mo(os.path.join('src', 'lib'), 'libdvdomatic', bld)