From 554351810a8af691413f092e3fd68bac61e8ee55 Mon Sep 17 00:00:00 2001 From: Martchus Date: Wed, 16 Nov 2016 22:06:12 +0100 Subject: [PATCH] Implement determine tag/index pos for MKV --- abstractcontainer.cpp | 6 ++++++ matroska/matroskacontainer.cpp | 31 +++++++++++++++++++++++++++++-- matroska/matroskacontainer.h | 1 + 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/abstractcontainer.cpp b/abstractcontainer.cpp index 97e0429..38a8cfe 100644 --- a/abstractcontainer.cpp +++ b/abstractcontainer.cpp @@ -175,6 +175,9 @@ bool AbstractContainer::supportsTrackModifications() const * \brief Determines the position of the index. * \returns Returns ElementPosition::BeforeData or ElementPosition::AfterData if the position could * be determined; otherwise returns ElementPosition::Keep. + * \remarks + * - It might be required to parse tracks before the index position can be determined. + * - Not be applicable for files composed of multiple segments. */ ElementPosition AbstractContainer::determineIndexPosition() const { @@ -329,6 +332,9 @@ void AbstractContainer::removeAllTags() * \brief Determines the position of the tags inside the file. * \returns Returns ElementPosition::BeforeData or ElementPosition::AfterData if the position could * be determined; otherwise returns ElementPosition::Keep. + * \remarks + * - It might be required to parse tags before the tag position can be determined. + * - Not be applicable for files composed of multiple segments. */ ElementPosition AbstractContainer::determineTagPosition() const { diff --git a/matroska/matroskacontainer.cpp b/matroska/matroskacontainer.cpp index 458a99b..515440c 100644 --- a/matroska/matroskacontainer.cpp +++ b/matroska/matroskacontainer.cpp @@ -332,14 +332,41 @@ generateRandomId: return attachment.get(); } +/*! + * \brief Determines the position of the element with the specified \a elementId. + * \sa determineTagPosition() and determineIndexPosition() + */ +ElementPosition MatroskaContainer::determineElementPosition(uint64 elementId) const +{ + if(m_firstElement && m_segmentCount == 1) { + if(const EbmlElement *segmentElement = m_firstElement->siblingById(MatroskaIds::Segment, true)) { + for(const EbmlElement *childElement = segmentElement->firstChild(); childElement; childElement = childElement->nextSibling()) { + if(childElement->id() == elementId) { + return ElementPosition::BeforeData; + } else if(childElement->id() == MatroskaIds::Cluster) { + for(const auto &seekInfo : m_seekInfos) { + for(const auto &info : seekInfo->info()) { + if(info.first == elementId) { + return ElementPosition::AfterData; + } + } + } + return ElementPosition::Keep; + } + } + } + } + return ElementPosition::Keep; +} + ElementPosition MatroskaContainer::determineTagPosition() const { - return ElementPosition::Keep; // TODO + return determineElementPosition(MatroskaIds::Tags); } ElementPosition MatroskaContainer::determineIndexPosition() const { - return ElementPosition::Keep; // TODO + return determineElementPosition(MatroskaIds::Cues); } void MatroskaContainer::internalParseHeader() diff --git a/matroska/matroskacontainer.h b/matroska/matroskacontainer.h index 0766f52..54fedb9 100644 --- a/matroska/matroskacontainer.h +++ b/matroska/matroskacontainer.h @@ -41,6 +41,7 @@ public: MatroskaAttachment *createAttachment(); MatroskaAttachment *attachment(std::size_t index); std::size_t attachmentCount() const; + ElementPosition determineElementPosition(uint64 elementId) const; ElementPosition determineTagPosition() const; ElementPosition determineIndexPosition() const;