diff --git a/gst/qtdemux/Makefile.am b/gst/qtdemux/Makefile.am index 4d32fc722d..74c683c55a 100644 --- a/gst/qtdemux/Makefile.am +++ b/gst/qtdemux/Makefile.am @@ -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 diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index 90b82a1462..81d0b88cf9 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -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 index 0000000000..9a46d9075e --- /dev/null +++ b/gst/qtdemux/qtdemux_lang.c @@ -0,0 +1,205 @@ +/* GStreamer Quicktime/ISO demuxer language utility functions + * Copyright (C) 2010 Tim-Philipp Müller + * + * 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 + +/* 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 index 0000000000..a5fdec0fdb --- /dev/null +++ b/gst/qtdemux/qtdemux_lang.h @@ -0,0 +1,31 @@ +/* GStreamer Quicktime/ISO demuxer language utility functions + * Copyright (C) 2010 Tim-Philipp Müller + * + * 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 + +void qtdemux_lang_map_qt_code_to_iso (gchar id[4], guint16 qt_lang_code); + +G_END_DECLS + +#endif /* __GST_QTDEMUX_LANG_H__ */