kax_analyzer_c: store EBML head; let callers retrieve it

Callers can use the EBML head in order to determine whether a file is
a WebM or a Matroska file (via the "doc type" child).
This commit is contained in:
Moritz Bunkus 2017-07-22 12:36:27 +02:00
parent 480bbb8766
commit 4ea7659e7d
2 changed files with 22 additions and 7 deletions

View File

@ -15,7 +15,6 @@
#include <algorithm>
#include <ebml/EbmlHead.h>
#include <ebml/EbmlStream.h>
#include <ebml/EbmlVoid.h>
#include <matroska/KaxCluster.h>
@ -280,13 +279,20 @@ kax_analyzer_c::process_internal() {
m_stream = new EbmlStream(*m_file);
// Find the EbmlHead element. Must be the first one.
EbmlElement *l0 = m_stream->FindNextID(EBML_INFO(EbmlHead), 0xFFFFFFFFL);
if (!l0)
m_ebml_head.reset(static_cast<EbmlHead *>(m_stream->FindNextID(EBML_INFO(EbmlHead), 0xFFFFFFFFL)));
if (!m_ebml_head)
throw mtx::kax_analyzer_x(Y("Not a valid Matroska file (no EBML head found)"));
// Don't verify its data for now.
l0->SkipData(*m_stream, EBML_CONTEXT(l0));
delete l0;
EbmlElement *l0{};
int upper_lvl_el{};
m_ebml_head->Read(*m_stream, EBML_CONTEXT(m_ebml_head.get()), upper_lvl_el, l0, true, SCOPE_ALL_DATA);
m_ebml_head->SkipData(*m_stream, EBML_CONTEXT(m_ebml_head.get()));
if (l0) {
delete l0;
l0 = nullptr;
}
while (1) {
// Next element must be a segment
@ -302,12 +308,12 @@ kax_analyzer_c::process_internal() {
}
m_segment = std::shared_ptr<KaxSegment>(static_cast<KaxSegment *>(l0));
int upper_lvl_el = 0;
bool aborted = false;
bool cluster_found = false;
bool meta_seek_found = false;
m_segment_end = m_segment->IsFiniteSize() ? m_segment->GetElementPosition() + m_segment->HeadSize() + m_segment->GetSize() : m_file->get_size();
EbmlElement *l1 = nullptr;
upper_lvl_el = 0;
// In certain situations the caller doesn't way to have to pay the
// price for full analysis. Then it can configure the parser to
@ -1431,6 +1437,11 @@ kax_analyzer_c::get_placement_strategy_for(EbmlElement *e) {
return Is<KaxTags>(e) ? ps_end : ps_anywhere;
}
EbmlHead &
kax_analyzer_c::get_ebml_head() {
return *m_ebml_head;
}
uint64_t
kax_analyzer_c::get_segment_pos()
const {

View File

@ -16,6 +16,7 @@
#include "common/common_pch.h"
#include <ebml/EbmlHead.h>
#include <matroska/KaxSegment.h>
#include "common/ebml.h"
@ -101,6 +102,7 @@ private:
mm_io_c *m_file{};
bool m_close_file{true};
std::shared_ptr<KaxSegment> m_segment;
std::shared_ptr<EbmlHead> m_ebml_head;
uint64_t m_segment_end{};
std::map<int64_t, bool> m_meta_seeks_by_position;
EbmlStream *m_stream{};
@ -131,6 +133,8 @@ public:
virtual void with_elements(const EbmlId &id, std::function<void(kax_analyzer_data_c const &)> worker) const;
virtual int find(EbmlId const &id);
virtual EbmlHead &get_ebml_head();
virtual uint64_t get_segment_pos() const;
virtual uint64_t get_segment_data_start_pos() const;