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
""
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)
# find 3rd party libraries

View File

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

View File

@ -11,6 +11,7 @@
#include <c++utilities/chrono/timespan.h>
#include <c++utilities/io/binaryreader.h>
#include <c++utilities/io/binarywriter.h>
#include <c++utilities/misc/flagenumclass.h>
#include <iosfwd>
#include <string>
@ -36,6 +37,28 @@ enum class TrackType {
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 {
friend class MpegAudioFrameStream;
friend class WaveAudioStream;
@ -52,6 +75,7 @@ public:
CppUtilities::BinaryReader &reader();
CppUtilities::BinaryWriter &writer();
std::uint64_t startOffset() const;
TrackFlags flags() const;
MediaFormat format() const;
double version() const;
const char *formatName() const;
@ -121,7 +145,7 @@ protected:
CppUtilities::BinaryReader m_reader;
CppUtilities::BinaryWriter m_writer;
std::uint64_t m_startOffset;
bool m_headerValid;
TrackFlags m_flags;
MediaFormat m_format;
std::string m_formatId;
std::string m_formatName;
@ -155,15 +179,7 @@ protected:
std::uint32_t m_fps;
const char *m_chromaFormat;
AspectRatio m_pixelAspectRatio;
bool m_interlaced;
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;
Margin m_cropping;
@ -247,6 +263,15 @@ inline std::uint64_t AbstractTrack::startOffset() const
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.
*/
@ -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.
*/
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();
break;
case MatroskaIds::FlagInterlaced:
m_interlaced = subElement->readUInteger();
modFlagEnum(m_flags, TrackFlags::Interlaced, subElement->readUInteger());
break;
case MatroskaIds::ColorSpace:
m_colorSpace = subElement->readUInteger();
@ -424,16 +424,16 @@ void MatroskaTrack::internalParseHeader(Diagnostics &diag)
case MatroskaIds::CodecDelay:
break; // TODO
case MatroskaIds::TrackFlagEnabled:
m_enabled = trackInfoElement->readUInteger();
modFlagEnum(m_flags, TrackFlags::Enabled, trackInfoElement->readUInteger());
break;
case MatroskaIds::TrackFlagDefault:
m_default = trackInfoElement->readUInteger();
modFlagEnum(m_flags, TrackFlags::Default, trackInfoElement->readUInteger());
break;
case MatroskaIds::TrackFlagForced:
m_forced = trackInfoElement->readUInteger();
modFlagEnum(m_flags, TrackFlags::Forced, trackInfoElement->readUInteger());
break;
case MatroskaIds::TrackFlagLacing:
m_lacing = trackInfoElement->readUInteger();
modFlagEnum(m_flags, TrackFlags::Lacing, trackInfoElement->readUInteger());
break;
case MatroskaIds::DefaultDuration:
defaultDuration = trackInfoElement->readUInteger();

View File

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

View File

@ -1203,13 +1203,13 @@ void Mp4Track::makeTrackHeader(Diagnostics &diag)
// make version and flags
writer().writeByte(version);
std::uint32_t flags = 0;
if (m_enabled) {
if (isEnabled()) {
flags |= 0x000001;
}
if (m_usedInPresentation) {
if (m_flags & TrackFlags::UsedInPresentation) {
flags |= 0x000002;
}
if (m_usedWhenPreviewing) {
if (m_flags & TrackFlags::UsedWhenPreviewing) {
flags |= 0x000004;
}
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
auto atomVersion = reader.readByte(); // read version
const auto flags = reader.readUInt24BE();
m_enabled = flags & 0x000001;
m_usedInPresentation = flags & 0x000002;
m_usedWhenPreviewing = flags & 0x000004;
modFlagEnum(m_flags, TrackFlags::Enabled, flags & 0x000001);
modFlagEnum(m_flags, TrackFlags::UsedInPresentation, flags & 0x000002);
modFlagEnum(m_flags, TrackFlags::UsedWhenPreviewing, flags & 0x000004);
switch (atomVersion) {
case 0:
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
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)

View File

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