diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f2b4f9..2a23941 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/abstracttrack.cpp b/abstracttrack.cpp index edc86ce..23aaf8f 100644 --- a/abstracttrack.cpp +++ b/abstracttrack.cpp @@ -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(m_startOffset), ios_base::beg); try { internalParseHeader(diag); - m_headerValid = true; - } catch (Failure &) { + m_flags += TrackFlags::HeaderValid; + } catch (const Failure &) { throw; } } diff --git a/abstracttrack.h b/abstracttrack.h index d1e1e6f..b461d14 100644 --- a/abstracttrack.h +++ b/abstracttrack.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -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; } /*! diff --git a/matroska/matroskatrack.cpp b/matroska/matroskatrack.cpp index 50bbc07..2d07104 100644 --- a/matroska/matroskatrack.cpp +++ b/matroska/matroskatrack.cpp @@ -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(); diff --git a/mp4/mp4tagfield.cpp b/mp4/mp4tagfield.cpp index b03fdd3..218d061 100644 --- a/mp4/mp4tagfield.cpp +++ b/mp4/mp4tagfield.cpp @@ -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(); diff --git a/mp4/mp4track.cpp b/mp4/mp4track.cpp index 5455266..826b323 100644 --- a/mp4/mp4track.cpp +++ b/mp4/mp4track.cpp @@ -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(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()); diff --git a/ogg/oggstream.cpp b/ogg/oggstream.cpp index e9b1c39..b7a06b3 100644 --- a/ogg/oggstream.cpp +++ b/ogg/oggstream.cpp @@ -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(m_size) / (m_bitrate * 125.0) * 1.1); } - m_headerValid = true; } void OggStream::calculateDurationViaSampleCount(std::uint16_t preSkip) diff --git a/tagvalue.h b/tagvalue.h index c73a791..b633685 100644 --- a/tagvalue.h +++ b/tagvalue.h @@ -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); } /*!