Use flags instead of tons of boolean fields in AbstractTrack

This commit is contained in:
Martchus 2020-12-14 20:27:54 +01:00
parent b5983d40ad
commit 4cc2dbd9e6
8 changed files with 57 additions and 41 deletions

View File

@ -182,7 +182,7 @@ set(DOC_FILES README.md doc/adding-new-fields.md)
set(CONFIGURATION_PACKAGE_SUFFIX set(CONFIGURATION_PACKAGE_SUFFIX
"" ""
CACHE STRING "sets the suffix for find_package() calls to packages configured via c++utilities") CACHE STRING "sets the suffix for find_package() calls to packages configured via c++utilities")
find_package(c++utilities${CONFIGURATION_PACKAGE_SUFFIX} 5.0.0 REQUIRED) find_package(c++utilities${CONFIGURATION_PACKAGE_SUFFIX} 5.10.0 REQUIRED)
use_cpp_utilities(VISIBILITY PUBLIC) use_cpp_utilities(VISIBILITY PUBLIC)
# find 3rd party libraries # find 3rd party libraries

View File

@ -34,7 +34,7 @@ AbstractTrack::AbstractTrack(istream &inputStream, ostream &outputStream, std::u
, m_reader(BinaryReader(&inputStream)) , m_reader(BinaryReader(&inputStream))
, m_writer(BinaryWriter(&outputStream)) , m_writer(BinaryWriter(&outputStream))
, m_startOffset(startOffset) , m_startOffset(startOffset)
, m_headerValid(false) , m_flags(TrackFlags::Enabled | TrackFlags::UsedInPresentation | TrackFlags::UsedWhenPreviewing)
, m_format() , m_format()
, m_mediaType(MediaType::Unknown) , m_mediaType(MediaType::Unknown)
, m_version(0.0) , m_version(0.0)
@ -55,15 +55,7 @@ AbstractTrack::AbstractTrack(istream &inputStream, ostream &outputStream, std::u
, m_depth(0) , m_depth(0)
, m_fps(0) , m_fps(0)
, m_chromaFormat(nullptr) , m_chromaFormat(nullptr)
, m_interlaced(false)
, m_timeScale(0) , m_timeScale(0)
, m_enabled(true)
, m_default(false)
, m_forced(false)
, m_lacing(false)
, m_encrypted(false)
, m_usedInPresentation(true)
, m_usedWhenPreviewing(true)
, m_colorSpace(0) , m_colorSpace(0)
{ {
} }
@ -244,12 +236,12 @@ string AbstractTrack::shortDescription() const
*/ */
void AbstractTrack::parseHeader(Diagnostics &diag) void AbstractTrack::parseHeader(Diagnostics &diag)
{ {
m_headerValid = false; m_flags -= TrackFlags::HeaderValid;
m_istream->seekg(static_cast<streamoff>(m_startOffset), ios_base::beg); m_istream->seekg(static_cast<streamoff>(m_startOffset), ios_base::beg);
try { try {
internalParseHeader(diag); internalParseHeader(diag);
m_headerValid = true; m_flags += TrackFlags::HeaderValid;
} catch (Failure &) { } catch (const Failure &) {
throw; throw;
} }
} }

View File

@ -11,6 +11,7 @@
#include <c++utilities/chrono/timespan.h> #include <c++utilities/chrono/timespan.h>
#include <c++utilities/io/binaryreader.h> #include <c++utilities/io/binaryreader.h>
#include <c++utilities/io/binarywriter.h> #include <c++utilities/io/binarywriter.h>
#include <c++utilities/misc/flagenumclass.h>
#include <iosfwd> #include <iosfwd>
#include <string> #include <string>
@ -36,6 +37,28 @@ enum class TrackType {
IvfStream, /**< The track is a TagParser::IvfStream. */ IvfStream, /**< The track is a TagParser::IvfStream. */
}; };
/*!
* \brief The TrackFlags enum specifies miscellaneous boolean properties of a track.
*/
enum class TrackFlags : std::uint64_t {
None = 0, /**< No flags present */
HeaderValid = (1 << 0), /**< The track header is valid. Set by AbstractTrack::parseHeader() on success. */
Enabled = (1 << 2), /**< The track is marked as enabled. */
Default = (1 << 3), /**< The track is marked as default. */
Forced = (1 << 4), /**< The track is marked as forced. */
Lacing = (1 << 5), /**< The track has lacing. */
Encrypted = (1 << 6), /**< The track is encrypted. */
UsedInPresentation = (1 << 7), /**< The track is supposed to be used in presentation. */
UsedWhenPreviewing = (1 << 8), /**< The track is supposed to be used when previewing. */
Interlaced = (1 << 9), /**< The video is interlaced. */
};
} // namespace TagParser
CPP_UTILITIES_MARK_FLAG_ENUM_CLASS(TagParser, TagParser::TrackFlags)
namespace TagParser {
class TAG_PARSER_EXPORT AbstractTrack { class TAG_PARSER_EXPORT AbstractTrack {
friend class MpegAudioFrameStream; friend class MpegAudioFrameStream;
friend class WaveAudioStream; friend class WaveAudioStream;
@ -52,6 +75,7 @@ public:
CppUtilities::BinaryReader &reader(); CppUtilities::BinaryReader &reader();
CppUtilities::BinaryWriter &writer(); CppUtilities::BinaryWriter &writer();
std::uint64_t startOffset() const; std::uint64_t startOffset() const;
TrackFlags flags() const;
MediaFormat format() const; MediaFormat format() const;
double version() const; double version() const;
const char *formatName() const; const char *formatName() const;
@ -121,7 +145,7 @@ protected:
CppUtilities::BinaryReader m_reader; CppUtilities::BinaryReader m_reader;
CppUtilities::BinaryWriter m_writer; CppUtilities::BinaryWriter m_writer;
std::uint64_t m_startOffset; std::uint64_t m_startOffset;
bool m_headerValid; TrackFlags m_flags;
MediaFormat m_format; MediaFormat m_format;
std::string m_formatId; std::string m_formatId;
std::string m_formatName; std::string m_formatName;
@ -155,15 +179,7 @@ protected:
std::uint32_t m_fps; std::uint32_t m_fps;
const char *m_chromaFormat; const char *m_chromaFormat;
AspectRatio m_pixelAspectRatio; AspectRatio m_pixelAspectRatio;
bool m_interlaced;
std::uint32_t m_timeScale; std::uint32_t m_timeScale;
bool m_enabled;
bool m_default;
bool m_forced;
bool m_lacing;
bool m_encrypted;
bool m_usedInPresentation;
bool m_usedWhenPreviewing;
std::uint32_t m_colorSpace; std::uint32_t m_colorSpace;
Margin m_cropping; Margin m_cropping;
@ -247,6 +263,15 @@ inline std::uint64_t AbstractTrack::startOffset() const
return m_startOffset; return m_startOffset;
} }
/*!
* \brief Returns flags (various boolean properties) of this track.
* \sa TrackFlags
*/
inline TrackFlags AbstractTrack::flags() const
{
return m_flags;
}
/*! /*!
* \brief Returns the format of the track if known; otherwise returns MediaFormat::Unknown. * \brief Returns the format of the track if known; otherwise returns MediaFormat::Unknown.
*/ */
@ -576,13 +601,13 @@ inline const AspectRatio &AbstractTrack::pixelAspectRatio() const
} }
/*! /*!
* \brief Returns true if the video is denoted as interlaced; otherwise returns false. * \brief Returns true if the video is interlaced; otherwise returns false.
* *
* This value only makes sense for video tracks. * This value only makes sense for video tracks.
*/ */
inline bool AbstractTrack::isInterlaced() const inline bool AbstractTrack::isInterlaced() const
{ {
return m_interlaced; return m_flags & TrackFlags::Interlaced;
} }
/*! /*!

View File

@ -361,7 +361,7 @@ void MatroskaTrack::internalParseHeader(Diagnostics &diag)
m_fps = subElement->readFloat(); m_fps = subElement->readFloat();
break; break;
case MatroskaIds::FlagInterlaced: case MatroskaIds::FlagInterlaced:
m_interlaced = subElement->readUInteger(); modFlagEnum(m_flags, TrackFlags::Interlaced, subElement->readUInteger());
break; break;
case MatroskaIds::ColorSpace: case MatroskaIds::ColorSpace:
m_colorSpace = subElement->readUInteger(); m_colorSpace = subElement->readUInteger();
@ -424,16 +424,16 @@ void MatroskaTrack::internalParseHeader(Diagnostics &diag)
case MatroskaIds::CodecDelay: case MatroskaIds::CodecDelay:
break; // TODO break; // TODO
case MatroskaIds::TrackFlagEnabled: case MatroskaIds::TrackFlagEnabled:
m_enabled = trackInfoElement->readUInteger(); modFlagEnum(m_flags, TrackFlags::Enabled, trackInfoElement->readUInteger());
break; break;
case MatroskaIds::TrackFlagDefault: case MatroskaIds::TrackFlagDefault:
m_default = trackInfoElement->readUInteger(); modFlagEnum(m_flags, TrackFlags::Default, trackInfoElement->readUInteger());
break; break;
case MatroskaIds::TrackFlagForced: case MatroskaIds::TrackFlagForced:
m_forced = trackInfoElement->readUInteger(); modFlagEnum(m_flags, TrackFlags::Forced, trackInfoElement->readUInteger());
break; break;
case MatroskaIds::TrackFlagLacing: case MatroskaIds::TrackFlagLacing:
m_lacing = trackInfoElement->readUInteger(); modFlagEnum(m_flags, TrackFlags::Lacing, trackInfoElement->readUInteger());
break; break;
case MatroskaIds::DefaultDuration: case MatroskaIds::DefaultDuration:
defaultDuration = trackInfoElement->readUInteger(); defaultDuration = trackInfoElement->readUInteger();

View File

@ -111,8 +111,8 @@ void Mp4TagField::reparse(Mp4Atom &ilstChild, Diagnostics &diag)
} catch (const Failure &) { } catch (const Failure &) {
// tag id is unknown, it is not possible to validate parsed data type // tag id is unknown, it is not possible to validate parsed data type
} }
m_countryIndicator = reader.readUInt16BE(); m_countryIndicator = reader.readUInt16BE(); // FIXME: use locale within the tag value
m_langIndicator = reader.readUInt16BE(); m_langIndicator = reader.readUInt16BE(); // FIXME: use locale within the tag value
switch (m_parsedRawDataType) { switch (m_parsedRawDataType) {
case RawDataType::Utf8: case RawDataType::Utf8:
case RawDataType::Utf16: case RawDataType::Utf16:
@ -596,8 +596,8 @@ void Mp4TagFieldMaker::make(ostream &stream)
m_writer.writeUInt32BE(Mp4AtomIds::Data); // id of data atom m_writer.writeUInt32BE(Mp4AtomIds::Data); // id of data atom
m_writer.writeByte(0); // version m_writer.writeByte(0); // version
m_writer.writeUInt24BE(m_rawDataType); m_writer.writeUInt24BE(m_rawDataType);
m_writer.writeUInt16BE(m_field.countryIndicator()); m_writer.writeUInt16BE(m_field.countryIndicator()); // FIXME: use locale within the tag value
m_writer.writeUInt16BE(m_field.languageIndicator()); m_writer.writeUInt16BE(m_field.languageIndicator()); // FIXME: use locale within the tag value
if (m_convertedData.tellp()) { if (m_convertedData.tellp()) {
// write converted data // write converted data
stream << m_convertedData.rdbuf(); stream << m_convertedData.rdbuf();

View File

@ -1203,13 +1203,13 @@ void Mp4Track::makeTrackHeader(Diagnostics &diag)
// make version and flags // make version and flags
writer().writeByte(version); writer().writeByte(version);
std::uint32_t flags = 0; std::uint32_t flags = 0;
if (m_enabled) { if (isEnabled()) {
flags |= 0x000001; flags |= 0x000001;
} }
if (m_usedInPresentation) { if (m_flags & TrackFlags::UsedInPresentation) {
flags |= 0x000002; flags |= 0x000002;
} }
if (m_usedWhenPreviewing) { if (m_flags & TrackFlags::UsedWhenPreviewing) {
flags |= 0x000004; flags |= 0x000004;
} }
writer().writeUInt24BE(flags); writer().writeUInt24BE(flags);
@ -1533,9 +1533,9 @@ void Mp4Track::internalParseHeader(Diagnostics &diag)
m_istream->seekg(static_cast<streamoff>(m_tkhdAtom->startOffset() + 8)); // seek to beg, skip size and name m_istream->seekg(static_cast<streamoff>(m_tkhdAtom->startOffset() + 8)); // seek to beg, skip size and name
auto atomVersion = reader.readByte(); // read version auto atomVersion = reader.readByte(); // read version
const auto flags = reader.readUInt24BE(); const auto flags = reader.readUInt24BE();
m_enabled = flags & 0x000001; modFlagEnum(m_flags, TrackFlags::Enabled, flags & 0x000001);
m_usedInPresentation = flags & 0x000002; modFlagEnum(m_flags, TrackFlags::UsedInPresentation, flags & 0x000002);
m_usedWhenPreviewing = flags & 0x000004; modFlagEnum(m_flags, TrackFlags::UsedWhenPreviewing, flags & 0x000004);
switch (atomVersion) { switch (atomVersion) {
case 0: case 0:
m_creationTime = startDate + TimeSpan::fromSeconds(reader.readUInt32BE()); m_creationTime = startDate + TimeSpan::fromSeconds(reader.readUInt32BE());

View File

@ -283,7 +283,6 @@ void OggStream::internalParseHeader(Diagnostics &diag)
// calculate duration from stream size and bitrate, assuming 1 % overhead // calculate duration from stream size and bitrate, assuming 1 % overhead
m_duration = TimeSpan::fromSeconds(static_cast<double>(m_size) / (m_bitrate * 125.0) * 1.1); m_duration = TimeSpan::fromSeconds(static_cast<double>(m_size) / (m_bitrate * 125.0) * 1.1);
} }
m_headerValid = true;
} }
void OggStream::calculateDurationViaSampleCount(std::uint16_t preSkip) void OggStream::calculateDurationViaSampleCount(std::uint16_t preSkip)

View File

@ -667,7 +667,7 @@ inline bool TagValue::isLabeledAsReadonly() const
*/ */
inline void TagValue::setReadonly(bool readOnly) inline void TagValue::setReadonly(bool readOnly)
{ {
readOnly ? (m_flags += TagValueFlags::ReadOnly) : (m_flags -= TagValueFlags::ReadOnly); CppUtilities::modFlagEnum(m_flags, TagValueFlags::ReadOnly, readOnly);
} }
/*! /*!