From 9afc43b2096b915fc298e1719a040a4990245284 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Wed, 13 Jun 2018 17:57:20 +0200 Subject: [PATCH] HEVC/h.265 ES reader: clear parser's buffer after reading the headers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After reading the headers, the file is read again from the start. Therefore no data must be left in the parser's internal buffers. That was the intention behind calling `flush()` - but that isn't actually what flush does. Instead it tries to use the remaining data in the buffers as a frame. This is not only wrong, it can also fail and cause an exception to be thrown. That in turn causes a failure when reading the headers — both identification and muxing abort at that point. This is the HEVC analog for what was fixed for AVC in #2325. --- NEWS.md | 3 +++ src/common/hevc_es_parser.cpp | 7 +++++++ src/common/hevc_es_parser.h | 1 + src/input/r_hevc.cpp | 5 ++--- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 6db2b19d9..fd42ec61b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,9 @@ * mkvmerge: AVC/h.264: fixed file identification failing for certain elementary streams due to internal buffers not being cleared properly. Fixes #2325. +* mkvmerge: HEVC/h.265: fixed file identification failing for certain + elementary streams due to internal buffers not being cleared properly. This + is the HEVC analog to what was fixed for AVC in #2325. # Version 24.0.0 "Beyond The Pale" 2018-06-10 diff --git a/src/common/hevc_es_parser.cpp b/src/common/hevc_es_parser.cpp index 558b1834d..ae6d934c0 100644 --- a/src/common/hevc_es_parser.cpp +++ b/src/common/hevc_es_parser.cpp @@ -192,6 +192,13 @@ es_parser_c::flush() { cleanup(); } +void +es_parser_c::clear() { + m_unparsed_buffer.reset(); + m_have_incomplete_frame = false; + m_parsed_position = 0; +} + void es_parser_c::add_timestamp(int64_t timestamp) { m_provided_timestamps.emplace_back(timestamp, m_stream_position); diff --git a/src/common/hevc_es_parser.h b/src/common/hevc_es_parser.h index e421adc8e..09fc7218d 100644 --- a/src/common/hevc_es_parser.h +++ b/src/common/hevc_es_parser.h @@ -119,6 +119,7 @@ public: } void flush(); + void clear(); bool frame_available() { return !m_frames_out.empty(); diff --git a/src/input/r_hevc.cpp b/src/input/r_hevc.cpp index 7c9fa36b4..0f9f3f7c7 100644 --- a/src/input/r_hevc.cpp +++ b/src/input/r_hevc.cpp @@ -89,14 +89,13 @@ hevc_es_reader_c::read_headers() { break; } - if (parser.headers_parsed()) - parser.flush(); - m_width = parser.get_width(); m_height = parser.get_height(); m_in->setFilePointer(0, seek_beginning); + parser.clear(); + } catch (...) { throw mtx::input::open_x(); }