Tag Parser
9.0.0
C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags
|
Go to the documentation of this file.
4 #include "../vorbis/vorbisidentificationheader.h"
5 #include "../vorbis/vorbispackagetypes.h"
7 #include "../opus/opusidentificationheader.h"
9 #include "../flac/flactooggmappingheader.h"
11 #include "../exceptions.h"
12 #include "../mediafileinfo.h"
13 #include "../mediaformat.h"
15 #include <c++utilities/chrono/timespan.h>
21 using namespace std::placeholders;
34 OggStream::OggStream(
OggContainer &container, vector<OggPage>::size_type startPage)
35 :
AbstractTrack(container.stream(), container.m_iterator.pages()[startPage].startOffset())
36 , m_startPage(startPage)
37 , m_container(container)
38 , m_currentSequenceNumber(0)
51 static const string context(
"parsing OGG page header");
55 const OggPage &firstPage = iterator.
pages()[m_startPage];
64 for (
bool hasIdentificationHeader =
false, hasCommentHeader =
false; iterator && (!hasIdentificationHeader || !hasCommentHeader); ++iterator) {
66 if (currentSize >= 8) {
69 const std::uint64_t sig =
reader().readUInt64BE();
71 if ((sig & 0x00ffffffffffff00u) == 0x00766F7262697300u) {
88 if (!hasIdentificationHeader) {
103 calculateDurationViaSampleCount();
104 hasIdentificationHeader =
true;
107 "Vorbis identification header appears more than once. Oversupplied occurrence will be ignored.", context);
112 if (!hasCommentHeader) {
114 hasCommentHeader =
true;
117 DiagLevel::Critical,
"Vorbis comment header appears more than once. Oversupplied occurrence will be ignored.", context);
125 }
else if (sig == 0x4F70757348656164u) {
138 if (!hasIdentificationHeader) {
145 calculateDurationViaSampleCount(ind.
preSkip());
146 hasIdentificationHeader =
true;
149 DiagLevel::Critical,
"Opus identification header appears more than once. Oversupplied occurrence will be ignored.", context);
152 }
else if (sig == 0x4F70757354616773u) {
167 if (!hasCommentHeader) {
169 hasCommentHeader =
true;
172 DiagLevel::Critical,
"Opus tags/comment header appears more than once. Oversupplied occurrence will be ignored.", context);
175 }
else if ((sig & 0xFFFFFFFFFF000000u) == 0x7F464C4143000000u) {
189 if (!hasIdentificationHeader) {
198 calculateDurationViaSampleCount();
199 hasIdentificationHeader =
true;
202 DiagLevel::Critical,
"FLAC-to-Ogg mapping header appears more than once. Oversupplied occurrence will be ignored.", context);
205 if (!hasCommentHeader) {
209 iterator.
read(buff, 4);
213 m_container.announceComment(
215 hasCommentHeader =
true;
218 DiagLevel::Critical,
"OGG page after FLAC-to-Ogg mapping header doesn't contain Vorbis comment.", context);
222 DiagLevel::Critical,
"No more OGG pages after FLAC-to-Ogg mapping header (Vorbis comment expected).", context);
226 }
else if ((sig & 0x00ffffffffffff00u) == 0x007468656F726100u) {
241 }
else if ((sig & 0xFFFFFFFFFFFF0000u) == 0x5370656578200000u) {
255 }
else if (sig == 0x595556344D504547u) {
289 void OggStream::calculateDurationViaSampleCount(std::uint16_t preSkip)
295 const auto &iterator = m_container.m_iterator;
297 const auto &pages = iterator.
pages();
298 const auto firstPage = find_if(pages.cbegin(), pages.cend(), pred);
299 const auto lastPage = find_if(pages.crbegin(), pages.crend(), pred);
300 if (firstPage != pages.cend() && lastPage != pages.crend()) {
301 m_sampleCount = lastPage->absoluteGranulePosition() - firstPage->absoluteGranulePosition();
std::uint32_t m_samplingFrequency
void setPageIndex(std::vector< OggPage >::size_type index)
Sets the current page index.
std::uint32_t streamSerialNumber() const
Returns the stream serial number.
The OggIterator class helps iterating through all segments of an OGG bitstream.
std::uint8_t streamStructureVersion() const
Returns the stream structure version.
std::uint64_t currentSegmentOffset() const
Returns the start offset of the current segment in the input stream if the iterator is valid; otherwi...
Implementation of TagParser::AbstractContainer for OGG files.
const char * m_chromaFormat
The Diagnostics class is a container for DiagMessage.
Contains all classes and functions of the TagInfo library.
std::vector< OggPage >::size_type currentPageIndex() const
Returns the index of the current page if the iterator is valid; otherwise an undefined index is retur...
std::uint64_t m_sampleCount
void setFilter(std::uint32_t streamSerialId)
Allows to filter pages by the specified streamSerialId.
CppUtilities::TimeSpan m_duration
The OggPage class is used to parse OGG pages.
std::istream & inputStream()
Returns the associated input stream.
bool matchesStreamSerialNumber(std::uint32_t streamSerialNumber) const
Returns whether the stream serial number of the current instance matches the specified one.
The AbstractTrack class parses and stores technical information about video, audio and other kinds of...
std::uint16_t m_channelCount
~OggStream() override
Destroys the track.
std::uint16_t m_bitsPerSample
void internalParseHeader(Diagnostics &diag) override
This method is internally called to parse header information. It needs to be implemented when subclas...
CppUtilities::BinaryReader & reader()
Returns a binary reader for the associated stream.
std::vector< std::uint32_t >::size_type currentSegmentIndex() const
Returns the index of the current segment (in the current page) if the iterator is valid; otherwise an...
const std::vector< OggPage > & pages() const
Returns a vector of containing the OGG pages that have been fetched yet.
std::uint32_t currentSegmentSize() const
Returns the size of the current segment.
void read(char *buffer, std::size_t count)
Reads count bytes from the OGG stream and writes it to the specified buffer.