Determine "effective size" via file info instead of track implementations
This allows removing duplicated code from the track implementations to take APE tags into account.
This commit is contained in:
parent
8ad28f857b
commit
c5cd20682d
|
@ -132,6 +132,7 @@ public:
|
||||||
MediaType mediaType() const;
|
MediaType mediaType() const;
|
||||||
std::string_view mediaTypeName() const;
|
std::string_view mediaTypeName() const;
|
||||||
std::uint64_t size() const;
|
std::uint64_t size() const;
|
||||||
|
void setSize(std::uint64_t size);
|
||||||
std::uint32_t trackNumber() const;
|
std::uint32_t trackNumber() const;
|
||||||
void setTrackNumber(std::uint32_t trackNumber);
|
void setTrackNumber(std::uint32_t trackNumber);
|
||||||
std::uint64_t id() const;
|
std::uint64_t id() const;
|
||||||
|
@ -396,6 +397,19 @@ inline std::uint64_t AbstractTrack::size() const
|
||||||
return m_size;
|
return m_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the size in bytes.
|
||||||
|
* \remarks
|
||||||
|
* This is used by MediaFileInfo to set the track size for certain types of tracks before invoking the parsing.
|
||||||
|
* If you use this a class derived from AbstractTrack directly you may want to do the same if not the entire
|
||||||
|
* input stream is supposed to be considered part of the track and the parser would otherwise assume that (like
|
||||||
|
* the parser of MpegAudioFrameStream might do).
|
||||||
|
*/
|
||||||
|
inline void AbstractTrack::setSize(std::uint64_t size)
|
||||||
|
{
|
||||||
|
m_size = size;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the track number if known; otherwise returns 0.
|
* \brief Returns the track number if known; otherwise returns 0.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,15 +24,8 @@ void AdtsStream::internalParseHeader(Diagnostics &diag, AbortableProgressFeedbac
|
||||||
if (!m_istream) {
|
if (!m_istream) {
|
||||||
throw NoDataFoundException();
|
throw NoDataFoundException();
|
||||||
}
|
}
|
||||||
// get size
|
|
||||||
m_istream->seekg(-128, ios_base::end);
|
|
||||||
if (m_reader.readUInt24BE() == 0x544147) {
|
|
||||||
m_size = static_cast<std::uint64_t>(m_istream->tellg()) - 3u - m_startOffset;
|
|
||||||
} else {
|
|
||||||
m_size = static_cast<std::uint64_t>(m_istream->tellg()) + 125u - m_startOffset;
|
|
||||||
}
|
|
||||||
m_istream->seekg(static_cast<streamoff>(m_startOffset), ios_base::beg);
|
|
||||||
// parse frame header
|
// parse frame header
|
||||||
|
m_istream->seekg(static_cast<std::streamoff>(m_startOffset), ios_base::beg);
|
||||||
m_firstFrame.parseHeader(m_reader);
|
m_firstFrame.parseHeader(m_reader);
|
||||||
m_format = Mpeg4AudioObjectIds::idToMediaFormat(m_firstFrame.mpeg4AudioObjectId());
|
m_format = Mpeg4AudioObjectIds::idToMediaFormat(m_firstFrame.mpeg4AudioObjectId());
|
||||||
m_channelCount = Mpeg4ChannelConfigs::channelCount(m_channelConfig = m_firstFrame.mpeg4ChannelConfig());
|
m_channelCount = Mpeg4ChannelConfigs::channelCount(m_channelConfig = m_firstFrame.mpeg4ChannelConfig());
|
||||||
|
|
|
@ -83,6 +83,7 @@ MediaFileInfo::MediaFileInfo(std::string &&path)
|
||||||
, m_containerFormat(ContainerFormat::Unknown)
|
, m_containerFormat(ContainerFormat::Unknown)
|
||||||
, m_containerOffset(0)
|
, m_containerOffset(0)
|
||||||
, m_paddingSize(0)
|
, m_paddingSize(0)
|
||||||
|
, m_effectiveSize(0)
|
||||||
, m_fileStructureFlags(MediaFileStructureFlags::None)
|
, m_fileStructureFlags(MediaFileStructureFlags::None)
|
||||||
, m_tracksParsingStatus(ParsingStatus::NotParsedYet)
|
, m_tracksParsingStatus(ParsingStatus::NotParsedYet)
|
||||||
, m_tagsParsingStatus(ParsingStatus::NotParsedYet)
|
, m_tagsParsingStatus(ParsingStatus::NotParsedYet)
|
||||||
|
@ -354,6 +355,13 @@ void MediaFileInfo::parseTracks(Diagnostics &diag, AbortableProgressFeedback &pr
|
||||||
default:
|
default:
|
||||||
throw NotImplementedException();
|
throw NotImplementedException();
|
||||||
}
|
}
|
||||||
|
if (m_containerFormat != ContainerFormat::Flac) {
|
||||||
|
// ensure the effective size has been determined
|
||||||
|
// note: This is not required for FLAC and should also be avoided as parseTags() will invoke
|
||||||
|
// parseTracks() when dealing with FLAC files.
|
||||||
|
parseTags(diag, progress);
|
||||||
|
m_singleTrack->setSize(m_effectiveSize);
|
||||||
|
}
|
||||||
m_singleTrack->parseHeader(diag, progress);
|
m_singleTrack->parseHeader(diag, progress);
|
||||||
|
|
||||||
// take padding for some "single-track" formats into account
|
// take padding for some "single-track" formats into account
|
||||||
|
@ -453,6 +461,9 @@ void MediaFileInfo::parseTags(Diagnostics &diag, AbortableProgressFeedback &prog
|
||||||
m_id3v2Tags.emplace_back(id3v2Tag.release());
|
m_id3v2Tags.emplace_back(id3v2Tag.release());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// compute effective size
|
||||||
|
m_effectiveSize = static_cast<std::uint64_t>(effectiveSize - m_containerOffset);
|
||||||
|
|
||||||
// check for tags in tracks (FLAC only) or via container object
|
// check for tags in tracks (FLAC only) or via container object
|
||||||
try {
|
try {
|
||||||
if (m_containerFormat == ContainerFormat::Flac) {
|
if (m_containerFormat == ContainerFormat::Flac) {
|
||||||
|
|
|
@ -105,6 +105,7 @@ public:
|
||||||
std::string_view mimeType() const;
|
std::string_view mimeType() const;
|
||||||
std::uint64_t containerOffset() const;
|
std::uint64_t containerOffset() const;
|
||||||
std::uint64_t paddingSize() const;
|
std::uint64_t paddingSize() const;
|
||||||
|
std::uint64_t effectiveSize() const;
|
||||||
AbstractContainer *container() const;
|
AbstractContainer *container() const;
|
||||||
ParsingStatus containerParsingStatus() const;
|
ParsingStatus containerParsingStatus() const;
|
||||||
// ... the chapters
|
// ... the chapters
|
||||||
|
@ -201,6 +202,7 @@ private:
|
||||||
ContainerFormat m_containerFormat;
|
ContainerFormat m_containerFormat;
|
||||||
std::streamoff m_containerOffset;
|
std::streamoff m_containerOffset;
|
||||||
std::uint64_t m_paddingSize;
|
std::uint64_t m_paddingSize;
|
||||||
|
std::uint64_t m_effectiveSize;
|
||||||
std::vector<std::streamoff> m_actualId3v2TagOffsets;
|
std::vector<std::streamoff> m_actualId3v2TagOffsets;
|
||||||
std::unique_ptr<AbstractContainer> m_container;
|
std::unique_ptr<AbstractContainer> m_container;
|
||||||
MediaFileStructureFlags m_fileStructureFlags;
|
MediaFileStructureFlags m_fileStructureFlags;
|
||||||
|
@ -296,6 +298,15 @@ inline std::uint64_t MediaFileInfo::paddingSize() const
|
||||||
return m_paddingSize;
|
return m_paddingSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the "effective size" of the file if know; otherwise returns 0.
|
||||||
|
* \remarks This is the size of the file minus tags at the beginning and the end.
|
||||||
|
*/
|
||||||
|
inline std::uint64_t MediaFileInfo::effectiveSize() const
|
||||||
|
{
|
||||||
|
return m_effectiveSize;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns an indication whether tag information has been parsed yet.
|
* \brief Returns an indication whether tag information has been parsed yet.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -35,15 +35,8 @@ void MpegAudioFrameStream::internalParseHeader(Diagnostics &diag, AbortableProgr
|
||||||
if (!m_istream) {
|
if (!m_istream) {
|
||||||
throw NoDataFoundException();
|
throw NoDataFoundException();
|
||||||
}
|
}
|
||||||
// get size
|
|
||||||
m_istream->seekg(-128, ios_base::end);
|
|
||||||
if (m_reader.readUInt24BE() == 0x544147) {
|
|
||||||
m_size = static_cast<std::uint64_t>(m_istream->tellg()) - 3u - m_startOffset;
|
|
||||||
} else {
|
|
||||||
m_size = static_cast<std::uint64_t>(m_istream->tellg()) + 125u - m_startOffset;
|
|
||||||
}
|
|
||||||
m_istream->seekg(static_cast<streamoff>(m_startOffset), ios_base::beg);
|
|
||||||
// parse frames until the first valid, non-empty frame is reached
|
// parse frames until the first valid, non-empty frame is reached
|
||||||
|
m_istream->seekg(static_cast<std::streamoff>(m_startOffset), ios_base::beg);
|
||||||
for (size_t invalidByteskipped = 0; m_frames.size() < 200 && invalidByteskipped <= 0x600u;) {
|
for (size_t invalidByteskipped = 0; m_frames.size() < 200 && invalidByteskipped <= 0x600u;) {
|
||||||
MpegAudioFrame &frame = invalidByteskipped > 0 ? m_frames.back() : m_frames.emplace_back();
|
MpegAudioFrame &frame = invalidByteskipped > 0 ? m_frames.back() : m_frames.emplace_back();
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue