mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2025-01-08 11:11:51 +00:00
Matroska reader: only analyze last 5 MB of a file if no seek head is found
This commit is contained in:
parent
92f054dc79
commit
dfee7a2226
@ -1,3 +1,12 @@
|
||||
2015-11-29 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvmerge: bug fix: the change to do a deeper file analysis if no
|
||||
seek head was found was causing huge increases in file type
|
||||
detection time as popular tools like x264 don't write seek
|
||||
heads. The way elements at the end are searched has been changed
|
||||
to only scan the last 5 MB of the file instead of iterating over
|
||||
every level 1 element from the beginning of the file.
|
||||
|
||||
2015-11-28 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* Released v8.6.0.
|
||||
|
@ -216,6 +216,12 @@ kax_analyzer_c::set_throw_on_error(bool throw_on_error) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
kax_analyzer_c &
|
||||
kax_analyzer_c::set_parser_start_position(uint64_t position) {
|
||||
m_parser_start_position.reset(position);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
kax_analyzer_c::process() {
|
||||
try {
|
||||
@ -278,6 +284,14 @@ kax_analyzer_c::process_internal() {
|
||||
auto segment_end = m_segment->IsFiniteSize() ? m_segment->GetElementPosition() + m_segment->HeadSize() + m_segment->GetSize() : m_file->get_size();
|
||||
EbmlElement *l1 = nullptr;
|
||||
|
||||
// In certain situations the caller doesn't way to have to pay the
|
||||
// price for full analysis. Then it can configure the parser to
|
||||
// start parsing at a certain offset. EbmlStream::FindNextElement()
|
||||
// should take care of re-syncing to a known level 1 element. But
|
||||
// take care not to start before the segment's data start position.
|
||||
if (m_parser_start_position)
|
||||
m_file->setFilePointer(std::max<uint64_t>(*m_parser_start_position, m_segment->GetElementPosition() + m_segment->HeadSize()));
|
||||
|
||||
// We've got our segment, so let's find all level 1 elements.
|
||||
while (m_file->getFilePointer() < segment_end) {
|
||||
if (!l1)
|
||||
|
@ -102,6 +102,7 @@ private:
|
||||
parse_mode_e m_parse_mode{parse_mode_full};
|
||||
open_mode m_open_mode{MODE_WRITE};
|
||||
bool m_throw_on_error{};
|
||||
boost::optional<uint64_t> m_parser_start_position;
|
||||
|
||||
public: // Static functions
|
||||
static bool probe(std::string file_name);
|
||||
@ -130,6 +131,7 @@ public:
|
||||
virtual kax_analyzer_c &set_parse_mode(parse_mode_e parse_mode);
|
||||
virtual kax_analyzer_c &set_open_mode(open_mode mode);
|
||||
virtual kax_analyzer_c &set_throw_on_error(bool throw_on_error);
|
||||
virtual kax_analyzer_c &set_parser_start_position(uint64_t position);
|
||||
|
||||
virtual bool process();
|
||||
|
||||
|
@ -1205,15 +1205,13 @@ kax_reader_c::read_headers() {
|
||||
|
||||
void
|
||||
kax_reader_c::find_level1_elements_via_analyzer() {
|
||||
if (!debugging_c::requested("kax_reader_deep_scan"))
|
||||
return;
|
||||
|
||||
try {
|
||||
auto analyzer = std::make_shared<kax_analyzer_c>(m_in.get());
|
||||
auto ok = analyzer
|
||||
->set_parse_mode(kax_analyzer_c::parse_mode_fast)
|
||||
auto start_pos = m_in->get_size() - std::min<int64_t>(m_in->get_size(), 5 * 1024 * 1024);
|
||||
auto analyzer = std::make_shared<kax_analyzer_c>(m_in.get());
|
||||
auto ok = analyzer
|
||||
->set_parse_mode(kax_analyzer_c::parse_mode_full)
|
||||
.set_open_mode(MODE_READ)
|
||||
.set_throw_on_error(true)
|
||||
.set_parser_start_position(start_pos)
|
||||
.process();
|
||||
|
||||
if (!ok)
|
||||
|
Loading…
Reference in New Issue
Block a user