diff options
30 files changed, 6 insertions, 4048 deletions
diff --git a/contrib/ffmpeg/module.defs b/contrib/ffmpeg/module.defs index a86671db3..9956083f4 100644 --- a/contrib/ffmpeg/module.defs +++ b/contrib/ffmpeg/module.defs @@ -47,7 +47,6 @@ FFMPEG.CONFIGURE.extra += \ --enable-encoder=libfdk_aac endif -ifeq (1,$(FEATURE.avformat)) FFMPEG.CONFIGURE.extra += \ --enable-muxer=matroska \ --enable-muxer=webm \ @@ -55,7 +54,6 @@ FFMPEG.CONFIGURE.extra += \ --enable-muxer=mp4 \ --enable-muxer=psp \ --enable-muxer=ipod -endif ## check against tuple: B-SYSTEM where B is { 0 | 1 } for cross-compiling flag ifeq (0-cygwin,$(BUILD.cross)-$(BUILD.system)) diff --git a/contrib/libmkv/A00-private-data-offset.patch b/contrib/libmkv/A00-private-data-offset.patch deleted file mode 100644 index beddda548..000000000 --- a/contrib/libmkv/A00-private-data-offset.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/src/matroska.c b/src/matroska.c -index 45d5b1e..faa29d2 100644 ---- a/src/matroska.c -+++ b/src/matroska.c -@@ -174,6 +174,7 @@ int mk_writeHeader(mk_Writer *w, const char *writingApp) - w->seek_data.tracks = w->root->d_cur - w->segment_ptr; - - if (w->tracks) { -+ offset = 0; - CHECK(mk_closeContext(w->tracks, &offset)); - for (i = 0; i < w->num_tracks; i++) { - tk = w->tracks_arr[i]; diff --git a/contrib/libmkv/A01-hbmv-pgs.patch b/contrib/libmkv/A01-hbmv-pgs.patch deleted file mode 100644 index 9f863cac4..000000000 --- a/contrib/libmkv/A01-hbmv-pgs.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/include/libmkv.h b/include/libmkv.h -index 146a91f..f03d608 100644 ---- a/include/libmkv.h -+++ b/include/libmkv.h -@@ -94,6 +94,7 @@ extern "C" { - #define MK_SUBTITLE_USF "S_TEXT/USF" - #define MK_SUBTITLE_VOBSUB "S_VOBSUB" - #define MK_SUBTITLE_BMP "S_IMAGE/BMP" -+#define MK_SUBTITLE_PGS "S_HDMV/PGS" - - /* Official Tags */ - #define MK_TAG_TITLE "TITLE" diff --git a/contrib/libmkv/A02-audio-out-sampling-freq.patch b/contrib/libmkv/A02-audio-out-sampling-freq.patch deleted file mode 100644 index ea31957c1..000000000 --- a/contrib/libmkv/A02-audio-out-sampling-freq.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff --git a/include/libmkv.h b/include/libmkv.h -index 146a91f..f03d608 100644 ---- a/include/libmkv.h -+++ b/include/libmkv.h -@@ -203,6 +204,7 @@ struct mk_TrackConfig_s { - } video; - struct { - float samplingFreq; /* Sampling Frequency in Hz */ -+ float outputSamplingFreq; /* Playback Sampling Frequency in Hz (e.g. for AAC w/SBR) */ - unsigned channels; /* Number of channels for this track */ - unsigned bitDepth; /* Bits per sample (PCM) */ - } audio; -diff --git a/src/tracks.c b/src/tracks.c -index f9c7e48..a2a60ca 100644 ---- a/src/tracks.c -+++ b/src/tracks.c -@@ -174,6 +174,11 @@ mk_Track *mk_createTrack(mk_Writer *w, mk_TrackConfig *tc) - /* SamplingFrequency */ - if (mk_writeFloat(v, MATROSKA_ID_AUDIOSAMPLINGFREQ, tc->extra.audio.samplingFreq) < 0) - return NULL; -+ if (tc->extra.audio.outputSamplingFreq) { -+ /* Output SamplingFrequency */ -+ if (mk_writeFloat(v, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, tc->extra.audio.outputSamplingFreq) < 0) -+ return NULL; -+ } - /* Channels */ - if (mk_writeUInt(v, MATROSKA_ID_AUDIOCHANNELS, tc->extra.audio.channels) < 0) - return NULL; diff --git a/contrib/libmkv/P00-mingw-large-file.patch b/contrib/libmkv/P00-mingw-large-file.patch deleted file mode 100644 index 6a83eacca..000000000 --- a/contrib/libmkv/P00-mingw-large-file.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- libmkv.orig/src/matroska.c 2009-01-12 23:14:26.000000000 -0800 -+++ libmkv/src/matroska.c 2009-03-25 15:22:30.000000000 -0700 -@@ -27,6 +27,11 @@ - - #include <sys/time.h> - -+#if defined( __MINGW32__ ) -+#undef fseeko -+#define fseeko fseeko64 -+#endif -+ - #define RESERVED_SEEKHEAD 0x100 - /* 256 bytes should be enough room for our Seek entries. */ - #define RESERVED_CHAPTERS 0x800 -@@ -34,7 +39,7 @@ - - int mk_seekFile(mk_Writer *w, uint64_t pos) - { -- if (fseek(w->fp, pos, SEEK_SET)) -+ if (fseeko(w->fp, pos, SEEK_SET)) - return -1; - - w->f_pos = pos; - diff --git a/contrib/libmkv/module.defs b/contrib/libmkv/module.defs deleted file mode 100644 index 083895e19..000000000 --- a/contrib/libmkv/module.defs +++ /dev/null @@ -1,14 +0,0 @@ -$(eval $(call import.MODULE.defs,LIBMKV,libmkv)) -$(eval $(call import.CONTRIB.defs,LIBMKV)) - -LIBMKV.FETCH.url = http://download.handbrake.fr/handbrake/contrib/libmkv-0.6.5-0-g82075ae.tar.gz - -LIBMKV.CONFIGURE.bootstrap = rm -fr aclocal.m4 autom4te.cache; mkdir m4; autoreconf -fiv; - -ifeq (mingw,$(BUILD.system)) - LIBMKV.GCC.D += random=rand srandom=srand -endif - -## optional static libs need to be marked -LIBMKV.OSL.libs = mkv -LIBMKV.OSL.files = $(foreach i,$(LIBMKV.OSL.libs),$(call fn.ABSOLUTE,$(CONTRIB.build/)lib/lib$(i).a)) diff --git a/contrib/libmkv/module.rules b/contrib/libmkv/module.rules deleted file mode 100644 index 7f443fe04..000000000 --- a/contrib/libmkv/module.rules +++ /dev/null @@ -1,2 +0,0 @@ -$(eval $(call import.MODULE.rules,LIBMKV)) -$(eval $(call import.CONTRIB.rules,LIBMKV)) diff --git a/contrib/mp4v2/A00-nero-vobsub.patch b/contrib/mp4v2/A00-nero-vobsub.patch deleted file mode 100644 index beb8be6d8..000000000 --- a/contrib/mp4v2/A00-nero-vobsub.patch +++ /dev/null @@ -1,142 +0,0 @@ -diff -Naur mp4v2-trunk-r355/include/mp4v2/general.h mp4v2-trunk-r355/include/mp4v2/general.h ---- mp4v2-trunk-r355/include/mp4v2/general.h 2009-05-23 06:09:58.000000000 -0700 -+++ mp4v2-trunk-r355/include/mp4v2/general.h 2010-05-23 14:22:21.949288657 -0700 -@@ -75,6 +75,7 @@ - #define MP4_CNTL_TRACK_TYPE "cntl" /**< Constant: control track. */ - #define MP4_TEXT_TRACK_TYPE "text" /**< Constant: text track. */ - #define MP4_SUBTITLE_TRACK_TYPE "sbtl" /**< Constant: subtitle track. */ -+#define MP4_SUBPIC_TRACK_TYPE "subp" /**< Constant: subtitle track. */ - /* - * This second set of track types should be created - * via MP4AddSystemsTrack(type) -diff -Naur mp4v2-trunk-r355/include/mp4v2/track.h mp4v2-trunk-r355/include/mp4v2/track.h ---- mp4v2-trunk-r355/include/mp4v2/track.h 2009-05-23 06:21:49.000000000 -0700 -+++ mp4v2-trunk-r355/include/mp4v2/track.h 2010-05-23 15:43:47.249286008 -0700 -@@ -310,6 +310,13 @@ - uint16_t height ); - - MP4V2_EXPORT -+MP4TrackId MP4AddSubpicTrack( -+ MP4FileHandle hFile, -+ uint32_t timescale, -+ uint16_t width, -+ uint16_t height ); -+ -+MP4V2_EXPORT - MP4TrackId MP4AddPixelAspectRatio( - MP4FileHandle hFile, - MP4TrackId refTrackId, -diff -Naur mp4v2-trunk-r355/src/descriptors.h mp4v2-trunk-r355/src/descriptors.h ---- mp4v2-trunk-r355/src/descriptors.h 2009-05-20 19:52:32.000000000 -0700 -+++ mp4v2-trunk-r355/src/descriptors.h 2010-05-23 16:29:34.800935677 -0700 -@@ -119,6 +119,7 @@ - // ES objectTypeId - const uint8_t MP4SystemsV1ObjectType = 0x01; - const uint8_t MP4SystemsV2ObjectType = 0x02; -+const uint8_t MP4SubpicObjectType = 0xe0; - - // ES streamType - const uint8_t MP4ObjectDescriptionStreamType = 0x01; -@@ -131,6 +132,7 @@ - const uint8_t MP4OCIStreamType = 0x08; - const uint8_t MP4MPEGJStreamType = 0x09; - const uint8_t MP4UserPrivateStreamType = 0x20; -+const uint8_t MP4NeroSubpicStreamType = 0x38; - - /////////////////////////////////////////////////////////////////////////////// - -diff -Naur mp4v2-trunk-r355/src/mp4.cpp mp4v2-trunk-r355/src/mp4.cpp ---- mp4v2-trunk-r355/src/mp4.cpp 2009-05-23 06:29:37.000000000 -0700 -+++ mp4v2-trunk-r355/src/mp4.cpp 2010-05-23 15:45:28.852222074 -0700 -@@ -1174,6 +1174,23 @@ - return MP4_INVALID_TRACK_ID; - } - -+ MP4TrackId MP4AddSubpicTrack(MP4FileHandle hFile, -+ uint32_t timescale, -+ uint16_t width, -+ uint16_t height) -+ { -+ if (MP4_IS_VALID_FILE_HANDLE(hFile)) { -+ try { -+ return ((MP4File*)hFile)->AddSubpicTrack(timescale, width, height); -+ } -+ catch (MP4Error* e) { -+ PRINT_ERROR(e); -+ delete e; -+ } -+ } -+ return MP4_INVALID_TRACK_ID; -+ } -+ - MP4TrackId MP4AddChapterTextTrack( - MP4FileHandle hFile, MP4TrackId refTrackId, uint32_t timescale) - { -diff -Naur mp4v2-trunk-r355/src/mp4file.cpp mp4v2-trunk-r355/src/mp4file.cpp ---- mp4v2-trunk-r355/src/mp4file.cpp 2009-05-26 19:34:56.000000000 -0700 -+++ mp4v2-trunk-r355/src/mp4file.cpp 2010-05-23 16:32:52.654220633 -0700 -@@ -2095,6 +2095,50 @@ - return trackId; - } - -+MP4TrackId MP4File::AddSubpicTrack(uint32_t timescale, -+ uint16_t width, -+ uint16_t height) -+{ -+ MP4TrackId trackId = -+ AddTrack(MP4_SUBPIC_TRACK_TYPE, timescale); -+ -+ InsertChildAtom(MakeTrackName(trackId, "mdia.minf"), "nmhd", 0); -+ -+ (void)AddChildAtom(MakeTrackName(trackId, "mdia.minf.stbl.stsd"), "mp4s"); -+ -+ SetTrackFloatProperty(trackId, "tkhd.width", width); -+ SetTrackFloatProperty(trackId, "tkhd.height", height); -+ SetTrackIntegerProperty(trackId, "tkhd.layer", 0); -+ -+ // stsd is a unique beast in that it has a count of the number -+ // of child atoms that needs to be incremented after we add the mp4s atom -+ MP4Integer32Property* pStsdCountProperty; -+ FindIntegerProperty( -+ MakeTrackName(trackId, "mdia.minf.stbl.stsd.entryCount"), -+ (MP4Property**)&pStsdCountProperty); -+ pStsdCountProperty->IncrementValue(); -+ -+ SetTrackIntegerProperty(trackId, -+ "mdia.minf.stbl.stsd.mp4s.esds.ESID", -+#if 0 -+ // note - for a file, these values need to -+ // be 0 - wmay - 04/16/2003 -+ trackId -+#else -+ 0 -+#endif -+ ); -+ -+ SetTrackIntegerProperty(trackId, -+ "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr.objectTypeId", -+ MP4SubpicObjectType); -+ -+ SetTrackIntegerProperty(trackId, -+ "mdia.minf.stbl.stsd.mp4s.esds.decConfigDescr.streamType", -+ MP4NeroSubpicStreamType); -+ return trackId; -+} -+ - MP4TrackId MP4File::AddChapterTextTrack(MP4TrackId refTrackId, uint32_t timescale) - { - // validate reference track id -diff -Naur mp4v2-trunk-r355/src/mp4file.h mp4v2-trunk-r355/src/mp4file.h ---- mp4v2-trunk-r355/src/mp4file.h 2009-05-23 06:29:37.000000000 -0700 -+++ mp4v2-trunk-r355/src/mp4file.h 2010-05-23 15:44:57.568026299 -0700 -@@ -388,6 +388,10 @@ - uint16_t width, - uint16_t height); - -+ MP4TrackId AddSubpicTrack(uint32_t timescale, -+ uint16_t width, -+ uint16_t height); -+ - MP4TrackId AddPixelAspectRatio(MP4TrackId trackId, uint32_t hSpacing, uint32_t vSpacing); - MP4TrackId AddColr(MP4TrackId trackId, uint16_t pri, uint16_t tran, uint16_t mat); - diff --git a/contrib/mp4v2/A01-divide-zero.patch b/contrib/mp4v2/A01-divide-zero.patch deleted file mode 100644 index 4d6aa4d2a..000000000 --- a/contrib/mp4v2/A01-divide-zero.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- mp4v2-r355/src/mp4track.cpp 2012-01-05 15:44:29.000000000 +0100 -+++ mp4v2-r355/src/mp4track.cpp 2012-01-05 15:47:34.000000000 +0100 -@@ -819,13 +819,14 @@ - (thisSecStart + timeScale) - lastSampleTime; - // calculate the duration of the last sample - MP4Duration lastSampleDur = sampleTime - lastSampleTime; -- uint32_t overflow_bytes; - // now, calculate the number of bytes we overflowed. Round up. -- overflow_bytes = -- ((lastSampleSize * overflow_dur) + (lastSampleDur - 1)) / lastSampleDur; -+ if( lastSampleDur > 0 ) { -+ uint32_t overflow_bytes = 0; -+ overflow_bytes = ((lastSampleSize * overflow_dur) + (lastSampleDur - 1)) / lastSampleDur; - -- if (bytesThisSec - overflow_bytes > maxBytesPerSec) { -- maxBytesPerSec = bytesThisSec - overflow_bytes; -+ if (bytesThisSec - overflow_bytes > maxBytesPerSec) { -+ maxBytesPerSec = bytesThisSec - overflow_bytes; -+ } - } - - // now adjust the values for this sample. Remove the bytes diff --git a/contrib/mp4v2/A02-meaningful-4gb-warning.patch b/contrib/mp4v2/A02-meaningful-4gb-warning.patch deleted file mode 100644 index 987298bd5..000000000 --- a/contrib/mp4v2/A02-meaningful-4gb-warning.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -Naur mp4v2-trunk-r355/src/mp4atom.cpp mp4v2-trunk-r355/src/mp4atom.cpp ---- mp4v2-trunk-r355/src/mp4atom.cpp 2012-02-21 19:40:03.000000000 +0100 -+++ mp4v2-trunk-r355/src/mp4atom.cpp 2012-02-21 19:36:38.000000000 +0100 -@@ -543,6 +543,10 @@ - m_pFile->SetPosition(m_start + 8); - m_pFile->WriteUInt64(m_size); - } else { -+ if (!(m_size <= (uint64_t)0xFFFFFFFF)) { -+ // Let the user know what the following assert is all about -+ fprintf(stderr, "MP4ERROR: File size exceeded 4 GB; output unplayable. Enable \"Large file size\" to fix it.\n"); -+ } - ASSERT(m_size <= (uint64_t)0xFFFFFFFF); - m_pFile->SetPosition(m_start); - m_pFile->WriteUInt32(m_size); diff --git a/contrib/mp4v2/A03-clang.patch b/contrib/mp4v2/A03-clang.patch deleted file mode 100644 index 73fec39df..000000000 --- a/contrib/mp4v2/A03-clang.patch +++ /dev/null @@ -1,1472 +0,0 @@ -diff --git mp4v2-trunk-r355/src/bmff/typebmff.cpp mp4v2-trunk-r355/src/bmff/typebmff.cpp -index c34f831..f917069 100644 ---- mp4v2-trunk-r355/src/bmff/typebmff.cpp -+++ mp4v2-trunk-r355/src/bmff/typebmff.cpp -@@ -23,518 +23,507 @@ - - #include "impl.h" - --// VStudio idiocy prevents defining template instanced static data --// in a namespace. Workaround it by defining in global scope. --// Other platforms will continue to put things in the proper namespace. --#if defined( _MSC_VER ) --using namespace mp4v2::impl::bmff; --#else --namespace mp4v2 { namespace impl { namespace bmff { --#endif -+namespace mp4v2 { namespace impl { - - /////////////////////////////////////////////////////////////////////////////// - - template <> --const EnumLanguageCode::Entry EnumLanguageCode::data[] = { -- { mp4v2::impl::bmff::ILC_AAR, "aar", "Afar" }, -- { mp4v2::impl::bmff::ILC_ABK, "abk", "Abkhazian" }, -- { mp4v2::impl::bmff::ILC_ACE, "ace", "Achinese" }, -- { mp4v2::impl::bmff::ILC_ACH, "ach", "Acoli" }, -- { mp4v2::impl::bmff::ILC_ADA, "ada", "Adangme" }, -- { mp4v2::impl::bmff::ILC_ADY, "ady", "Adyghe; Adygei" }, -- { mp4v2::impl::bmff::ILC_AFA, "afa", "Afro-Asiatic (Other)" }, -- { mp4v2::impl::bmff::ILC_AFH, "afh", "Afrihili" }, -- { mp4v2::impl::bmff::ILC_AFR, "afr", "Afrikaans" }, -- { mp4v2::impl::bmff::ILC_AIN, "ain", "Ainu" }, -- { mp4v2::impl::bmff::ILC_AKA, "aka", "Akan" }, -- { mp4v2::impl::bmff::ILC_AKK, "akk", "Akkadian" }, -- { mp4v2::impl::bmff::ILC_SQI, "sqi", "Albanian" }, -- { mp4v2::impl::bmff::ILC_ALE, "ale", "Aleut" }, -- { mp4v2::impl::bmff::ILC_ALG, "alg", "Algonquian languages" }, -- { mp4v2::impl::bmff::ILC_ALT, "alt", "Southern Altai" }, -- { mp4v2::impl::bmff::ILC_AMH, "amh", "Amharic" }, -- { mp4v2::impl::bmff::ILC_ANG, "ang", "English, Old (ca.450-1100)" }, -- { mp4v2::impl::bmff::ILC_ANP, "anp", "Angika" }, -- { mp4v2::impl::bmff::ILC_APA, "apa", "Apache languages" }, -- { mp4v2::impl::bmff::ILC_ARA, "ara", "Arabic" }, -- { mp4v2::impl::bmff::ILC_ARC, "arc", "Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)" }, -- { mp4v2::impl::bmff::ILC_ARG, "arg", "Aragonese" }, -- { mp4v2::impl::bmff::ILC_HYE, "hye", "Armenian" }, -- { mp4v2::impl::bmff::ILC_ARN, "arn", "Mapudungun; Mapuche" }, -- { mp4v2::impl::bmff::ILC_ARP, "arp", "Arapaho" }, -- { mp4v2::impl::bmff::ILC_ART, "art", "Artificial (Other)" }, -- { mp4v2::impl::bmff::ILC_ARW, "arw", "Arawak" }, -- { mp4v2::impl::bmff::ILC_ASM, "asm", "Assamese" }, -- { mp4v2::impl::bmff::ILC_AST, "ast", "Asturian; Bable; Leonese; Asturleonese" }, -- { mp4v2::impl::bmff::ILC_ATH, "ath", "Athapascan languages" }, -- { mp4v2::impl::bmff::ILC_AUS, "aus", "Australian languages" }, -- { mp4v2::impl::bmff::ILC_AVA, "ava", "Avaric" }, -- { mp4v2::impl::bmff::ILC_AVE, "ave", "Avestan" }, -- { mp4v2::impl::bmff::ILC_AWA, "awa", "Awadhi" }, -- { mp4v2::impl::bmff::ILC_AYM, "aym", "Aymara" }, -- { mp4v2::impl::bmff::ILC_AZE, "aze", "Azerbaijani" }, -- { mp4v2::impl::bmff::ILC_BAD, "bad", "Banda languages" }, -- { mp4v2::impl::bmff::ILC_BAI, "bai", "Bamileke languages" }, -- { mp4v2::impl::bmff::ILC_BAK, "bak", "Bashkir" }, -- { mp4v2::impl::bmff::ILC_BAL, "bal", "Baluchi" }, -- { mp4v2::impl::bmff::ILC_BAM, "bam", "Bambara" }, -- { mp4v2::impl::bmff::ILC_BAN, "ban", "Balinese" }, -- { mp4v2::impl::bmff::ILC_EUS, "eus", "Basque" }, -- { mp4v2::impl::bmff::ILC_BAS, "bas", "Basa" }, -- { mp4v2::impl::bmff::ILC_BAT, "bat", "Baltic (Other)" }, -- { mp4v2::impl::bmff::ILC_BEJ, "bej", "Beja; Bedawiyet" }, -- { mp4v2::impl::bmff::ILC_BEL, "bel", "Belarusian" }, -- { mp4v2::impl::bmff::ILC_BEM, "bem", "Bemba" }, -- { mp4v2::impl::bmff::ILC_BEN, "ben", "Bengali" }, -- { mp4v2::impl::bmff::ILC_BER, "ber", "Berber (Other)" }, -- { mp4v2::impl::bmff::ILC_BHO, "bho", "Bhojpuri" }, -- { mp4v2::impl::bmff::ILC_BIH, "bih", "Bihari" }, -- { mp4v2::impl::bmff::ILC_BIK, "bik", "Bikol" }, -- { mp4v2::impl::bmff::ILC_BIN, "bin", "Bini; Edo" }, -- { mp4v2::impl::bmff::ILC_BIS, "bis", "Bislama" }, -- { mp4v2::impl::bmff::ILC_BLA, "bla", "Siksika" }, -- { mp4v2::impl::bmff::ILC_BNT, "bnt", "Bantu (Other)" }, -- { mp4v2::impl::bmff::ILC_BOS, "bos", "Bosnian" }, -- { mp4v2::impl::bmff::ILC_BRA, "bra", "Braj" }, -- { mp4v2::impl::bmff::ILC_BRE, "bre", "Breton" }, -- { mp4v2::impl::bmff::ILC_BTK, "btk", "Batak languages" }, -- { mp4v2::impl::bmff::ILC_BUA, "bua", "Buriat" }, -- { mp4v2::impl::bmff::ILC_BUG, "bug", "Buginese" }, -- { mp4v2::impl::bmff::ILC_BUL, "bul", "Bulgarian" }, -- { mp4v2::impl::bmff::ILC_MYA, "mya", "Burmese" }, -- { mp4v2::impl::bmff::ILC_BYN, "byn", "Blin; Bilin" }, -- { mp4v2::impl::bmff::ILC_CAD, "cad", "Caddo" }, -- { mp4v2::impl::bmff::ILC_CAI, "cai", "Central American Indian (Other)" }, -- { mp4v2::impl::bmff::ILC_CAR, "car", "Galibi Carib" }, -- { mp4v2::impl::bmff::ILC_CAT, "cat", "Catalan; Valencian" }, -- { mp4v2::impl::bmff::ILC_CAU, "cau", "Caucasian (Other)" }, -- { mp4v2::impl::bmff::ILC_CEB, "ceb", "Cebuano" }, -- { mp4v2::impl::bmff::ILC_CEL, "cel", "Celtic (Other)" }, -- { mp4v2::impl::bmff::ILC_CHA, "cha", "Chamorro" }, -- { mp4v2::impl::bmff::ILC_CHB, "chb", "Chibcha" }, -- { mp4v2::impl::bmff::ILC_CHE, "che", "Chechen" }, -- { mp4v2::impl::bmff::ILC_CHG, "chg", "Chagatai" }, -- { mp4v2::impl::bmff::ILC_ZHO, "zho", "Chinese" }, -- { mp4v2::impl::bmff::ILC_CHK, "chk", "Chuukese" }, -- { mp4v2::impl::bmff::ILC_CHM, "chm", "Mari" }, -- { mp4v2::impl::bmff::ILC_CHN, "chn", "Chinook jargon" }, -- { mp4v2::impl::bmff::ILC_CHO, "cho", "Choctaw" }, -- { mp4v2::impl::bmff::ILC_CHP, "chp", "Chipewyan; Dene Suline" }, -- { mp4v2::impl::bmff::ILC_CHR, "chr", "Cherokee" }, -- { mp4v2::impl::bmff::ILC_CHU, "chu", "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic" }, -- { mp4v2::impl::bmff::ILC_CHV, "chv", "Chuvash" }, -- { mp4v2::impl::bmff::ILC_CHY, "chy", "Cheyenne" }, -- { mp4v2::impl::bmff::ILC_CMC, "cmc", "Chamic languages" }, -- { mp4v2::impl::bmff::ILC_COP, "cop", "Coptic" }, -- { mp4v2::impl::bmff::ILC_COR, "cor", "Cornish" }, -- { mp4v2::impl::bmff::ILC_COS, "cos", "Corsican" }, -- { mp4v2::impl::bmff::ILC_CPE, "cpe", "Creoles and pidgins, English based (Other)" }, -- { mp4v2::impl::bmff::ILC_CPF, "cpf", "Creoles and pidgins, French-based (Other)" }, -- { mp4v2::impl::bmff::ILC_CPP, "cpp", "Creoles and pidgins, Portuguese-based (Other)" }, -- { mp4v2::impl::bmff::ILC_CRE, "cre", "Cree" }, -- { mp4v2::impl::bmff::ILC_CRH, "crh", "Crimean Tatar; Crimean Turkish" }, -- { mp4v2::impl::bmff::ILC_CRP, "crp", "Creoles and pidgins (Other)" }, -- { mp4v2::impl::bmff::ILC_CSB, "csb", "Kashubian" }, -- { mp4v2::impl::bmff::ILC_CUS, "cus", "Cushitic (Other)" }, -- { mp4v2::impl::bmff::ILC_CES, "ces", "Czech" }, -- { mp4v2::impl::bmff::ILC_DAK, "dak", "Dakota" }, -- { mp4v2::impl::bmff::ILC_DAN, "dan", "Danish" }, -- { mp4v2::impl::bmff::ILC_DAR, "dar", "Dargwa" }, -- { mp4v2::impl::bmff::ILC_DAY, "day", "Land Dayak languages" }, -- { mp4v2::impl::bmff::ILC_DEL, "del", "Delaware" }, -- { mp4v2::impl::bmff::ILC_DEN, "den", "Slave (Athapascan)" }, -- { mp4v2::impl::bmff::ILC_DGR, "dgr", "Dogrib" }, -- { mp4v2::impl::bmff::ILC_DIN, "din", "Dinka" }, -- { mp4v2::impl::bmff::ILC_DIV, "div", "Divehi; Dhivehi; Maldivian" }, -- { mp4v2::impl::bmff::ILC_DOI, "doi", "Dogri" }, -- { mp4v2::impl::bmff::ILC_DRA, "dra", "Dravidian (Other)" }, -- { mp4v2::impl::bmff::ILC_DSB, "dsb", "Lower Sorbian" }, -- { mp4v2::impl::bmff::ILC_DUA, "dua", "Duala" }, -- { mp4v2::impl::bmff::ILC_DUM, "dum", "Dutch, Middle (ca.1050-1350)" }, -- { mp4v2::impl::bmff::ILC_NLD, "nld", "Dutch; Flemish" }, -- { mp4v2::impl::bmff::ILC_DYU, "dyu", "Dyula" }, -- { mp4v2::impl::bmff::ILC_DZO, "dzo", "Dzongkha" }, -- { mp4v2::impl::bmff::ILC_EFI, "efi", "Efik" }, -- { mp4v2::impl::bmff::ILC_EGY, "egy", "Egyptian (Ancient)" }, -- { mp4v2::impl::bmff::ILC_EKA, "eka", "Ekajuk" }, -- { mp4v2::impl::bmff::ILC_ELX, "elx", "Elamite" }, -- { mp4v2::impl::bmff::ILC_ENG, "eng", "English" }, -- { mp4v2::impl::bmff::ILC_ENM, "enm", "English, Middle (1100-1500)" }, -- { mp4v2::impl::bmff::ILC_EPO, "epo", "Esperanto" }, -- { mp4v2::impl::bmff::ILC_EST, "est", "Estonian" }, -- { mp4v2::impl::bmff::ILC_EWE, "ewe", "Ewe" }, -- { mp4v2::impl::bmff::ILC_EWO, "ewo", "Ewondo" }, -- { mp4v2::impl::bmff::ILC_FAN, "fan", "Fang" }, -- { mp4v2::impl::bmff::ILC_FAO, "fao", "Faroese" }, -- { mp4v2::impl::bmff::ILC_FAT, "fat", "Fanti" }, -- { mp4v2::impl::bmff::ILC_FIJ, "fij", "Fijian" }, -- { mp4v2::impl::bmff::ILC_FIL, "fil", "Filipino; Pilipino" }, -- { mp4v2::impl::bmff::ILC_FIN, "fin", "Finnish" }, -- { mp4v2::impl::bmff::ILC_FIU, "fiu", "Finno-Ugrian (Other)" }, -- { mp4v2::impl::bmff::ILC_FON, "fon", "Fon" }, -- { mp4v2::impl::bmff::ILC_FRA, "fra", "French" }, -- { mp4v2::impl::bmff::ILC_FRM, "frm", "French, Middle (ca.1400-1600)" }, -- { mp4v2::impl::bmff::ILC_FRO, "fro", "French, Old (842-ca.1400)" }, -- { mp4v2::impl::bmff::ILC_FRR, "frr", "Northern Frisian" }, -- { mp4v2::impl::bmff::ILC_FRS, "frs", "Eastern Frisian" }, -- { mp4v2::impl::bmff::ILC_FRY, "fry", "Western Frisian" }, -- { mp4v2::impl::bmff::ILC_FUL, "ful", "Fulah" }, -- { mp4v2::impl::bmff::ILC_FUR, "fur", "Friulian" }, -- { mp4v2::impl::bmff::ILC_GAA, "gaa", "Ga" }, -- { mp4v2::impl::bmff::ILC_GAY, "gay", "Gayo" }, -- { mp4v2::impl::bmff::ILC_GBA, "gba", "Gbaya" }, -- { mp4v2::impl::bmff::ILC_GEM, "gem", "Germanic (Other)" }, -- { mp4v2::impl::bmff::ILC_KAT, "kat", "Georgian" }, -- { mp4v2::impl::bmff::ILC_DEU, "deu", "German" }, -- { mp4v2::impl::bmff::ILC_GEZ, "gez", "Geez" }, -- { mp4v2::impl::bmff::ILC_GIL, "gil", "Gilbertese" }, -- { mp4v2::impl::bmff::ILC_GLA, "gla", "Gaelic; Scottish Gaelic" }, -- { mp4v2::impl::bmff::ILC_GLE, "gle", "Irish" }, -- { mp4v2::impl::bmff::ILC_GLG, "glg", "Galician" }, -- { mp4v2::impl::bmff::ILC_GLV, "glv", "Manx" }, -- { mp4v2::impl::bmff::ILC_GMH, "gmh", "German, Middle High (ca.1050-1500)" }, -- { mp4v2::impl::bmff::ILC_GOH, "goh", "German, Old High (ca.750-1050)" }, -- { mp4v2::impl::bmff::ILC_GON, "gon", "Gondi" }, -- { mp4v2::impl::bmff::ILC_GOR, "gor", "Gorontalo" }, -- { mp4v2::impl::bmff::ILC_GOT, "got", "Gothic" }, -- { mp4v2::impl::bmff::ILC_GRB, "grb", "Grebo" }, -- { mp4v2::impl::bmff::ILC_GRC, "grc", "Greek, Ancient (to 1453)" }, -- { mp4v2::impl::bmff::ILC_ELL, "ell", "Greek, Modern (1453-)" }, -- { mp4v2::impl::bmff::ILC_GRN, "grn", "Guarani" }, -- { mp4v2::impl::bmff::ILC_GSW, "gsw", "Swiss German; Alemannic; Alsatian" }, -- { mp4v2::impl::bmff::ILC_GUJ, "guj", "Gujarati" }, -- { mp4v2::impl::bmff::ILC_GWI, "gwi", "Gwich'in" }, -- { mp4v2::impl::bmff::ILC_HAI, "hai", "Haida" }, -- { mp4v2::impl::bmff::ILC_HAT, "hat", "Haitian; Haitian Creole" }, -- { mp4v2::impl::bmff::ILC_HAU, "hau", "Hausa" }, -- { mp4v2::impl::bmff::ILC_HAW, "haw", "Hawaiian" }, -- { mp4v2::impl::bmff::ILC_HEB, "heb", "Hebrew" }, -- { mp4v2::impl::bmff::ILC_HER, "her", "Herero" }, -- { mp4v2::impl::bmff::ILC_HIL, "hil", "Hiligaynon" }, -- { mp4v2::impl::bmff::ILC_HIM, "him", "Himachali" }, -- { mp4v2::impl::bmff::ILC_HIN, "hin", "Hindi" }, -- { mp4v2::impl::bmff::ILC_HIT, "hit", "Hittite" }, -- { mp4v2::impl::bmff::ILC_HMN, "hmn", "Hmong" }, -- { mp4v2::impl::bmff::ILC_HMO, "hmo", "Hiri Motu" }, -- { mp4v2::impl::bmff::ILC_HRV, "hrv", "Croatian" }, -- { mp4v2::impl::bmff::ILC_HSB, "hsb", "Upper Sorbian" }, -- { mp4v2::impl::bmff::ILC_HUN, "hun", "Hungarian" }, -- { mp4v2::impl::bmff::ILC_HUP, "hup", "Hupa" }, -- { mp4v2::impl::bmff::ILC_IBA, "iba", "Iban" }, -- { mp4v2::impl::bmff::ILC_IBO, "ibo", "Igbo" }, -- { mp4v2::impl::bmff::ILC_ISL, "isl", "Icelandic" }, -- { mp4v2::impl::bmff::ILC_IDO, "ido", "Ido" }, -- { mp4v2::impl::bmff::ILC_III, "iii", "Sichuan Yi; Nuosu" }, -- { mp4v2::impl::bmff::ILC_IJO, "ijo", "Ijo languages" }, -- { mp4v2::impl::bmff::ILC_IKU, "iku", "Inuktitut" }, -- { mp4v2::impl::bmff::ILC_ILE, "ile", "Interlingue; Occidental" }, -- { mp4v2::impl::bmff::ILC_ILO, "ilo", "Iloko" }, -- { mp4v2::impl::bmff::ILC_INA, "ina", "Interlingua (International Auxiliary Language Association)" }, -- { mp4v2::impl::bmff::ILC_INC, "inc", "Indic (Other)" }, -- { mp4v2::impl::bmff::ILC_IND, "ind", "Indonesian" }, -- { mp4v2::impl::bmff::ILC_INE, "ine", "Indo-European (Other)" }, -- { mp4v2::impl::bmff::ILC_INH, "inh", "Ingush" }, -- { mp4v2::impl::bmff::ILC_IPK, "ipk", "Inupiaq" }, -- { mp4v2::impl::bmff::ILC_IRA, "ira", "Iranian (Other)" }, -- { mp4v2::impl::bmff::ILC_IRO, "iro", "Iroquoian languages" }, -- { mp4v2::impl::bmff::ILC_ITA, "ita", "Italian" }, -- { mp4v2::impl::bmff::ILC_JAV, "jav", "Javanese" }, -- { mp4v2::impl::bmff::ILC_JBO, "jbo", "Lojban" }, -- { mp4v2::impl::bmff::ILC_JPN, "jpn", "Japanese" }, -- { mp4v2::impl::bmff::ILC_JPR, "jpr", "Judeo-Persian" }, -- { mp4v2::impl::bmff::ILC_JRB, "jrb", "Judeo-Arabic" }, -- { mp4v2::impl::bmff::ILC_KAA, "kaa", "Kara-Kalpak" }, -- { mp4v2::impl::bmff::ILC_KAB, "kab", "Kabyle" }, -- { mp4v2::impl::bmff::ILC_KAC, "kac", "Kachin; Jingpho" }, -- { mp4v2::impl::bmff::ILC_KAL, "kal", "Kalaallisut; Greenlandic" }, -- { mp4v2::impl::bmff::ILC_KAM, "kam", "Kamba" }, -- { mp4v2::impl::bmff::ILC_KAN, "kan", "Kannada" }, -- { mp4v2::impl::bmff::ILC_KAR, "kar", "Karen languages" }, -- { mp4v2::impl::bmff::ILC_KAS, "kas", "Kashmiri" }, -- { mp4v2::impl::bmff::ILC_KAU, "kau", "Kanuri" }, -- { mp4v2::impl::bmff::ILC_KAW, "kaw", "Kawi" }, -- { mp4v2::impl::bmff::ILC_KAZ, "kaz", "Kazakh" }, -- { mp4v2::impl::bmff::ILC_KBD, "kbd", "Kabardian" }, -- { mp4v2::impl::bmff::ILC_KHA, "kha", "Khasi" }, -- { mp4v2::impl::bmff::ILC_KHI, "khi", "Khoisan (Other)" }, -- { mp4v2::impl::bmff::ILC_KHM, "khm", "Central Khmer" }, -- { mp4v2::impl::bmff::ILC_KHO, "kho", "Khotanese; Sakan" }, -- { mp4v2::impl::bmff::ILC_KIK, "kik", "Kikuyu; Gikuyu" }, -- { mp4v2::impl::bmff::ILC_KIN, "kin", "Kinyarwanda" }, -- { mp4v2::impl::bmff::ILC_KIR, "kir", "Kirghiz; Kyrgyz" }, -- { mp4v2::impl::bmff::ILC_KMB, "kmb", "Kimbundu" }, -- { mp4v2::impl::bmff::ILC_KOK, "kok", "Konkani" }, -- { mp4v2::impl::bmff::ILC_KOM, "kom", "Komi" }, -- { mp4v2::impl::bmff::ILC_KON, "kon", "Kongo" }, -- { mp4v2::impl::bmff::ILC_KOR, "kor", "Korean" }, -- { mp4v2::impl::bmff::ILC_KOS, "kos", "Kosraean" }, -- { mp4v2::impl::bmff::ILC_KPE, "kpe", "Kpelle" }, -- { mp4v2::impl::bmff::ILC_KRC, "krc", "Karachay-Balkar" }, -- { mp4v2::impl::bmff::ILC_KRL, "krl", "Karelian" }, -- { mp4v2::impl::bmff::ILC_KRO, "kro", "Kru languages" }, -- { mp4v2::impl::bmff::ILC_KRU, "kru", "Kurukh" }, -- { mp4v2::impl::bmff::ILC_KUA, "kua", "Kuanyama; Kwanyama" }, -- { mp4v2::impl::bmff::ILC_KUM, "kum", "Kumyk" }, -- { mp4v2::impl::bmff::ILC_KUR, "kur", "Kurdish" }, -- { mp4v2::impl::bmff::ILC_KUT, "kut", "Kutenai" }, -- { mp4v2::impl::bmff::ILC_LAD, "lad", "Ladino" }, -- { mp4v2::impl::bmff::ILC_LAH, "lah", "Lahnda" }, -- { mp4v2::impl::bmff::ILC_LAM, "lam", "Lamba" }, -- { mp4v2::impl::bmff::ILC_LAO, "lao", "Lao" }, -- { mp4v2::impl::bmff::ILC_LAT, "lat", "Latin" }, -- { mp4v2::impl::bmff::ILC_LAV, "lav", "Latvian" }, -- { mp4v2::impl::bmff::ILC_LEZ, "lez", "Lezghian" }, -- { mp4v2::impl::bmff::ILC_LIM, "lim", "Limburgan; Limburger; Limburgish" }, -- { mp4v2::impl::bmff::ILC_LIN, "lin", "Lingala" }, -- { mp4v2::impl::bmff::ILC_LIT, "lit", "Lithuanian" }, -- { mp4v2::impl::bmff::ILC_LOL, "lol", "Mongo" }, -- { mp4v2::impl::bmff::ILC_LOZ, "loz", "Lozi" }, -- { mp4v2::impl::bmff::ILC_LTZ, "ltz", "Luxembourgish; Letzeburgesch" }, -- { mp4v2::impl::bmff::ILC_LUA, "lua", "Luba-Lulua" }, -- { mp4v2::impl::bmff::ILC_LUB, "lub", "Luba-Katanga" }, -- { mp4v2::impl::bmff::ILC_LUG, "lug", "Ganda" }, -- { mp4v2::impl::bmff::ILC_LUI, "lui", "Luiseno" }, -- { mp4v2::impl::bmff::ILC_LUN, "lun", "Lunda" }, -- { mp4v2::impl::bmff::ILC_LUO, "luo", "Luo (Kenya and Tanzania)" }, -- { mp4v2::impl::bmff::ILC_LUS, "lus", "Lushai" }, -- { mp4v2::impl::bmff::ILC_MKD, "mkd", "Macedonian" }, -- { mp4v2::impl::bmff::ILC_MAD, "mad", "Madurese" }, -- { mp4v2::impl::bmff::ILC_MAG, "mag", "Magahi" }, -- { mp4v2::impl::bmff::ILC_MAH, "mah", "Marshallese" }, -- { mp4v2::impl::bmff::ILC_MAI, "mai", "Maithili" }, -- { mp4v2::impl::bmff::ILC_MAK, "mak", "Makasar" }, -- { mp4v2::impl::bmff::ILC_MAL, "mal", "Malayalam" }, -- { mp4v2::impl::bmff::ILC_MAN, "man", "Mandingo" }, -- { mp4v2::impl::bmff::ILC_MRI, "mri", "Maori" }, -- { mp4v2::impl::bmff::ILC_MAP, "map", "Austronesian (Other)" }, -- { mp4v2::impl::bmff::ILC_MAR, "mar", "Marathi" }, -- { mp4v2::impl::bmff::ILC_MAS, "mas", "Masai" }, -- { mp4v2::impl::bmff::ILC_MSA, "msa", "Malay" }, -- { mp4v2::impl::bmff::ILC_MDF, "mdf", "Moksha" }, -- { mp4v2::impl::bmff::ILC_MDR, "mdr", "Mandar" }, -- { mp4v2::impl::bmff::ILC_MEN, "men", "Mende" }, -- { mp4v2::impl::bmff::ILC_MGA, "mga", "Irish, Middle (900-1200)" }, -- { mp4v2::impl::bmff::ILC_MIC, "mic", "Mi'kmaq; Micmac" }, -- { mp4v2::impl::bmff::ILC_MIN, "min", "Minangkabau" }, -- { mp4v2::impl::bmff::ILC_MIS, "mis", "Uncoded languages" }, -- { mp4v2::impl::bmff::ILC_MKH, "mkh", "Mon-Khmer (Other)" }, -- { mp4v2::impl::bmff::ILC_MLG, "mlg", "Malagasy" }, -- { mp4v2::impl::bmff::ILC_MLT, "mlt", "Maltese" }, -- { mp4v2::impl::bmff::ILC_MNC, "mnc", "Manchu" }, -- { mp4v2::impl::bmff::ILC_MNI, "mni", "Manipuri" }, -- { mp4v2::impl::bmff::ILC_MNO, "mno", "Manobo languages" }, -- { mp4v2::impl::bmff::ILC_MOH, "moh", "Mohawk" }, -- { mp4v2::impl::bmff::ILC_MON, "mon", "Mongolian" }, -- { mp4v2::impl::bmff::ILC_MOS, "mos", "Mossi" }, -- { mp4v2::impl::bmff::ILC_MUL, "mul", "Multiple languages" }, -- { mp4v2::impl::bmff::ILC_MUN, "mun", "Munda languages" }, -- { mp4v2::impl::bmff::ILC_MUS, "mus", "Creek" }, -- { mp4v2::impl::bmff::ILC_MWL, "mwl", "Mirandese" }, -- { mp4v2::impl::bmff::ILC_MWR, "mwr", "Marwari" }, -- { mp4v2::impl::bmff::ILC_MYN, "myn", "Mayan languages" }, -- { mp4v2::impl::bmff::ILC_MYV, "myv", "Erzya" }, -- { mp4v2::impl::bmff::ILC_NAH, "nah", "Nahuatl languages" }, -- { mp4v2::impl::bmff::ILC_NAI, "nai", "North American Indian" }, -- { mp4v2::impl::bmff::ILC_NAP, "nap", "Neapolitan" }, -- { mp4v2::impl::bmff::ILC_NAU, "nau", "Nauru" }, -- { mp4v2::impl::bmff::ILC_NAV, "nav", "Navajo; Navaho" }, -- { mp4v2::impl::bmff::ILC_NBL, "nbl", "Ndebele, South; South Ndebele" }, -- { mp4v2::impl::bmff::ILC_NDE, "nde", "Ndebele, North; North Ndebele" }, -- { mp4v2::impl::bmff::ILC_NDO, "ndo", "Ndonga" }, -- { mp4v2::impl::bmff::ILC_NDS, "nds", "Low German; Low Saxon; German, Low; Saxon, Low" }, -- { mp4v2::impl::bmff::ILC_NEP, "nep", "Nepali" }, -- { mp4v2::impl::bmff::ILC_NEW, "new", "Nepal Bhasa; Newari" }, -- { mp4v2::impl::bmff::ILC_NIA, "nia", "Nias" }, -- { mp4v2::impl::bmff::ILC_NIC, "nic", "Niger-Kordofanian (Other)" }, -- { mp4v2::impl::bmff::ILC_NIU, "niu", "Niuean" }, -- { mp4v2::impl::bmff::ILC_NNO, "nno", "Norwegian Nynorsk; Nynorsk, Norwegian" }, -- { mp4v2::impl::bmff::ILC_NOB, "nob", "Bokmål, Norwegian; Norwegian Bokmål" }, -- { mp4v2::impl::bmff::ILC_NOG, "nog", "Nogai" }, -- { mp4v2::impl::bmff::ILC_NON, "non", "Norse, Old" }, -- { mp4v2::impl::bmff::ILC_NOR, "nor", "Norwegian" }, -- { mp4v2::impl::bmff::ILC_NQO, "nqo", "N'Ko" }, -- { mp4v2::impl::bmff::ILC_NSO, "nso", "Pedi; Sepedi; Northern Sotho" }, -- { mp4v2::impl::bmff::ILC_NUB, "nub", "Nubian languages" }, -- { mp4v2::impl::bmff::ILC_NWC, "nwc", "Classical Newari; Old Newari; Classical Nepal Bhasa" }, -- { mp4v2::impl::bmff::ILC_NYA, "nya", "Chichewa; Chewa; Nyanja" }, -- { mp4v2::impl::bmff::ILC_NYM, "nym", "Nyamwezi" }, -- { mp4v2::impl::bmff::ILC_NYN, "nyn", "Nyankole" }, -- { mp4v2::impl::bmff::ILC_NYO, "nyo", "Nyoro" }, -- { mp4v2::impl::bmff::ILC_NZI, "nzi", "Nzima" }, -- { mp4v2::impl::bmff::ILC_OCI, "oci", "Occitan (post 1500); Provençal" }, -- { mp4v2::impl::bmff::ILC_OJI, "oji", "Ojibwa" }, -- { mp4v2::impl::bmff::ILC_ORI, "ori", "Oriya" }, -- { mp4v2::impl::bmff::ILC_ORM, "orm", "Oromo" }, -- { mp4v2::impl::bmff::ILC_OSA, "osa", "Osage" }, -- { mp4v2::impl::bmff::ILC_OSS, "oss", "Ossetian; Ossetic" }, -- { mp4v2::impl::bmff::ILC_OTA, "ota", "Turkish, Ottoman (1500-1928)" }, -- { mp4v2::impl::bmff::ILC_OTO, "oto", "Otomian languages" }, -- { mp4v2::impl::bmff::ILC_PAA, "paa", "Papuan (Other)" }, -- { mp4v2::impl::bmff::ILC_PAG, "pag", "Pangasinan" }, -- { mp4v2::impl::bmff::ILC_PAL, "pal", "Pahlavi" }, -- { mp4v2::impl::bmff::ILC_PAM, "pam", "Pampanga; Kapampangan" }, -- { mp4v2::impl::bmff::ILC_PAN, "pan", "Panjabi; Punjabi" }, -- { mp4v2::impl::bmff::ILC_PAP, "pap", "Papiamento" }, -- { mp4v2::impl::bmff::ILC_PAU, "pau", "Palauan" }, -- { mp4v2::impl::bmff::ILC_PEO, "peo", "Persian, Old (ca.600-400 B.C.)" }, -- { mp4v2::impl::bmff::ILC_FAS, "fas", "Persian" }, -- { mp4v2::impl::bmff::ILC_PHI, "phi", "Philippine (Other)" }, -- { mp4v2::impl::bmff::ILC_PHN, "phn", "Phoenician" }, -- { mp4v2::impl::bmff::ILC_PLI, "pli", "Pali" }, -- { mp4v2::impl::bmff::ILC_POL, "pol", "Polish" }, -- { mp4v2::impl::bmff::ILC_PON, "pon", "Pohnpeian" }, -- { mp4v2::impl::bmff::ILC_POR, "por", "Portuguese" }, -- { mp4v2::impl::bmff::ILC_PRA, "pra", "Prakrit languages" }, -- { mp4v2::impl::bmff::ILC_PRO, "pro", "Provençal, Old (to 1500)" }, -- { mp4v2::impl::bmff::ILC_PUS, "pus", "Pushto; Pashto" }, -- { mp4v2::impl::bmff::ILC_QUE, "que", "Quechua" }, -- { mp4v2::impl::bmff::ILC_RAJ, "raj", "Rajasthani" }, -- { mp4v2::impl::bmff::ILC_RAP, "rap", "Rapanui" }, -- { mp4v2::impl::bmff::ILC_RAR, "rar", "Rarotongan; Cook Islands Maori" }, -- { mp4v2::impl::bmff::ILC_ROA, "roa", "Romance (Other)" }, -- { mp4v2::impl::bmff::ILC_ROH, "roh", "Romansh" }, -- { mp4v2::impl::bmff::ILC_ROM, "rom", "Romany" }, -- { mp4v2::impl::bmff::ILC_RON, "ron", "Romanian; Moldavian; Moldovan" }, -- { mp4v2::impl::bmff::ILC_RUN, "run", "Rundi" }, -- { mp4v2::impl::bmff::ILC_RUP, "rup", "Aromanian; Arumanian; Macedo-Romanian" }, -- { mp4v2::impl::bmff::ILC_RUS, "rus", "Russian" }, -- { mp4v2::impl::bmff::ILC_SAD, "sad", "Sandawe" }, -- { mp4v2::impl::bmff::ILC_SAG, "sag", "Sango" }, -- { mp4v2::impl::bmff::ILC_SAH, "sah", "Yakut" }, -- { mp4v2::impl::bmff::ILC_SAI, "sai", "South American Indian (Other)" }, -- { mp4v2::impl::bmff::ILC_SAL, "sal", "Salishan languages" }, -- { mp4v2::impl::bmff::ILC_SAM, "sam", "Samaritan Aramaic" }, -- { mp4v2::impl::bmff::ILC_SAN, "san", "Sanskrit" }, -- { mp4v2::impl::bmff::ILC_SAS, "sas", "Sasak" }, -- { mp4v2::impl::bmff::ILC_SAT, "sat", "Santali" }, -- { mp4v2::impl::bmff::ILC_SCN, "scn", "Sicilian" }, -- { mp4v2::impl::bmff::ILC_SCO, "sco", "Scots" }, -- { mp4v2::impl::bmff::ILC_SEL, "sel", "Selkup" }, -- { mp4v2::impl::bmff::ILC_SEM, "sem", "Semitic (Other)" }, -- { mp4v2::impl::bmff::ILC_SGA, "sga", "Irish, Old (to 900)" }, -- { mp4v2::impl::bmff::ILC_SGN, "sgn", "Sign Languages" }, -- { mp4v2::impl::bmff::ILC_SHN, "shn", "Shan" }, -- { mp4v2::impl::bmff::ILC_SID, "sid", "Sidamo" }, -- { mp4v2::impl::bmff::ILC_SIN, "sin", "Sinhala; Sinhalese" }, -- { mp4v2::impl::bmff::ILC_SIO, "sio", "Siouan languages" }, -- { mp4v2::impl::bmff::ILC_SIT, "sit", "Sino-Tibetan (Other)" }, -- { mp4v2::impl::bmff::ILC_SLA, "sla", "Slavic (Other)" }, -- { mp4v2::impl::bmff::ILC_SLK, "slk", "Slovak" }, -- { mp4v2::impl::bmff::ILC_SLV, "slv", "Slovenian" }, -- { mp4v2::impl::bmff::ILC_SMA, "sma", "Southern Sami" }, -- { mp4v2::impl::bmff::ILC_SME, "sme", "Northern Sami" }, -- { mp4v2::impl::bmff::ILC_SMI, "smi", "Sami languages (Other)" }, -- { mp4v2::impl::bmff::ILC_SMJ, "smj", "Lule Sami" }, -- { mp4v2::impl::bmff::ILC_SMN, "smn", "Inari Sami" }, -- { mp4v2::impl::bmff::ILC_SMO, "smo", "Samoan" }, -- { mp4v2::impl::bmff::ILC_SMS, "sms", "Skolt Sami" }, -- { mp4v2::impl::bmff::ILC_SNA, "sna", "Shona" }, -- { mp4v2::impl::bmff::ILC_SND, "snd", "Sindhi" }, -- { mp4v2::impl::bmff::ILC_SNK, "snk", "Soninke" }, -- { mp4v2::impl::bmff::ILC_SOG, "sog", "Sogdian" }, -- { mp4v2::impl::bmff::ILC_SOM, "som", "Somali" }, -- { mp4v2::impl::bmff::ILC_SON, "son", "Songhai languages" }, -- { mp4v2::impl::bmff::ILC_SOT, "sot", "Sotho, Southern" }, -- { mp4v2::impl::bmff::ILC_SPA, "spa", "Spanish; Castilian" }, -- { mp4v2::impl::bmff::ILC_SRD, "srd", "Sardinian" }, -- { mp4v2::impl::bmff::ILC_SRN, "srn", "Sranan Tongo" }, -- { mp4v2::impl::bmff::ILC_SRP, "srp", "Serbian" }, -- { mp4v2::impl::bmff::ILC_SRR, "srr", "Serer" }, -- { mp4v2::impl::bmff::ILC_SSA, "ssa", "Nilo-Saharan (Other)" }, -- { mp4v2::impl::bmff::ILC_SSW, "ssw", "Swati" }, -- { mp4v2::impl::bmff::ILC_SUK, "suk", "Sukuma" }, -- { mp4v2::impl::bmff::ILC_SUN, "sun", "Sundanese" }, -- { mp4v2::impl::bmff::ILC_SUS, "sus", "Susu" }, -- { mp4v2::impl::bmff::ILC_SUX, "sux", "Sumerian" }, -- { mp4v2::impl::bmff::ILC_SWA, "swa", "Swahili" }, -- { mp4v2::impl::bmff::ILC_SWE, "swe", "Swedish" }, -- { mp4v2::impl::bmff::ILC_SYC, "syc", "Classical Syriac" }, -- { mp4v2::impl::bmff::ILC_SYR, "syr", "Syriac" }, -- { mp4v2::impl::bmff::ILC_TAH, "tah", "Tahitian" }, -- { mp4v2::impl::bmff::ILC_TAI, "tai", "Tai (Other)" }, -- { mp4v2::impl::bmff::ILC_TAM, "tam", "Tamil" }, -- { mp4v2::impl::bmff::ILC_TAT, "tat", "Tatar" }, -- { mp4v2::impl::bmff::ILC_TEL, "tel", "Telugu" }, -- { mp4v2::impl::bmff::ILC_TEM, "tem", "Timne" }, -- { mp4v2::impl::bmff::ILC_TER, "ter", "Tereno" }, -- { mp4v2::impl::bmff::ILC_TET, "tet", "Tetum" }, -- { mp4v2::impl::bmff::ILC_TGK, "tgk", "Tajik" }, -- { mp4v2::impl::bmff::ILC_TGL, "tgl", "Tagalog" }, -- { mp4v2::impl::bmff::ILC_THA, "tha", "Thai" }, -- { mp4v2::impl::bmff::ILC_BOD, "bod", "Tibetan" }, -- { mp4v2::impl::bmff::ILC_TIG, "tig", "Tigre" }, -- { mp4v2::impl::bmff::ILC_TIR, "tir", "Tigrinya" }, -- { mp4v2::impl::bmff::ILC_TIV, "tiv", "Tiv" }, -- { mp4v2::impl::bmff::ILC_TKL, "tkl", "Tokelau" }, -- { mp4v2::impl::bmff::ILC_TLH, "tlh", "Klingon; tlhIngan-Hol" }, -- { mp4v2::impl::bmff::ILC_TLI, "tli", "Tlingit" }, -- { mp4v2::impl::bmff::ILC_TMH, "tmh", "Tamashek" }, -- { mp4v2::impl::bmff::ILC_TOG, "tog", "Tonga (Nyasa)" }, -- { mp4v2::impl::bmff::ILC_TON, "ton", "Tonga (Tonga Islands)" }, -- { mp4v2::impl::bmff::ILC_TPI, "tpi", "Tok Pisin" }, -- { mp4v2::impl::bmff::ILC_TSI, "tsi", "Tsimshian" }, -- { mp4v2::impl::bmff::ILC_TSN, "tsn", "Tswana" }, -- { mp4v2::impl::bmff::ILC_TSO, "tso", "Tsonga" }, -- { mp4v2::impl::bmff::ILC_TUK, "tuk", "Turkmen" }, -- { mp4v2::impl::bmff::ILC_TUM, "tum", "Tumbuka" }, -- { mp4v2::impl::bmff::ILC_TUP, "tup", "Tupi languages" }, -- { mp4v2::impl::bmff::ILC_TUR, "tur", "Turkish" }, -- { mp4v2::impl::bmff::ILC_TUT, "tut", "Altaic (Other)" }, -- { mp4v2::impl::bmff::ILC_TVL, "tvl", "Tuvalu" }, -- { mp4v2::impl::bmff::ILC_TWI, "twi", "Twi" }, -- { mp4v2::impl::bmff::ILC_TYV, "tyv", "Tuvinian" }, -- { mp4v2::impl::bmff::ILC_UDM, "udm", "Udmurt" }, -- { mp4v2::impl::bmff::ILC_UGA, "uga", "Ugaritic" }, -- { mp4v2::impl::bmff::ILC_UIG, "uig", "Uighur; Uyghur" }, -- { mp4v2::impl::bmff::ILC_UKR, "ukr", "Ukrainian" }, -- { mp4v2::impl::bmff::ILC_UMB, "umb", "Umbundu" }, -- { mp4v2::impl::bmff::ILC_UND, "und", "Undetermined" }, -- { mp4v2::impl::bmff::ILC_URD, "urd", "Urdu" }, -- { mp4v2::impl::bmff::ILC_UZB, "uzb", "Uzbek" }, -- { mp4v2::impl::bmff::ILC_VAI, "vai", "Vai" }, -- { mp4v2::impl::bmff::ILC_VEN, "ven", "Venda" }, -- { mp4v2::impl::bmff::ILC_VIE, "vie", "Vietnamese" }, -- { mp4v2::impl::bmff::ILC_VOL, "vol", "Volapük" }, -- { mp4v2::impl::bmff::ILC_VOT, "vot", "Votic" }, -- { mp4v2::impl::bmff::ILC_WAK, "wak", "Wakashan languages" }, -- { mp4v2::impl::bmff::ILC_WAL, "wal", "Walamo" }, -- { mp4v2::impl::bmff::ILC_WAR, "war", "Waray" }, -- { mp4v2::impl::bmff::ILC_WAS, "was", "Washo" }, -- { mp4v2::impl::bmff::ILC_CYM, "cym", "Welsh" }, -- { mp4v2::impl::bmff::ILC_WEN, "wen", "Sorbian languages" }, -- { mp4v2::impl::bmff::ILC_WLN, "wln", "Walloon" }, -- { mp4v2::impl::bmff::ILC_WOL, "wol", "Wolof" }, -- { mp4v2::impl::bmff::ILC_XAL, "xal", "Kalmyk; Oirat" }, -- { mp4v2::impl::bmff::ILC_XHO, "xho", "Xhosa" }, -- { mp4v2::impl::bmff::ILC_YAO, "yao", "Yao" }, -- { mp4v2::impl::bmff::ILC_YAP, "yap", "Yapese" }, -- { mp4v2::impl::bmff::ILC_YID, "yid", "Yiddish" }, -- { mp4v2::impl::bmff::ILC_YOR, "yor", "Yoruba" }, -- { mp4v2::impl::bmff::ILC_YPK, "ypk", "Yupik languages" }, -- { mp4v2::impl::bmff::ILC_ZAP, "zap", "Zapotec" }, -- { mp4v2::impl::bmff::ILC_ZBL, "zbl", "Blissymbols; Blissymbolics; Bliss" }, -- { mp4v2::impl::bmff::ILC_ZEN, "zen", "Zenaga" }, -- { mp4v2::impl::bmff::ILC_ZHA, "zha", "Zhuang; Chuang" }, -- { mp4v2::impl::bmff::ILC_ZND, "znd", "Zande languages" }, -- { mp4v2::impl::bmff::ILC_ZUL, "zul", "Zulu" }, -- { mp4v2::impl::bmff::ILC_ZUN, "zun", "Zuni" }, -- { mp4v2::impl::bmff::ILC_ZXX, "zxx", "No linguistic content; Not applicable" }, -- { mp4v2::impl::bmff::ILC_ZZA, "zza", "Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki" }, -+const bmff::EnumLanguageCode::Entry bmff::EnumLanguageCode::data[] = { -+ { bmff::ILC_AAR, "aar", "Afar" }, -+ { bmff::ILC_ABK, "abk", "Abkhazian" }, -+ { bmff::ILC_ACE, "ace", "Achinese" }, -+ { bmff::ILC_ACH, "ach", "Acoli" }, -+ { bmff::ILC_ADA, "ada", "Adangme" }, -+ { bmff::ILC_ADY, "ady", "Adyghe; Adygei" }, -+ { bmff::ILC_AFA, "afa", "Afro-Asiatic (Other)" }, -+ { bmff::ILC_AFH, "afh", "Afrihili" }, -+ { bmff::ILC_AFR, "afr", "Afrikaans" }, -+ { bmff::ILC_AIN, "ain", "Ainu" }, -+ { bmff::ILC_AKA, "aka", "Akan" }, -+ { bmff::ILC_AKK, "akk", "Akkadian" }, -+ { bmff::ILC_SQI, "sqi", "Albanian" }, -+ { bmff::ILC_ALE, "ale", "Aleut" }, -+ { bmff::ILC_ALG, "alg", "Algonquian languages" }, -+ { bmff::ILC_ALT, "alt", "Southern Altai" }, -+ { bmff::ILC_AMH, "amh", "Amharic" }, -+ { bmff::ILC_ANG, "ang", "English, Old (ca.450-1100)" }, -+ { bmff::ILC_ANP, "anp", "Angika" }, -+ { bmff::ILC_APA, "apa", "Apache languages" }, -+ { bmff::ILC_ARA, "ara", "Arabic" }, -+ { bmff::ILC_ARC, "arc", "Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)" }, -+ { bmff::ILC_ARG, "arg", "Aragonese" }, -+ { bmff::ILC_HYE, "hye", "Armenian" }, -+ { bmff::ILC_ARN, "arn", "Mapudungun; Mapuche" }, -+ { bmff::ILC_ARP, "arp", "Arapaho" }, -+ { bmff::ILC_ART, "art", "Artificial (Other)" }, -+ { bmff::ILC_ARW, "arw", "Arawak" }, -+ { bmff::ILC_ASM, "asm", "Assamese" }, -+ { bmff::ILC_AST, "ast", "Asturian; Bable; Leonese; Asturleonese" }, -+ { bmff::ILC_ATH, "ath", "Athapascan languages" }, -+ { bmff::ILC_AUS, "aus", "Australian languages" }, -+ { bmff::ILC_AVA, "ava", "Avaric" }, -+ { bmff::ILC_AVE, "ave", "Avestan" }, -+ { bmff::ILC_AWA, "awa", "Awadhi" }, -+ { bmff::ILC_AYM, "aym", "Aymara" }, -+ { bmff::ILC_AZE, "aze", "Azerbaijani" }, -+ { bmff::ILC_BAD, "bad", "Banda languages" }, -+ { bmff::ILC_BAI, "bai", "Bamileke languages" }, -+ { bmff::ILC_BAK, "bak", "Bashkir" }, -+ { bmff::ILC_BAL, "bal", "Baluchi" }, -+ { bmff::ILC_BAM, "bam", "Bambara" }, -+ { bmff::ILC_BAN, "ban", "Balinese" }, -+ { bmff::ILC_EUS, "eus", "Basque" }, -+ { bmff::ILC_BAS, "bas", "Basa" }, -+ { bmff::ILC_BAT, "bat", "Baltic (Other)" }, -+ { bmff::ILC_BEJ, "bej", "Beja; Bedawiyet" }, -+ { bmff::ILC_BEL, "bel", "Belarusian" }, -+ { bmff::ILC_BEM, "bem", "Bemba" }, -+ { bmff::ILC_BEN, "ben", "Bengali" }, -+ { bmff::ILC_BER, "ber", "Berber (Other)" }, -+ { bmff::ILC_BHO, "bho", "Bhojpuri" }, -+ { bmff::ILC_BIH, "bih", "Bihari" }, -+ { bmff::ILC_BIK, "bik", "Bikol" }, -+ { bmff::ILC_BIN, "bin", "Bini; Edo" }, -+ { bmff::ILC_BIS, "bis", "Bislama" }, -+ { bmff::ILC_BLA, "bla", "Siksika" }, -+ { bmff::ILC_BNT, "bnt", "Bantu (Other)" }, -+ { bmff::ILC_BOS, "bos", "Bosnian" }, -+ { bmff::ILC_BRA, "bra", "Braj" }, -+ { bmff::ILC_BRE, "bre", "Breton" }, -+ { bmff::ILC_BTK, "btk", "Batak languages" }, -+ { bmff::ILC_BUA, "bua", "Buriat" }, -+ { bmff::ILC_BUG, "bug", "Buginese" }, -+ { bmff::ILC_BUL, "bul", "Bulgarian" }, -+ { bmff::ILC_MYA, "mya", "Burmese" }, -+ { bmff::ILC_BYN, "byn", "Blin; Bilin" }, -+ { bmff::ILC_CAD, "cad", "Caddo" }, -+ { bmff::ILC_CAI, "cai", "Central American Indian (Other)" }, -+ { bmff::ILC_CAR, "car", "Galibi Carib" }, -+ { bmff::ILC_CAT, "cat", "Catalan; Valencian" }, -+ { bmff::ILC_CAU, "cau", "Caucasian (Other)" }, -+ { bmff::ILC_CEB, "ceb", "Cebuano" }, -+ { bmff::ILC_CEL, "cel", "Celtic (Other)" }, -+ { bmff::ILC_CHA, "cha", "Chamorro" }, -+ { bmff::ILC_CHB, "chb", "Chibcha" }, -+ { bmff::ILC_CHE, "che", "Chechen" }, -+ { bmff::ILC_CHG, "chg", "Chagatai" }, -+ { bmff::ILC_ZHO, "zho", "Chinese" }, -+ { bmff::ILC_CHK, "chk", "Chuukese" }, -+ { bmff::ILC_CHM, "chm", "Mari" }, -+ { bmff::ILC_CHN, "chn", "Chinook jargon" }, -+ { bmff::ILC_CHO, "cho", "Choctaw" }, -+ { bmff::ILC_CHP, "chp", "Chipewyan; Dene Suline" }, -+ { bmff::ILC_CHR, "chr", "Cherokee" }, -+ { bmff::ILC_CHU, "chu", "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic" }, -+ { bmff::ILC_CHV, "chv", "Chuvash" }, -+ { bmff::ILC_CHY, "chy", "Cheyenne" }, -+ { bmff::ILC_CMC, "cmc", "Chamic languages" }, -+ { bmff::ILC_COP, "cop", "Coptic" }, -+ { bmff::ILC_COR, "cor", "Cornish" }, -+ { bmff::ILC_COS, "cos", "Corsican" }, -+ { bmff::ILC_CPE, "cpe", "Creoles and pidgins, English based (Other)" }, -+ { bmff::ILC_CPF, "cpf", "Creoles and pidgins, French-based (Other)" }, -+ { bmff::ILC_CPP, "cpp", "Creoles and pidgins, Portuguese-based (Other)" }, -+ { bmff::ILC_CRE, "cre", "Cree" }, -+ { bmff::ILC_CRH, "crh", "Crimean Tatar; Crimean Turkish" }, -+ { bmff::ILC_CRP, "crp", "Creoles and pidgins (Other)" }, -+ { bmff::ILC_CSB, "csb", "Kashubian" }, -+ { bmff::ILC_CUS, "cus", "Cushitic (Other)" }, -+ { bmff::ILC_CES, "ces", "Czech" }, -+ { bmff::ILC_DAK, "dak", "Dakota" }, -+ { bmff::ILC_DAN, "dan", "Danish" }, -+ { bmff::ILC_DAR, "dar", "Dargwa" }, -+ { bmff::ILC_DAY, "day", "Land Dayak languages" }, -+ { bmff::ILC_DEL, "del", "Delaware" }, -+ { bmff::ILC_DEN, "den", "Slave (Athapascan)" }, -+ { bmff::ILC_DGR, "dgr", "Dogrib" }, -+ { bmff::ILC_DIN, "din", "Dinka" }, -+ { bmff::ILC_DIV, "div", "Divehi; Dhivehi; Maldivian" }, -+ { bmff::ILC_DOI, "doi", "Dogri" }, -+ { bmff::ILC_DRA, "dra", "Dravidian (Other)" }, -+ { bmff::ILC_DSB, "dsb", "Lower Sorbian" }, -+ { bmff::ILC_DUA, "dua", "Duala" }, -+ { bmff::ILC_DUM, "dum", "Dutch, Middle (ca.1050-1350)" }, -+ { bmff::ILC_NLD, "nld", "Dutch; Flemish" }, -+ { bmff::ILC_DYU, "dyu", "Dyula" }, -+ { bmff::ILC_DZO, "dzo", "Dzongkha" }, -+ { bmff::ILC_EFI, "efi", "Efik" }, -+ { bmff::ILC_EGY, "egy", "Egyptian (Ancient)" }, -+ { bmff::ILC_EKA, "eka", "Ekajuk" }, -+ { bmff::ILC_ELX, "elx", "Elamite" }, -+ { bmff::ILC_ENG, "eng", "English" }, -+ { bmff::ILC_ENM, "enm", "English, Middle (1100-1500)" }, -+ { bmff::ILC_EPO, "epo", "Esperanto" }, -+ { bmff::ILC_EST, "est", "Estonian" }, -+ { bmff::ILC_EWE, "ewe", "Ewe" }, -+ { bmff::ILC_EWO, "ewo", "Ewondo" }, -+ { bmff::ILC_FAN, "fan", "Fang" }, -+ { bmff::ILC_FAO, "fao", "Faroese" }, -+ { bmff::ILC_FAT, "fat", "Fanti" }, -+ { bmff::ILC_FIJ, "fij", "Fijian" }, -+ { bmff::ILC_FIL, "fil", "Filipino; Pilipino" }, -+ { bmff::ILC_FIN, "fin", "Finnish" }, -+ { bmff::ILC_FIU, "fiu", "Finno-Ugrian (Other)" }, -+ { bmff::ILC_FON, "fon", "Fon" }, -+ { bmff::ILC_FRA, "fra", "French" }, -+ { bmff::ILC_FRM, "frm", "French, Middle (ca.1400-1600)" }, -+ { bmff::ILC_FRO, "fro", "French, Old (842-ca.1400)" }, -+ { bmff::ILC_FRR, "frr", "Northern Frisian" }, -+ { bmff::ILC_FRS, "frs", "Eastern Frisian" }, -+ { bmff::ILC_FRY, "fry", "Western Frisian" }, -+ { bmff::ILC_FUL, "ful", "Fulah" }, -+ { bmff::ILC_FUR, "fur", "Friulian" }, -+ { bmff::ILC_GAA, "gaa", "Ga" }, -+ { bmff::ILC_GAY, "gay", "Gayo" }, -+ { bmff::ILC_GBA, "gba", "Gbaya" }, -+ { bmff::ILC_GEM, "gem", "Germanic (Other)" }, -+ { bmff::ILC_KAT, "kat", "Georgian" }, -+ { bmff::ILC_DEU, "deu", "German" }, -+ { bmff::ILC_GEZ, "gez", "Geez" }, -+ { bmff::ILC_GIL, "gil", "Gilbertese" }, -+ { bmff::ILC_GLA, "gla", "Gaelic; Scottish Gaelic" }, -+ { bmff::ILC_GLE, "gle", "Irish" }, -+ { bmff::ILC_GLG, "glg", "Galician" }, -+ { bmff::ILC_GLV, "glv", "Manx" }, -+ { bmff::ILC_GMH, "gmh", "German, Middle High (ca.1050-1500)" }, -+ { bmff::ILC_GOH, "goh", "German, Old High (ca.750-1050)" }, -+ { bmff::ILC_GON, "gon", "Gondi" }, -+ { bmff::ILC_GOR, "gor", "Gorontalo" }, -+ { bmff::ILC_GOT, "got", "Gothic" }, -+ { bmff::ILC_GRB, "grb", "Grebo" }, -+ { bmff::ILC_GRC, "grc", "Greek, Ancient (to 1453)" }, -+ { bmff::ILC_ELL, "ell", "Greek, Modern (1453-)" }, -+ { bmff::ILC_GRN, "grn", "Guarani" }, -+ { bmff::ILC_GSW, "gsw", "Swiss German; Alemannic; Alsatian" }, -+ { bmff::ILC_GUJ, "guj", "Gujarati" }, -+ { bmff::ILC_GWI, "gwi", "Gwich'in" }, -+ { bmff::ILC_HAI, "hai", "Haida" }, -+ { bmff::ILC_HAT, "hat", "Haitian; Haitian Creole" }, -+ { bmff::ILC_HAU, "hau", "Hausa" }, -+ { bmff::ILC_HAW, "haw", "Hawaiian" }, -+ { bmff::ILC_HEB, "heb", "Hebrew" }, -+ { bmff::ILC_HER, "her", "Herero" }, -+ { bmff::ILC_HIL, "hil", "Hiligaynon" }, -+ { bmff::ILC_HIM, "him", "Himachali" }, -+ { bmff::ILC_HIN, "hin", "Hindi" }, -+ { bmff::ILC_HIT, "hit", "Hittite" }, -+ { bmff::ILC_HMN, "hmn", "Hmong" }, -+ { bmff::ILC_HMO, "hmo", "Hiri Motu" }, -+ { bmff::ILC_HRV, "hrv", "Croatian" }, -+ { bmff::ILC_HSB, "hsb", "Upper Sorbian" }, -+ { bmff::ILC_HUN, "hun", "Hungarian" }, -+ { bmff::ILC_HUP, "hup", "Hupa" }, -+ { bmff::ILC_IBA, "iba", "Iban" }, -+ { bmff::ILC_IBO, "ibo", "Igbo" }, -+ { bmff::ILC_ISL, "isl", "Icelandic" }, -+ { bmff::ILC_IDO, "ido", "Ido" }, -+ { bmff::ILC_III, "iii", "Sichuan Yi; Nuosu" }, -+ { bmff::ILC_IJO, "ijo", "Ijo languages" }, -+ { bmff::ILC_IKU, "iku", "Inuktitut" }, -+ { bmff::ILC_ILE, "ile", "Interlingue; Occidental" }, -+ { bmff::ILC_ILO, "ilo", "Iloko" }, -+ { bmff::ILC_INA, "ina", "Interlingua (International Auxiliary Language Association)" }, -+ { bmff::ILC_INC, "inc", "Indic (Other)" }, -+ { bmff::ILC_IND, "ind", "Indonesian" }, -+ { bmff::ILC_INE, "ine", "Indo-European (Other)" }, -+ { bmff::ILC_INH, "inh", "Ingush" }, -+ { bmff::ILC_IPK, "ipk", "Inupiaq" }, -+ { bmff::ILC_IRA, "ira", "Iranian (Other)" }, -+ { bmff::ILC_IRO, "iro", "Iroquoian languages" }, -+ { bmff::ILC_ITA, "ita", "Italian" }, -+ { bmff::ILC_JAV, "jav", "Javanese" }, -+ { bmff::ILC_JBO, "jbo", "Lojban" }, -+ { bmff::ILC_JPN, "jpn", "Japanese" }, -+ { bmff::ILC_JPR, "jpr", "Judeo-Persian" }, -+ { bmff::ILC_JRB, "jrb", "Judeo-Arabic" }, -+ { bmff::ILC_KAA, "kaa", "Kara-Kalpak" }, -+ { bmff::ILC_KAB, "kab", "Kabyle" }, -+ { bmff::ILC_KAC, "kac", "Kachin; Jingpho" }, -+ { bmff::ILC_KAL, "kal", "Kalaallisut; Greenlandic" }, -+ { bmff::ILC_KAM, "kam", "Kamba" }, -+ { bmff::ILC_KAN, "kan", "Kannada" }, -+ { bmff::ILC_KAR, "kar", "Karen languages" }, -+ { bmff::ILC_KAS, "kas", "Kashmiri" }, -+ { bmff::ILC_KAU, "kau", "Kanuri" }, -+ { bmff::ILC_KAW, "kaw", "Kawi" }, -+ { bmff::ILC_KAZ, "kaz", "Kazakh" }, -+ { bmff::ILC_KBD, "kbd", "Kabardian" }, -+ { bmff::ILC_KHA, "kha", "Khasi" }, -+ { bmff::ILC_KHI, "khi", "Khoisan (Other)" }, -+ { bmff::ILC_KHM, "khm", "Central Khmer" }, -+ { bmff::ILC_KHO, "kho", "Khotanese; Sakan" }, -+ { bmff::ILC_KIK, "kik", "Kikuyu; Gikuyu" }, -+ { bmff::ILC_KIN, "kin", "Kinyarwanda" }, -+ { bmff::ILC_KIR, "kir", "Kirghiz; Kyrgyz" }, -+ { bmff::ILC_KMB, "kmb", "Kimbundu" }, -+ { bmff::ILC_KOK, "kok", "Konkani" }, -+ { bmff::ILC_KOM, "kom", "Komi" }, -+ { bmff::ILC_KON, "kon", "Kongo" }, -+ { bmff::ILC_KOR, "kor", "Korean" }, -+ { bmff::ILC_KOS, "kos", "Kosraean" }, -+ { bmff::ILC_KPE, "kpe", "Kpelle" }, -+ { bmff::ILC_KRC, "krc", "Karachay-Balkar" }, -+ { bmff::ILC_KRL, "krl", "Karelian" }, -+ { bmff::ILC_KRO, "kro", "Kru languages" }, -+ { bmff::ILC_KRU, "kru", "Kurukh" }, -+ { bmff::ILC_KUA, "kua", "Kuanyama; Kwanyama" }, -+ { bmff::ILC_KUM, "kum", "Kumyk" }, -+ { bmff::ILC_KUR, "kur", "Kurdish" }, -+ { bmff::ILC_KUT, "kut", "Kutenai" }, -+ { bmff::ILC_LAD, "lad", "Ladino" }, -+ { bmff::ILC_LAH, "lah", "Lahnda" }, -+ { bmff::ILC_LAM, "lam", "Lamba" }, -+ { bmff::ILC_LAO, "lao", "Lao" }, -+ { bmff::ILC_LAT, "lat", "Latin" }, -+ { bmff::ILC_LAV, "lav", "Latvian" }, -+ { bmff::ILC_LEZ, "lez", "Lezghian" }, -+ { bmff::ILC_LIM, "lim", "Limburgan; Limburger; Limburgish" }, -+ { bmff::ILC_LIN, "lin", "Lingala" }, -+ { bmff::ILC_LIT, "lit", "Lithuanian" }, -+ { bmff::ILC_LOL, "lol", "Mongo" }, -+ { bmff::ILC_LOZ, "loz", "Lozi" }, -+ { bmff::ILC_LTZ, "ltz", "Luxembourgish; Letzeburgesch" }, -+ { bmff::ILC_LUA, "lua", "Luba-Lulua" }, -+ { bmff::ILC_LUB, "lub", "Luba-Katanga" }, -+ { bmff::ILC_LUG, "lug", "Ganda" }, -+ { bmff::ILC_LUI, "lui", "Luiseno" }, -+ { bmff::ILC_LUN, "lun", "Lunda" }, -+ { bmff::ILC_LUO, "luo", "Luo (Kenya and Tanzania)" }, -+ { bmff::ILC_LUS, "lus", "Lushai" }, -+ { bmff::ILC_MKD, "mkd", "Macedonian" }, -+ { bmff::ILC_MAD, "mad", "Madurese" }, -+ { bmff::ILC_MAG, "mag", "Magahi" }, -+ { bmff::ILC_MAH, "mah", "Marshallese" }, -+ { bmff::ILC_MAI, "mai", "Maithili" }, -+ { bmff::ILC_MAK, "mak", "Makasar" }, -+ { bmff::ILC_MAL, "mal", "Malayalam" }, -+ { bmff::ILC_MAN, "man", "Mandingo" }, -+ { bmff::ILC_MRI, "mri", "Maori" }, -+ { bmff::ILC_MAP, "map", "Austronesian (Other)" }, -+ { bmff::ILC_MAR, "mar", "Marathi" }, -+ { bmff::ILC_MAS, "mas", "Masai" }, -+ { bmff::ILC_MSA, "msa", "Malay" }, -+ { bmff::ILC_MDF, "mdf", "Moksha" }, -+ { bmff::ILC_MDR, "mdr", "Mandar" }, -+ { bmff::ILC_MEN, "men", "Mende" }, -+ { bmff::ILC_MGA, "mga", "Irish, Middle (900-1200)" }, -+ { bmff::ILC_MIC, "mic", "Mi'kmaq; Micmac" }, -+ { bmff::ILC_MIN, "min", "Minangkabau" }, -+ { bmff::ILC_MIS, "mis", "Uncoded languages" }, -+ { bmff::ILC_MKH, "mkh", "Mon-Khmer (Other)" }, -+ { bmff::ILC_MLG, "mlg", "Malagasy" }, -+ { bmff::ILC_MLT, "mlt", "Maltese" }, -+ { bmff::ILC_MNC, "mnc", "Manchu" }, -+ { bmff::ILC_MNI, "mni", "Manipuri" }, -+ { bmff::ILC_MNO, "mno", "Manobo languages" }, -+ { bmff::ILC_MOH, "moh", "Mohawk" }, -+ { bmff::ILC_MON, "mon", "Mongolian" }, -+ { bmff::ILC_MOS, "mos", "Mossi" }, -+ { bmff::ILC_MUL, "mul", "Multiple languages" }, -+ { bmff::ILC_MUN, "mun", "Munda languages" }, -+ { bmff::ILC_MUS, "mus", "Creek" }, -+ { bmff::ILC_MWL, "mwl", "Mirandese" }, -+ { bmff::ILC_MWR, "mwr", "Marwari" }, -+ { bmff::ILC_MYN, "myn", "Mayan languages" }, -+ { bmff::ILC_MYV, "myv", "Erzya" }, -+ { bmff::ILC_NAH, "nah", "Nahuatl languages" }, -+ { bmff::ILC_NAI, "nai", "North American Indian" }, -+ { bmff::ILC_NAP, "nap", "Neapolitan" }, -+ { bmff::ILC_NAU, "nau", "Nauru" }, -+ { bmff::ILC_NAV, "nav", "Navajo; Navaho" }, -+ { bmff::ILC_NBL, "nbl", "Ndebele, South; South Ndebele" }, -+ { bmff::ILC_NDE, "nde", "Ndebele, North; North Ndebele" }, -+ { bmff::ILC_NDO, "ndo", "Ndonga" }, -+ { bmff::ILC_NDS, "nds", "Low German; Low Saxon; German, Low; Saxon, Low" }, -+ { bmff::ILC_NEP, "nep", "Nepali" }, -+ { bmff::ILC_NEW, "new", "Nepal Bhasa; Newari" }, -+ { bmff::ILC_NIA, "nia", "Nias" }, -+ { bmff::ILC_NIC, "nic", "Niger-Kordofanian (Other)" }, -+ { bmff::ILC_NIU, "niu", "Niuean" }, -+ { bmff::ILC_NNO, "nno", "Norwegian Nynorsk; Nynorsk, Norwegian" }, -+ { bmff::ILC_NOB, "nob", "Bokmål, Norwegian; Norwegian Bokmål" }, -+ { bmff::ILC_NOG, "nog", "Nogai" }, -+ { bmff::ILC_NON, "non", "Norse, Old" }, -+ { bmff::ILC_NOR, "nor", "Norwegian" }, -+ { bmff::ILC_NQO, "nqo", "N'Ko" }, -+ { bmff::ILC_NSO, "nso", "Pedi; Sepedi; Northern Sotho" }, -+ { bmff::ILC_NUB, "nub", "Nubian languages" }, -+ { bmff::ILC_NWC, "nwc", "Classical Newari; Old Newari; Classical Nepal Bhasa" }, -+ { bmff::ILC_NYA, "nya", "Chichewa; Chewa; Nyanja" }, -+ { bmff::ILC_NYM, "nym", "Nyamwezi" }, -+ { bmff::ILC_NYN, "nyn", "Nyankole" }, -+ { bmff::ILC_NYO, "nyo", "Nyoro" }, -+ { bmff::ILC_NZI, "nzi", "Nzima" }, -+ { bmff::ILC_OCI, "oci", "Occitan (post 1500); Provençal" }, -+ { bmff::ILC_OJI, "oji", "Ojibwa" }, -+ { bmff::ILC_ORI, "ori", "Oriya" }, -+ { bmff::ILC_ORM, "orm", "Oromo" }, -+ { bmff::ILC_OSA, "osa", "Osage" }, -+ { bmff::ILC_OSS, "oss", "Ossetian; Ossetic" }, -+ { bmff::ILC_OTA, "ota", "Turkish, Ottoman (1500-1928)" }, -+ { bmff::ILC_OTO, "oto", "Otomian languages" }, -+ { bmff::ILC_PAA, "paa", "Papuan (Other)" }, -+ { bmff::ILC_PAG, "pag", "Pangasinan" }, -+ { bmff::ILC_PAL, "pal", "Pahlavi" }, -+ { bmff::ILC_PAM, "pam", "Pampanga; Kapampangan" }, -+ { bmff::ILC_PAN, "pan", "Panjabi; Punjabi" }, -+ { bmff::ILC_PAP, "pap", "Papiamento" }, -+ { bmff::ILC_PAU, "pau", "Palauan" }, -+ { bmff::ILC_PEO, "peo", "Persian, Old (ca.600-400 B.C.)" }, -+ { bmff::ILC_FAS, "fas", "Persian" }, -+ { bmff::ILC_PHI, "phi", "Philippine (Other)" }, -+ { bmff::ILC_PHN, "phn", "Phoenician" }, -+ { bmff::ILC_PLI, "pli", "Pali" }, -+ { bmff::ILC_POL, "pol", "Polish" }, -+ { bmff::ILC_PON, "pon", "Pohnpeian" }, -+ { bmff::ILC_POR, "por", "Portuguese" }, -+ { bmff::ILC_PRA, "pra", "Prakrit languages" }, -+ { bmff::ILC_PRO, "pro", "Provençal, Old (to 1500)" }, -+ { bmff::ILC_PUS, "pus", "Pushto; Pashto" }, -+ { bmff::ILC_QUE, "que", "Quechua" }, -+ { bmff::ILC_RAJ, "raj", "Rajasthani" }, -+ { bmff::ILC_RAP, "rap", "Rapanui" }, -+ { bmff::ILC_RAR, "rar", "Rarotongan; Cook Islands Maori" }, -+ { bmff::ILC_ROA, "roa", "Romance (Other)" }, -+ { bmff::ILC_ROH, "roh", "Romansh" }, -+ { bmff::ILC_ROM, "rom", "Romany" }, -+ { bmff::ILC_RON, "ron", "Romanian; Moldavian; Moldovan" }, -+ { bmff::ILC_RUN, "run", "Rundi" }, -+ { bmff::ILC_RUP, "rup", "Aromanian; Arumanian; Macedo-Romanian" }, -+ { bmff::ILC_RUS, "rus", "Russian" }, -+ { bmff::ILC_SAD, "sad", "Sandawe" }, -+ { bmff::ILC_SAG, "sag", "Sango" }, -+ { bmff::ILC_SAH, "sah", "Yakut" }, -+ { bmff::ILC_SAI, "sai", "South American Indian (Other)" }, -+ { bmff::ILC_SAL, "sal", "Salishan languages" }, -+ { bmff::ILC_SAM, "sam", "Samaritan Aramaic" }, -+ { bmff::ILC_SAN, "san", "Sanskrit" }, -+ { bmff::ILC_SAS, "sas", "Sasak" }, -+ { bmff::ILC_SAT, "sat", "Santali" }, -+ { bmff::ILC_SCN, "scn", "Sicilian" }, -+ { bmff::ILC_SCO, "sco", "Scots" }, -+ { bmff::ILC_SEL, "sel", "Selkup" }, -+ { bmff::ILC_SEM, "sem", "Semitic (Other)" }, -+ { bmff::ILC_SGA, "sga", "Irish, Old (to 900)" }, -+ { bmff::ILC_SGN, "sgn", "Sign Languages" }, -+ { bmff::ILC_SHN, "shn", "Shan" }, -+ { bmff::ILC_SID, "sid", "Sidamo" }, -+ { bmff::ILC_SIN, "sin", "Sinhala; Sinhalese" }, -+ { bmff::ILC_SIO, "sio", "Siouan languages" }, -+ { bmff::ILC_SIT, "sit", "Sino-Tibetan (Other)" }, -+ { bmff::ILC_SLA, "sla", "Slavic (Other)" }, -+ { bmff::ILC_SLK, "slk", "Slovak" }, -+ { bmff::ILC_SLV, "slv", "Slovenian" }, -+ { bmff::ILC_SMA, "sma", "Southern Sami" }, -+ { bmff::ILC_SME, "sme", "Northern Sami" }, -+ { bmff::ILC_SMI, "smi", "Sami languages (Other)" }, -+ { bmff::ILC_SMJ, "smj", "Lule Sami" }, -+ { bmff::ILC_SMN, "smn", "Inari Sami" }, -+ { bmff::ILC_SMO, "smo", "Samoan" }, -+ { bmff::ILC_SMS, "sms", "Skolt Sami" }, -+ { bmff::ILC_SNA, "sna", "Shona" }, -+ { bmff::ILC_SND, "snd", "Sindhi" }, -+ { bmff::ILC_SNK, "snk", "Soninke" }, -+ { bmff::ILC_SOG, "sog", "Sogdian" }, -+ { bmff::ILC_SOM, "som", "Somali" }, -+ { bmff::ILC_SON, "son", "Songhai languages" }, -+ { bmff::ILC_SOT, "sot", "Sotho, Southern" }, -+ { bmff::ILC_SPA, "spa", "Spanish; Castilian" }, -+ { bmff::ILC_SRD, "srd", "Sardinian" }, -+ { bmff::ILC_SRN, "srn", "Sranan Tongo" }, -+ { bmff::ILC_SRP, "srp", "Serbian" }, -+ { bmff::ILC_SRR, "srr", "Serer" }, -+ { bmff::ILC_SSA, "ssa", "Nilo-Saharan (Other)" }, -+ { bmff::ILC_SSW, "ssw", "Swati" }, -+ { bmff::ILC_SUK, "suk", "Sukuma" }, -+ { bmff::ILC_SUN, "sun", "Sundanese" }, -+ { bmff::ILC_SUS, "sus", "Susu" }, -+ { bmff::ILC_SUX, "sux", "Sumerian" }, -+ { bmff::ILC_SWA, "swa", "Swahili" }, -+ { bmff::ILC_SWE, "swe", "Swedish" }, -+ { bmff::ILC_SYC, "syc", "Classical Syriac" }, -+ { bmff::ILC_SYR, "syr", "Syriac" }, -+ { bmff::ILC_TAH, "tah", "Tahitian" }, -+ { bmff::ILC_TAI, "tai", "Tai (Other)" }, -+ { bmff::ILC_TAM, "tam", "Tamil" }, -+ { bmff::ILC_TAT, "tat", "Tatar" }, -+ { bmff::ILC_TEL, "tel", "Telugu" }, -+ { bmff::ILC_TEM, "tem", "Timne" }, -+ { bmff::ILC_TER, "ter", "Tereno" }, -+ { bmff::ILC_TET, "tet", "Tetum" }, -+ { bmff::ILC_TGK, "tgk", "Tajik" }, -+ { bmff::ILC_TGL, "tgl", "Tagalog" }, -+ { bmff::ILC_THA, "tha", "Thai" }, -+ { bmff::ILC_BOD, "bod", "Tibetan" }, -+ { bmff::ILC_TIG, "tig", "Tigre" }, -+ { bmff::ILC_TIR, "tir", "Tigrinya" }, -+ { bmff::ILC_TIV, "tiv", "Tiv" }, -+ { bmff::ILC_TKL, "tkl", "Tokelau" }, -+ { bmff::ILC_TLH, "tlh", "Klingon; tlhIngan-Hol" }, -+ { bmff::ILC_TLI, "tli", "Tlingit" }, -+ { bmff::ILC_TMH, "tmh", "Tamashek" }, -+ { bmff::ILC_TOG, "tog", "Tonga (Nyasa)" }, -+ { bmff::ILC_TON, "ton", "Tonga (Tonga Islands)" }, -+ { bmff::ILC_TPI, "tpi", "Tok Pisin" }, -+ { bmff::ILC_TSI, "tsi", "Tsimshian" }, -+ { bmff::ILC_TSN, "tsn", "Tswana" }, -+ { bmff::ILC_TSO, "tso", "Tsonga" }, -+ { bmff::ILC_TUK, "tuk", "Turkmen" }, -+ { bmff::ILC_TUM, "tum", "Tumbuka" }, -+ { bmff::ILC_TUP, "tup", "Tupi languages" }, -+ { bmff::ILC_TUR, "tur", "Turkish" }, -+ { bmff::ILC_TUT, "tut", "Altaic (Other)" }, -+ { bmff::ILC_TVL, "tvl", "Tuvalu" }, -+ { bmff::ILC_TWI, "twi", "Twi" }, -+ { bmff::ILC_TYV, "tyv", "Tuvinian" }, -+ { bmff::ILC_UDM, "udm", "Udmurt" }, -+ { bmff::ILC_UGA, "uga", "Ugaritic" }, -+ { bmff::ILC_UIG, "uig", "Uighur; Uyghur" }, -+ { bmff::ILC_UKR, "ukr", "Ukrainian" }, -+ { bmff::ILC_UMB, "umb", "Umbundu" }, -+ { bmff::ILC_UND, "und", "Undetermined" }, -+ { bmff::ILC_URD, "urd", "Urdu" }, -+ { bmff::ILC_UZB, "uzb", "Uzbek" }, -+ { bmff::ILC_VAI, "vai", "Vai" }, -+ { bmff::ILC_VEN, "ven", "Venda" }, -+ { bmff::ILC_VIE, "vie", "Vietnamese" }, -+ { bmff::ILC_VOL, "vol", "Volapük" }, -+ { bmff::ILC_VOT, "vot", "Votic" }, -+ { bmff::ILC_WAK, "wak", "Wakashan languages" }, -+ { bmff::ILC_WAL, "wal", "Walamo" }, -+ { bmff::ILC_WAR, "war", "Waray" }, -+ { bmff::ILC_WAS, "was", "Washo" }, -+ { bmff::ILC_CYM, "cym", "Welsh" }, -+ { bmff::ILC_WEN, "wen", "Sorbian languages" }, -+ { bmff::ILC_WLN, "wln", "Walloon" }, -+ { bmff::ILC_WOL, "wol", "Wolof" }, -+ { bmff::ILC_XAL, "xal", "Kalmyk; Oirat" }, -+ { bmff::ILC_XHO, "xho", "Xhosa" }, -+ { bmff::ILC_YAO, "yao", "Yao" }, -+ { bmff::ILC_YAP, "yap", "Yapese" }, -+ { bmff::ILC_YID, "yid", "Yiddish" }, -+ { bmff::ILC_YOR, "yor", "Yoruba" }, -+ { bmff::ILC_YPK, "ypk", "Yupik languages" }, -+ { bmff::ILC_ZAP, "zap", "Zapotec" }, -+ { bmff::ILC_ZBL, "zbl", "Blissymbols; Blissymbolics; Bliss" }, -+ { bmff::ILC_ZEN, "zen", "Zenaga" }, -+ { bmff::ILC_ZHA, "zha", "Zhuang; Chuang" }, -+ { bmff::ILC_ZND, "znd", "Zande languages" }, -+ { bmff::ILC_ZUL, "zul", "Zulu" }, -+ { bmff::ILC_ZUN, "zun", "Zuni" }, -+ { bmff::ILC_ZXX, "zxx", "No linguistic content; Not applicable" }, -+ { bmff::ILC_ZZA, "zza", "Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki" }, - -- { mp4v2::impl::bmff::ILC_UNDEFINED } // must be last -+ { bmff::ILC_UNDEFINED } // must be last - }; - - /////////////////////////////////////////////////////////////////////////////// - --#if defined( _MSC_VER ) --namespace mp4v2 { namespace impl { namespace bmff { --#endif -+namespace bmff { -+ // must come after static data init -+ const EnumLanguageCode enumLanguageCode; -+} - - /////////////////////////////////////////////////////////////////////////////// - --// must come after static data init --const EnumLanguageCode enumLanguageCode; -- --/////////////////////////////////////////////////////////////////////////////// -- --}}} // namespace mp4v2::impl::bmff -+}} // namespace mp4v2::impl -diff --git mp4v2-trunk-r355/src/itmf/type.cpp mp4v2-trunk-r355/src/itmf/type.cpp -index da76720..85391c5 100644 ---- mp4v2-trunk-r355/src/itmf/type.cpp -+++ mp4v2-trunk-r355/src/itmf/type.cpp -@@ -24,251 +24,242 @@ - - #include "impl.h" - --// VStudio idiocy prevents defining template instanced static data --// in a namespace. Workaround it by defining in global scope. --// Other platforms will continue to put things in the proper namespace. --#if defined( _MSC_VER ) --using namespace mp4v2::impl::itmf; --#else --namespace mp4v2 { namespace impl { namespace itmf { --#endif -+namespace mp4v2 { namespace impl { - - /////////////////////////////////////////////////////////////////////////////// - - template <> --const EnumBasicType::Entry EnumBasicType::data[] = { -- { mp4v2::impl::itmf::BT_IMPLICIT, "implicit", "implicit" }, -- { mp4v2::impl::itmf::BT_UTF8, "utf8", "UTF-8" }, -- { mp4v2::impl::itmf::BT_UTF16, "utf16", "UTF-16" }, -- { mp4v2::impl::itmf::BT_SJIS, "sjis", "S/JIS" }, -- { mp4v2::impl::itmf::BT_HTML, "html", "HTML" }, -- { mp4v2::impl::itmf::BT_XML, "xml", "XML" }, -- { mp4v2::impl::itmf::BT_UUID, "uuid", "UUID" }, -- { mp4v2::impl::itmf::BT_ISRC, "isrc", "ISRC" }, -- { mp4v2::impl::itmf::BT_MI3P, "mi3p", "MI3P" }, -- { mp4v2::impl::itmf::BT_GIF, "gif", "GIF" }, -- { mp4v2::impl::itmf::BT_JPEG, "jpeg", "JPEG" }, -- { mp4v2::impl::itmf::BT_PNG, "png", "PNG" }, -- { mp4v2::impl::itmf::BT_URL, "url", "URL" }, -- { mp4v2::impl::itmf::BT_DURATION, "duration", "duration" }, -- { mp4v2::impl::itmf::BT_DATETIME, "datetime", "date/time" }, -- { mp4v2::impl::itmf::BT_GENRES, "genres", "genres" }, -- { mp4v2::impl::itmf::BT_INTEGER, "integer", "integer" }, -- { mp4v2::impl::itmf::BT_RIAA_PA, "riaapa", "RIAA-PA" }, -- { mp4v2::impl::itmf::BT_UPC, "upc", "UPC" }, -- { mp4v2::impl::itmf::BT_BMP, "bmp", "BMP" }, -- -- { mp4v2::impl::itmf::BT_UNDEFINED } // must be last -+const itmf::EnumBasicType::Entry itmf::EnumBasicType::data[] = { -+ { itmf::BT_IMPLICIT, "implicit", "implicit" }, -+ { itmf::BT_UTF8, "utf8", "UTF-8" }, -+ { itmf::BT_UTF16, "utf16", "UTF-16" }, -+ { itmf::BT_SJIS, "sjis", "S/JIS" }, -+ { itmf::BT_HTML, "html", "HTML" }, -+ { itmf::BT_XML, "xml", "XML" }, -+ { itmf::BT_UUID, "uuid", "UUID" }, -+ { itmf::BT_ISRC, "isrc", "ISRC" }, -+ { itmf::BT_MI3P, "mi3p", "MI3P" }, -+ { itmf::BT_GIF, "gif", "GIF" }, -+ { itmf::BT_JPEG, "jpeg", "JPEG" }, -+ { itmf::BT_PNG, "png", "PNG" }, -+ { itmf::BT_URL, "url", "URL" }, -+ { itmf::BT_DURATION, "duration", "duration" }, -+ { itmf::BT_DATETIME, "datetime", "date/time" }, -+ { itmf::BT_GENRES, "genres", "genres" }, -+ { itmf::BT_INTEGER, "integer", "integer" }, -+ { itmf::BT_RIAA_PA, "riaapa", "RIAA-PA" }, -+ { itmf::BT_UPC, "upc", "UPC" }, -+ { itmf::BT_BMP, "bmp", "BMP" }, -+ -+ { itmf::BT_UNDEFINED } // must be last - }; - - /////////////////////////////////////////////////////////////////////////////// - - template <> --const EnumGenreType::Entry EnumGenreType::data[] = { -- { mp4v2::impl::itmf::GENRE_BLUES, "blues", "Blues" }, -- { mp4v2::impl::itmf::GENRE_CLASSIC_ROCK, "classicrock", "Classic Rock" }, -- { mp4v2::impl::itmf::GENRE_COUNTRY, "country", "Country" }, -- { mp4v2::impl::itmf::GENRE_DANCE, "dance", "Dance" }, -- { mp4v2::impl::itmf::GENRE_DISCO, "disco", "Disco" }, -- { mp4v2::impl::itmf::GENRE_FUNK, "funk", "Funk" }, -- { mp4v2::impl::itmf::GENRE_GRUNGE, "grunge", "Grunge" }, -- { mp4v2::impl::itmf::GENRE_HIP_HOP, "hiphop", "Hop-Hop" }, -- { mp4v2::impl::itmf::GENRE_JAZZ, "jazz", "Jazz" }, -- { mp4v2::impl::itmf::GENRE_METAL, "metal", "Metal" }, -- { mp4v2::impl::itmf::GENRE_NEW_AGE, "newage", "New Age" }, -- { mp4v2::impl::itmf::GENRE_OLDIES, "oldies", "Oldies" }, -- { mp4v2::impl::itmf::GENRE_OTHER, "other", "Other" }, -- { mp4v2::impl::itmf::GENRE_POP, "pop", "Pop" }, -- { mp4v2::impl::itmf::GENRE_R_AND_B, "rand_b", "R&B" }, -- { mp4v2::impl::itmf::GENRE_RAP, "rap", "Rap" }, -- { mp4v2::impl::itmf::GENRE_REGGAE, "reggae", "Reggae" }, -- { mp4v2::impl::itmf::GENRE_ROCK, "rock", "Rock" }, -- { mp4v2::impl::itmf::GENRE_TECHNO, "techno", "Techno" }, -- { mp4v2::impl::itmf::GENRE_INDUSTRIAL, "industrial", "Industrial" }, -- { mp4v2::impl::itmf::GENRE_ALTERNATIVE, "alternative", "Alternative" }, -- { mp4v2::impl::itmf::GENRE_SKA, "ska", "Ska" }, -- { mp4v2::impl::itmf::GENRE_DEATH_METAL, "deathmetal", "Death Metal" }, -- { mp4v2::impl::itmf::GENRE_PRANKS, "pranks", "Pranks" }, -- { mp4v2::impl::itmf::GENRE_SOUNDTRACK, "soundtrack", "Soundtrack" }, -- { mp4v2::impl::itmf::GENRE_EURO_TECHNO, "eurotechno", "Euro-Techno" }, -- { mp4v2::impl::itmf::GENRE_AMBIENT, "ambient", "Ambient" }, -- { mp4v2::impl::itmf::GENRE_TRIP_HOP, "triphop", "Trip-Hop" }, -- { mp4v2::impl::itmf::GENRE_VOCAL, "vocal", "Vocal" }, -- { mp4v2::impl::itmf::GENRE_JAZZ_FUNK, "jazzfunk", "Jazz+Funk" }, -- { mp4v2::impl::itmf::GENRE_FUSION, "fusion", "Fusion" }, -- { mp4v2::impl::itmf::GENRE_TRANCE, "trance", "Trance" }, -- { mp4v2::impl::itmf::GENRE_CLASSICAL, "classical", "Classical" }, -- { mp4v2::impl::itmf::GENRE_INSTRUMENTAL, "instrumental", "Instrumental" }, -- { mp4v2::impl::itmf::GENRE_ACID, "acid", "Acid" }, -- { mp4v2::impl::itmf::GENRE_HOUSE, "house", "House" }, -- { mp4v2::impl::itmf::GENRE_GAME, "game", "Game" }, -- { mp4v2::impl::itmf::GENRE_SOUND_CLIP, "soundclip", "Sound Clip" }, -- { mp4v2::impl::itmf::GENRE_GOSPEL, "gospel", "Gospel" }, -- { mp4v2::impl::itmf::GENRE_NOISE, "noise", "Noise" }, -- { mp4v2::impl::itmf::GENRE_ALTERNROCK, "alternrock", "AlternRock" }, -- { mp4v2::impl::itmf::GENRE_BASS, "bass", "Bass" }, -- { mp4v2::impl::itmf::GENRE_SOUL, "soul", "Soul" }, -- { mp4v2::impl::itmf::GENRE_PUNK, "punk", "Punk" }, -- { mp4v2::impl::itmf::GENRE_SPACE, "space", "Space" }, -- { mp4v2::impl::itmf::GENRE_MEDITATIVE, "meditative", "Meditative" }, -- { mp4v2::impl::itmf::GENRE_INSTRUMENTAL_POP, "instrumentalpop", "Instrumental Pop" }, -- { mp4v2::impl::itmf::GENRE_INSTRUMENTAL_ROCK, "instrumentalrock", "Instrumental Rock" }, -- { mp4v2::impl::itmf::GENRE_ETHNIC, "ethnic", "Ethnic" }, -- { mp4v2::impl::itmf::GENRE_GOTHIC, "gothic", "Gothic" }, -- { mp4v2::impl::itmf::GENRE_DARKWAVE, "darkwave", "Darkwave" }, -- { mp4v2::impl::itmf::GENRE_TECHNO_INDUSTRIAL, "technoindustrial", "Techno-Industrial" }, -- { mp4v2::impl::itmf::GENRE_ELECTRONIC, "electronic", "Electronic" }, -- { mp4v2::impl::itmf::GENRE_POP_FOLK, "popfolk", "Pop-Folk" }, -- { mp4v2::impl::itmf::GENRE_EURODANCE, "eurodance", "Eurodance" }, -- { mp4v2::impl::itmf::GENRE_DREAM, "dream", "Dream" }, -- { mp4v2::impl::itmf::GENRE_SOUTHERN_ROCK, "southernrock", "Southern Rock" }, -- { mp4v2::impl::itmf::GENRE_COMEDY, "comedy", "Comedy" }, -- { mp4v2::impl::itmf::GENRE_CULT, "cult", "Cult" }, -- { mp4v2::impl::itmf::GENRE_GANGSTA, "gangsta", "Gangsta" }, -- { mp4v2::impl::itmf::GENRE_TOP_40, "top40", "Top 40" }, -- { mp4v2::impl::itmf::GENRE_CHRISTIAN_RAP, "christianrap", "Christian Rap" }, -- { mp4v2::impl::itmf::GENRE_POP_FUNK, "popfunk", "Pop/Funk" }, -- { mp4v2::impl::itmf::GENRE_JUNGLE, "jungle", "Jungle" }, -- { mp4v2::impl::itmf::GENRE_NATIVE_AMERICAN, "nativeamerican", "Native American" }, -- { mp4v2::impl::itmf::GENRE_CABARET, "cabaret", "Cabaret" }, -- { mp4v2::impl::itmf::GENRE_NEW_WAVE, "newwave", "New Wave" }, -- { mp4v2::impl::itmf::GENRE_PSYCHEDELIC, "psychedelic", "Psychedelic" }, -- { mp4v2::impl::itmf::GENRE_RAVE, "rave", "Rave" }, -- { mp4v2::impl::itmf::GENRE_SHOWTUNES, "showtunes", "Showtunes" }, -- { mp4v2::impl::itmf::GENRE_TRAILER, "trailer", "Trailer" }, -- { mp4v2::impl::itmf::GENRE_LO_FI, "lofi", "Lo-Fi" }, -- { mp4v2::impl::itmf::GENRE_TRIBAL, "tribal", "Tribal" }, -- { mp4v2::impl::itmf::GENRE_ACID_PUNK, "acidpunk", "Acid Punk" }, -- { mp4v2::impl::itmf::GENRE_ACID_JAZZ, "acidjazz", "Acid Jazz" }, -- { mp4v2::impl::itmf::GENRE_POLKA, "polka", "Polka" }, -- { mp4v2::impl::itmf::GENRE_RETRO, "retro", "Retro" }, -- { mp4v2::impl::itmf::GENRE_MUSICAL, "musical", "Musical" }, -- { mp4v2::impl::itmf::GENRE_ROCK_AND_ROLL, "rockand_roll", "Rock & Roll" }, -- -- { mp4v2::impl::itmf::GENRE_HARD_ROCK, "hardrock", "Hard Rock" }, -- { mp4v2::impl::itmf::GENRE_FOLK, "folk", "Folk" }, -- { mp4v2::impl::itmf::GENRE_FOLK_ROCK, "folkrock", "Folk-Rock" }, -- { mp4v2::impl::itmf::GENRE_NATIONAL_FOLK, "nationalfolk", "National Folk" }, -- { mp4v2::impl::itmf::GENRE_SWING, "swing", "Swing" }, -- { mp4v2::impl::itmf::GENRE_FAST_FUSION, "fastfusion", "Fast Fusion" }, -- { mp4v2::impl::itmf::GENRE_BEBOB, "bebob", "Bebob" }, -- { mp4v2::impl::itmf::GENRE_LATIN, "latin", "Latin" }, -- { mp4v2::impl::itmf::GENRE_REVIVAL, "revival", "Revival" }, -- { mp4v2::impl::itmf::GENRE_CELTIC, "celtic", "Celtic" }, -- { mp4v2::impl::itmf::GENRE_BLUEGRASS, "bluegrass", "Bluegrass" }, -- { mp4v2::impl::itmf::GENRE_AVANTGARDE, "avantgarde", "Avantgarde" }, -- { mp4v2::impl::itmf::GENRE_GOTHIC_ROCK, "gothicrock", "Gothic Rock" }, -- { mp4v2::impl::itmf::GENRE_PROGRESSIVE_ROCK, "progressiverock", "Progresive Rock" }, -- { mp4v2::impl::itmf::GENRE_PSYCHEDELIC_ROCK, "psychedelicrock", "Psychedelic Rock" }, -- { mp4v2::impl::itmf::GENRE_SYMPHONIC_ROCK, "symphonicrock", "SYMPHONIC_ROCK" }, -- { mp4v2::impl::itmf::GENRE_SLOW_ROCK, "slowrock", "Slow Rock" }, -- { mp4v2::impl::itmf::GENRE_BIG_BAND, "bigband", "Big Band" }, -- { mp4v2::impl::itmf::GENRE_CHORUS, "chorus", "Chorus" }, -- { mp4v2::impl::itmf::GENRE_EASY_LISTENING, "easylistening", "Easy Listening" }, -- { mp4v2::impl::itmf::GENRE_ACOUSTIC, "acoustic", "Acoustic" }, -- { mp4v2::impl::itmf::GENRE_HUMOUR, "humour", "Humor" }, -- { mp4v2::impl::itmf::GENRE_SPEECH, "speech", "Speech" }, -- { mp4v2::impl::itmf::GENRE_CHANSON, "chanson", "Chason" }, -- { mp4v2::impl::itmf::GENRE_OPERA, "opera", "Opera" }, -- { mp4v2::impl::itmf::GENRE_CHAMBER_MUSIC, "chambermusic", "Chamber Music" }, -- { mp4v2::impl::itmf::GENRE_SONATA, "sonata", "Sonata" }, -- { mp4v2::impl::itmf::GENRE_SYMPHONY, "symphony", "Symphony" }, -- { mp4v2::impl::itmf::GENRE_BOOTY_BASS, "bootybass", "Booty Bass" }, -- { mp4v2::impl::itmf::GENRE_PRIMUS, "primus", "Primus" }, -- { mp4v2::impl::itmf::GENRE_PORN_GROOVE, "porngroove", "Porn Groove" }, -- { mp4v2::impl::itmf::GENRE_SATIRE, "satire", "Satire" }, -- { mp4v2::impl::itmf::GENRE_SLOW_JAM, "slowjam", "Slow Jam" }, -- { mp4v2::impl::itmf::GENRE_CLUB, "club", "Club" }, -- { mp4v2::impl::itmf::GENRE_TANGO, "tango", "Tango" }, -- { mp4v2::impl::itmf::GENRE_SAMBA, "samba", "Samba" }, -- { mp4v2::impl::itmf::GENRE_FOLKLORE, "folklore", "Folklore" }, -- { mp4v2::impl::itmf::GENRE_BALLAD, "ballad", "Ballad" }, -- { mp4v2::impl::itmf::GENRE_POWER_BALLAD, "powerballad", "Power Ballad" }, -- { mp4v2::impl::itmf::GENRE_RHYTHMIC_SOUL, "rhythmicsoul", "Rhythmic Soul" }, -- { mp4v2::impl::itmf::GENRE_FREESTYLE, "freestyle", "Freestyle" }, -- { mp4v2::impl::itmf::GENRE_DUET, "duet", "Duet" }, -- { mp4v2::impl::itmf::GENRE_PUNK_ROCK, "punkrock", "Punk Rock" }, -- { mp4v2::impl::itmf::GENRE_DRUM_SOLO, "drumsolo", "Drum Solo" }, -- { mp4v2::impl::itmf::GENRE_A_CAPELLA, "acapella", "A capella" }, -- { mp4v2::impl::itmf::GENRE_EURO_HOUSE, "eurohouse", "Euro-House" }, -- { mp4v2::impl::itmf::GENRE_DANCE_HALL, "dancehall", "Dance Hall" }, -- { mp4v2::impl::itmf::GENRE_NONE, "none", "none" }, -- -- { mp4v2::impl::itmf::GENRE_UNDEFINED } // must be last -+const itmf::EnumGenreType::Entry itmf::EnumGenreType::data[] = { -+ { itmf::GENRE_BLUES, "blues", "Blues" }, -+ { itmf::GENRE_CLASSIC_ROCK, "classicrock", "Classic Rock" }, -+ { itmf::GENRE_COUNTRY, "country", "Country" }, -+ { itmf::GENRE_DANCE, "dance", "Dance" }, -+ { itmf::GENRE_DISCO, "disco", "Disco" }, -+ { itmf::GENRE_FUNK, "funk", "Funk" }, -+ { itmf::GENRE_GRUNGE, "grunge", "Grunge" }, -+ { itmf::GENRE_HIP_HOP, "hiphop", "Hop-Hop" }, -+ { itmf::GENRE_JAZZ, "jazz", "Jazz" }, -+ { itmf::GENRE_METAL, "metal", "Metal" }, -+ { itmf::GENRE_NEW_AGE, "newage", "New Age" }, -+ { itmf::GENRE_OLDIES, "oldies", "Oldies" }, -+ { itmf::GENRE_OTHER, "other", "Other" }, -+ { itmf::GENRE_POP, "pop", "Pop" }, -+ { itmf::GENRE_R_AND_B, "rand_b", "R&B" }, -+ { itmf::GENRE_RAP, "rap", "Rap" }, -+ { itmf::GENRE_REGGAE, "reggae", "Reggae" }, -+ { itmf::GENRE_ROCK, "rock", "Rock" }, -+ { itmf::GENRE_TECHNO, "techno", "Techno" }, -+ { itmf::GENRE_INDUSTRIAL, "industrial", "Industrial" }, -+ { itmf::GENRE_ALTERNATIVE, "alternative", "Alternative" }, -+ { itmf::GENRE_SKA, "ska", "Ska" }, -+ { itmf::GENRE_DEATH_METAL, "deathmetal", "Death Metal" }, -+ { itmf::GENRE_PRANKS, "pranks", "Pranks" }, -+ { itmf::GENRE_SOUNDTRACK, "soundtrack", "Soundtrack" }, -+ { itmf::GENRE_EURO_TECHNO, "eurotechno", "Euro-Techno" }, -+ { itmf::GENRE_AMBIENT, "ambient", "Ambient" }, -+ { itmf::GENRE_TRIP_HOP, "triphop", "Trip-Hop" }, -+ { itmf::GENRE_VOCAL, "vocal", "Vocal" }, -+ { itmf::GENRE_JAZZ_FUNK, "jazzfunk", "Jazz+Funk" }, -+ { itmf::GENRE_FUSION, "fusion", "Fusion" }, -+ { itmf::GENRE_TRANCE, "trance", "Trance" }, -+ { itmf::GENRE_CLASSICAL, "classical", "Classical" }, -+ { itmf::GENRE_INSTRUMENTAL, "instrumental", "Instrumental" }, -+ { itmf::GENRE_ACID, "acid", "Acid" }, -+ { itmf::GENRE_HOUSE, "house", "House" }, -+ { itmf::GENRE_GAME, "game", "Game" }, -+ { itmf::GENRE_SOUND_CLIP, "soundclip", "Sound Clip" }, -+ { itmf::GENRE_GOSPEL, "gospel", "Gospel" }, -+ { itmf::GENRE_NOISE, "noise", "Noise" }, -+ { itmf::GENRE_ALTERNROCK, "alternrock", "AlternRock" }, -+ { itmf::GENRE_BASS, "bass", "Bass" }, -+ { itmf::GENRE_SOUL, "soul", "Soul" }, -+ { itmf::GENRE_PUNK, "punk", "Punk" }, -+ { itmf::GENRE_SPACE, "space", "Space" }, -+ { itmf::GENRE_MEDITATIVE, "meditative", "Meditative" }, -+ { itmf::GENRE_INSTRUMENTAL_POP, "instrumentalpop", "Instrumental Pop" }, -+ { itmf::GENRE_INSTRUMENTAL_ROCK, "instrumentalrock", "Instrumental Rock" }, -+ { itmf::GENRE_ETHNIC, "ethnic", "Ethnic" }, -+ { itmf::GENRE_GOTHIC, "gothic", "Gothic" }, -+ { itmf::GENRE_DARKWAVE, "darkwave", "Darkwave" }, -+ { itmf::GENRE_TECHNO_INDUSTRIAL, "technoindustrial", "Techno-Industrial" }, -+ { itmf::GENRE_ELECTRONIC, "electronic", "Electronic" }, -+ { itmf::GENRE_POP_FOLK, "popfolk", "Pop-Folk" }, -+ { itmf::GENRE_EURODANCE, "eurodance", "Eurodance" }, -+ { itmf::GENRE_DREAM, "dream", "Dream" }, -+ { itmf::GENRE_SOUTHERN_ROCK, "southernrock", "Southern Rock" }, -+ { itmf::GENRE_COMEDY, "comedy", "Comedy" }, -+ { itmf::GENRE_CULT, "cult", "Cult" }, -+ { itmf::GENRE_GANGSTA, "gangsta", "Gangsta" }, -+ { itmf::GENRE_TOP_40, "top40", "Top 40" }, -+ { itmf::GENRE_CHRISTIAN_RAP, "christianrap", "Christian Rap" }, -+ { itmf::GENRE_POP_FUNK, "popfunk", "Pop/Funk" }, -+ { itmf::GENRE_JUNGLE, "jungle", "Jungle" }, -+ { itmf::GENRE_NATIVE_AMERICAN, "nativeamerican", "Native American" }, -+ { itmf::GENRE_CABARET, "cabaret", "Cabaret" }, -+ { itmf::GENRE_NEW_WAVE, "newwave", "New Wave" }, -+ { itmf::GENRE_PSYCHEDELIC, "psychedelic", "Psychedelic" }, -+ { itmf::GENRE_RAVE, "rave", "Rave" }, -+ { itmf::GENRE_SHOWTUNES, "showtunes", "Showtunes" }, -+ { itmf::GENRE_TRAILER, "trailer", "Trailer" }, -+ { itmf::GENRE_LO_FI, "lofi", "Lo-Fi" }, -+ { itmf::GENRE_TRIBAL, "tribal", "Tribal" }, -+ { itmf::GENRE_ACID_PUNK, "acidpunk", "Acid Punk" }, -+ { itmf::GENRE_ACID_JAZZ, "acidjazz", "Acid Jazz" }, -+ { itmf::GENRE_POLKA, "polka", "Polka" }, -+ { itmf::GENRE_RETRO, "retro", "Retro" }, -+ { itmf::GENRE_MUSICAL, "musical", "Musical" }, -+ { itmf::GENRE_ROCK_AND_ROLL, "rockand_roll", "Rock & Roll" }, -+ -+ { itmf::GENRE_HARD_ROCK, "hardrock", "Hard Rock" }, -+ { itmf::GENRE_FOLK, "folk", "Folk" }, -+ { itmf::GENRE_FOLK_ROCK, "folkrock", "Folk-Rock" }, -+ { itmf::GENRE_NATIONAL_FOLK, "nationalfolk", "National Folk" }, -+ { itmf::GENRE_SWING, "swing", "Swing" }, -+ { itmf::GENRE_FAST_FUSION, "fastfusion", "Fast Fusion" }, -+ { itmf::GENRE_BEBOB, "bebob", "Bebob" }, -+ { itmf::GENRE_LATIN, "latin", "Latin" }, -+ { itmf::GENRE_REVIVAL, "revival", "Revival" }, -+ { itmf::GENRE_CELTIC, "celtic", "Celtic" }, -+ { itmf::GENRE_BLUEGRASS, "bluegrass", "Bluegrass" }, -+ { itmf::GENRE_AVANTGARDE, "avantgarde", "Avantgarde" }, -+ { itmf::GENRE_GOTHIC_ROCK, "gothicrock", "Gothic Rock" }, -+ { itmf::GENRE_PROGRESSIVE_ROCK, "progressiverock", "Progresive Rock" }, -+ { itmf::GENRE_PSYCHEDELIC_ROCK, "psychedelicrock", "Psychedelic Rock" }, -+ { itmf::GENRE_SYMPHONIC_ROCK, "symphonicrock", "SYMPHONIC_ROCK" }, -+ { itmf::GENRE_SLOW_ROCK, "slowrock", "Slow Rock" }, -+ { itmf::GENRE_BIG_BAND, "bigband", "Big Band" }, -+ { itmf::GENRE_CHORUS, "chorus", "Chorus" }, -+ { itmf::GENRE_EASY_LISTENING, "easylistening", "Easy Listening" }, -+ { itmf::GENRE_ACOUSTIC, "acoustic", "Acoustic" }, -+ { itmf::GENRE_HUMOUR, "humour", "Humor" }, -+ { itmf::GENRE_SPEECH, "speech", "Speech" }, -+ { itmf::GENRE_CHANSON, "chanson", "Chason" }, -+ { itmf::GENRE_OPERA, "opera", "Opera" }, -+ { itmf::GENRE_CHAMBER_MUSIC, "chambermusic", "Chamber Music" }, -+ { itmf::GENRE_SONATA, "sonata", "Sonata" }, -+ { itmf::GENRE_SYMPHONY, "symphony", "Symphony" }, -+ { itmf::GENRE_BOOTY_BASS, "bootybass", "Booty Bass" }, -+ { itmf::GENRE_PRIMUS, "primus", "Primus" }, -+ { itmf::GENRE_PORN_GROOVE, "porngroove", "Porn Groove" }, -+ { itmf::GENRE_SATIRE, "satire", "Satire" }, -+ { itmf::GENRE_SLOW_JAM, "slowjam", "Slow Jam" }, -+ { itmf::GENRE_CLUB, "club", "Club" }, -+ { itmf::GENRE_TANGO, "tango", "Tango" }, -+ { itmf::GENRE_SAMBA, "samba", "Samba" }, -+ { itmf::GENRE_FOLKLORE, "folklore", "Folklore" }, -+ { itmf::GENRE_BALLAD, "ballad", "Ballad" }, -+ { itmf::GENRE_POWER_BALLAD, "powerballad", "Power Ballad" }, -+ { itmf::GENRE_RHYTHMIC_SOUL, "rhythmicsoul", "Rhythmic Soul" }, -+ { itmf::GENRE_FREESTYLE, "freestyle", "Freestyle" }, -+ { itmf::GENRE_DUET, "duet", "Duet" }, -+ { itmf::GENRE_PUNK_ROCK, "punkrock", "Punk Rock" }, -+ { itmf::GENRE_DRUM_SOLO, "drumsolo", "Drum Solo" }, -+ { itmf::GENRE_A_CAPELLA, "acapella", "A capella" }, -+ { itmf::GENRE_EURO_HOUSE, "eurohouse", "Euro-House" }, -+ { itmf::GENRE_DANCE_HALL, "dancehall", "Dance Hall" }, -+ { itmf::GENRE_NONE, "none", "none" }, -+ -+ { itmf::GENRE_UNDEFINED } // must be last - }; - - /////////////////////////////////////////////////////////////////////////////// - - template <> --const EnumStikType::Entry EnumStikType::data[] = { -- { mp4v2::impl::itmf::STIK_OLD_MOVIE, "oldmovie", "Movie" }, -- { mp4v2::impl::itmf::STIK_NORMAL, "normal", "Normal" }, -- { mp4v2::impl::itmf::STIK_AUDIOBOOK, "audiobook", "Audio Book" }, -- { mp4v2::impl::itmf::STIK_MUSIC_VIDEO, "musicvideo", "Music Video" }, -- { mp4v2::impl::itmf::STIK_MOVIE, "movie", "Movie" }, -- { mp4v2::impl::itmf::STIK_TV_SHOW, "tvshow", "TV Show" }, -- { mp4v2::impl::itmf::STIK_BOOKLET, "booklet", "Booklet" }, -- { mp4v2::impl::itmf::STIK_RINGTONE, "ringtone", "Ringtone" }, -- -- { mp4v2::impl::itmf::STIK_UNDEFINED } // must be last -+const itmf::EnumStikType::Entry itmf::EnumStikType::data[] = { -+ { itmf::STIK_OLD_MOVIE, "oldmovie", "Movie" }, -+ { itmf::STIK_NORMAL, "normal", "Normal" }, -+ { itmf::STIK_AUDIOBOOK, "audiobook", "Audio Book" }, -+ { itmf::STIK_MUSIC_VIDEO, "musicvideo", "Music Video" }, -+ { itmf::STIK_MOVIE, "movie", "Movie" }, -+ { itmf::STIK_TV_SHOW, "tvshow", "TV Show" }, -+ { itmf::STIK_BOOKLET, "booklet", "Booklet" }, -+ { itmf::STIK_RINGTONE, "ringtone", "Ringtone" }, -+ -+ { itmf::STIK_UNDEFINED } // must be last - }; - - /////////////////////////////////////////////////////////////////////////////// - - template <> --const EnumAccountType::Entry EnumAccountType::data[] = { -- { mp4v2::impl::itmf::AT_ITUNES, "itunes", "iTunes" }, -- { mp4v2::impl::itmf::AT_AOL, "aol", "AOL" }, -+const itmf::EnumAccountType::Entry itmf::EnumAccountType::data[] = { -+ { itmf::AT_ITUNES, "itunes", "iTunes" }, -+ { itmf::AT_AOL, "aol", "AOL" }, - -- { mp4v2::impl::itmf::AT_UNDEFINED } // must be last -+ { itmf::AT_UNDEFINED } // must be last - }; - - /////////////////////////////////////////////////////////////////////////////// - - template <> --const EnumCountryCode::Entry EnumCountryCode::data[] = { -- { mp4v2::impl::itmf::CC_USA, "usa", "United States" }, -- { mp4v2::impl::itmf::CC_USA, "fra", "France" }, -- { mp4v2::impl::itmf::CC_DEU, "ger", "Germany" }, -- { mp4v2::impl::itmf::CC_GBR, "gbr", "United Kingdom" }, -- { mp4v2::impl::itmf::CC_AUT, "aut", "Austria" }, -- { mp4v2::impl::itmf::CC_BEL, "bel", "Belgium" }, -- { mp4v2::impl::itmf::CC_FIN, "fin", "Finland" }, -- { mp4v2::impl::itmf::CC_GRC, "grc", "Greece" }, -- { mp4v2::impl::itmf::CC_IRL, "irl", "Ireland" }, -- { mp4v2::impl::itmf::CC_ITA, "ita", "Italy" }, -- { mp4v2::impl::itmf::CC_LUX, "lux", "Luxembourg" }, -- { mp4v2::impl::itmf::CC_NLD, "nld", "Netherlands" }, -- { mp4v2::impl::itmf::CC_PRT, "prt", "Portugal" }, -- { mp4v2::impl::itmf::CC_ESP, "esp", "Spain" }, -- { mp4v2::impl::itmf::CC_CAN, "can", "Canada" }, -- { mp4v2::impl::itmf::CC_SWE, "swe", "Sweden" }, -- { mp4v2::impl::itmf::CC_NOR, "nor", "Norway" }, -- { mp4v2::impl::itmf::CC_DNK, "dnk", "Denmark" }, -- { mp4v2::impl::itmf::CC_CHE, "che", "Switzerland" }, -- { mp4v2::impl::itmf::CC_AUS, "aus", "Australia" }, -- { mp4v2::impl::itmf::CC_NZL, "nzl", "New Zealand" }, -- { mp4v2::impl::itmf::CC_JPN, "jpn", "Japan" }, -- -- { mp4v2::impl::itmf::CC_UNDEFINED } // must be last -+const itmf::EnumCountryCode::Entry itmf::EnumCountryCode::data[] = { -+ { itmf::CC_USA, "usa", "United States" }, -+ { itmf::CC_USA, "fra", "France" }, -+ { itmf::CC_DEU, "ger", "Germany" }, -+ { itmf::CC_GBR, "gbr", "United Kingdom" }, -+ { itmf::CC_AUT, "aut", "Austria" }, -+ { itmf::CC_BEL, "bel", "Belgium" }, -+ { itmf::CC_FIN, "fin", "Finland" }, -+ { itmf::CC_GRC, "grc", "Greece" }, -+ { itmf::CC_IRL, "irl", "Ireland" }, -+ { itmf::CC_ITA, "ita", "Italy" }, -+ { itmf::CC_LUX, "lux", "Luxembourg" }, -+ { itmf::CC_NLD, "nld", "Netherlands" }, -+ { itmf::CC_PRT, "prt", "Portugal" }, -+ { itmf::CC_ESP, "esp", "Spain" }, -+ { itmf::CC_CAN, "can", "Canada" }, -+ { itmf::CC_SWE, "swe", "Sweden" }, -+ { itmf::CC_NOR, "nor", "Norway" }, -+ { itmf::CC_DNK, "dnk", "Denmark" }, -+ { itmf::CC_CHE, "che", "Switzerland" }, -+ { itmf::CC_AUS, "aus", "Australia" }, -+ { itmf::CC_NZL, "nzl", "New Zealand" }, -+ { itmf::CC_JPN, "jpn", "Japan" }, -+ -+ { itmf::CC_UNDEFINED } // must be last - }; - - /////////////////////////////////////////////////////////////////////////////// - - template <> --const EnumContentRating::Entry EnumContentRating::data[] = { -- { mp4v2::impl::itmf::CR_NONE, "none", "None" }, -- { mp4v2::impl::itmf::CR_CLEAN, "clean", "Clean" }, -- { mp4v2::impl::itmf::CR_EXPLICIT, "explicit", "Explicit" }, -+const itmf::EnumContentRating::Entry itmf::EnumContentRating::data[] = { -+ { itmf::CR_NONE, "none", "None" }, -+ { itmf::CR_CLEAN, "clean", "Clean" }, -+ { itmf::CR_EXPLICIT, "explicit", "Explicit" }, - -- { mp4v2::impl::itmf::CR_UNDEFINED } // must be last -+ { itmf::CR_UNDEFINED } // must be last - }; - - /////////////////////////////////////////////////////////////////////////////// - --#if defined( _MSC_VER ) --namespace mp4v2 { namespace impl { namespace itmf { --#endif -+namespace itmf { - - /////////////////////////////////////////////////////////////////////////////// - diff --git a/contrib/mp4v2/P00-mingw-dllimport.patch b/contrib/mp4v2/P00-mingw-dllimport.patch deleted file mode 100644 index 5b7f1a300..000000000 --- a/contrib/mp4v2/P00-mingw-dllimport.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- mp4v2-trunk-r355/include/mp4v2/platform.h 2009-05-20 19:52:26.000000000 -0700 -+++ xxx/include/mp4v2/platform.h 2010-09-11 09:36:20.881523832 -0700 -@@ -24,7 +24,7 @@ - #if defined( _WIN32 ) || defined( __MINGW32__ ) - # if defined( _WINDLL ) || defined( DLL_EXPORT ) - # define MP4V2_EXPORT __declspec(dllexport) --# elif defined( _DLL ) || defined( DLL_IMPORT ) -+# elif defined( DLL_IMPORT ) - # define MP4V2_EXPORT __declspec(dllimport) - # else - # define MP4V2_EXPORT diff --git a/contrib/mp4v2/module.defs b/contrib/mp4v2/module.defs deleted file mode 100644 index 67c95a5af..000000000 --- a/contrib/mp4v2/module.defs +++ /dev/null @@ -1,18 +0,0 @@ -$(eval $(call import.MODULE.defs,MP4V2,mp4v2)) -$(eval $(call import.CONTRIB.defs,MP4V2)) - -MP4V2.FETCH.url = http://download.handbrake.fr/handbrake/contrib/mp4v2-trunk-r355.tar.bz2 - -## propagate more flags -MP4V2.CONFIGURE.env.CFLAGS = CFLAGS="$(call fn.ARGS,MP4V2.GCC,*archs *sysroot *minver ?extra *D .g .O)" -MP4V2.CONFIGURE.env.CXXFLAGS = CXXFLAGS="$(call fn.ARGS,MP4V2.GCC,*archs *sysroot *minver ?extra *D .g .O)" - -## save some build-time by disabling utils -MP4V2.CONFIGURE.extra += --disable-util - -# gch causes build errors with -g3 on many gcc toolchains -MP4V2.CONFIGURE.extra += --disable-gch - -## optional static libs need to be marked -MP4V2.OSL.libs = mp4v2 -MP4V2.OSL.files = $(foreach i,$(MP4V2.OSL.libs),$(call fn.ABSOLUTE,$(CONTRIB.build/)lib/lib$(i).a)) diff --git a/contrib/mp4v2/module.rules b/contrib/mp4v2/module.rules deleted file mode 100644 index 95686c429..000000000 --- a/contrib/mp4v2/module.rules +++ /dev/null @@ -1,2 +0,0 @@ -$(eval $(call import.MODULE.rules,MP4V2)) -$(eval $(call import.CONTRIB.rules,MP4V2)) diff --git a/gtk/configure.ac b/gtk/configure.ac index f24323bf1..fac3f167b 100644 --- a/gtk/configure.ac +++ b/gtk/configure.ac @@ -60,14 +60,6 @@ AC_ARG_ENABLE(fdk-aac, AS_HELP_STRING([--enable-fdk-aac], [enable fdk aac encoder]), use_fdk_aac=yes, use_fdk_aac=no) -AC_ARG_ENABLE(mp4v2, - AS_HELP_STRING([--enable-mp4v2], [enable mp4v2 muxer]), - use_mp4v2=yes, use_mp4v2=no) - -AC_ARG_ENABLE(libmkv, - AS_HELP_STRING([--enable-libmkv], [enable libmkv muxer]), - use_libmkv=yes, use_libmkv=no) - AC_ARG_ENABLE(x265, AS_HELP_STRING([--enable-x265], [enable x265 encoder]), use_x265=yes, use_x265=no) @@ -189,14 +181,6 @@ if test "x$use_fdk_aac" = "xyes" ; then HB_LIBS+=" -lfdk-aac" fi -if test "x$use_mp4v2" = "xyes" ; then - HB_LIBS+=" -lmp4v2" -fi - -if test "x$use_libmkv" = "xyes" ; then - HB_LIBS+=" -lmkv" -fi - if test "x$use_x265" = "xyes" ; then HB_LIBS+=" -lx265" fi diff --git a/gtk/module.defs b/gtk/module.defs index c23d74fc9..b203ff74e 100644 --- a/gtk/module.defs +++ b/gtk/module.defs @@ -33,14 +33,6 @@ ifeq (1,$(FEATURE.fdk_aac)) GTK.CONFIGURE.extra += --enable-fdk-aac endif -ifeq (1,$(FEATURE.mp4v2)) - GTK.CONFIGURE.extra += --enable-mp4v2 -endif - -ifeq (1,$(FEATURE.libmkv)) - GTK.CONFIGURE.extra += --enable-libmkv -endif - ifeq (1,$(FEATURE.x265)) GTK.CONFIGURE.extra += --enable-x265 endif diff --git a/libhb/common.c b/libhb/common.c index 7015ae17a..f6e773777 100644 --- a/libhb/common.c +++ b/libhb/common.c @@ -339,16 +339,8 @@ static int hb_container_is_enabled(int format) { switch (format) { -#ifdef USE_MP4V2 - case HB_MUX_MP4V2: -#endif -#ifdef USE_LIBMKV - case HB_MUX_LIBMKV: -#endif -#ifdef USE_AVFORMAT case HB_MUX_AV_MP4: case HB_MUX_AV_MKV: -#endif return 1; default: diff --git a/libhb/decmetadata.c b/libhb/decmetadata.c deleted file mode 100644 index 85d27ca7f..000000000 --- a/libhb/decmetadata.c +++ /dev/null @@ -1,206 +0,0 @@ -/* decmetadata.c - - Copyright (c) 2003-2014 HandBrake Team - This file is part of the HandBrake source code - Homepage: <http://handbrake.fr/>. - It may be used under the terms of the GNU General Public License v2. - For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html - */ - - -#include "common.h" - -#if defined(USE_MP4V2) -#include <mp4v2/mp4v2.h> - -static int decmp4metadata( hb_title_t *title ) -{ - MP4FileHandle input_file; - int result = 0; - hb_deep_log( 2, "Got an MP4 input, read the metadata"); - - input_file = MP4Read( title->path, 0 ); - - if( input_file != MP4_INVALID_FILE_HANDLE ) - { - /* - * Store iTunes MetaData - */ - const MP4Tags* tags; - - /* alloc,fetch tags */ - tags = MP4TagsAlloc(); - MP4TagsFetch( tags, input_file ); - - if( tags->name ) { - hb_deep_log( 2, "Metadata Name in input file is '%s'", tags->name ); - hb_metadata_set_name(title->metadata, tags->name); - result = 1; - } - - if( tags->artist ) - { - hb_metadata_set_artist(title->metadata, tags->artist); - result = 1; - } - - if( tags->composer ) - { - hb_metadata_set_composer(title->metadata, tags->composer); - result = 1; - } - - if( tags->comments ) - { - hb_metadata_set_comment(title->metadata, tags->comments); - result = 1; - } - - if( tags->releaseDate ) - { - hb_metadata_set_release_date(title->metadata, tags->releaseDate); - result = 1; - } - - if( tags->album ) - { - hb_metadata_set_album(title->metadata, tags->album); - result = 1; - } - - if( tags->albumArtist ) - { - hb_metadata_set_album_artist(title->metadata, tags->albumArtist); - result = 1; - } - - if( tags->genre ) - { - hb_metadata_set_genre(title->metadata, tags->genre); - result = 1; - } - - if( tags->description ) - { - hb_metadata_set_description(title->metadata, tags->description); - result = 1; - } - - if( tags->longDescription ) - { - hb_metadata_set_long_description(title->metadata, tags->longDescription); - result = 1; - } - - int ii; - for ( ii = 0; ii < tags->artworkCount; ii++ ) - { - const MP4TagArtwork* art = tags->artwork + ii; - int type; - switch ( art->type ) - { - case MP4_ART_BMP: - type = HB_ART_BMP; - break; - case MP4_ART_GIF: - type = HB_ART_GIF; - break; - case MP4_ART_JPEG: - type = HB_ART_JPEG; - break; - case MP4_ART_PNG: - type = HB_ART_PNG; - break; - default: - type = HB_ART_UNDEFINED; - break; - } - hb_metadata_add_coverart( - title->metadata, art->data, art->size, type); - hb_deep_log( 2, "Got some cover art of type %d, size %d", - art->type, - art->size ); - result = 1; - } - - /* store,free tags */ - MP4TagsStore( tags, input_file ); - MP4TagsFree( tags ); - - /* - * Handle the chapters. - */ - MP4Chapter_t *chapter_list = NULL; - uint32_t chapter_count; - - MP4GetChapters( input_file, &chapter_list, &chapter_count, - MP4ChapterTypeQt ); - - if( chapter_list && ( hb_list_count( title->list_chapter ) == 0 ) ) { - uint32_t i = 1; - while( i <= chapter_count ) - { - hb_chapter_t * chapter; - chapter = calloc( sizeof( hb_chapter_t ), 1 ); - chapter->index = i; - chapter->duration = chapter_list[i-1].duration * 90; - - int seconds = ( chapter->duration + 45000 ) / 90000; - chapter->hours = ( seconds / 3600 ); - chapter->minutes = ( seconds % 3600 ) / 60; - chapter->seconds = ( seconds % 60 ); - - if( chapter_list[i-1].title ) - { - hb_chapter_set_title( chapter, chapter_list[i-1].title ); - } - else - { - char chapter_title[80]; - sprintf( chapter_title, "Chapter %d", chapter->index ); - hb_chapter_set_title( chapter, chapter_title ); - } - - hb_deep_log( 2, "Added chapter %i, name='%s', dur=%"PRId64", (%02i:%02i:%02i)", - chapter->index, chapter->title, chapter->duration, - chapter->hours, chapter->minutes, chapter->seconds); - - hb_list_add( title->list_chapter, chapter ); - i++; - } - } - - MP4Close( input_file ); - } - return result; -} -#endif // USE_MP4V2 - -/* - * decmetadata() - * - * Look at the title and extract whatever metadata we can from that title. - */ -int decmetadata( hb_title_t *title ) -{ - if( !title ) - { - return 0; - } - - if( !title->metadata ) - { - return 0; - } - -#if defined(USE_MP4V2) - /* - * Hacky way of figuring out if this is an MP4, in which case read the data using libmp4v2 - */ - if( title->container_name && strcmp(title->container_name, "mov,mp4,m4a,3gp,3g2,mj2") == 0 ) - { - return decmp4metadata( title ); - } -#endif - return 0; -} diff --git a/libhb/internal.h b/libhb/internal.h index c71b23ecd..f32c3d3ff 100644 --- a/libhb/internal.h +++ b/libhb/internal.h @@ -284,11 +284,6 @@ void hb_demux_null( hb_buffer_t * ps_buf, hb_list_t * es_list, hb_psdemux_t * ); extern const hb_muxer_t hb_demux[]; /*********************************************************************** - * decmetadata.c - **********************************************************************/ -extern int decmetadata( hb_title_t *title ); - -/*********************************************************************** * batch.c **********************************************************************/ typedef struct hb_batch_s hb_batch_t; diff --git a/libhb/module.defs b/libhb/module.defs index d0a2da131..b1920fdbd 100644 --- a/libhb/module.defs +++ b/libhb/module.defs @@ -1,6 +1,6 @@ __deps__ := A52DEC BZIP2 LIBVPX FFMPEG FONTCONFIG FREETYPE LAME LIBASS LIBDCA \ - LIBDVDREAD LIBDVDNAV LIBICONV LIBMKV LIBOGG LIBSAMPLERATE LIBTHEORA LIBVORBIS LIBXML2 \ - MP4V2 PTHREADW32 X264 X265 ZLIB LIBBLURAY FDKAAC LIBMFX + LIBDVDREAD LIBDVDNAV LIBICONV LIBOGG LIBSAMPLERATE LIBTHEORA LIBVORBIS LIBXML2 \ + PTHREADW32 X264 X265 ZLIB LIBBLURAY FDKAAC LIBMFX $(eval $(call import.MODULE.defs,LIBHB,libhb,$(__deps__))) $(eval $(call import.GCC,LIBHB)) @@ -42,15 +42,6 @@ endif ifeq (1,$(FEATURE.libav_aac)) LIBHB.GCC.D += USE_LIBAV_AAC endif -ifeq (1,$(FEATURE.mp4v2)) -LIBHB.GCC.D += USE_MP4V2 -endif -ifeq (1,$(FEATURE.libmkv)) -LIBHB.GCC.D += USE_LIBMKV -endif -ifeq (1,$(FEATURE.avformat)) -LIBHB.GCC.D += USE_AVFORMAT -endif LIBHB.GCC.D += __LIBHB__ USE_PTHREAD LIBHB.GCC.I += $(LIBHB.build/) $(CONTRIB.build/)include @@ -131,14 +122,6 @@ ifeq (1,$(FEATURE.x265)) LIBHB.dll.libs += $(CONTRIB.build/)lib/libx265.a endif -ifeq (1,$(FEATURE.mp4v2)) -LIBHB.dll.libs += $(CONTRIB.build/)lib/libmp4v2.a -endif - -ifeq (1,$(FEATURE.libmkv)) -LIBHB.dll.libs += $(CONTRIB.build/)lib/libmkv.a -endif - ifneq ($(HAS.iconv),1) LIBHB.dll.libs += $(CONTRIB.build/)lib/libiconv.a else diff --git a/libhb/muxavformat.c b/libhb/muxavformat.c index d39cbdd8f..67d1fff69 100644 --- a/libhb/muxavformat.c +++ b/libhb/muxavformat.c @@ -7,8 +7,6 @@ For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html */ -#if defined(USE_AVFORMAT) - #include <ogg/ogg.h> #include "libavformat/avformat.h" #include "libavutil/avstring.h" @@ -1323,5 +1321,3 @@ hb_mux_object_t * hb_mux_avformat_init( hb_job_t * job ) m->job = job; return m; } - -#endif // USE_AVFORMAT diff --git a/libhb/muxcommon.c b/libhb/muxcommon.c index f06651734..d1646e7fb 100644 --- a/libhb/muxcommon.c +++ b/libhb/muxcommon.c @@ -614,22 +614,10 @@ hb_work_object_t * hb_muxer_init( hb_job_t * job ) { switch( job->mux ) { -#ifdef USE_MP4V2 - case HB_MUX_MP4V2: - mux->m = hb_mux_mp4_init( job ); - break; -#endif -#ifdef USE_LIBMKV - case HB_MUX_LIBMKV: - mux->m = hb_mux_mkv_init( job ); - break; -#endif -#ifdef USE_AVFORMAT case HB_MUX_AV_MP4: case HB_MUX_AV_MKV: mux->m = hb_mux_avformat_init( job ); break; -#endif default: hb_error( "No muxer selected, exiting" ); *job->done_error = HB_ERROR_INIT; diff --git a/libhb/muxmkv.c b/libhb/muxmkv.c deleted file mode 100644 index 4a8de8a37..000000000 --- a/libhb/muxmkv.c +++ /dev/null @@ -1,710 +0,0 @@ -/* muxmkv.c - - Copyright (c) 2003-2014 HandBrake Team - This file is part of the HandBrake source code - Homepage: <http://handbrake.fr/>. - It may be used under the terms of the GNU General Public License v2. - For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html - */ - -/* libmkv header */ - -#if defined(USE_LIBMKV) - -#include "libmkv.h" - -#include <ogg/ogg.h> - -#include "hb.h" -#include "lang.h" - -/* Scale factor to apply to timecodes to convert from HandBrake's - * 1/90000s to nanoseconds as expected by libmkv */ -#define NANOSECOND_SCALE 1000000000L -#define TIMECODE_SCALE 1000000000L / 90000 - -struct hb_mux_object_s -{ - HB_MUX_COMMON; - - hb_job_t * job; - mk_Writer * file; - int delay; -}; - -struct hb_mux_data_s -{ - mk_Track * track; - uint64_t prev_chapter_tc; - uint16_t current_chapter; - int codec; - int subtitle; - int sub_format; -}; - -static uint8_t * create_flac_header( uint8_t *data, int size ) -{ - uint8_t * out; - uint8_t header[8] = { - 0x66, 0x4C, 0x61, 0x43, 0x80, 0x00, 0x00, 0x22 - }; - - out = malloc( size + 8 ); - memcpy( out, header, 8 ); - memcpy( out + 8, data, size ); - return out; -} - -static uint8_t* create_h264_header(hb_job_t *job, int *size) -{ - /* Taken from x264's muxers.c */ - int avcC_len = (5 + - 1 + 2 + job->config.h264.sps_length + - 1 + 2 + job->config.h264.pps_length); -#define MAX_AVCC_LEN 5 + 1 + 2 + 1024 + 1 + 2 + 1024 // FIXME - if (avcC_len > MAX_AVCC_LEN) - { - hb_log("create_h264_header: H.264 header too long (%d, max: %d)", - avcC_len, MAX_AVCC_LEN); - return NULL; - } - uint8_t *avcC = malloc(avcC_len); - if (avcC == NULL) - { - return NULL; - } - - avcC[0] = 1; - avcC[1] = job->config.h264.sps[1]; /* AVCProfileIndication */ - avcC[2] = job->config.h264.sps[2]; /* profile_compat */ - avcC[3] = job->config.h264.sps[3]; /* AVCLevelIndication */ - avcC[4] = 0xff; // nalu size length is four bytes - avcC[5] = 0xe1; // one sps - - avcC[6] = job->config.h264.sps_length >> 8; - avcC[7] = job->config.h264.sps_length; - memcpy(avcC + 8, job->config.h264.sps, job->config.h264.sps_length); - - avcC[8 + job->config.h264.sps_length] = 1; // one pps - avcC[9 + job->config.h264.sps_length] = job->config.h264.pps_length >> 8; - avcC[10 + job->config.h264.sps_length] = job->config.h264.pps_length; - memcpy(avcC + 11 + job->config.h264.sps_length, - job->config.h264.pps, job->config.h264.pps_length); - - if (size != NULL) - { - *size = avcC_len; - } - return avcC; -} - -/********************************************************************** - * MKVInit - ********************************************************************** - * Allocates hb_mux_data_t structures, create file and write headers - *********************************************************************/ -static int MKVInit( hb_mux_object_t * m ) -{ - hb_job_t * job = m->job; - hb_audio_t * audio; - hb_mux_data_t * mux_data; - - uint8_t *avcC = NULL; - uint8_t default_track_flag = 1; - uint8_t need_fonts = 0; - int avcC_len, i, j; - ogg_packet *ogg_headers[3]; - mk_TrackConfig *track; - iso639_lang_t *lang; - - track = calloc(1, sizeof(mk_TrackConfig)); - - // convert file name to current code page - char *path = hb_utf8_to_cp(job->file); - if (path == NULL) - { - hb_error("Could not convert string, out of memory?"); - job->mux_data = NULL; - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - return 0; - } - - m->file = mk_createWriter(path, 1000000, 1); - free(path); - - if( !m->file ) - { - hb_error( "Could not create output file, Disk Full?" ); - job->mux_data = NULL; - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - free(track); - return 0; - } - - /* Video track */ - mux_data = calloc(1, sizeof( hb_mux_data_t ) ); - job->mux_data = mux_data; - - track->trackType = MK_TRACK_VIDEO; - track->flagDefault = 1; - track->flagEnabled = 1; - switch (job->vcodec) - { - case HB_VCODEC_X264: - case HB_VCODEC_QSV_H264: - avcC = create_h264_header(job, &avcC_len); - if (avcC == NULL) - { - free(track); - return -1; - } - track->codecID = MK_VCODEC_MP4AVC; - track->codecPrivate = avcC; - track->codecPrivateSize = avcC_len; - if (job->areBframes) - track->minCache = 1; - break; - case HB_VCODEC_FFMPEG_MPEG4: - track->codecID = MK_VCODEC_MP4ASP; - track->codecPrivate = job->config.mpeg4.bytes; - track->codecPrivateSize = job->config.mpeg4.length; - if (job->areBframes) - track->minCache = 1; - break; - case HB_VCODEC_FFMPEG_MPEG2: - track->codecID = MK_VCODEC_MPEG2; - track->codecPrivate = job->config.mpeg4.bytes; - track->codecPrivateSize = job->config.mpeg4.length; - if (job->areBframes) - track->minCache = 1; - break; - case HB_VCODEC_FFMPEG_VP8: - track->codecID = "V_VP8"; - track->codecPrivate = NULL; - track->codecPrivateSize = 0; - break; - case HB_VCODEC_THEORA: - { - int i; - uint64_t cp_size = 0; - track->codecID = MK_VCODEC_THEORA; - uint64_t header_sizes[3]; - for (i = 0; i < 3; ++i) - { - ogg_headers[i] = (ogg_packet *)job->config.theora.headers[i]; - ogg_headers[i]->packet = (unsigned char *)&job->config.theora.headers[i] + sizeof( ogg_packet ); - header_sizes[i] = ogg_headers[i]->bytes; - } - track->codecPrivate = mk_laceXiph(header_sizes, 2, &cp_size); - track->codecPrivate = realloc(track->codecPrivate, cp_size + ogg_headers[0]->bytes + ogg_headers[1]->bytes + ogg_headers[2]->bytes); - for(i = 0; i < 3; ++i) - { - memcpy(track->codecPrivate + cp_size, ogg_headers[i]->packet, ogg_headers[i]->bytes); - cp_size += ogg_headers[i]->bytes; - } - track->codecPrivateSize = cp_size; - } - break; - default: - *job->done_error = HB_ERROR_WRONG_INPUT; - *job->die = 1; - hb_error("muxmkv: Unknown video codec: %x", job->vcodec); - free(track); - return 0; - } - - track->extra.video.pixelWidth = job->width; - track->extra.video.pixelHeight = job->height; - track->extra.video.displayHeight = job->height; - if( job->anamorphic.mode ) - { - track->extra.video.displayWidth = job->width * ((double)job->anamorphic.par_width / (double)job->anamorphic.par_height); - } - else - { - track->extra.video.displayWidth = job->width; - } - - int vrate_base, vrate; - if( job->pass == 2 ) - { - hb_interjob_t * interjob = hb_interjob_get( job->h ); - vrate_base = interjob->vrate_base; - vrate = interjob->vrate; - } - else - { - vrate_base = job->vrate_base; - vrate = job->vrate; - } - track->defaultDuration = (int64_t)(((float)vrate_base / (float)vrate) * 1000000000); - - mux_data->track = mk_createTrack(m->file, track); - - /* add the audio tracks */ - for( i = 0; i < hb_list_count( job->list_audio ); i++ ) - { - audio = hb_list_item( job->list_audio, i ); - mux_data = calloc(1, sizeof( hb_mux_data_t ) ); - audio->priv.mux_data = mux_data; - - if (audio->config.out.delay > m->delay) - m->delay = audio->config.out.delay; - - mux_data->codec = audio->config.out.codec; - - memset(track, 0, sizeof(mk_TrackConfig)); - switch (audio->config.out.codec & HB_ACODEC_MASK) - { - case HB_ACODEC_DCA: - case HB_ACODEC_DCA_HD: - track->codecPrivate = NULL; - track->codecPrivateSize = 0; - track->codecID = MK_ACODEC_DTS; - break; - case HB_ACODEC_AC3: - track->codecPrivate = NULL; - track->codecPrivateSize = 0; - track->codecID = MK_ACODEC_AC3; - break; - case HB_ACODEC_LAME: - case HB_ACODEC_MP3: - track->codecPrivate = NULL; - track->codecPrivateSize = 0; - track->codecID = MK_ACODEC_MP3; - break; - case HB_ACODEC_VORBIS: - { - int i; - uint64_t cp_size = 0; - track->codecID = MK_ACODEC_VORBIS; - uint64_t header_sizes[3]; - for (i = 0; i < 3; ++i) - { - ogg_headers[i] = (ogg_packet *)audio->priv.config.vorbis.headers[i]; - ogg_headers[i]->packet = (unsigned char *)&audio->priv.config.vorbis.headers[i] + sizeof( ogg_packet ); - header_sizes[i] = ogg_headers[i]->bytes; - } - track->codecPrivate = mk_laceXiph(header_sizes, 2, &cp_size); - track->codecPrivate = realloc(track->codecPrivate, cp_size + ogg_headers[0]->bytes + ogg_headers[1]->bytes + ogg_headers[2]->bytes); - for(i = 0; i < 3; ++i) - { - memcpy(track->codecPrivate + cp_size, ogg_headers[i]->packet, ogg_headers[i]->bytes); - cp_size += ogg_headers[i]->bytes; - } - track->codecPrivateSize = cp_size; - } - break; - case HB_ACODEC_FFFLAC: - case HB_ACODEC_FFFLAC24: - if (audio->priv.config.extradata.bytes) - { - track->codecPrivate = create_flac_header(audio->priv.config.extradata.bytes, - audio->priv.config.extradata.length); - track->codecPrivateSize = audio->priv.config.extradata.length + 8; - } - track->codecID = MK_ACODEC_FLAC; - break; - case HB_ACODEC_FFAAC: - case HB_ACODEC_CA_AAC: - case HB_ACODEC_CA_HAAC: - case HB_ACODEC_FDK_AAC: - case HB_ACODEC_FDK_HAAC: - track->codecPrivate = audio->priv.config.extradata.bytes; - track->codecPrivateSize = audio->priv.config.extradata.length; - track->codecID = MK_ACODEC_AAC; - break; - default: - *job->done_error = HB_ERROR_WRONG_INPUT; - *job->die = 1; - hb_error("muxmkv: Unknown audio codec: %x", audio->config.out.codec); - return 0; - } - - if( default_track_flag ) - { - track->flagDefault = 1; - default_track_flag = 0; - } - else - { - track->flagDefault = 0; - } - track->flagEnabled = 1; - track->trackType = MK_TRACK_AUDIO; - // MKV lang codes should be ISO-639-2/B - lang = lang_for_code2( audio->config.lang.iso639_2 ); - track->language = lang->iso639_2b ? lang->iso639_2b : lang->iso639_2; - // sample rate - if ((audio->config.out.codec == HB_ACODEC_CA_HAAC) || - (audio->config.out.codec == HB_ACODEC_FDK_HAAC) || - (audio->config.out.codec == HB_ACODEC_AAC_PASS && - audio->config.in.samples_per_frame > 1024)) - { - // For HE-AAC, write outputSamplingFreq too - // samplingFreq is half of outputSamplingFreq - track->extra.audio.outputSamplingFreq = (float)audio->config.out.samplerate; - track->extra.audio.samplingFreq = track->extra.audio.outputSamplingFreq / 2.; - } - else - { - track->extra.audio.samplingFreq = (float)audio->config.out.samplerate; - } - if (audio->config.out.codec & HB_ACODEC_PASS_FLAG) - { - track->extra.audio.channels = av_get_channel_layout_nb_channels(audio->config.in.channel_layout); - } - else - { - track->extra.audio.channels = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown); - } - mux_data->track = mk_createTrack(m->file, track); - if (audio->config.out.codec == HB_ACODEC_VORBIS || - audio->config.out.codec == HB_ACODEC_FFFLAC || - audio->config.out.codec == HB_ACODEC_FFFLAC24) - free(track->codecPrivate); - } - - char * subidx_fmt = - "size: %dx%d\n" - "org: %d, %d\n" - "scale: 100%%, 100%%\n" - "alpha: 100%%\n" - "smooth: OFF\n" - "fadein/out: 50, 50\n" - "align: OFF at LEFT TOP\n" - "time offset: 0\n" - "forced subs: %s\n" - "palette: %06x, %06x, %06x, %06x, %06x, %06x, " - "%06x, %06x, %06x, %06x, %06x, %06x, %06x, %06x, %06x, %06x\n" - "custom colors: OFF, tridx: 0000, " - "colors: 000000, 000000, 000000, 000000\n"; - - for( i = 0; i < hb_list_count( job->list_subtitle ); i++ ) - { - hb_subtitle_t * subtitle; - uint32_t rgb[16]; - char subidx[2048]; - int len; - - subtitle = hb_list_item( job->list_subtitle, i ); - if (subtitle->config.dest != PASSTHRUSUB) - continue; - - memset(track, 0, sizeof(mk_TrackConfig)); - switch (subtitle->source) - { - case VOBSUB: - track->codecID = MK_SUBTITLE_VOBSUB; - for (j = 0; j < 16; j++) - rgb[j] = hb_yuv2rgb(subtitle->palette[j]); - len = snprintf(subidx, 2048, subidx_fmt, - subtitle->width, subtitle->height, - 0, 0, "OFF", - rgb[0], rgb[1], rgb[2], rgb[3], - rgb[4], rgb[5], rgb[6], rgb[7], - rgb[8], rgb[9], rgb[10], rgb[11], - rgb[12], rgb[13], rgb[14], rgb[15]); - track->codecPrivate = subidx; - track->codecPrivateSize = len + 1; - break; - case PGSSUB: - track->codecPrivate = NULL; - track->codecPrivateSize = 0; - track->codecID = MK_SUBTITLE_PGS; - break; - case CC608SUB: - case CC708SUB: - case TX3GSUB: - case UTF8SUB: - case SRTSUB: - case SSASUB: - track->codecID = MK_SUBTITLE_SSA; - need_fonts = 1; - track->codecPrivate = subtitle->extradata; - track->codecPrivateSize = subtitle->extradata_size; - break; - default: - continue; - } - if ( subtitle->config.default_track ) - { - track->flagDefault = 1; - } - - mux_data = calloc(1, sizeof( hb_mux_data_t ) ); - subtitle->mux_data = mux_data; - mux_data->subtitle = 1; - mux_data->sub_format = subtitle->format; - - track->flagEnabled = 1; - track->trackType = MK_TRACK_SUBTITLE; - // MKV lang codes should be ISO-639-2/B - lang = lang_for_code2( subtitle->iso639_2 ); - track->language = lang->iso639_2b ? lang->iso639_2b : lang->iso639_2; - - mux_data->track = mk_createTrack(m->file, track); - } - - if (need_fonts) - { - hb_list_t * list_attachment = job->list_attachment; - int i; - for ( i = 0; i < hb_list_count(list_attachment); i++ ) - { - hb_attachment_t * attachment = hb_list_item( list_attachment, i ); - - if ( attachment->type == FONT_TTF_ATTACH ) - { - mk_createAttachment( - m->file, - attachment->name, - NULL, - "application/x-truetype-font", - attachment->data, - attachment->size); - } - } - } - - if( mk_writeHeader( m->file, "HandBrake " HB_PROJECT_VERSION) < 0 ) - { - hb_error( "Failed to write to output file, disk full?"); - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - } - if (track != NULL) - free(track); - if (avcC != NULL) - free(avcC); - - return 0; -} - -static int MKVMux(hb_mux_object_t *m, hb_mux_data_t *mux_data, hb_buffer_t *buf) -{ - char chapter_name[1024]; - hb_chapter_t *chapter_data; - uint64_t timecode = 0; - hb_job_t *job = m->job; - - // Adjust for audio preroll and scale units - timecode = (buf->s.start + m->delay) * TIMECODE_SCALE; - if (mux_data == job->mux_data) - { - /* Video */ - if (job->chapter_markers && buf->s.new_chap) - { - // reached chapter N, write marker for chapter N-1 - mux_data->current_chapter = buf->s.new_chap - 1; - - // chapter numbers start at 1, but the list starts at 0 - chapter_data = hb_list_item(job->list_chapter, - mux_data->current_chapter - 1); - - // make sure we're not writing a chapter that has 0 length - if (chapter_data != NULL && mux_data->prev_chapter_tc < timecode) - { - if (chapter_data->title != NULL) - { - snprintf(chapter_name, 1023, "%s", chapter_data->title); - } - else - { - snprintf(chapter_name, 1023, "Chapter %d", - mux_data->current_chapter); - } - mk_createChapterSimple(m->file, - mux_data->prev_chapter_tc, - mux_data->prev_chapter_tc, chapter_name); - } - mux_data->prev_chapter_tc = timecode; - } - } - else if (mux_data->subtitle) - { - if( mk_startFrame(m->file, mux_data->track) < 0) - { - hb_error("Failed to write frame to output file, Disk Full?"); - *job->done_error = HB_ERROR_UNKNOWN; - *job->die = 1; - } - uint64_t duration; - if (buf->s.duration < 0) - { - duration = 10 * NANOSECOND_SCALE; - } - else - { - duration = buf->s.duration * TIMECODE_SCALE; - } - mk_addFrameData(m->file, mux_data->track, buf->data, buf->size); - mk_setFrameFlags(m->file, mux_data->track, timecode, 1, duration); - mk_flushFrame(m->file, mux_data->track); - hb_buffer_close(&buf); - return 0; - } - else - { - /* Audio */ - } - - if( mk_startFrame(m->file, mux_data->track) < 0) - { - hb_error( "Failed to write frame to output file, Disk Full?" ); - *job->done_error = HB_ERROR_UNKNOWN; - *job->die = 1; - } - mk_addFrameData(m->file, mux_data->track, buf->data, buf->size); - mk_setFrameFlags(m->file, mux_data->track, timecode, - ((mux_data == job->mux_data && - ((job->vcodec & HB_VCODEC_H264_MASK) || - (job->vcodec & HB_VCODEC_FFMPEG_MASK))) ? - (buf->s.frametype == HB_FRAME_IDR) : - (buf->s.frametype & HB_FRAME_KEY) != 0), 0); - hb_buffer_close(&buf); - return 0; -} - -static int MKVEnd(hb_mux_object_t *m) -{ - char chapter_name[1024]; - hb_chapter_t *chapter_data; - hb_job_t *job = m->job; - hb_mux_data_t *mux_data = job->mux_data; - - if( !job->mux_data ) - { - /* - * We must have failed to create the file in the first place. - */ - return 0; - } - - if (job->chapter_markers) - { - // get the last chapter - chapter_data = hb_list_item(job->list_chapter, - mux_data->current_chapter++); - - // only write the last chapter marker if it lasts at least 1.5 second - if (chapter_data != NULL && chapter_data->duration > 135000LL) - { - if (chapter_data->title != NULL) - { - snprintf(chapter_name, 1023, "%s", chapter_data->title); - } - else - { - snprintf(chapter_name, 1023, "Chapter %d", - mux_data->current_chapter); - } - mk_createChapterSimple(m->file, - mux_data->prev_chapter_tc, - mux_data->prev_chapter_tc, chapter_name); - } - } - - if( job->metadata ) - { - hb_metadata_t *md = job->metadata; - - hb_deep_log( 2, "Writing Metadata to output file..."); - if ( md->name ) - { - mk_createTagSimple( m->file, MK_TAG_TITLE, md->name ); - } - if ( md->artist ) - { - mk_createTagSimple( m->file, "ARTIST", md->artist ); - } - if ( md->album_artist ) - { - mk_createTagSimple( m->file, "DIRECTOR", md->album_artist ); - } - if ( md->composer ) - { - mk_createTagSimple( m->file, "COMPOSER", md->composer ); - } - if ( md->release_date ) - { - mk_createTagSimple( m->file, "DATE_RELEASED", md->release_date ); - } - if ( md->comment ) - { - mk_createTagSimple( m->file, "SUMMARY", md->comment ); - } - if ( !md->name && md->album ) - { - mk_createTagSimple( m->file, MK_TAG_TITLE, md->album ); - } - if ( md->genre ) - { - mk_createTagSimple( m->file, MK_TAG_GENRE, md->genre ); - } - if ( md->description ) - { - mk_createTagSimple( m->file, "DESCRIPTION", md->description ); - } - if ( md->long_description ) - { - mk_createTagSimple( m->file, "SYNOPSIS", md->long_description ); - } - } - - // Update and track private data that can change during - // encode. - int i; - for( i = 0; i < hb_list_count( job->list_audio ); i++ ) - { - mk_Track * track; - hb_audio_t * audio; - - audio = hb_list_item( job->list_audio, i ); - track = audio->priv.mux_data->track; - - switch (audio->config.out.codec & HB_ACODEC_MASK) - { - case HB_ACODEC_FFFLAC: - case HB_ACODEC_FFFLAC24: - if( audio->priv.config.extradata.bytes ) - { - uint8_t *header; - header = create_flac_header( - audio->priv.config.extradata.bytes, - audio->priv.config.extradata.length ); - mk_updateTrackPrivateData( m->file, track, - header, - audio->priv.config.extradata.length + 8 ); - free( header ); - } - break; - default: - break; - } - } - - if( mk_close(m->file) < 0 ) - { - hb_error( "Failed to flush the last frame and close the output file, Disk Full?" ); - *job->done_error = HB_ERROR_UNKNOWN; - *job->die = 1; - } - - // TODO: Free what we alloc'd - - return 0; -} - -hb_mux_object_t * hb_mux_mkv_init( hb_job_t * job ) -{ - hb_mux_object_t * m = calloc( sizeof( hb_mux_object_t ), 1 ); - m->init = MKVInit; - m->mux = MKVMux; - m->end = MKVEnd; - m->job = job; - return m; -} -#endif // USE_LIBMKV diff --git a/libhb/muxmp4.c b/libhb/muxmp4.c deleted file mode 100644 index 946277574..000000000 --- a/libhb/muxmp4.c +++ /dev/null @@ -1,1249 +0,0 @@ -/* muxmp4.c - - Copyright (c) 2003-2014 HandBrake Team - This file is part of the HandBrake source code - Homepage: <http://handbrake.fr/>. - It may be used under the terms of the GNU General Public License v2. - For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html - */ - -#include "hb.h" - -#if defined(USE_MP4V2) - -#include "mp4v2/mp4v2.h" - -struct hb_mux_object_s -{ - HB_MUX_COMMON; - - hb_job_t * job; - - /* output file name in current code page */ - char * path; - /* libmp4v2 handle */ - MP4FileHandle file; - - int64_t sum_dur; // sum of video frame durations so far - - hb_buffer_t *delay_buf; - - /* Chapter state information for muxing */ - MP4TrackId chapter_track; - int current_chapter; - uint64_t chapter_duration; -}; - -struct hb_mux_data_s -{ - MP4TrackId track; - uint8_t subtitle; - int sub_format; - - uint64_t sum_dur; // sum of the frame durations so far - - // audio frame duration info - int sample_rate; - int samples_per_frame; -}; - -/* Tune video track chunk duration. - * libmp4v2 default duration == dusamplerate == 1 second. - * Per van's suggestion we desire duration == 4 frames. - * Should be invoked immediately after track creation. - * - * return true on fail, false on success. - */ -static int MP4TuneTrackDurationPerChunk( hb_mux_object_t* m, MP4TrackId trackId ) -{ - uint32_t tscale; - MP4Duration dur; - - tscale = MP4GetTrackTimeScale( m->file, trackId ); - dur = (MP4Duration)ceil( (double)tscale * (double)m->job->vrate_base / (double)m->job->vrate * 4.0 ); - - if( !MP4SetTrackDurationPerChunk( m->file, trackId, dur )) - { - hb_error( "muxmp4.c: MP4SetTrackDurationPerChunk failed!" ); - *m->job->done_error = HB_ERROR_UNKNOWN; - *m->job->die = 1; - return 0; - } - - hb_deep_log( 2, "muxmp4: track %u, chunk duration %"PRIu64, MP4FindTrackIndex( m->file, trackId ), dur ); - return 1; -} - -static const uint16_t ac3_sample_rate_tab[3] = { 48000, 44100, 32000 }; -/* possible bitrates */ -static const uint16_t ac3_bitrate_tab[19] = { - 32, 40, 48, 56, 64, 80, 96, 112, 128, - 160, 192, 224, 256, 320, 384, 448, 512, 576, 640 -}; - - -/********************************************************************** - * MP4Init - ********************************************************************** - * Allocates hb_mux_data_t structures, create file and write headers - *********************************************************************/ -static int MP4Init( hb_mux_object_t * m ) -{ - hb_job_t * job = m->job; - hb_title_t * title = job->title; - - hb_audio_t * audio; - hb_mux_data_t * mux_data; - int i; - int subtitle_default; - - /* Flags for enabling/disabling tracks in an MP4. */ - enum - { - TRACK_DISABLED = 0x0, - TRACK_ENABLED = 0x1, - TRACK_IN_MOVIE = 0x2, - TRACK_IN_PREVIEW = 0x4, - TRACK_IN_POSTER = 0x8 - }; - - m->path = hb_utf8_to_cp(job->file); - if (m->path == NULL) - { - hb_error("Could not convert string, out of memory?"); - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - return 0; - } - - /* Create an empty mp4 file */ - if (job->largeFileSize) - /* Use 64-bit MP4 file */ - { - m->file = MP4Create(m->path, MP4_DETAILS_ERROR, MP4_CREATE_64BIT_DATA); - hb_deep_log( 2, "muxmp4: using 64-bit MP4 formatting."); - } - else - /* Limit MP4s to less than 4 GB */ - { - m->file = MP4Create(m->path, MP4_DETAILS_ERROR, 0); - } - - if (m->file == MP4_INVALID_FILE_HANDLE) - { - hb_error("muxmp4.c: MP4Create failed!"); - *job->done_error = HB_ERROR_WRONG_INPUT; - *job->die = 1; - return 0; - } - - /* Video track */ - mux_data = calloc(1, sizeof( hb_mux_data_t ) ); - job->mux_data = mux_data; - - if (!(MP4SetTimeScale( m->file, 90000 ))) - { - hb_error("muxmp4.c: MP4SetTimeScale failed!"); - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - return 0; - } - - if (job->vcodec & HB_VCODEC_H264_MASK) - { - /* Stolen from mp4creator */ - MP4SetVideoProfileLevel( m->file, 0x7F ); - mux_data->track = MP4AddH264VideoTrack( m->file, 90000, - MP4_INVALID_DURATION, job->width, job->height, - job->config.h264.sps[1], /* AVCProfileIndication */ - job->config.h264.sps[2], /* profile_compat */ - job->config.h264.sps[3], /* AVCLevelIndication */ - 3 ); /* 4 bytes length before each NAL unit */ - if ( mux_data->track == MP4_INVALID_TRACK_ID ) - { - hb_error( "muxmp4.c: MP4AddH264VideoTrack failed!" ); - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - return 0; - } - - /* Tune track chunk duration */ - if( !MP4TuneTrackDurationPerChunk( m, mux_data->track )) - { - return 0; - } - - MP4AddH264SequenceParameterSet( m->file, mux_data->track, - job->config.h264.sps, job->config.h264.sps_length ); - MP4AddH264PictureParameterSet( m->file, mux_data->track, - job->config.h264.pps, job->config.h264.pps_length ); - - if( job->ipod_atom ) - { - hb_deep_log( 2, "muxmp4: adding iPod atom"); - MP4AddIPodUUID(m->file, mux_data->track); - } - } - else if ( job->vcodec == HB_VCODEC_FFMPEG_MPEG4 ) /* FFmpeg MPEG-4 */ - { - MP4SetVideoProfileLevel( m->file, MPEG4_SP_L3 ); - mux_data->track = MP4AddVideoTrack( m->file, 90000, - MP4_INVALID_DURATION, job->width, job->height, - MP4_MPEG4_VIDEO_TYPE ); - if (mux_data->track == MP4_INVALID_TRACK_ID) - { - hb_error("muxmp4.c: MP4AddVideoTrack failed!"); - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - return 0; - } - - /* Tune track chunk duration */ - if( !MP4TuneTrackDurationPerChunk( m, mux_data->track )) - { - return 0; - } - - /* VOL from FFmpeg or XviD */ - if (!(MP4SetTrackESConfiguration( m->file, mux_data->track, - job->config.mpeg4.bytes, job->config.mpeg4.length ))) - { - hb_error("muxmp4.c: MP4SetTrackESConfiguration failed!"); - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - return 0; - } - } - else if ( job->vcodec == HB_VCODEC_FFMPEG_MPEG2 ) /* FFmpeg MPEG-2 */ - { - mux_data->track = MP4AddVideoTrack( m->file, 90000, - MP4_INVALID_DURATION, job->width, job->height, - MP4_MPEG2_VIDEO_TYPE ); - if (mux_data->track == MP4_INVALID_TRACK_ID) - { - hb_error("muxmp4.c: MP4AddVideoTrack failed!"); - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - return 0; - } - - /* Tune track chunk duration */ - if( !MP4TuneTrackDurationPerChunk( m, mux_data->track )) - { - return 0; - } - - /* VOL from FFmpeg */ - if (!(MP4SetTrackESConfiguration( m->file, mux_data->track, - job->config.mpeg4.bytes, job->config.mpeg4.length ))) - { - hb_error("muxmp4.c: MP4SetTrackESConfiguration failed!"); - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - return 0; - } - } - else - { - hb_error("muxmp4.c: Unsupported video encoder!"); - } - - /* COLR atom for color and gamma correction. Per the notes at: - * http://developer.apple.com/quicktime/icefloe/dispatch019.html#colr - * http://forum.doom9.org/showthread.php?t=133982#post1090068 - * The user can set it from job->color_matrix_code. */ - if( job->color_matrix_code == 4 ) - { - // Custom - MP4AddColr(m->file, mux_data->track, job->color_prim, job->color_transfer, job->color_matrix); - } - else if( job->color_matrix_code == 3 ) - { - // ITU BT.709 HD content - MP4AddColr(m->file, mux_data->track, HB_COLR_PRI_BT709, HB_COLR_TRA_BT709, HB_COLR_MAT_BT709); - } - else if( job->color_matrix_code == 2 ) - { - // ITU BT.601 DVD or SD TV content (PAL) - MP4AddColr(m->file, mux_data->track, HB_COLR_PRI_EBUTECH, HB_COLR_TRA_BT709, HB_COLR_MAT_SMPTE170M); - } - else if( job->color_matrix_code == 1 ) - { - // ITU BT.601 DVD or SD TV content (NTSC) - MP4AddColr(m->file, mux_data->track, HB_COLR_PRI_SMPTEC, HB_COLR_TRA_BT709, HB_COLR_MAT_SMPTE170M); - } - else - { - // detected during scan - MP4AddColr(m->file, mux_data->track, title->color_prim, title->color_transfer, title->color_matrix); - } - - if( job->anamorphic.mode ) - { - /* PASP atom for anamorphic video */ - float width, height; - - width = job->anamorphic.par_width; - - height = job->anamorphic.par_height; - - MP4AddPixelAspectRatio(m->file, mux_data->track, (uint32_t)width, (uint32_t)height); - - MP4SetTrackFloatProperty(m->file, mux_data->track, "tkhd.width", job->width * (width / height)); - } - - /* add the audio tracks */ - for( i = 0; i < hb_list_count( job->list_audio ); i++ ) - { - audio = hb_list_item( job->list_audio, i ); - mux_data = calloc(1, sizeof( hb_mux_data_t ) ); - audio->priv.mux_data = mux_data; - - switch ( audio->config.out.codec & HB_ACODEC_MASK ) - { - case HB_ACODEC_AC3: - { - int ii, jj; - int bitrate; - int sr_shift, sr_code; - uint8_t bsid; - uint8_t bsmod; - uint8_t acmod; - uint8_t lfeon; - uint8_t br_code = 0; - - if ( audio->config.out.codec & HB_ACODEC_PASS_FLAG ) - { - bsmod = audio->config.in.mode; - switch (audio->config.in.channel_layout & ~AV_CH_LOW_FREQUENCY) - { - case AV_CH_LAYOUT_MONO: - acmod = 1; - break; - - case AV_CH_LAYOUT_STEREO: - acmod = 2; - break; - - case AV_CH_LAYOUT_SURROUND: - acmod = 3; - break; - - case AV_CH_LAYOUT_2_1: - acmod = 4; - break; - - case AV_CH_LAYOUT_4POINT0: - acmod = 5; - break; - - case AV_CH_LAYOUT_2_2: - acmod = 6; - break; - - case AV_CH_LAYOUT_5POINT0: - acmod = 7; - break; - - default: - hb_error("MP4Init: bad mixdown"); - acmod = 2; - break; - } - lfeon = !!(audio->config.in.channel_layout & AV_CH_LOW_FREQUENCY); - bitrate = audio->config.in.bitrate; - mux_data->sample_rate = audio->config.in.samplerate; - mux_data->samples_per_frame = audio->config.in.samples_per_frame; - } - else - { - bsmod = 0; - bitrate = audio->config.out.bitrate * 1000; - mux_data->sample_rate = audio->config.out.samplerate; - mux_data->samples_per_frame = audio->config.out.samples_per_frame; - switch (audio->config.out.mixdown) - { - case HB_AMIXDOWN_MONO: - acmod = 1; - lfeon = 0; - break; - - case HB_AMIXDOWN_STEREO: - case HB_AMIXDOWN_DOLBY: - case HB_AMIXDOWN_DOLBYPLII: - acmod = 2; - lfeon = 0; - break; - - case HB_AMIXDOWN_5POINT1: - acmod = 7; - lfeon = 1; - break; - - default: - hb_log("MP4Init: bad mixdown"); - acmod = 2; - lfeon = 0; - break; - } - } - - for (ii = 0; ii < 3; ii++) - { - for (jj = 0; jj < 3; jj++) - { - if ((ac3_sample_rate_tab[jj] >> ii) == mux_data->sample_rate) - { - goto rate_found1; - } - } - } - hb_error("Unknown AC3 samplerate"); - ii = jj = 0; - rate_found1: - sr_shift = ii; - sr_code = jj; - bsid = 8 + ii; - for (ii = 0; ii < 19; ii++) - { - if ((ac3_bitrate_tab[ii] >> sr_shift)*1000 == bitrate) - break; - } - if ( ii >= 19 ) - { - hb_error("Unknown AC3 bitrate"); - ii = 0; - } - br_code = ii; - - mux_data->track = MP4AddAC3AudioTrack(m->file, - mux_data->sample_rate, - sr_code, bsid, bsmod, - acmod, lfeon, br_code); - - /* Tune track chunk duration */ - MP4TuneTrackDurationPerChunk( m, mux_data->track ); - - if (audio->config.out.name == NULL) { - MP4SetTrackBytesProperty( - m->file, mux_data->track, - "udta.name.value", - (const uint8_t*)"Surround", strlen("Surround")); - } - else { - MP4SetTrackBytesProperty( - m->file, mux_data->track, - "udta.name.value", - (const uint8_t*)(audio->config.out.name), - strlen(audio->config.out.name)); - } - } break; - - case HB_ACODEC_FFAAC: - case HB_ACODEC_CA_AAC: - case HB_ACODEC_CA_HAAC: - case HB_ACODEC_FDK_AAC: - case HB_ACODEC_FDK_HAAC: - case HB_ACODEC_LAME: - case HB_ACODEC_MP3: - case HB_ACODEC_DCA_HD: - case HB_ACODEC_DCA: - { - uint8_t audio_type = MP4_MPEG4_AUDIO_TYPE; - int channels, config_len = 0; - uint8_t *config_bytes = NULL; - - switch ( audio->config.out.codec & HB_ACODEC_MASK ) - { - case HB_ACODEC_FFAAC: - case HB_ACODEC_CA_AAC: - case HB_ACODEC_CA_HAAC: - case HB_ACODEC_FDK_AAC: - case HB_ACODEC_FDK_HAAC: - { - audio_type = MP4_MPEG4_AUDIO_TYPE; - config_bytes = audio->priv.config.extradata.bytes; - config_len = audio->priv.config.extradata.length; - } break; - case HB_ACODEC_LAME: - case HB_ACODEC_MP3: - { - audio_type = MP4_MPEG2_AUDIO_TYPE; - } break; - case HB_ACODEC_DCA: - case HB_ACODEC_DCA_HD: - { - audio_type = 0xA9; - } break; - } - if (audio->config.out.codec & HB_ACODEC_PASS_FLAG) - { - mux_data->sample_rate = audio->config.in.samplerate; - mux_data->samples_per_frame = audio->config.in.samples_per_frame; - channels = av_get_channel_layout_nb_channels(audio->config.in.channel_layout); - } - else - { - mux_data->sample_rate = audio->config.out.samplerate; - mux_data->samples_per_frame = audio->config.out.samples_per_frame; - channels = hb_mixdown_get_discrete_channel_count(audio->config.out.mixdown); - } - mux_data->track = MP4AddAudioTrack(m->file, - mux_data->sample_rate, - // fixed frame duration, if applicable - mux_data->samples_per_frame > 0 ? - mux_data->samples_per_frame : MP4_INVALID_DURATION, - audio_type); - - /* Tune track chunk duration */ - MP4TuneTrackDurationPerChunk( m, mux_data->track ); - - if (audio->config.out.name == NULL) { - MP4SetTrackBytesProperty( - m->file, mux_data->track, - "udta.name.value", - (const uint8_t*)"Stereo", strlen("Stereo")); - } - else { - MP4SetTrackBytesProperty( - m->file, mux_data->track, - "udta.name.value", - (const uint8_t*)(audio->config.out.name), - strlen(audio->config.out.name)); - } - - MP4SetAudioProfileLevel( m->file, 0x0F ); - if ( config_bytes ) - { - MP4SetTrackESConfiguration( m->file, mux_data->track, - config_bytes, config_len ); - } - /* Set the correct number of channels for this track */ - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.*.channels", channels); - } break; - - default: - { - hb_log("MP4Mux: Unsupported audio codec %x", audio->config.out.codec); - } break; - } - - /* Set the language for this track */ - MP4SetTrackLanguage(m->file, mux_data->track, audio->config.lang.iso639_2); - - if( hb_list_count( job->list_audio ) > 1 ) - { - /* Set the audio track alternate group */ - MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.alternate_group", 1); - } - - if (i == 0) { - /* Enable the first audio track */ - MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_ENABLED | TRACK_IN_MOVIE)); - } - else - /* Disable the other audio tracks so QuickTime doesn't play - them all at once. */ - { - MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_DISABLED | TRACK_IN_MOVIE)); - hb_deep_log( 2, "muxmp4: disabled extra audio track %u", MP4FindTrackIndex( m->file, mux_data->track )); - } - - } - - // Quicktime requires that at least one subtitle is enabled, - // else it doesn't show any of the subtitles. - // So check to see if any of the subtitles are flagged to be - // the defualt. The default will the the enabled track, else - // enable the first track. - subtitle_default = 0; - for( i = 0; i < hb_list_count( job->list_subtitle ); i++ ) - { - hb_subtitle_t *subtitle = hb_list_item( job->list_subtitle, i ); - - if( subtitle && subtitle->format == TEXTSUB && - subtitle->config.dest == PASSTHRUSUB ) - { - if ( subtitle->config.default_track ) - subtitle_default = 1; - } - } - for( i = 0; i < hb_list_count( job->list_subtitle ); i++ ) - { - hb_subtitle_t *subtitle = hb_list_item( job->list_subtitle, i ); - - if( subtitle && subtitle->format == TEXTSUB && - subtitle->config.dest == PASSTHRUSUB ) - { - uint64_t width, height = 60; - if( job->anamorphic.mode ) - width = job->width * ( (float) job->anamorphic.par_width / job->anamorphic.par_height ); - else - width = job->width; - - mux_data = calloc(1, sizeof( hb_mux_data_t ) ); - subtitle->mux_data = mux_data; - mux_data->subtitle = 1; - mux_data->sub_format = subtitle->format; - mux_data->track = MP4AddSubtitleTrack( m->file, 90000, width, height ); - - MP4SetTrackLanguage(m->file, mux_data->track, subtitle->iso639_2); - - /* Tune track chunk duration */ - MP4TuneTrackDurationPerChunk( m, mux_data->track ); - - const uint8_t textColor[4] = { 255,255,255,255 }; - - MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.alternate_group", 2); - - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.dataReferenceIndex", 1); - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.horizontalJustification", 1); - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.verticalJustification", 255); - - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.bgColorAlpha", 255); - - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.defTextBoxBottom", height); - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.defTextBoxRight", width); - - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.fontID", 1); - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.fontSize", 24); - - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.fontColorRed", textColor[0]); - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.fontColorGreen", textColor[1]); - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.fontColorBlue", textColor[2]); - MP4SetTrackIntegerProperty(m->file, mux_data->track, "mdia.minf.stbl.stsd.tx3g.fontColorAlpha", textColor[3]); - - /* translate the track */ - uint8_t* val; - uint8_t nval[36]; - uint32_t *ptr32 = (uint32_t*) nval; - uint32_t size; - - MP4GetTrackBytesProperty(m->file, mux_data->track, "tkhd.matrix", &val, &size); - memcpy(nval, val, size); - - const uint32_t ytranslation = (job->height - height) * 0x10000; - -#ifdef WORDS_BIGENDIAN - ptr32[7] = ytranslation; -#else - /* we need to switch the endianness, as the file format expects big endian */ - ptr32[7] = ((ytranslation & 0x000000FF) << 24) + ((ytranslation & 0x0000FF00) << 8) + - ((ytranslation & 0x00FF0000) >> 8) + ((ytranslation & 0xFF000000) >> 24); -#endif - - MP4SetTrackBytesProperty(m->file, mux_data->track, "tkhd.matrix", nval, size); - if ( !subtitle_default || subtitle->config.default_track ) { - /* Enable the default subtitle track */ - MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_ENABLED | TRACK_IN_MOVIE)); - subtitle_default = 1; - } - else - { - MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_DISABLED | TRACK_IN_MOVIE)); - } - } - else if( subtitle && subtitle->format == PICTURESUB && - subtitle->config.dest == PASSTHRUSUB ) - { - mux_data = calloc(1, sizeof( hb_mux_data_t ) ); - subtitle->mux_data = mux_data; - mux_data->subtitle = 1; - mux_data->sub_format = subtitle->format; - - mux_data->track = MP4AddSubpicTrack( m->file, 90000, subtitle->width, subtitle->height ); - - MP4SetTrackLanguage(m->file, mux_data->track, subtitle->iso639_2); - - /* Tune track chunk duration */ - MP4TuneTrackDurationPerChunk( m, mux_data->track ); - uint8_t palette[16][4]; - int ii; - for ( ii = 0; ii < 16; ii++ ) - { - palette[ii][0] = 0; - palette[ii][1] = (subtitle->palette[ii] >> 16) & 0xff; - palette[ii][2] = (subtitle->palette[ii] >> 8) & 0xff; - palette[ii][3] = (subtitle->palette[ii]) & 0xff; - } - if (!(MP4SetTrackESConfiguration( m->file, mux_data->track, - (uint8_t*)palette, 16 * 4 ))) - { - hb_error("muxmp4.c: MP4SetTrackESConfiguration failed!"); - *job->done_error = HB_ERROR_INIT; - *job->die = 1; - return 0; - } - if ( !subtitle_default || subtitle->config.default_track ) { - /* Enable the default subtitle track */ - MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_ENABLED | TRACK_IN_MOVIE)); - subtitle_default = 1; - } - else - { - MP4SetTrackIntegerProperty(m->file, mux_data->track, "tkhd.flags", (TRACK_DISABLED | TRACK_IN_MOVIE)); - } - } - } - - if (job->chapter_markers) - { - /* add a text track for the chapters. We add the 'chap' atom to track - one which is usually the video track & should never be disabled. - The Quicktime spec says it doesn't matter which media track the - chap atom is on but it has to be an enabled track. */ - MP4TrackId textTrack; - textTrack = MP4AddChapterTextTrack(m->file, 1, 0); - - m->chapter_track = textTrack; - m->chapter_duration = 0; - m->current_chapter = job->chapter_start; - } - - /* Add encoded-by metadata listing version and build date */ - char *tool_string; - tool_string = (char *)malloc(80); - snprintf( tool_string, 80, "HandBrake %s %i", HB_PROJECT_VERSION, HB_PROJECT_BUILD); - - /* allocate,fetch,populate,store,free tags structure */ - const MP4Tags* tags; - tags = MP4TagsAlloc(); - MP4TagsFetch( tags, m->file ); - MP4TagsSetEncodingTool( tags, tool_string ); - MP4TagsStore( tags, m->file ); - MP4TagsFree( tags ); - - free(tool_string); - - return 0; -} - -static int MP4Mux( hb_mux_object_t * m, hb_mux_data_t * mux_data, - hb_buffer_t * buf ) -{ - hb_job_t * job = m->job; - int64_t duration, stop = AV_NOPTS_VALUE; - int64_t offset = 0; - hb_buffer_t *tmp; - - if (buf != NULL) - { - if (buf->s.duration >= 0) - { - stop = buf->s.start + buf->s.duration; - } - else if (mux_data->subtitle) - { - buf->s.duration = 10 * 90000; - stop = buf->s.start + buf->s.duration; - } - } - - if( mux_data == job->mux_data ) - { - /* Video */ - if ((job->vcodec & HB_VCODEC_H264_MASK) || - (job->vcodec & HB_VCODEC_FFMPEG_MASK)) - { - if ( buf && buf->s.start < buf->s.renderOffset ) - { - hb_log("MP4Mux: PTS %"PRId64" < DTS %"PRId64, - buf->s.start, buf->s.renderOffset ); - buf->s.renderOffset = buf->s.start; - } - } - - // We delay muxing video by one frame so that we can calculate - // the dts to dts duration of the frames. - tmp = buf; - buf = m->delay_buf; - m->delay_buf = tmp; - - if ( !buf ) - return 0; - - stop = buf->s.start + buf->s.duration; - - if ((job->vcodec & HB_VCODEC_H264_MASK) || - (job->vcodec & HB_VCODEC_FFMPEG_MASK)) - { - // x264 supplies us with DTS, so offset is PTS - DTS - offset = buf->s.start - buf->s.renderOffset; - } - - /* Add the sample before the new frame. - It is important that this be calculated prior to the duration - of the new video sample, as we want to sync to right after it. - (This is because of how durations for text tracks work in QT) */ - if( job->chapter_markers && buf->s.new_chap ) - { - hb_chapter_t *chapter = NULL; - - // this chapter is postioned by writing out the previous chapter. - // the duration of the previous chapter is the duration up to but - // not including the current frame minus the duration of all - // chapters up to the previous. - // The initial and final chapters can be very short (a second or - // less) since they're not really chapters but just a placeholder to - // insert a cell command. We don't write chapters shorter than 1.5 sec. - duration = m->sum_dur - m->chapter_duration + offset; - if ( duration >= (90000*3)/2 ) - { - chapter = hb_list_item( m->job->list_chapter, - buf->s.new_chap - 2 ); - - MP4AddChapter( m->file, - m->chapter_track, - duration, - (chapter != NULL) ? chapter->title : NULL); - - m->current_chapter = buf->s.new_chap; - m->chapter_duration += duration; - } - } - - if ((job->vcodec & HB_VCODEC_H264_MASK) || - (job->vcodec & HB_VCODEC_FFMPEG_MASK)) - { - // x264 supplies us with DTS - if ( m->delay_buf ) - { - duration = m->delay_buf->s.renderOffset - buf->s.renderOffset; - } - else - { - duration = stop - m->sum_dur; - // Due to how libx264 generates DTS, it's possible for the - // above calculation to be negative. - // - // x264 generates DTS by rearranging PTS in this sequence: - // pts0 - delay, pts1 - delay, pts2 - delay, pts1, pts2, pts3... - // - // where delay == pts2. This guarantees that DTS <= PTS for - // any frame, but also generates this sequence of durations: - // d0 + d1 + d0 + d1 + d2 + d3 ... + d(N-2) - // - // so the sum up to the last frame is: - // sum_dur = d0 + d1 + d0 + d1 + d2 + d3 ... + d(N-3) - // - // while the original total duration of the video was: - // duration = d0 + d1 + d2 + d3 ... + d(N) - // - // Note that if d0 + d1 != d(N-1) + d(N), the total - // length of the video changes since d(N-1) and d(N) are - // replaced by d0 and d1 in the final duration sum. - // - // To keep the total length of the video the same as the source - // we try to make - // d(N-2) = duration - sum_dur - // - // But if d0 + d1 >= d(N-1) + d(N), the above calculation - // results in a nagative value and we need to fix it. - if ( duration <= 0 ) - duration = 90000. / ((double)job->vrate / (double)job->vrate_base); - } - } - else - { - // We're getting the frames in decode order but the timestamps are - // for presentation so we have to use durations and effectively - // compute a DTS. - duration = buf->s.duration; - } - - if ( duration <= 0 ) - { - /* We got an illegal mp4/h264 duration. This shouldn't - be possible and usually indicates a bug in the upstream code. - Complain in the hope that someone will go find the bug but - try to fix the error so that the file will still be playable. */ - hb_log("MP4Mux: illegal duration %"PRId64", start %"PRId64"," - "stop %"PRId64", sum_dur %"PRId64, - duration, buf->s.start, stop, m->sum_dur ); - /* we don't know when the next frame starts so we can't pick a - valid duration for this one. we pick something "short" - (roughly 1/3 of an NTSC frame time) to take time from - the next frame. */ - duration = 1000; - } - m->sum_dur += duration; - } - else - { - /* Audio */ - if (mux_data->samples_per_frame > 0) - // frame size is fixed and known - duration = MP4_INVALID_DURATION; - else - // frame size has to be computed - duration = buf->s.duration * mux_data->sample_rate / 90000; - } - - /* Here's where the sample actually gets muxed. */ - if (mux_data == job->mux_data && ((job->vcodec & HB_VCODEC_H264_MASK) || - (job->vcodec & HB_VCODEC_FFMPEG_MASK))) - { - /* Compute dependency flags. - * - * This mechanism is (optionally) used by media players such as QuickTime - * to offer better scrubbing performance. The most influential bits are - * MP4_SDT_HAS_NO_DEPENDENTS and MP4_SDT_EARLIER_DISPLAY_TIMES_ALLOWED. - * - * Other bits are possible but no example media using such bits have been - * found. - * - * It is acceptable to supply 0-bits for any samples which characteristics - * cannot be positively guaranteed. - */ - int sync = 0; - uint32_t dflags = 0; - - /* encoding layer signals if frame is referenced by other frames */ - if( buf->s.flags & HB_FRAME_REF ) - dflags |= MP4_SDT_HAS_DEPENDENTS; - else - dflags |= MP4_SDT_HAS_NO_DEPENDENTS; /* disposable */ - - switch( buf->s.frametype ) - { - case HB_FRAME_IDR: - sync = 1; - break; - case HB_FRAME_I: - dflags |= MP4_SDT_EARLIER_DISPLAY_TIMES_ALLOWED; - break; - case HB_FRAME_P: - dflags |= MP4_SDT_EARLIER_DISPLAY_TIMES_ALLOWED; - break; - case HB_FRAME_BREF: - case HB_FRAME_B: - default: - break; /* nothing to mark */ - } - - if( !MP4WriteSampleDependency( m->file, - mux_data->track, - buf->data, - buf->size, - duration, - offset, - sync, - dflags )) - { - hb_error("Failed to write to output file, disk full?"); - *job->done_error = HB_ERROR_UNKNOWN; - *job->die = 1; - } - } - else if (mux_data->subtitle) - { - if( mux_data->sub_format == TEXTSUB ) - { - /* MPEG4 timed text does not allow overlapping samples; upstream - code should coalesce overlapping subtitle lines. */ - if( buf->s.start < mux_data->sum_dur ) - { - if ( stop - mux_data->sum_dur > 90*500 ) - { - hb_log("MP4Mux: shortening overlapping subtitle, " - "start %"PRId64", stop %"PRId64", sum_dur %"PRId64, - buf->s.start, stop, m->sum_dur); - buf->s.start = mux_data->sum_dur; - } - } - if( buf->s.start < mux_data->sum_dur ) - { - hb_log("MP4Mux: skipping overlapping subtitle, " - "start %"PRId64", stop %"PRId64", sum_dur %"PRId64, - buf->s.start, stop, m->sum_dur); - } - else - { - /* Write an empty sample */ - if ( mux_data->sum_dur < buf->s.start ) - { - uint8_t empty[2] = {0,0}; - if( !MP4WriteSample( m->file, - mux_data->track, - empty, - 2, - buf->s.start - mux_data->sum_dur, - 0, - 1 )) - { - hb_error("Failed to write to output file, disk full?"); - *job->done_error = HB_ERROR_UNKNOWN; - *job->die = 1; - } - mux_data->sum_dur += buf->s.start - mux_data->sum_dur; - } - uint8_t styleatom[2048];; - uint16_t stylesize = 0; - uint8_t buffer[2048]; - uint16_t buffersize = 0; - uint8_t output[2048]; - - *buffer = '\0'; - - /* - * Copy the subtitle into buffer stripping markup and creating - * style atoms for them. - */ - hb_muxmp4_process_subtitle_style( buf->data, - buffer, - styleatom, &stylesize ); - - buffersize = strlen((char*)buffer); - - hb_deep_log(3, "MuxMP4:Sub:%fs:%"PRId64":%"PRId64":%f: %s", - (float)buf->s.start / 90000, buf->s.start, stop, - buf->s.duration, buffer); - - /* Write the subtitle sample */ - memcpy( output + 2, buffer, buffersize ); - memcpy( output + 2 + buffersize, styleatom, stylesize); - output[0] = ( buffersize >> 8 ) & 0xff; - output[1] = buffersize & 0xff; - - if( !MP4WriteSample( m->file, - mux_data->track, - output, - buffersize + stylesize + 2, - buf->s.duration, - 0, - 1 )) - { - hb_error("Failed to write to output file, disk full?"); - *job->done_error = HB_ERROR_UNKNOWN; - *job->die = 1; - } - - mux_data->sum_dur += buf->s.duration; - } - } - else if( mux_data->sub_format == PICTURESUB ) - { - /* Write an empty sample */ - if ( mux_data->sum_dur < buf->s.start ) - { - uint8_t empty[2] = {0,0}; - if( !MP4WriteSample( m->file, - mux_data->track, - empty, - 2, - buf->s.start - mux_data->sum_dur, - 0, - 1 )) - { - hb_error("Failed to write to output file, disk full?"); - *job->done_error = HB_ERROR_UNKNOWN; - *job->die = 1; - } - mux_data->sum_dur += buf->s.start - mux_data->sum_dur; - } - if( !MP4WriteSample( m->file, - mux_data->track, - buf->data, - buf->size, - buf->s.duration, - 0, - 1 )) - { - hb_error("Failed to write to output file, disk full?"); - *job->done_error = HB_ERROR_UNKNOWN; - *job->die = 1; - } - - mux_data->sum_dur += buf->s.duration; - } - } - else - { - /* - * Audio - */ - if( !MP4WriteSample( m->file, - mux_data->track, - buf->data, - buf->size, - duration, - offset, - ( buf->s.frametype & HB_FRAME_KEY ) != 0 )) - { - hb_error("Failed to write to output file, disk full?"); - *job->done_error = HB_ERROR_UNKNOWN; - *job->die = 1; - } - } - hb_buffer_close( &buf ); - - return 0; -} - -static int MP4End( hb_mux_object_t * m ) -{ - hb_job_t * job = m->job; - int i; - - if (m->file != MP4_INVALID_FILE_HANDLE) - { - // Flush the delayed frame - if ( m->delay_buf ) - MP4Mux( m, job->mux_data, NULL ); - - /* Write our final chapter marker */ - if( m->job->chapter_markers ) - { - hb_chapter_t *chapter = NULL; - int64_t duration = m->sum_dur - m->chapter_duration; - /* The final chapter can have a very short duration - if it's less - * than 1.5 seconds just skip it. */ - if ( duration >= (90000*3)/2 ) - { - - chapter = hb_list_item( m->job->list_chapter, - m->current_chapter - 1 ); - - MP4AddChapter( m->file, - m->chapter_track, - duration, - (chapter != NULL) ? chapter->title : NULL); - } - } - - if ( job->config.h264.init_delay ) - { - // Insert track edit to get A/V back in sync. The edit amount is - // the init_delay. - int64_t edit_amt = job->config.h264.init_delay; - MP4AddTrackEdit(m->file, 1, MP4_INVALID_EDIT_ID, edit_amt, - MP4GetTrackDuration(m->file, 1), 0); - if ( m->job->chapter_markers ) - { - // apply same edit to chapter track to keep it in sync with video - MP4AddTrackEdit(m->file, m->chapter_track, MP4_INVALID_EDIT_ID, - edit_amt, - MP4GetTrackDuration(m->file, m->chapter_track), 0); - } - } - - // Check for audio preroll and add edit entries for audio - for( i = 0; i < hb_list_count( job->list_audio ); i++ ) - { - hb_audio_t *audio = hb_list_item( job->list_audio, i ); - hb_mux_data_t *mux_data = audio->priv.mux_data; - if (audio->config.out.delay > 0) - { - int64_t edit_amt = audio->config.out.delay; - MP4AddTrackEdit(m->file, mux_data->track, MP4_INVALID_EDIT_ID, - edit_amt, MP4GetTrackDuration(m->file, 1), 0); - } - } - - /* - * Write the MP4 iTunes metadata if we have any metadata - */ - if( job->metadata ) - { - hb_metadata_t *md = job->metadata; - const MP4Tags* tags; - - hb_deep_log( 2, "Writing Metadata to output file..."); - - /* allocate tags structure */ - tags = MP4TagsAlloc(); - /* fetch data from MP4 file (in case it already has some data) */ - MP4TagsFetch( tags, m->file ); - - /* populate */ - if( md->name ) - MP4TagsSetName( tags, md->name ); - if( md->artist ) - MP4TagsSetArtist( tags, md->artist ); - if( md->composer ) - MP4TagsSetComposer( tags, md->composer ); - if( md->comment ) - MP4TagsSetComments( tags, md->comment ); - if( md->release_date ) - MP4TagsSetReleaseDate( tags, md->release_date ); - if( md->album ) - MP4TagsSetAlbum( tags, md->album ); - if( md->album_artist ) - MP4TagsSetAlbumArtist( tags, md->album_artist ); - if( md->genre ) - MP4TagsSetGenre( tags, md->genre ); - if( md->description ) - MP4TagsSetDescription( tags, md->description ); - if( md->long_description ) - MP4TagsSetLongDescription( tags, md->long_description ); - - if( md->list_coverart ) - { - hb_coverart_t * coverart; - int ii; - - for ( ii = 0; ii < hb_list_count( md->list_coverart ); ii++ ) - { - coverart = hb_list_item( md->list_coverart, ii ); - MP4TagArtwork art; - int type; - switch ( coverart->type ) - { - case HB_ART_BMP: - type = MP4_ART_BMP; - break; - case HB_ART_GIF: - type = MP4_ART_GIF; - break; - case HB_ART_JPEG: - type = MP4_ART_JPEG; - break; - case HB_ART_PNG: - type = MP4_ART_PNG; - break; - default: - type = MP4_ART_UNDEFINED; - break; - } - art.data = coverart->data; - art.size = coverart->size; - art.type = type; - MP4TagsAddArtwork( tags, &art ); - } - } - - /* push data to MP4 file */ - MP4TagsStore( tags, m->file ); - /* free memory associated with structure */ - MP4TagsFree( tags ); - } - - MP4Close( m->file ); - - if ( job->mp4_optimize ) - { - hb_log( "muxmp4: optimizing file" ); - char filename[1024]; memset( filename, 0, 1024 ); - snprintf(filename, 1024, "%s.tmp", m->path); - MP4Optimize(m->path, filename, MP4_DETAILS_ERROR); - remove(m->path); - rename(filename, m->path); - } - - } - free(m->path); - - return 0; -} - -hb_mux_object_t * hb_mux_mp4_init( hb_job_t * job ) -{ - hb_mux_object_t * m = calloc( sizeof( hb_mux_object_t ), 1 ); - m->init = MP4Init; - m->mux = MP4Mux; - m->end = MP4End; - m->job = job; - return m; -} - -#endif // USE_MP4V2 diff --git a/libhb/stream.c b/libhb/stream.c index 5ebdc3639..05f1e9fc9 100644 --- a/libhb/stream.c +++ b/libhb/stream.c @@ -5523,11 +5523,7 @@ static hb_title_t *ffmpeg_title_scan( hb_stream_t *stream, hb_title_t *title ) /* * Fill the metadata. */ - // JJJ: is this necessary? can we just get this metadata from libav api's? - if (!decmetadata( title )) - { - ffmpeg_decmetadata( ic->metadata, title ); - } + ffmpeg_decmetadata( ic->metadata, title ); if( hb_list_count( title->list_chapter ) == 0 ) { diff --git a/macosx/Controller.m b/macosx/Controller.m index e1a45d206..efbf6e863 100644 --- a/macosx/Controller.m +++ b/macosx/Controller.m @@ -4507,8 +4507,6 @@ fWorkingCount = 0; [fDstMp4iPodFileCheck setHidden:YES]; switch (videoContainer) { - case HB_MUX_MP4V2: - [fDstMp4LargeFileCheck setHidden:NO]; case HB_MUX_AV_MP4: [fDstMp4HttpOptFileCheck setHidden:NO]; [fDstMp4iPodFileCheck setHidden:NO]; diff --git a/macosx/HandBrake.xcodeproj/project.pbxproj b/macosx/HandBrake.xcodeproj/project.pbxproj index c2e14bebb..c92c026eb 100644 --- a/macosx/HandBrake.xcodeproj/project.pbxproj +++ b/macosx/HandBrake.xcodeproj/project.pbxproj @@ -298,8 +298,6 @@ 277EFE8917ED4F5D001D4A6A /* osx108.i386.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = osx108.i386.xcconfig; sourceTree = "<group>"; }; 277EFE8B17ED4F63001D4A6A /* osx108.x86_64.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = osx108.x86_64.xcconfig; sourceTree = "<group>"; }; 277EFE8D17ED5628001D4A6A /* supplemental.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = supplemental.xcconfig; sourceTree = "<group>"; }; - 277EFE8F17ED7296001D4A6A /* libmp4v2.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmp4v2.a; path = external/contrib/lib/libmp4v2.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 277EFE9017ED72A1001D4A6A /* libmkv.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmkv.a; path = external/contrib/lib/libmkv.a; sourceTree = BUILT_PRODUCTS_DIR; }; 277EFE9217ED799E001D4A6A /* libfdk-aac.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libfdk-aac.a"; path = "external/contrib/lib/libfdk-aac.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 27D6C72414B1019100B785E4 /* libhandbrake.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libhandbrake.a; path = external/libhb/libhandbrake.a; sourceTree = BUILT_PRODUCTS_DIR; }; 27D6C72814B102DA00B785E4 /* libass.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libass.a; path = external/contrib/lib/libass.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -729,8 +727,6 @@ isa = PBXGroup; children = ( 277EFE9217ED799E001D4A6A /* libfdk-aac.a */, - 277EFE9017ED72A1001D4A6A /* libmkv.a */, - 277EFE8F17ED7296001D4A6A /* libmp4v2.a */, 22CC9E74191EBEA500C69D81 /* libx265.a */, ); name = "Static Libraries (optional)"; diff --git a/macosx/xcconfig/supplemental.xcconfig b/macosx/xcconfig/supplemental.xcconfig index a92536f8d..5f72bce04 100644 --- a/macosx/xcconfig/supplemental.xcconfig +++ b/macosx/xcconfig/supplemental.xcconfig @@ -1,4 +1,4 @@ // ## THIS FILE IS INTENDED FOR LOCAL WORKSPACE ONLY. // ## THIS FILE SHOULD NEVER BE COMMITTED TO REPOSITORY WITH UNCOMMENTED LINES. -// EXTERNAL_CONFIGURE = --disable-mp4v2 --disable-mkv +// EXTERNAL_CONFIGURE = diff --git a/make/configure.py b/make/configure.py index 36c7cb31d..4081e26af 100644 --- a/make/configure.py +++ b/make/configure.py @@ -1208,7 +1208,8 @@ def createCLI(): grp.add_option( '--enable-hwd', default=False, action='store_true', help=h ) h = IfHost( 'enable use of x265 encoding', '*-*-*', none=optparse.SUPPRESS_HELP ).value - grp.add_option( '--enable-x265', default=False, action='store_true', help=h ) + grp.add_option( '--enable-x265', default=True, action='store_true', help=h ) + grp.add_option( '--disable-x265', dest="enable_x265", action='store_false' ) h = IfHost( 'enable use of fdk-aac encoder', '*-*-*', none=optparse.SUPPRESS_HELP ).value grp.add_option( '--enable-fdk-aac', dest="enable_fdk_aac", default=not host.match( '*-*-darwin*' ), action='store_true', help=h ) @@ -1218,18 +1219,6 @@ def createCLI(): grp.add_option( '--enable-libav-aac', dest="enable_libav_aac", default=not host.match( '*-*-darwin*' ), action='store_true', help=h ) grp.add_option( '--disable-libav-aac', dest="enable_libav_aac", action='store_false' ) - h = IfHost( 'enable use of mp4v2 muxer', '*-*-*', none=optparse.SUPPRESS_HELP ).value - grp.add_option( '--enable-mp4v2', dest="enable_mp4v2", default=True, action='store_true', help=h ) - grp.add_option( '--disable-mp4v2', dest="enable_mp4v2", action='store_false' ) - - h = IfHost( 'enable use of libmkv muxer', '*-*-*', none=optparse.SUPPRESS_HELP ).value - grp.add_option( '--enable-libmkv', dest="enable_libmkv", default=True, action='store_true', help=h ) - grp.add_option( '--disable-libmkv', dest="enable_libmkv", action='store_false' ) - - h = IfHost( 'enable use of avformat muxer', '*-*-*', none=optparse.SUPPRESS_HELP ).value - grp.add_option( '--enable-avformat', dest="enable_avformat", default=True, action='store_true', help=h ) - grp.add_option( '--disable-avformat', dest="enable_avformat", action='store_false' ) - cli.add_option_group( grp ) ## add launch options @@ -1679,9 +1668,6 @@ int main () doc.add( 'FEATURE.gst', int( not options.disable_gst )) doc.add( 'FEATURE.fdk_aac', int( options.enable_fdk_aac )) doc.add( 'FEATURE.libav_aac', int( options.enable_libav_aac )) - doc.add( 'FEATURE.mp4v2', int( options.enable_mp4v2 )) - doc.add( 'FEATURE.libmkv', int( options.enable_libmkv )) - doc.add( 'FEATURE.avformat', int( options.enable_avformat )) doc.add( 'FEATURE.qsv', int( options.enable_qsv )) doc.add( 'FEATURE.hwd', int( options.enable_hwd )) doc.add( 'FEATURE.xcode', int( not (Tools.xcodebuild.fail or options.disable_xcode or options.cross) )) diff --git a/make/include/main.defs b/make/include/main.defs index 513afe116..e756e9565 100644 --- a/make/include/main.defs +++ b/make/include/main.defs @@ -45,14 +45,6 @@ ifeq (1,$(FEATURE.fdk_aac)) MODULES += contrib/fdk-aac endif -ifeq (1,$(FEATURE.mp4v2)) - MODULES += contrib/mp4v2 -endif - -ifeq (1,$(FEATURE.libmkv)) - MODULES += contrib/libmkv -endif - ifeq (1,$(FEATURE.x265)) MODULES += contrib/x265 endif |