From 287b77720017d1cb5ddd8de8ca3ea28af1b34ec3 Mon Sep 17 00:00:00 2001 From: nekohkr <182421472+nekohkr@users.noreply.github.com> Date: Sun, 5 Jul 2026 23:42:22 +0900 Subject: [PATCH] Optimize parser buffer handling --- src/dataUnit.cpp | 19 ++++++++----------- src/dataUnit.h | 6 +++--- src/fragmentAssembler.cpp | 4 ++-- src/fragmentAssembler.h | 7 ++++--- src/mmtTlvDemuxer.cpp | 12 +++++------- src/mpu.cpp | 5 ++--- src/mpu.h | 4 ++-- src/mpuApplicationProcessor.cpp | 4 ++-- src/mpuApplicationProcessor.h | 4 ++-- src/mpuAudioProcessor.cpp | 4 ++-- src/mpuAudioProcessor.h | 4 ++-- src/mpuProcessorBase.h | 7 ++++--- src/mpuSubtitleProcessor.cpp | 4 ++-- src/mpuSubtitleProcessor.h | 4 ++-- src/mpuVideoProcessor.cpp | 4 ++-- src/mpuVideoProcessor.h | 4 ++-- src/stream.cpp | 27 ++++++++++++++------------- src/stream.h | 32 ++++++++++++++++++++++++-------- 18 files changed, 84 insertions(+), 71 deletions(-) diff --git a/src/dataUnit.cpp b/src/dataUnit.cpp index a012f69..9e4f57c 100644 --- a/src/dataUnit.cpp +++ b/src/dataUnit.cpp @@ -2,8 +2,9 @@ namespace MmtTlv { -bool DataUnit::unpack(Common::ReadStream& stream, bool timedFlag, bool aggregateFlag) { - try { +bool DataUnit::unpack(Common::ReadStream& stream, bool timedFlag, bool aggregateFlag) { + try { + data = {}; if (timedFlag) { if (aggregateFlag == 0) { movieFragmentSequenceNumber = stream.getBe32U(); @@ -12,8 +13,7 @@ bool DataUnit::unpack(Common::ReadStream& stream, bool timedFlag, bool aggregate priority = stream.get8U(); dependencyCounter = stream.get8U(); - data.resize(stream.leftBytes()); - stream.read(data.data(), stream.leftBytes()); + data = stream.readView(stream.leftBytes()); } else { dataUnitLength = stream.getBe16U(); @@ -29,22 +29,19 @@ bool DataUnit::unpack(Common::ReadStream& stream, bool timedFlag, bool aggregate return false; } - data.resize(dataUnitLength - 4 * 3 - 2); - stream.read(data.data(), dataUnitLength - 4 * 3 - 2); + data = stream.readView(dataUnitLength - 4 * 3 - 2); } } else { if (aggregateFlag == 0) { itemId = stream.getBe32U(); - data.resize(stream.leftBytes()); - stream.read(data.data(), stream.leftBytes()); + data = stream.readView(stream.leftBytes()); } else { dataUnitLength = stream.getBe16U(); - data.resize(dataUnitLength); - stream.read(data.data(), dataUnitLength); + data = stream.readView(dataUnitLength); } } } @@ -55,4 +52,4 @@ bool DataUnit::unpack(Common::ReadStream& stream, bool timedFlag, bool aggregate return true; } -} \ No newline at end of file +} diff --git a/src/dataUnit.h b/src/dataUnit.h index 6f10704..bbc2248 100644 --- a/src/dataUnit.h +++ b/src/dataUnit.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #include "stream.h" namespace MmtTlv { @@ -15,7 +15,7 @@ class DataUnit { uint8_t priority; uint8_t dependencyCounter; uint32_t itemId; - std::vector data; + std::span data; }; -} \ No newline at end of file +} diff --git a/src/fragmentAssembler.cpp b/src/fragmentAssembler.cpp index f6efe00..1c6de2c 100644 --- a/src/fragmentAssembler.cpp +++ b/src/fragmentAssembler.cpp @@ -3,7 +3,7 @@ namespace MmtTlv { -bool FragmentAssembler::assemble(const std::vector& fragment, FragmentationIndicator fragmentationIndicator, uint32_t packetSequenceNumber) { +bool FragmentAssembler::assemble(std::span fragment, FragmentationIndicator fragmentationIndicator, uint32_t packetSequenceNumber) { switch (fragmentationIndicator) { case FragmentationIndicator::NotFragmented: if (state == State::InFragment) { @@ -104,4 +104,4 @@ void FragmentValidator::clear() { state = State::NotStarted; } -} \ No newline at end of file +} diff --git a/src/fragmentAssembler.h b/src/fragmentAssembler.h index 0691c83..48f4454 100644 --- a/src/fragmentAssembler.h +++ b/src/fragmentAssembler.h @@ -1,5 +1,6 @@ #pragma once -#include +#include +#include #include #include "mmtFragment.h" @@ -24,7 +25,7 @@ class FragmentValidator { class FragmentAssembler { public: - bool assemble(const std::vector& fragment, FragmentationIndicator fragmentationIndicator, uint32_t packetSequenceNumber); + bool assemble(std::span fragment, FragmentationIndicator fragmentationIndicator, uint32_t packetSequenceNumber); void checkState(uint32_t packetSequenceNumber); void clear(); @@ -41,4 +42,4 @@ class FragmentAssembler { uint32_t last_seq = 0; }; -} \ No newline at end of file +} diff --git a/src/mmtTlvDemuxer.cpp b/src/mmtTlvDemuxer.cpp index 94f3948..d3b8d77 100644 --- a/src/mmtTlvDemuxer.cpp +++ b/src/mmtTlvDemuxer.cpp @@ -792,7 +792,7 @@ void MmtTlvDemuxer::processMpu(Common::ReadStream& stream) { } } -void MmtTlvDemuxer::processMfuData(Common::ReadStream& stream) { +void MmtTlvDemuxer::processMfuData(Common::ReadStream& stream) { MmtStream* mmtStream = getStream(mmtp.packetId); auto validator = getFragmentValidator(mmtp.packetId); @@ -800,10 +800,8 @@ void MmtTlvDemuxer::processMfuData(Common::ReadStream& stream) { return; } - std::vector data(stream.leftBytes()); - stream.read(data.data(), stream.leftBytes()); - - const auto ret = mmtStream->mpuProcessor->process(*mmtStream, data, mpu.fragmentationIndicator); + const auto data = stream.readView(stream.leftBytes()); + const auto ret = mmtStream->mpuProcessor->process(*mmtStream, data, mpu.fragmentationIndicator); if (ret) { const auto& mfuData = ret.value(); auto* mmtStream = getStreamByIdx(mfuData.streamIndex); @@ -864,7 +862,7 @@ void MmtTlvDemuxer::processSignalingMessages(Common::ReadStream& stream) { std::vector message; message.resize(length); - stream.read(message.data(), length); + nstream.read(message.data(), length); if (assembler->assemble(message, signalingMessage.fragmentationIndicator, mmtp.packetSequenceNumber)) { Common::ReadStream messageStream(assembler->data); @@ -913,4 +911,4 @@ bool MmtTlvDemuxer::isValidTlv(Common::ReadStream& stream) const { return true; } -} \ No newline at end of file +} diff --git a/src/mpu.cpp b/src/mpu.cpp index e61c52e..c4d4aa3 100644 --- a/src/mpu.cpp +++ b/src/mpu.cpp @@ -18,8 +18,7 @@ bool Mpu::unpack(Common::ReadStream& stream) fragmentCounter = stream.get8U(); mpuSequenceNumber = stream.getBe32U(); - payload.resize(payloadLength - 6); - stream.read(payload.data(), payloadLength - 6); + payload = stream.readView(payloadLength - 6); } catch (const std::out_of_range&) { @@ -29,4 +28,4 @@ bool Mpu::unpack(Common::ReadStream& stream) return true; } -} \ No newline at end of file +} diff --git a/src/mpu.h b/src/mpu.h index d15035d..ddaf419 100644 --- a/src/mpu.h +++ b/src/mpu.h @@ -1,5 +1,5 @@ #pragma once -#include +#include #include "stream.h" #include "mmtFragment.h" @@ -16,7 +16,7 @@ class Mpu { bool aggregateFlag; uint8_t fragmentCounter; uint32_t mpuSequenceNumber; - std::vector payload; + std::span payload; }; } diff --git a/src/mpuApplicationProcessor.cpp b/src/mpuApplicationProcessor.cpp index 402222a..21143d8 100644 --- a/src/mpuApplicationProcessor.cpp +++ b/src/mpuApplicationProcessor.cpp @@ -3,7 +3,7 @@ namespace MmtTlv { -std::optional MpuApplicationProcessor::process(MmtStream& mmtStream, const std::vector& data, FragmentationIndicator fragmentationIndicator) { +std::optional MpuApplicationProcessor::process(MmtStream& mmtStream, std::span data, FragmentationIndicator fragmentationIndicator) { Common::ReadStream stream(data); size_t size = stream.leftBytes(); if (size == 0) { @@ -19,4 +19,4 @@ std::optional MpuApplicationProcessor::process(MmtStream& mmtStream, co return mfuData; } -} \ No newline at end of file +} diff --git a/src/mpuApplicationProcessor.h b/src/mpuApplicationProcessor.h index c497b60..0c696b0 100644 --- a/src/mpuApplicationProcessor.h +++ b/src/mpuApplicationProcessor.h @@ -5,8 +5,8 @@ namespace MmtTlv { class MpuApplicationProcessor : public MpuProcessorTemplate { public: - std::optional process(MmtStream& mmtStream, const std::vector& data, FragmentationIndicator fragmentationIndicator) override; + std::optional process(MmtStream& mmtStream, std::span data, FragmentationIndicator fragmentationIndicator) override; }; -} \ No newline at end of file +} diff --git a/src/mpuAudioProcessor.cpp b/src/mpuAudioProcessor.cpp index 550563d..5162355 100644 --- a/src/mpuAudioProcessor.cpp +++ b/src/mpuAudioProcessor.cpp @@ -7,7 +7,7 @@ namespace MmtTlv { constexpr int MAX_AAC_FRAME_SIZE = 1024 * 10; -std::optional MpuAudioProcessor::process(MmtStream& mmtStream, const std::vector& data, FragmentationIndicator fragmentationIndicator) { +std::optional MpuAudioProcessor::process(MmtStream& mmtStream, std::span data, FragmentationIndicator fragmentationIndicator) { aacFragment.insert(aacFragment.end(), data.begin(), data.end()); MfuData mfuData; @@ -81,4 +81,4 @@ void MpuAudioProcessor::clear() { aacFragment.clear(); } -} \ No newline at end of file +} diff --git a/src/mpuAudioProcessor.h b/src/mpuAudioProcessor.h index d89f388..256ce46 100644 --- a/src/mpuAudioProcessor.h +++ b/src/mpuAudioProcessor.h @@ -5,7 +5,7 @@ namespace MmtTlv { class MpuAudioProcessor : public MpuProcessorTemplate { public: - std::optional process(MmtStream& mmtStream, const std::vector& data, FragmentationIndicator fragmentationIndicator) override; + std::optional process(MmtStream& mmtStream, std::span data, FragmentationIndicator fragmentationIndicator) override; void clear() override; private: @@ -15,4 +15,4 @@ class MpuAudioProcessor : public MpuProcessorTemplate { }; -} \ No newline at end of file +} diff --git a/src/mpuProcessorBase.h b/src/mpuProcessorBase.h index 9b9c751..8a02016 100644 --- a/src/mpuProcessorBase.h +++ b/src/mpuProcessorBase.h @@ -1,7 +1,8 @@ #pragma once #include #include -#include +#include +#include #include "mmtp.h" #include "dataUnit.h" #include "mpu.h" @@ -36,7 +37,7 @@ class MmtStream; class MpuProcessorBase { public: virtual ~MpuProcessorBase() = default; - virtual std::optional process(MmtStream& mmtStream, const std::vector& data, FragmentationIndicator fragmentationIndicator) { return std::nullopt; } + virtual std::optional process(MmtStream& mmtStream, std::span data, FragmentationIndicator fragmentationIndicator) { return std::nullopt; } virtual void clear() {} }; @@ -50,4 +51,4 @@ class MpuProcessorTemplate : public MpuProcessorBase { }; -} \ No newline at end of file +} diff --git a/src/mpuSubtitleProcessor.cpp b/src/mpuSubtitleProcessor.cpp index e618dd1..86a2dbe 100644 --- a/src/mpuSubtitleProcessor.cpp +++ b/src/mpuSubtitleProcessor.cpp @@ -3,7 +3,7 @@ namespace MmtTlv { -std::optional MpuSubtitleProcessor::process(MmtStream& mmtStream, const std::vector& data, FragmentationIndicator fragmentationIndicator) { +std::optional MpuSubtitleProcessor::process(MmtStream& mmtStream, std::span data, FragmentationIndicator fragmentationIndicator) { Common::ReadStream stream(data); uint16_t subsampleNumber = stream.getBe16U(); @@ -50,4 +50,4 @@ std::optional MpuSubtitleProcessor::process(MmtStream& mmtStream, const return mfuData; } -} \ No newline at end of file +} diff --git a/src/mpuSubtitleProcessor.h b/src/mpuSubtitleProcessor.h index 1d13a09..f7842bb 100644 --- a/src/mpuSubtitleProcessor.h +++ b/src/mpuSubtitleProcessor.h @@ -5,10 +5,10 @@ namespace MmtTlv { class MpuSubtitleProcessor : public MpuProcessorTemplate { public: - std::optional process(MmtStream& mmtStream, const std::vector& data, FragmentationIndicator fragmentationIndicator) override; + std::optional process(MmtStream& mmtStream, std::span data, FragmentationIndicator fragmentationIndicator) override; private: std::vector pendingData; }; -} \ No newline at end of file +} diff --git a/src/mpuVideoProcessor.cpp b/src/mpuVideoProcessor.cpp index 9d1cef1..4333652 100644 --- a/src/mpuVideoProcessor.cpp +++ b/src/mpuVideoProcessor.cpp @@ -9,7 +9,7 @@ constexpr uint8_t CRA_NUT = 0x15; constexpr uint8_t NAL_AUD = 0x23; constexpr uint32_t MAX_NAL_SIZE = 1024 * 1024; -std::optional MpuVideoProcessor::process(MmtStream& mmtStream, const std::vector& data, FragmentationIndicator fragmentationIndicator) { +std::optional MpuVideoProcessor::process(MmtStream& mmtStream, std::span data, FragmentationIndicator fragmentationIndicator) { Common::ReadStream stream(data); MfuData mfuData; @@ -89,4 +89,4 @@ void MpuVideoProcessor::clear() { } -} \ No newline at end of file +} diff --git a/src/mpuVideoProcessor.h b/src/mpuVideoProcessor.h index 4dc5f59..3b90d92 100644 --- a/src/mpuVideoProcessor.h +++ b/src/mpuVideoProcessor.h @@ -5,7 +5,7 @@ namespace MmtTlv { class MpuVideoProcessor : public MpuProcessorTemplate { public: - std::optional process(MmtStream& mmtStream, const std::vector& data, FragmentationIndicator fragmentationIndicator) override; + std::optional process(MmtStream& mmtStream, std::span data, FragmentationIndicator fragmentationIndicator) override; void clear(); private: @@ -18,4 +18,4 @@ class MpuVideoProcessor : public MpuProcessorTemplate { }; -} \ No newline at end of file +} diff --git a/src/stream.cpp b/src/stream.cpp index 811f5c2..73c4e99 100644 --- a/src/stream.cpp +++ b/src/stream.cpp @@ -2,19 +2,20 @@ namespace MmtTlv { -namespace Common { - -ReadStream::ReadStream(const std::vector& buffer) - : buffer(buffer) -{ - this->hasSize = true; - this->size = buffer.size(); -} +namespace Common { + +ReadStream::ReadStream(std::span buffer) + : buffer(buffer), hasSize(true), size(buffer.size()) +{ +} + +ReadStream::ReadStream(const std::vector& buffer) + : ReadStream(std::span(buffer)) {} ReadStream::ReadStream(const std::vector& buffer, size_t size) - : buffer(buffer) + : buffer(buffer) { - if (buffer.size() < size) { + if (this->buffer.size() < size) { throw std::out_of_range("Access out of bounds"); } @@ -22,10 +23,10 @@ ReadStream::ReadStream(const std::vector& buffer, size_t size) this->size = size; } -ReadStream::ReadStream(ReadStream& stream, size_t size) +ReadStream::ReadStream(ReadStream& stream, size_t size) : buffer(stream.buffer) { - if (stream.buffer.size() < stream.pos + size) { + if (stream.size < stream.pos + size) { throw std::out_of_range("Access out of bounds"); } @@ -44,4 +45,4 @@ ReadStream::ReadStream(ReadStream& stream) } -} \ No newline at end of file +} diff --git a/src/stream.h b/src/stream.h index ee092e2..12ebe45 100644 --- a/src/stream.h +++ b/src/stream.h @@ -9,9 +9,10 @@ namespace MmtTlv { namespace Common { -class ReadStream final { -public: - explicit ReadStream(const std::vector& data); +class ReadStream final { +public: + explicit ReadStream(std::span data); + explicit ReadStream(const std::vector& data); explicit ReadStream(const std::vector& data, size_t size); explicit ReadStream(ReadStream& stream, size_t size); explicit ReadStream(ReadStream& stream); @@ -24,7 +25,20 @@ class ReadStream final { bool isEof() const { return size == pos; } size_t leftBytes() const { return size - pos; } - size_t getPos() const { return pos; } + size_t getPos() const { return pos; } + + [[nodiscard]] std::span remaining() const noexcept { + return buffer.subspan(pos, size - pos); + } + + std::span readView(size_t count) { + if (count > leftBytes()) { + throw std::out_of_range("Access out of bounds"); + } + const auto view = buffer.subspan(pos, count); + pos += count; + return view; + } void seek(size_t pos) { if (size < pos) { @@ -116,10 +130,12 @@ class ReadStream final { if (size < pos + sizeof(T)) { throw std::out_of_range("Access out of bounds"); } - return *reinterpret_cast(buffer.data() + pos); - } - - const std::vector& buffer; + T value{}; + memcpy(&value, buffer.data() + pos, sizeof(T)); + return value; + } + + std::span buffer; bool hasSize = false; mutable size_t size = 0; mutable size_t pos = 0;