qtdemux: extract stream language in more cases
authorTim-Philipp Müller <tim.muller@collabora.co.uk>
Fri, 26 Mar 2010 16:50:22 +0000 (16:50 +0000)
committerTim-Philipp Müller <tim.muller@collabora.co.uk>
Fri, 26 Mar 2010 17:02:50 +0000 (17:02 +0000)
The 16-bit language code can be either a packed ISO-639-2T code
or a 'Macintosh language code'. Handle the latter type of language
codes as well, and map to the matching ISO code. Lastly, fix
language code posting for language #0, which is valid and stands
for 'English'.

Fixes #614001.

gst/qtdemux/Makefile.am
gst/qtdemux/qtdemux.c
gst/qtdemux/qtdemux_lang.c [new file with mode: 0644]
gst/qtdemux/qtdemux_lang.h [new file with mode: 0644]

index 4d32fc7..74c683c 100644 (file)
@@ -10,7 +10,8 @@ libgstqtdemux_la_LIBADD = \
     -lgsttag-@GST_MAJORMINOR@ \
     $(GST_BASE_LIBS) $(GST_LIBS) $(ZLIB_LIBS)
 libgstqtdemux_la_LDFLAGS = ${GST_PLUGIN_LDFLAGS} 
-libgstqtdemux_la_SOURCES = quicktime.c gstrtpxqtdepay.c qtdemux.c qtdemux_types.c qtdemux_dump.c
+libgstqtdemux_la_SOURCES = quicktime.c gstrtpxqtdepay.c \
+       qtdemux.c qtdemux_types.c qtdemux_dump.c qtdemux_lang.c
 libgstqtdemux_la_LIBTOOLFLAGS = --tag=disable-static
 
 noinst_HEADERS = \
@@ -19,5 +20,6 @@ noinst_HEADERS = \
        qtdemux_types.h  \
        qtdemux_dump.h   \
        qtdemux_fourcc.h \
+       qtdemux_lang.h   \
        qtpalette.h      \
        gstrtpxqtdepay.h
index 90b82a1..81d0b88 100644 (file)
@@ -55,6 +55,7 @@
 #include "qtdemux_types.h"
 #include "qtdemux_dump.h"
 #include "qtdemux_fourcc.h"
+#include "qtdemux_lang.h"
 #include "qtdemux.h"
 #include "qtpalette.h"
 
@@ -200,8 +201,7 @@ struct _QtDemuxStream
   guint32 timescale;
 
   /* language */
-  guint lang_code;
-  gchar lang_id[4];             /* in ISO 639-2 */
+  gchar lang_id[4];             /* ISO 639-2T language code */
 
   /* our samples */
   guint32 n_samples;
@@ -5037,6 +5037,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
   GstTagList *list = NULL;
   gchar *codec = NULL;
   const guint8 *stsd_data;
+  guint16 lang_code;            /* quicktime lang code or packed iso code */
   guint32 version;
   guint32 tkhd_flags = 0;
   guint8 tkhd_version = 0;
@@ -5080,26 +5081,30 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
       goto corrupt_file;
     stream->timescale = QT_UINT32 ((guint8 *) mdhd->data + 28);
     stream->duration = QT_UINT64 ((guint8 *) mdhd->data + 32);
-    stream->lang_code = QT_UINT16 ((guint8 *) mdhd->data + 36);
+    lang_code = QT_UINT16 ((guint8 *) mdhd->data + 36);
   } else {
     if (len < 30)
       goto corrupt_file;
     stream->timescale = QT_UINT32 ((guint8 *) mdhd->data + 20);
     stream->duration = QT_UINT32 ((guint8 *) mdhd->data + 24);
-    stream->lang_code = QT_UINT16 ((guint8 *) mdhd->data + 28);
+    lang_code = QT_UINT16 ((guint8 *) mdhd->data + 28);
   }
 
