Improve dealing with muxing/writing application of Matroska files
* Allow reading the current muxing/writing application * Allow to preserve the original muxing/writing application instead of always overriding
This commit is contained in:
parent
f5497fb300
commit
e6bb98d6e6
|
@ -7,7 +7,9 @@ using namespace CppUtilities;
|
||||||
namespace TagParser {
|
namespace TagParser {
|
||||||
|
|
||||||
/// \brief The AbstractContainerPrivate struct contains private fields of the AbstractContainer class.
|
/// \brief The AbstractContainerPrivate struct contains private fields of the AbstractContainer class.
|
||||||
struct AbstractContainerPrivate {};
|
struct AbstractContainerPrivate {
|
||||||
|
std::vector<std::string> muxingApps, writingApps;
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \class TagParser::AbstractContainer
|
* \class TagParser::AbstractContainer
|
||||||
|
@ -475,6 +477,40 @@ bool AbstractContainer::supportsTitle() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the muxing applications specified as meta-data.
|
||||||
|
*/
|
||||||
|
const std::vector<std::string> &AbstractContainer::muxingApplications() const
|
||||||
|
{
|
||||||
|
static const auto empty = std::vector<std::string>();
|
||||||
|
return m_p ? m_p->muxingApps : empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the muxing applications specified as meta-data.
|
||||||
|
*/
|
||||||
|
std::vector<std::string> &AbstractContainer::muxingApplications()
|
||||||
|
{
|
||||||
|
return p()->muxingApps;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the writing applications specified as meta-data.
|
||||||
|
*/
|
||||||
|
const std::vector<std::string> &AbstractContainer::writingApplications() const
|
||||||
|
{
|
||||||
|
static const auto empty = std::vector<std::string>();
|
||||||
|
return m_p ? m_p->writingApps : empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the writing applications specified as meta-data.
|
||||||
|
*/
|
||||||
|
std::vector<std::string> &AbstractContainer::writingApplications()
|
||||||
|
{
|
||||||
|
return p()->writingApps;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the number of segments.
|
* \brief Returns the number of segments.
|
||||||
*/
|
*/
|
||||||
|
@ -502,4 +538,15 @@ void AbstractContainer::reset()
|
||||||
m_titles.clear();
|
m_titles.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the private data for the container.
|
||||||
|
*/
|
||||||
|
std::unique_ptr<AbstractContainerPrivate> &AbstractContainer::p()
|
||||||
|
{
|
||||||
|
if (!m_p) {
|
||||||
|
m_p = std::make_unique<AbstractContainerPrivate>();
|
||||||
|
}
|
||||||
|
return m_p;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace TagParser
|
} // namespace TagParser
|
||||||
|
|
|
@ -80,6 +80,8 @@ public:
|
||||||
const std::vector<std::string> &titles() const;
|
const std::vector<std::string> &titles() const;
|
||||||
void setTitle(std::string_view title, std::size_t segmentIndex = 0);
|
void setTitle(std::string_view title, std::size_t segmentIndex = 0);
|
||||||
virtual bool supportsTitle() const;
|
virtual bool supportsTitle() const;
|
||||||
|
const std::vector<std::string> &muxingApplications() const;
|
||||||
|
const std::vector<std::string> &writingApplications() const;
|
||||||
virtual std::size_t segmentCount() const;
|
virtual std::size_t segmentCount() const;
|
||||||
CppUtilities::TimeSpan duration() const;
|
CppUtilities::TimeSpan duration() const;
|
||||||
CppUtilities::DateTime creationTime() const;
|
CppUtilities::DateTime creationTime() const;
|
||||||
|
@ -97,6 +99,8 @@ protected:
|
||||||
virtual void internalParseChapters(Diagnostics &diag, AbortableProgressFeedback &progress);
|
virtual void internalParseChapters(Diagnostics &diag, AbortableProgressFeedback &progress);
|
||||||
virtual void internalParseAttachments(Diagnostics &diag, AbortableProgressFeedback &progress);
|
virtual void internalParseAttachments(Diagnostics &diag, AbortableProgressFeedback &progress);
|
||||||
virtual void internalMakeFile(Diagnostics &diag, AbortableProgressFeedback &progress);
|
virtual void internalMakeFile(Diagnostics &diag, AbortableProgressFeedback &progress);
|
||||||
|
std::vector<std::string> &muxingApplications();
|
||||||
|
std::vector<std::string> &writingApplications();
|
||||||
|
|
||||||
std::uint64_t m_version;
|
std::uint64_t m_version;
|
||||||
std::uint64_t m_readVersion;
|
std::uint64_t m_readVersion;
|
||||||
|
@ -117,6 +121,8 @@ protected:
|
||||||
bool m_attachmentsParsed;
|
bool m_attachmentsParsed;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<AbstractContainerPrivate> &p();
|
||||||
|
|
||||||
std::uint64_t m_startOffset;
|
std::uint64_t m_startOffset;
|
||||||
std::iostream *m_stream;
|
std::iostream *m_stream;
|
||||||
CppUtilities::BinaryReader m_reader;
|
CppUtilities::BinaryReader m_reader;
|
||||||
|
|
|
@ -627,6 +627,12 @@ void MatroskaContainer::parseSegmentInfo(Diagnostics &diag)
|
||||||
case MatroskaIds::TimeCodeScale:
|
case MatroskaIds::TimeCodeScale:
|
||||||
timeScale = subElement->readUInteger();
|
timeScale = subElement->readUInteger();
|
||||||
break;
|
break;
|
||||||
|
case MatroskaIds::MuxingApp:
|
||||||
|
muxingApplications().emplace_back(subElement->readString());
|
||||||
|
break;
|
||||||
|
case MatroskaIds::WrittingApp:
|
||||||
|
writingApplications().emplace_back(subElement->readString());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
subElement = subElement->nextSibling();
|
subElement = subElement->nextSibling();
|
||||||
}
|
}
|
||||||
|
@ -942,13 +948,18 @@ void MatroskaContainer::internalMakeFile(Diagnostics &diag, AbortableProgressFee
|
||||||
const std::uint64_t ebmlHeaderSize = 4 + EbmlElement::calculateSizeDenotationLength(ebmlHeaderDataSize) + ebmlHeaderDataSize;
|
const std::uint64_t ebmlHeaderSize = 4 + EbmlElement::calculateSizeDenotationLength(ebmlHeaderDataSize) + ebmlHeaderDataSize;
|
||||||
|
|
||||||
// calculate size of "WritingLib"-element
|
// calculate size of "WritingLib"-element
|
||||||
constexpr std::string_view muxingAppName = APP_NAME " v" APP_VERSION;
|
const auto &muxingApps = const_cast<const MatroskaContainer *>(this)->muxingApplications();
|
||||||
constexpr std::uint64_t muxingAppElementTotalSize = 2 + 1 + muxingAppName.size();
|
const auto muxingAppName = (fileInfo().fileHandlingFlags() == MediaFileHandlingFlags::PreserveMuxingApplication && !muxingApps.empty())
|
||||||
|
? std::string_view(muxingApps.front())
|
||||||
|
: std::string_view(APP_NAME " v" APP_VERSION);
|
||||||
|
const auto muxingAppElementTotalSize = std::uint64_t(2 + 1 + muxingAppName.size());
|
||||||
|
|
||||||
// calculate size of "WritingApp"-element
|
// calculate size of "WritingApp"-element
|
||||||
const std::uint64_t writingAppElementDataSize
|
const auto writingApps = const_cast<const MatroskaContainer *>(this)->writingApplications();
|
||||||
= fileInfo().writingApplication().empty() ? muxingAppName.size() : fileInfo().writingApplication().size();
|
const auto writingAppName = (fileInfo().fileHandlingFlags() == MediaFileHandlingFlags::PreserveWritingApplication && !writingApps.empty())
|
||||||
const std::uint64_t writingAppElementTotalSize = 2 + 1 + writingAppElementDataSize;
|
? std::string_view(writingApps.front())
|
||||||
|
: std::string_view(fileInfo().writingApplication().empty() ? muxingAppName : std::string_view(fileInfo().writingApplication()));
|
||||||
|
const auto writingAppElementTotalSize = std::uint64_t(2 + 1 + writingAppName.size());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// calculate size of "Tags"-element
|
// calculate size of "Tags"-element
|
||||||
|
|
|
@ -43,7 +43,7 @@ enum SeekIds { SeekID = 0x53AB, SeekPosition = 0x53AC };
|
||||||
enum SegmentInfoIds {
|
enum SegmentInfoIds {
|
||||||
TimeCodeScale = 0x2AD7B1,
|
TimeCodeScale = 0x2AD7B1,
|
||||||
Duration = 0x4489,
|
Duration = 0x4489,
|
||||||
WrittingApp = 0x5741,
|
WrittingApp = 0x5741, // TODOv13: change to WritingApp
|
||||||
MuxingApp = 0x4D80,
|
MuxingApp = 0x4D80,
|
||||||
DateUTC = 0x4461,
|
DateUTC = 0x4461,
|
||||||
SegmentUID = 0x73A4,
|
SegmentUID = 0x73A4,
|
||||||
|
|
|
@ -64,6 +64,8 @@ enum class MediaFileHandlingFlags : std::uint64_t {
|
||||||
ForceIndexPosition = (1 << 3), /**< enforces the index position when applying changes, see remarks of MediaFileInfo::setIndexPosition() */
|
ForceIndexPosition = (1 << 3), /**< enforces the index position when applying changes, see remarks of MediaFileInfo::setIndexPosition() */
|
||||||
NormalizeKnownTagFieldIds = (1 << 4), /**< normalizes known tag field IDs when parsing to match the tag specification's recommendations */
|
NormalizeKnownTagFieldIds = (1 << 4), /**< normalizes known tag field IDs when parsing to match the tag specification's recommendations */
|
||||||
PreserveRawTimingValues = (1 << 8), /**< preverves raw timing values (so far only used when making MP4 tracks) */
|
PreserveRawTimingValues = (1 << 8), /**< preverves raw timing values (so far only used when making MP4 tracks) */
|
||||||
|
PreserveMuxingApplication = (1 << 9), /**< preverves the muxing application (so far only used when making Matroska container) */
|
||||||
|
PreserveWritingApplication = (1 << 10), /**< preverves the writing application (so far only used when making Matroska container) */
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace TagParser
|
} // namespace TagParser
|
||||||
|
@ -471,7 +473,9 @@ inline const std::string &MediaFileInfo::writingApplication() const
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Sets the writing application as container-level meta-data. Put the name of your application here.
|
* \brief Sets the writing application as container-level meta-data. Put the name of your application here.
|
||||||
* \remarks Might not be used (depends on the format).
|
* \remarks
|
||||||
|
* - Currently only used when making Matroska files.
|
||||||
|
* - The assigned value is ignored when MediaFileHandlingFlags::PreserveWritingApplication is set.
|
||||||
*/
|
*/
|
||||||
inline void MediaFileInfo::setWritingApplication(std::string_view writingApplication)
|
inline void MediaFileInfo::setWritingApplication(std::string_view writingApplication)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue