4 #include "../vorbis/vorbispackagetypes.h" 5 #include "../vorbis/vorbisidentificationheader.h" 7 #include "../opus/opusidentificationheader.h" 9 #include "../flac/flactooggmappingheader.h" 11 #include "../mediafileinfo.h" 12 #include "../exceptions.h" 13 #include "../mediaformat.h" 15 #include <c++utilities/chrono/timespan.h> 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)
49 static const string context(
"parsing OGG page header");
53 const OggPage &firstPage = iterator.
pages()[m_startPage];
62 for(
bool hasIdentificationHeader =
false, hasCommentHeader =
false; iterator && (!hasIdentificationHeader || !hasCommentHeader); ++iterator) {
64 if(currentSize >= 8) {
67 const uint64 sig =
reader().readUInt64BE();
69 if((sig & 0x00ffffffffffff00u) == 0x00766F7262697300u) {
86 if(!hasIdentificationHeader) {
101 calculateDurationViaSampleCount();
102 hasIdentificationHeader =
true;
109 if(!hasCommentHeader) {
111 hasCommentHeader =
true;
122 }
else if(sig == 0x4F70757348656164u) {
135 if(!hasIdentificationHeader) {
142 calculateDurationViaSampleCount(ind.
preSkip());
143 hasIdentificationHeader =
true;
148 }
else if(sig == 0x4F70757354616773u) {
163 if(!hasCommentHeader) {
165 hasCommentHeader =
true;
170 }
else if((sig & 0xFFFFFFFFFF000000u) == 0x7F464C4143000000u) {
184 if(!hasIdentificationHeader) {
193 calculateDurationViaSampleCount();
194 hasIdentificationHeader =
true;
199 if(!hasCommentHeader) {
203 iterator.
read(buff, 4);
208 hasCommentHeader =
true;
217 }
else if((sig & 0x00ffffffffffff00u) == 0x007468656F726100u) {
232 }
else if((sig & 0xFFFFFFFFFFFF0000u) == 0x5370656578200000u) {
246 }
else if(sig == 0x595556344D504547u) {
280 void OggStream::calculateDurationViaSampleCount(uint16 preSkip)
286 const auto &iterator = m_container.m_iterator;
288 const auto &pages = iterator.
pages();
289 const auto firstPage = find_if(pages.cbegin(), pages.cend(), pred);
290 const auto lastPage = find_if(pages.crbegin(), pages.crend(), pred);
291 if(firstPage != pages.cend() && lastPage != pages.crend()) {
292 m_sampleCount = lastPage->absoluteGranulePosition() - firstPage->absoluteGranulePosition();
bool matchesStreamSerialNumber(uint32 streamSerialNumber) const
Returns whether the stream serial number of the current instance matches the specified one...
uint32 streamSerialNumber() const
Returns the stream serial number.
The OggPage class is used to parse OGG pages.
byte streamStructureVersion() const
Returns the stream structure version.