diff --git a/Libraries/LibMedia/Containers/Matroska/Reader.cpp b/Libraries/LibMedia/Containers/Matroska/Reader.cpp index 3483f3277d..95634d6d3b 100644 --- a/Libraries/LibMedia/Containers/Matroska/Reader.cpp +++ b/Libraries/LibMedia/Containers/Matroska/Reader.cpp @@ -117,9 +117,9 @@ static DecoderErrorOr parse_master_element(Streamer& streamer, [[maybe_u bool first_element = true; auto first_element_position = streamer.position(); + auto element_data_end = first_element_position + element_data_size; - streamer.push_octets_read(); - while (streamer.octets_read() < element_data_size) { + while (streamer.position() < element_data_end) { dbgln_if(MATROSKA_TRACE_DEBUG, "====== Reading element ======"); auto element_id = TRY(streamer.read_variable_size_integer(false)); dbgln_if(MATROSKA_TRACE_DEBUG, "{:s} element ID is {:#010x}", element_name, element_id); @@ -160,14 +160,13 @@ static DecoderErrorOr parse_master_element(Streamer& streamer, [[maybe_u if (result.value() == ElementIterationDecision::BreakHere) break; if (result.value() == ElementIterationDecision::BreakAtEnd) { - TRY(streamer.seek_to_position(first_element_position + element_data_size)); + TRY(streamer.seek_to_position(element_data_end)); break; } - dbgln_if(MATROSKA_TRACE_DEBUG, "Read {} octets of the {} so far.", streamer.octets_read(), element_name); + dbgln_if(MATROSKA_TRACE_DEBUG, "Read {} octets of the {} so far.", streamer.position() - first_element_position, element_name); first_element = false; } - streamer.pop_octets_read(); return first_element_position; } @@ -772,7 +771,7 @@ DecoderErrorOr> SampleIterator::get_frames(Block block) Vector frames; if (block.lacing() == Block::Lacing::EBML) { - auto octets_read_before_frame_sizes = streamer.octets_read(); + auto frames_start_position = streamer.position(); auto frame_count = TRY(streamer.read_octet()) + 1; Vector frame_sizes; frame_sizes.ensure_capacity(frame_count); @@ -796,7 +795,7 @@ DecoderErrorOr> SampleIterator::get_frames(Block block) frame_size_sum += frame_size; previous_frame_size = frame_size; } - frame_sizes.append(block.data_size() - frame_size_sum - (streamer.octets_read() - octets_read_before_frame_sizes)); + frame_sizes.append(block.data_size() - frame_size_sum - (streamer.position() - frames_start_position)); for (int i = 0; i < frame_count; i++) { // FIXME: ReadonlyBytes instead of copying the frame data? @@ -809,7 +808,7 @@ DecoderErrorOr> SampleIterator::get_frames(Block block) for (int i = 0; i < frame_count; i++) frames.append(TRY(streamer.read_raw_octets(individual_frame_size))); } else if (block.lacing() == Block::Lacing::XIPH) { - auto frames_start_position = streamer.octets_read(); + auto frames_start_position = streamer.position(); auto frame_count_minus_one = TRY(streamer.read_octet()); frames.ensure_capacity(frame_count_minus_one + 1); @@ -829,7 +828,7 @@ DecoderErrorOr> SampleIterator::get_frames(Block block) for (auto i = 0; i < frame_count_minus_one; i++) frames.append(TRY(streamer.read_raw_octets(frame_sizes[i]))); - frames.append(TRY(streamer.read_raw_octets(block.data_size() - (streamer.octets_read() - frames_start_position)))); + frames.append(TRY(streamer.read_raw_octets(block.data_size() - (streamer.position() - frames_start_position)))); } else { frames.append(TRY(streamer.read_raw_octets(block.data_size()))); } @@ -1250,7 +1249,6 @@ DecoderErrorOr Streamer::read_octet() u8 result; Bytes bytes { &result, 1 }; TRY(m_stream_cursor->read_into(bytes)); - m_octets_read.last()++; return bytes[0]; } @@ -1319,7 +1317,6 @@ DecoderErrorOr Streamer::read_raw_octets(size_t num_octets) auto result = MUST(ByteBuffer::create_uninitialized(num_octets)); auto bytes = result.bytes(); TRY(m_stream_cursor->read_into(bytes)); - m_octets_read.last() += num_octets; return result; } @@ -1358,7 +1355,6 @@ DecoderErrorOr Streamer::read_unknown_element() auto element_length = TRY(read_variable_size_integer()); dbgln_if(MATROSKA_TRACE_DEBUG, "Skipping unknown element of size {}.", element_length); TRY(m_stream_cursor->seek(element_length, IncrementallyPopulatedStream::Cursor::SeekMode::FromCurrentPosition)); - m_octets_read.last() += element_length; return {}; } diff --git a/Libraries/LibMedia/Containers/Matroska/Reader.h b/Libraries/LibMedia/Containers/Matroska/Reader.h index 8bab4740ef..b991149cec 100644 --- a/Libraries/LibMedia/Containers/Matroska/Reader.h +++ b/Libraries/LibMedia/Containers/Matroska/Reader.h @@ -128,17 +128,6 @@ public: { } - size_t octets_read() { return m_octets_read.last(); } - - void push_octets_read() { m_octets_read.append(0); } - - void pop_octets_read() - { - auto popped = m_octets_read.take_last(); - if (!m_octets_read.is_empty()) - m_octets_read.last() += popped; - } - DecoderErrorOr read_octet(); DecoderErrorOr read_i16(); @@ -161,7 +150,6 @@ public: private: NonnullRefPtr m_stream_cursor; - Vector m_octets_read { 0 }; }; } diff --git a/Tests/LibMedia/TestParseMatroska.cpp b/Tests/LibMedia/TestParseMatroska.cpp index 59e3f74c0e..dd5949e668 100644 --- a/Tests/LibMedia/TestParseMatroska.cpp +++ b/Tests/LibMedia/TestParseMatroska.cpp @@ -53,3 +53,26 @@ TEST_CASE(seek_in_multi_frame_blocks) EXPECT(coded_frame_after_backward_seek.timestamp() > AK::Duration::zero()); EXPECT(coded_frame_after_backward_seek.timestamp() <= backward_seek_time); } + +TEST_CASE(block_group) +{ + auto file = MUST(Core::File::open("./test-matroska-block-group.mkv"sv, Core::File::OpenMode::Read)); + auto stream = Media::IncrementallyPopulatedStream::create_from_buffer(MUST(file->read_until_eof())); + auto matroska_reader = MUST(Media::Matroska::Reader::from_stream(stream->create_cursor())); + u64 video_track = 0; + MUST(matroska_reader.for_each_track_of_type(Media::Matroska::TrackEntry::TrackType::Video, [&](Media::Matroska::TrackEntry const& track_entry) -> Media::DecoderErrorOr { + video_track = track_entry.track_number(); + return IterationDecision::Break; + })); + VERIFY(video_track == 1); + + auto iterator = MUST(matroska_reader.create_sample_iterator(stream->create_cursor(), video_track)); + + auto first_block = MUST(iterator.next_block()); + EXPECT(first_block.duration().has_value()); + EXPECT_EQ(first_block.duration()->to_milliseconds(), 33); + + auto second_block = MUST(iterator.next_block()); + EXPECT_EQ(second_block.timestamp().to_milliseconds(), 33); + EXPECT(second_block.only_keyframes()); +} diff --git a/Tests/LibMedia/test-matroska-block-group.mkv b/Tests/LibMedia/test-matroska-block-group.mkv new file mode 100644 index 0000000000..303dd16f99 Binary files /dev/null and b/Tests/LibMedia/test-matroska-block-group.mkv differ