-  stream->lang_id[0] = 0x60 + ((stream->lang_code >> 10) & 0x1F);
-  stream->lang_id[1] = 0x60 + ((stream->lang_code >> 5) & 0x1F);
-  stream->lang_id[2] = 0x60 + (stream->lang_code & 0x1F);
-  stream->lang_id[3] = 0;
+  if (lang_code < 0x800) {
+    qtdemux_lang_map_qt_code_to_iso (stream->lang_id, lang_code);
+  } else {
+    stream->lang_id[0] = 0x60 + ((lang_code >> 10) & 0x1F);
+    stream->lang_id[1] = 0x60 + ((lang_code >> 5) & 0x1F);
+    stream->lang_id[2] = 0x60 + (lang_code & 0x1F);
+    stream->lang_id[3] = 0;
+  }
 
   GST_LOG_OBJECT (qtdemux, "track timescale: %" G_GUINT32_FORMAT,
       stream->timescale);
   GST_LOG_OBJECT (qtdemux, "track duration: %" G_GUINT64_FORMAT,
       stream->duration);
-  GST_LOG_OBJECT (qtdemux, "track language code/id: 0x%x/%s",
-      stream->lang_code, stream->lang_id);
+  GST_LOG_OBJECT (qtdemux, "track language code/id: 0x%04x/%s",
+      lang_code, stream->lang_id);
 
   if (G_UNLIKELY (stream->timescale == 0 || qtdemux->timescale == 0))
     goto corrupt_file;
@@ -5950,7 +5955,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
     goto segments_failed;
 
   /* add some language tag, if useful */
