diff --git a/mediafileinfo.cpp b/mediafileinfo.cpp index 8cb17d4..96e3b9c 100644 --- a/mediafileinfo.cpp +++ b/mediafileinfo.cpp @@ -247,7 +247,7 @@ startParsingSignature: addNotifications(notifications); break; } case ContainerFormat::Ogg: - // Ogg is handled using OggContainer instance + // Ogg is handled by OggContainer instance m_container = make_unique(*this, m_containerOffset); static_cast(m_container.get())->setChecksumValidationEnabled(m_forceFullParse); break; @@ -713,16 +713,31 @@ const char *MediaFileInfo::containerFormatAbbreviation() const MediaType mediaType = MediaType::Unknown; unsigned int version = 0; switch(m_containerFormat) { - case ContainerFormat::Ogg: - // check whether only Opus tracks are present - version = static_cast(GeneralMediaFormat::Opus); + case ContainerFormat::Ogg: { + // check for video track or whether only Opus or Speex tracks are present + const auto &tracks = static_cast(m_container.get())->tracks(); + if(tracks.empty()) { + break; + } + bool onlyOpus = true, onlySpeex = true; for(const auto &track : static_cast(m_container.get())->tracks()) { + if(track->mediaType() == MediaType::Video) { + mediaType = MediaType::Video; + } if(track->format().general != GeneralMediaFormat::Opus) { - version = 0; - break; + onlyOpus = false; + } + if(track->format().general != GeneralMediaFormat::Speex) { + onlySpeex = false; } } - case ContainerFormat::Matroska: + if(onlyOpus) { + version = static_cast(GeneralMediaFormat::Opus); + } else if(onlySpeex) { + version = static_cast(GeneralMediaFormat::Speex); + } + break; + } case ContainerFormat::Matroska: case ContainerFormat::Mp4: mediaType = hasTracksOfType(MediaType::Video) ? MediaType::Video : MediaType::Audio; break; diff --git a/mediaformat.cpp b/mediaformat.cpp index 2abaf03..40ca596 100644 --- a/mediaformat.cpp +++ b/mediaformat.cpp @@ -242,6 +242,7 @@ const char *MediaFormat::name() const default: return "Windows Media Video"; } case GeneralMediaFormat::DvbSub: return "DVB subtitles"; + case GeneralMediaFormat::Speex: return "Speex"; default: return "unknown"; } } @@ -412,6 +413,7 @@ const char *MediaFormat::abbreviation() const case GeneralMediaFormat::WindowsMediaAudio: return "WMA"; case GeneralMediaFormat::WindowsMediaVideo: return "WMV"; case GeneralMediaFormat::DvbSub: return "DVBSUB"; + case GeneralMediaFormat::Speex: return "Speex"; default: return ""; } } @@ -564,6 +566,7 @@ const char *MediaFormat::shortAbbreviation() const case GeneralMediaFormat::WindowsMediaAudio: return "WMA"; case GeneralMediaFormat::WindowsMediaVideo: return "WMV"; case GeneralMediaFormat::DvbSub: return "DVBSUB"; + case GeneralMediaFormat::Speex: return "Speex"; default: return ""; } } diff --git a/mediaformat.h b/mediaformat.h index 08d6ed4..fc170d1 100644 --- a/mediaformat.h +++ b/mediaformat.h @@ -95,6 +95,7 @@ enum class GeneralMediaFormat WindowsMediaAudio, /**< Windows Media Audio */ WindowsMediaVideo, /**< Windows Media Video */ DvbSub, /**< DVBSUB */ + Speex, /**< Speex */ }; /*! diff --git a/ogg/oggstream.cpp b/ogg/oggstream.cpp index 0c755b4..eb70637 100644 --- a/ogg/oggstream.cpp +++ b/ogg/oggstream.cpp @@ -264,6 +264,20 @@ void OggStream::internalParseHeader() } // TODO: read more information about Theora stream + } else if((sig & 0xFFFFFFFFFFFF0000u) == 0x5370656578200000u) { + // Speex header detected + switch(m_format.general) { + case GeneralMediaFormat::Unknown: + m_format = GeneralMediaFormat::Speex; + m_mediaType = MediaType::Audio; + break; + case GeneralMediaFormat::Speex: + break; + default: + addNotification(NotificationType::Warning, "Stream format is inconsistent.", context); + continue; + } + // TODO: read more information about Speex stream } else if(sig == 0x595556344D504547u) { // YUV4MPEG header detected switch(m_format.general) { @@ -280,6 +294,7 @@ void OggStream::internalParseHeader() } // TODO: read more information about YUV4MPEG stream } + // currently only Vorbis, Opus, Theora, Speex and YUV4MPEG can be detected, TODO: detect more formats } else { // just ignore segments of only 8 byte or even less diff --git a/signature.cpp b/signature.cpp index 86fc550..c5571bd 100644 --- a/signature.cpp +++ b/signature.cpp @@ -277,6 +277,8 @@ const char *containerFormatAbbreviation(ContainerFormat containerFormat, MediaTy switch(version) { case static_cast(GeneralMediaFormat::Opus): return "opus"; + case static_cast(GeneralMediaFormat::Speex): + return "spx"; default: return "ogg"; }