diff --git a/src/common/codec.cpp b/src/common/codec.cpp new file mode 100644 index 000000000..adb698f00 --- /dev/null +++ b/src/common/codec.cpp @@ -0,0 +1,133 @@ +/* + mkvmerge -- utility for splicing together matroska files + from component media subtypes + + Distributed under the GPL + see the file COPYING for details + or visit http://www.gnu.org/copyleft/gpl.html + + Definitions for the various Codec IDs + + Written by Moritz Bunkus . +*/ + +#include "common/common_pch.h" + +#include "common/codec.h" +#include "common/mp4.h" + +std::vector codec_c::ms_codecs; + +void +codec_c::initialize() { + if (!ms_codecs.empty()) + return; + ms_codecs.emplace_back("MPEG-1/2", CT_V_MPEG12, "mpeg|mpg[12]|m[12]v.|mpgv|mp[12]v|h262|V_MPEG[12]"); + ms_codecs.emplace_back("MPEG-4p2", CT_V_MPEG4_P2, "3iv2|xvi[dx]|divx|dx50|fmp4|mp4v|V_MPEG4/ISO/(?:SP|AP|ASP)"); + ms_codecs.emplace_back("MPEG-4p10/AVC/h.264", CT_V_MPEG4_P10, "avc.|[hx]264|V_MPEG4/ISO/AVC"); + ms_codecs.emplace_back("RealVideo", CT_V_REAL, "rv[1234]\\d|V_REAL/RV\\d+"); + ms_codecs.emplace_back("Theora", CT_V_THEORA, "theo|thra|V_THEORA"); + ms_codecs.emplace_back("Dirac", CT_V_DIRAC, "drac|V_DIRAC"); + ms_codecs.emplace_back("VP8", CT_V_VP8, "vp8\\d|V_VP8"); + ms_codecs.emplace_back("VP9", CT_V_VP9, "vp9\\d|V_VP9"); + ms_codecs.emplace_back("VP9", CT_V_VP9, "vp9\\d|V_VP9"); + ms_codecs.emplace_back("Sorenson", CT_V_SVQ, "svq[i0-9]"); + ms_codecs.emplace_back("VC1", CT_V_VC1, "wvc1|vc-1"); + + ms_codecs.emplace_back("AAC", CT_A_AAC, "mp4a|aac.|raac|racp|A_AAC.*", std::vector{ 0x00ffu, 0x706du }); + ms_codecs.emplace_back("AC3/EAC3", CT_A_AC3, "ac3.|ac-3|sac3|eac3|a52[\\sb]|A_E?AC3", 0x2000u); + ms_codecs.emplace_back("ALAC", CT_A_ALAC, "alac|A_ALAC"); + ms_codecs.emplace_back("DTS", CT_A_DTS, "dts[\\sbcehl]|A_DTS", 0x2001u); + ms_codecs.emplace_back("MP2", CT_A_MP2, "mp2.|\\.mp[12]|mp2a|A_MPEG/L2", 0x0050); + ms_codecs.emplace_back("MP3", CT_A_MP3, "mp3.|\\.mp3|LAME|mpga|A_MPEG/L3", 0x0055); + ms_codecs.emplace_back("PCM", CT_A_PCM, "twos|sowt|A_PCM/(?:INT|FLOAT)/.+", std::vector{ 0x0001u, 0x0003u }); + ms_codecs.emplace_back("Vorbis", CT_A_VORBIS, "vor[1b]|A_VORBIS", std::vector{ 0x566fu, 0xfffeu }); + ms_codecs.emplace_back("Opus", CT_A_OPUS, "opus|A_OPUS(?:/EXPERIMENTAL)?"); + ms_codecs.emplace_back("QDMC", CT_A_QDMC, "qdm2|A_QUICKTIME/QDM[2C]"); + ms_codecs.emplace_back("FLAC", CT_A_FLAC, "flac|A_FLAC"); + ms_codecs.emplace_back("MLP", CT_A_MLP, "mlp\\s|A_MLP"); + ms_codecs.emplace_back("TrueHD", CT_A_TRUEHD, "trhd|A_TRUEHD"); + ms_codecs.emplace_back("TrueAudio", CT_A_TTA, "tta1|A_TTA1?"); + ms_codecs.emplace_back("WavPack4", CT_A_WAVPACK4, "wvpk|A_WAVPACK4"); + + ms_codecs.emplace_back("SubRip/SRT", CT_S_SRT, "S_TEXT/(?:UTF8|ASCII)"); + ms_codecs.emplace_back("SubStationAlpha", CT_S_SSA_ASS, "ssa\\s|ass\\s|S_TEXT/(?:SSA|ASS)"); + ms_codecs.emplace_back("UniversalSubtitleFormat", CT_S_USF, "usf\\s|S_TEXT/USF"); + ms_codecs.emplace_back("Kate", CT_S_KATE, "kate|S_KATE"); + ms_codecs.emplace_back("VobSub", CT_S_VOBSUB, "S_VOBSUB(?:/ZLIB)?"); + ms_codecs.emplace_back("PGS", CT_S_PGS, "S_HDMV/PGS"); + + ms_codecs.emplace_back("VobButton", CT_B_VOBBTN, "B_VOBBTN"); +} + +codec_c const +codec_c::look_up(std::string const &fourcc_or_codec_id) { + initialize(); + + auto itr = brng::find_if(ms_codecs, [&fourcc_or_codec_id](codec_c const &c) { return c.matches(fourcc_or_codec_id); }); + + return itr == ms_codecs.end() ? codec_c{} : *itr; +} + +codec_c const +codec_c::look_up(codec_type_e type) { + initialize(); + + auto itr = brng::find_if(ms_codecs, [type](codec_c const &c) { return c.m_type == type; }); + + return itr == ms_codecs.end() ? codec_c{} : *itr; +} + +codec_c const +codec_c::look_up(char const *fourcc_or_codec_id) { + return look_up(std::string{fourcc_or_codec_id}); +} + +codec_c const +codec_c::look_up(fourcc_c const &fourcc) { + return look_up(fourcc.str()); +} + +codec_c const +codec_c::look_up_audio_format(uint16_t audio_format) { + initialize(); + + auto itr = brng::find_if(ms_codecs, [audio_format](codec_c const &c) { return brng::find(c.m_audio_formats, audio_format) != c.m_audio_formats.end(); }); + + return itr == ms_codecs.end() ? codec_c{} : *itr; +} + +codec_c const +codec_c::look_up_object_type_id(unsigned int object_type_id) { + return look_up( ( (MP4OTI_MPEG4Audio == object_type_id) + || (MP4OTI_MPEG2AudioMain == object_type_id) + || (MP4OTI_MPEG2AudioLowComplexity == object_type_id) + || (MP4OTI_MPEG2AudioScaleableSamplingRate == object_type_id)) ? CT_A_AAC + : MP4OTI_MPEG1Audio == object_type_id ? CT_A_MP2 + : MP4OTI_MPEG2AudioPart3 == object_type_id ? CT_A_MP3 + : MP4OTI_DTS == object_type_id ? CT_A_DTS + : ( (MP4OTI_MPEG2VisualSimple == object_type_id) + || (MP4OTI_MPEG2VisualMain == object_type_id) + || (MP4OTI_MPEG2VisualSNR == object_type_id) + || (MP4OTI_MPEG2VisualSpatial == object_type_id) + || (MP4OTI_MPEG2VisualHigh == object_type_id) + || (MP4OTI_MPEG2Visual422 == object_type_id) + || (MP4OTI_MPEG1Visual == object_type_id)) ? CT_V_MPEG12 + : MP4OTI_MPEG4Visual == object_type_id ? CT_V_MPEG4_P2 + : MP4OTI_VOBSUB == object_type_id ? CT_S_VOBSUB + : CT_UNKNOWN); +} + +std::string const +codec_c::get_name(std::string const &fourcc_or_codec_id, + std::string const &fallback) { + auto codec = look_up(fourcc_or_codec_id); + return codec ? codec.m_name : fallback; +} + +std::string const +codec_c::get_name(codec_type_e type, + std::string const &fallback) { + auto codec = look_up(type); + return codec ? codec.m_name : fallback; +} diff --git a/src/common/codec.h b/src/common/codec.h index 9595de2f3..537a29787 100644 --- a/src/common/codec.h +++ b/src/common/codec.h @@ -14,6 +14,12 @@ #ifndef MTX_COMMON_CODEC_H #define MTX_COMMON_CODEC_H +#include "common/common_pch.h" + +#include + +#include "common/fourcc.h" + // see http://www.matroska.org/technical/specs/codecid/index.html #define MKV_A_AAC_2MAIN "A_AAC/MPEG2/MAIN" @@ -81,4 +87,128 @@ #define MKV_B_VOBBTN "B_VOBBTN" +enum codec_type_e { + CT_UNKNOWN = 0 + , CT_V_MPEG12 = 0x1000 + , CT_V_MPEG4_P2 + , CT_V_MPEG4_P10 + , CT_V_REAL + , CT_V_THEORA + , CT_V_DIRAC + , CT_V_VP8 + , CT_V_VP9 + , CT_V_SVQ + , CT_V_VC1 + + , CT_A_AAC = 0x2000 + , CT_A_AC3 + , CT_A_ALAC + , CT_A_DTS + , CT_A_MP2 + , CT_A_MP3 + , CT_A_PCM + , CT_A_VORBIS + , CT_A_OPUS + , CT_A_QDMC + , CT_A_FLAC + , CT_A_MLP + , CT_A_TRUEHD + , CT_A_TTA + , CT_A_WAVPACK4 + + , CT_S_SRT = 0x3000 + , CT_S_SSA_ASS + , CT_S_USF + , CT_S_VOBSUB + , CT_S_KATE + , CT_S_PGS + + , CT_B_VOBBTN = 0x4000 +}; + +class codec_c { +private: + static std::vector ms_codecs; + +protected: + boost::regex m_match_re; + std::string m_name; + codec_type_e m_type; + std::vector m_audio_formats; + +public: + codec_c() + : m_type{CT_UNKNOWN} + { + } + + codec_c(std::string const &name, codec_type_e type, std::string const &match_re, uint16_t audio_format = 0u) + : m_match_re{(boost::format("(?:%1%)") % match_re).str(), boost::regex::perl | boost::regex::icase} + , m_name{name} + , m_type{type} + { + if (audio_format) + m_audio_formats.push_back(audio_format); + } + + codec_c(std::string const &name, codec_type_e type, std::string const &match_re, std::vector audio_formats) + : m_match_re{(boost::format("(?:%1%)") % match_re).str(), boost::regex::perl | boost::regex::icase} + , m_name{name} + , m_type{type} + , m_audio_formats{audio_formats} + { + } + + bool matches(std::string const &fourcc_or_codec_id) const { + return boost::regex_match(fourcc_or_codec_id, m_match_re); + } + + bool valid() const { + return m_type != CT_UNKNOWN; + } + + operator bool() const { + return valid(); + } + + bool is(codec_type_e type) const { + return type == m_type; + } + + std::string const get_name(std::string fallback = "") const { + if (!valid()) + return fallback; + return m_name; + } + + codec_type_e get_type() const { + return m_type; + } + +private: + static void initialize(); + +public: // static + static codec_c const look_up(std::string const &fourcc_or_codec_id); + static codec_c const look_up(char const *fourcc_or_codec_id); + static codec_c const look_up(fourcc_c const &fourcc); + static codec_c const look_up(codec_type_e type); + static codec_c const look_up_audio_format(uint16_t audio_format); + static codec_c const look_up_object_type_id(unsigned int object_type_id); + + static std::string const get_name(std::string const &fourcc_or_codec_id, std::string const &fallback); + static std::string const get_name(codec_type_e type, std::string const &fallback); +}; + +inline std::ostream & +operator <<(std::ostream &out, + codec_c const &codec) { + if (codec) + out << (boost::format("%1% (0x%|2$04x|)") % codec.get_name() % codec.get_type()); + else + out << ""; + + return out; +} + #endif // MTX_COMMON_CODEC_H diff --git a/tests/unit/common/codec.cpp b/tests/unit/common/codec.cpp new file mode 100644 index 000000000..702732900 --- /dev/null +++ b/tests/unit/common/codec.cpp @@ -0,0 +1,229 @@ +#include "common/common_pch.h" + +#include "common/codec.h" +#include "common/mp4.h" + +#include "gtest/gtest.h" + +namespace { + +TEST(Codec, LookUpStringAudio) { + EXPECT_TRUE(codec_c::look_up(MKV_A_AAC_2MAIN).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up(MKV_A_AAC_2LC).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up(MKV_A_AAC_2SSR).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up(MKV_A_AAC_2SBR).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up(MKV_A_AAC_4MAIN).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up(MKV_A_AAC_4LC).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up(MKV_A_AAC_4LC).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up(MKV_A_AAC_4SSR).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up(MKV_A_AAC_4LTP).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up(MKV_A_AAC_4SBR).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up(MKV_A_AAC).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up("mp4a").is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up("aac ").is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up("aacl").is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up("aach").is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up("raac").is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up("racp").is(CT_A_AAC)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_AC3).is(CT_A_AC3)); + EXPECT_TRUE(codec_c::look_up(MKV_A_EAC3).is(CT_A_AC3)); + EXPECT_TRUE(codec_c::look_up("a52 ").is(CT_A_AC3)); + EXPECT_TRUE(codec_c::look_up("a52b").is(CT_A_AC3)); + EXPECT_TRUE(codec_c::look_up("ac-3").is(CT_A_AC3)); + EXPECT_TRUE(codec_c::look_up("sac3").is(CT_A_AC3)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_ALAC).is(CT_A_ALAC)); + EXPECT_TRUE(codec_c::look_up("ALAC").is(CT_A_ALAC)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_DTS).is(CT_A_DTS)); + EXPECT_TRUE(codec_c::look_up("dts ").is(CT_A_DTS)); + EXPECT_TRUE(codec_c::look_up("dtsb").is(CT_A_DTS)); + EXPECT_TRUE(codec_c::look_up("dtsc").is(CT_A_DTS)); + EXPECT_TRUE(codec_c::look_up("dtse").is(CT_A_DTS)); + EXPECT_TRUE(codec_c::look_up("dtsh").is(CT_A_DTS)); + EXPECT_TRUE(codec_c::look_up("dtsl").is(CT_A_DTS)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_MP2).is(CT_A_MP2)); + EXPECT_TRUE(codec_c::look_up("mp2a").is(CT_A_MP2)); + EXPECT_TRUE(codec_c::look_up(".mp1").is(CT_A_MP2)); + EXPECT_TRUE(codec_c::look_up(".mp2").is(CT_A_MP2)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_MP3).is(CT_A_MP3)); + EXPECT_TRUE(codec_c::look_up("mp3a").is(CT_A_MP3)); + EXPECT_TRUE(codec_c::look_up(".mp3").is(CT_A_MP3)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_PCM).is(CT_A_PCM)); + EXPECT_TRUE(codec_c::look_up(MKV_A_PCM_BE).is(CT_A_PCM)); + EXPECT_TRUE(codec_c::look_up(MKV_A_PCM_FLOAT).is(CT_A_PCM)); + EXPECT_TRUE(codec_c::look_up("twos").is(CT_A_PCM)); + EXPECT_TRUE(codec_c::look_up("sowt").is(CT_A_PCM)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_VORBIS).is(CT_A_VORBIS)); + EXPECT_TRUE(codec_c::look_up("vorb").is(CT_A_VORBIS)); + EXPECT_TRUE(codec_c::look_up("vor1").is(CT_A_VORBIS)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_OPUS).is(CT_A_OPUS)); + EXPECT_TRUE(codec_c::look_up(std::string{MKV_A_OPUS} + "/EXPERIMENTAL").is(CT_A_OPUS)); + EXPECT_TRUE(codec_c::look_up("opus").is(CT_A_OPUS)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_QDMC).is(CT_A_QDMC)); + EXPECT_TRUE(codec_c::look_up(MKV_A_QDMC2).is(CT_A_QDMC)); + EXPECT_TRUE(codec_c::look_up("qdm2").is(CT_A_QDMC)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_FLAC).is(CT_A_FLAC)); + EXPECT_TRUE(codec_c::look_up("flac").is(CT_A_FLAC)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_MLP).is(CT_A_MLP)); + EXPECT_TRUE(codec_c::look_up("mlp ").is(CT_A_MLP)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_TRUEHD).is(CT_A_TRUEHD)); + EXPECT_TRUE(codec_c::look_up("trhd").is(CT_A_TRUEHD)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_TTA).is(CT_A_TTA)); + EXPECT_TRUE(codec_c::look_up("tta1").is(CT_A_TTA)); + + EXPECT_TRUE(codec_c::look_up(MKV_A_WAVPACK4).is(CT_A_WAVPACK4)); + EXPECT_TRUE(codec_c::look_up("wvpk").is(CT_A_WAVPACK4)); +} + +TEST(Codec, LookUpStringVideo) { + EXPECT_TRUE(codec_c::look_up(MKV_V_MPEG1).is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up(MKV_V_MPEG2).is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up("h262").is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up("mp1v").is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up("mp2v").is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up("mpeg").is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up("mpg2").is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up("mpgv").is(CT_V_MPEG12)); + + EXPECT_TRUE(codec_c::look_up(MKV_V_MPEG4_SP).is(CT_V_MPEG4_P2)); + EXPECT_TRUE(codec_c::look_up(MKV_V_MPEG4_ASP).is(CT_V_MPEG4_P2)); + EXPECT_TRUE(codec_c::look_up(MKV_V_MPEG4_AP).is(CT_V_MPEG4_P2)); + EXPECT_TRUE(codec_c::look_up("3iv2").is(CT_V_MPEG4_P2)); + EXPECT_TRUE(codec_c::look_up("divx").is(CT_V_MPEG4_P2)); + EXPECT_TRUE(codec_c::look_up("dx50").is(CT_V_MPEG4_P2)); + EXPECT_TRUE(codec_c::look_up("fmp4").is(CT_V_MPEG4_P2)); + EXPECT_TRUE(codec_c::look_up("mp4v").is(CT_V_MPEG4_P2)); + EXPECT_TRUE(codec_c::look_up("xvid").is(CT_V_MPEG4_P2)); + EXPECT_TRUE(codec_c::look_up("xvix").is(CT_V_MPEG4_P2)); + + EXPECT_TRUE(codec_c::look_up(MKV_V_MPEG4_AVC).is(CT_V_MPEG4_P10)); + EXPECT_TRUE(codec_c::look_up("h264").is(CT_V_MPEG4_P10)); + EXPECT_TRUE(codec_c::look_up("x264").is(CT_V_MPEG4_P10)); + EXPECT_TRUE(codec_c::look_up("avc1").is(CT_V_MPEG4_P10)); + + EXPECT_TRUE(codec_c::look_up(MKV_V_REALV1).is(CT_V_REAL)); + EXPECT_TRUE(codec_c::look_up(MKV_V_REALV2).is(CT_V_REAL)); + EXPECT_TRUE(codec_c::look_up(MKV_V_REALV3).is(CT_V_REAL)); + EXPECT_TRUE(codec_c::look_up(MKV_V_REALV4).is(CT_V_REAL)); + EXPECT_TRUE(codec_c::look_up("rv10").is(CT_V_REAL)); + EXPECT_TRUE(codec_c::look_up("rv20").is(CT_V_REAL)); + EXPECT_TRUE(codec_c::look_up("rv30").is(CT_V_REAL)); + EXPECT_TRUE(codec_c::look_up("rv40").is(CT_V_REAL)); + + EXPECT_TRUE(codec_c::look_up(MKV_V_THEORA).is(CT_V_THEORA)); + EXPECT_TRUE(codec_c::look_up("theo").is(CT_V_THEORA)); + EXPECT_TRUE(codec_c::look_up("thra").is(CT_V_THEORA)); + + EXPECT_TRUE(codec_c::look_up(MKV_V_DIRAC).is(CT_V_DIRAC)); + EXPECT_TRUE(codec_c::look_up("drac").is(CT_V_DIRAC)); + + EXPECT_TRUE(codec_c::look_up(MKV_V_VP8).is(CT_V_VP8)); + EXPECT_TRUE(codec_c::look_up("vp80").is(CT_V_VP8)); + + EXPECT_TRUE(codec_c::look_up(MKV_V_VP9).is(CT_V_VP9)); + EXPECT_TRUE(codec_c::look_up("vp90").is(CT_V_VP9)); + + EXPECT_TRUE(codec_c::look_up("svq1").is(CT_V_SVQ)); + EXPECT_TRUE(codec_c::look_up("svq1").is(CT_V_SVQ)); + EXPECT_TRUE(codec_c::look_up("svqi").is(CT_V_SVQ)); + EXPECT_TRUE(codec_c::look_up("svq3").is(CT_V_SVQ)); + + EXPECT_TRUE(codec_c::look_up("vc-1").is(CT_V_VC1)); + EXPECT_TRUE(codec_c::look_up("wvc1").is(CT_V_VC1)); +} + +TEST(Codec, LookUpStringSubtitles) { + EXPECT_TRUE(codec_c::look_up(MKV_S_TEXTUTF8).is(CT_S_SRT)); + EXPECT_TRUE(codec_c::look_up(MKV_S_TEXTASCII).is(CT_S_SRT)); + + EXPECT_TRUE(codec_c::look_up(MKV_S_TEXTSSA).is(CT_S_SSA_ASS)); + EXPECT_TRUE(codec_c::look_up(MKV_S_TEXTASS).is(CT_S_SSA_ASS)); + EXPECT_TRUE(codec_c::look_up("ssa ").is(CT_S_SSA_ASS)); + EXPECT_TRUE(codec_c::look_up("ass ").is(CT_S_SSA_ASS)); + + EXPECT_TRUE(codec_c::look_up(MKV_S_TEXTUSF).is(CT_S_USF)); + EXPECT_TRUE(codec_c::look_up("usf ").is(CT_S_USF)); + + EXPECT_TRUE(codec_c::look_up(MKV_S_VOBSUB).is(CT_S_VOBSUB)); + EXPECT_TRUE(codec_c::look_up(MKV_S_VOBSUBZLIB).is(CT_S_VOBSUB)); + + EXPECT_TRUE(codec_c::look_up(MKV_S_KATE).is(CT_S_KATE)); + EXPECT_TRUE(codec_c::look_up("kate").is(CT_S_KATE)); + + EXPECT_TRUE(codec_c::look_up(MKV_S_HDMV_PGS).is(CT_S_PGS)); +} + +TEST(Codec, LookUpAudioFormat) { + EXPECT_TRUE(codec_c::look_up_audio_format(0x00ffu).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up_audio_format(0x706du).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up_audio_format(0x2000u).is(CT_A_AC3)); + EXPECT_TRUE(codec_c::look_up_audio_format(0x2001u).is(CT_A_DTS)); + EXPECT_TRUE(codec_c::look_up_audio_format(0x0050u).is(CT_A_MP2)); + EXPECT_TRUE(codec_c::look_up_audio_format(0x0055u).is(CT_A_MP3)); + EXPECT_TRUE(codec_c::look_up_audio_format(0x0001u).is(CT_A_PCM)); + EXPECT_TRUE(codec_c::look_up_audio_format(0x0003u).is(CT_A_PCM)); + EXPECT_TRUE(codec_c::look_up_audio_format(0x566fu).is(CT_A_VORBIS)); + EXPECT_TRUE(codec_c::look_up_audio_format(0xfffeu).is(CT_A_VORBIS)); +} + +TEST(Codec, LookUpObjectTypeId) { + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG2AudioMain).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG2AudioLowComplexity).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG2AudioScaleableSamplingRate).is(CT_A_AAC)); + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG2AudioPart3).is(CT_A_MP3)); + + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG1Audio).is(CT_A_MP2)); + + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_DTS).is(CT_A_DTS)); + + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG4Visual).is(CT_V_MPEG4_P2)); + + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG2VisualSimple).is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG2VisualMain).is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG2VisualSNR).is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG2VisualSpatial).is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG2VisualHigh).is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG2Visual422).is(CT_V_MPEG12)); + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_MPEG1Visual).is(CT_V_MPEG12)); + + EXPECT_TRUE(codec_c::look_up_object_type_id(MP4OTI_VOBSUB).is(CT_S_VOBSUB)); +} + +TEST(Codec, LookUpOverloading) { + EXPECT_TRUE(codec_c::look_up("kate").is(CT_S_KATE)); + EXPECT_TRUE(codec_c::look_up(std::string{"kate"}).is(CT_S_KATE)); + EXPECT_TRUE(codec_c::look_up(fourcc_c{"kate"}).is(CT_S_KATE)); + EXPECT_TRUE(codec_c::look_up(CT_S_KATE).is(CT_S_KATE)); +} + +TEST(Codec, LookUpValidity) { + EXPECT_FALSE(codec_c::look_up("DOES-NOT-EXIST").valid()); + EXPECT_FALSE(codec_c::look_up_audio_format(0x0000u).valid()); + EXPECT_FALSE(codec_c::look_up_audio_format(0x4711).valid()); + EXPECT_FALSE(codec_c::look_up_object_type_id(0x0000u).valid()); + EXPECT_FALSE(codec_c::look_up_object_type_id(0x4711).valid()); +} + +TEST(Codec, HandlingOfUnknownCodec) { + EXPECT_TRUE(codec_c::look_up(CT_UNKNOWN).is(CT_UNKNOWN)); + EXPECT_FALSE(codec_c::look_up(CT_UNKNOWN).valid()); +} + +TEST(Codec, GetNameFallbacks) { + EXPECT_EQ(codec_c::look_up("DOES-NOT-EXIST").get_name("HelloWorld"), "HelloWorld"); + EXPECT_EQ(codec_c::look_up("DOES-NOT-EXIST").get_name(), ""); +} + +}