-  if (stream->lang_code && strcmp (stream->lang_id, "unk") &&
+  if (stream->lang_id[0] != '\0' && strcmp (stream->lang_id, "unk") &&
       strcmp (stream->lang_id, "und")) {
     const gchar *lang_code;
 
diff --git a/gst/qtdemux/qtdemux_lang.c b/gst/qtdemux/qtdemux_lang.c
new file mode 100644 (file)
index 0000000..9a46d90
--- /dev/null
@@ -0,0 +1,205 @@
+/* GStreamer Quicktime/ISO demuxer language utility functions
+ * Copyright (C) 2010 Tim-Philipp Müller <tim centricular net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "qtdemux.h"
+#include "qtdemux_lang.h"
+
+#include <string.h>
+
+/* http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap4/qtff4.html */
+
+static const gchar qt_lang_map[][4] = {
+
+/* 000 English
+ * 001 French
+ * 002 German
+ * 003 Italian
+ * 004 Dutch
+ * 005 Swedish
+ * 006 Spanish
+ * 007 Danish
+ * 008 Portuguese
+ * 009 Norwegian
+ */
+  "eng", "fre", "deu", "ita", "nld", "swe", "spa", "dan", "por", "nor",
+
+/* 010 Hebrew
+ * 011 Japanese
+ * 012 Arabic
+ * 013 Finnish
+ * 014 Greek
+ * 015 Icelandic
+ * 016 Maltese
+ * 017 Turkish
+ * 018 Croatian
+ * 019 Traditional Chinese (ISO 639-2 can't express script differences, so zho)
+ */
+  "heb", "jpn", "ara", "fin", "ell", "isl", "mlt", "tur", "hrv", "zho",
+
+/* 020 Urdu
+ * 021 Hindi
+ * 022 Thai
+ * 023 Korean
+ * 024 Lithuanian
+ * 025 Polish
+ * 026 Hungarian
+ * 027 Estonian
+ * 028 Latvian / Lettish
+ * 029 Lappish / Saamish (used code for Nothern Sami)
+ */
+  "urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav", "sme",
+
+/* 030 Faeroese
+ * 031 Farsi
+ * 032 Russian
+ * 033 Simplified Chinese (ISO 639-2 can't express script differences, so zho)
+ * 034 Flemish (no ISO 639-2 code, used Dutch code)
+ * 035 Irish
+ * 036 Albanian
+ * 037 Romanian
+ * 038 Czech
+ * 039 Slovak
+ */
+  "fao", "fas", "rus", "zho", "nld", "gle", "sqi", "ron", "ces", "slk",
+
+/* 040 Slovenian
+ * 041 Yiddish
+ * 042 Serbian
+ * 043 Macedonian
+ * 044 Bulgarian
+ * 045 Ukrainian
+ * 046 Byelorussian
+ * 047 Uzbek
+ * 048 Kazakh
+ * 049 Azerbaijani
+ */
+  "slv", "yid", "srp", "mkd", "bul", "ukr", "bel", "uzb", "kaz", "aze",
+
+/* 050 AzerbaijanAr (presumably script difference? used aze here)
+ * 051 Armenian
+ * 052 Georgian
+ * 053 Moldavian
+ * 054 Kirghiz
+ * 055 Tajiki
+ * 056 Turkmen
+ * 057 Mongolian
+ * 058 MongolianCyr (presumably script difference? used mon here)
+ * 059 Pashto
+ */
+
+  "aze", "hye", "kat", "mol", "kir", "tgk", "tuk", "mon", "mon", "pus",
+
+
+/* 060 Kurdish
+ * 061 Kashmiri
+ * 062 Sindhi
+ * 063 Tibetan
+ * 064 Nepali
+ * 065 Sanskrit
+ * 066 Marathi
+ * 067 Bengali
+ * 068 Assamese
+ * 069 Gujarati
+ */
+  "kur", "kas", "snd", "bod", "nep", "san", "mar", "ben", "asm", "guj",
+
+/* 070 Punjabi
+ * 071 Oriya
+ * 072 Malayalam
+ * 073 Kannada
+ * 074 Tamil
+ * 075 Telugu
+ * 076 Sinhalese
+ * 077 Burmese
+ * 078 Khmer
+ * 079 Lao
+ */
+  "pan", "ori", "mal", "kan", "tam", "tel", "sin", "mya", "khm", "lao",
+
+/* 080 Vietnamese
+ * 081 Indonesian
+ * 082 Tagalog
+ * 083 MalayRoman
+ * 084 MalayArabic
+ * 085 Amharic
+ * 087 Galla (same as Oromo?)
+ * 087 Oromo
+ * 088 Somali
+ * 089 Swahili
+ */
+  "vie", "ind", "tgl", "msa", "msa", "amh", "orm", "orm", "som", "swa",
+
+/* 090 Ruanda
+ * 091 Rundi
+ * 092 Chewa
+ * 093 Malagasy
+ * 094 Esperanto
+ * 095 ---
+ * 096 ---
+ * 097 ---
+ * 098 ---
+ * 099 ---
+ */
+  "kin", "run", "nya", "mlg", "ep", "und", "und", "und", "und", "und",
+
+/* 100-109 ---
+ * 110-119 ---
+ */
+  "und", "und", "und", "und", "und", "und", "und", "und", "und", "und",
+  "und", "und", "und", "und", "und", "und", "und", "und", "und", "und",
+
+/* 120-127 ---
+ * 128 Welsh
+ * 129 Basque
+ */
+  "und", "und", "und", "und", "und", "und", "und", "und", "cym", "eus",
+
+/* 130 Catalan
+ * 131 Latin
+ * 132 Quechua
+ * 133 Guarani
+ * 134 Aymara
+ * 135 Tatar
+ * 136 Uighur
+ * 137 Dzongkha
+ * 138 JavaneseRom
+ */
+  "cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav"
+};
+
+/* map quicktime language code to ISO-639-2T id, returns "und" if unknown */
+void
+qtdemux_lang_map_qt_code_to_iso (gchar id[4], guint16 qt_lang_code)
+{
+  const gchar *iso_code;
+
+  g_assert (qt_lang_code < 0x800);
+
+  if (qt_lang_code < G_N_ELEMENTS (qt_lang_map))
+    iso_code = qt_lang_map[qt_lang_code];
+  else
+    iso_code = "und";
+
+  GST_DEBUG ("mapped quicktime language code %u to ISO 639-2T code '%s'",
+      qt_lang_code, iso_code);
+
+  memcpy (id, iso_code, 4);
+
+  g_assert (id[3] == '\0');
+}
diff --git a/gst/qtdemux/qtdemux_lang.h b/gst/qtdemux/qtdemux_lang.h
new file mode 100644 (file)
index 0000000..a5fdec0
--- /dev/null
@@ -0,0 +1,31 @@
+/* GStreamer Quicktime/ISO demuxer language utility functions
+ * Copyright (C) 2010 Tim-Philipp Müller <tim centricular net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_QTDEMUX_LANG_H__
+#define __GST_QTDEMUX_LANG_H__
+
+G_BEGIN_DECLS
+
+#include <glib.h>
+
+void qtdemux_lang_map_qt_code_to_iso (gchar id[4], guint16 qt_lang_code);
+
+G_END_DECLS
+
+#endif /* __GST_QTDEMUX_LANG_H__ */