From bfcc709409c35e32cfb9abdd89d84a4df53642b1 Mon Sep 17 00:00:00 2001 From: Mark Calderbank Date: Fri, 12 Dec 2008 18:12:29 +0000 Subject: [PATCH] Eliminate STL vector from PESPacket class (performance problems) --- demuxer.cc | 57 ++++++++++++++++++++++++++++++++++++++++++++----- demuxer.h | 11 ++++++---- demuxervdr.cc | 4 ++-- dvbsubtitles.cc | 2 +- 4 files changed, 62 insertions(+), 12 deletions(-) diff --git a/demuxer.cc b/demuxer.cc index 21a6eb6..398a737 100644 --- a/demuxer.cc +++ b/demuxer.cc @@ -25,6 +25,8 @@ #include "dvbsubtitles.h" #include "log.h" +#include + #define DEMUXER_SEQ_HEAD 0x000001B3 #define DEMUXER_PIC_HEAD 0x00000101 #define SEEK_THRESHOLD 150000 // About 1.5 seconds @@ -33,18 +35,56 @@ const int Demuxer::FrameRates[9] = { 0, 23, 24, 25, 29, 30, 50, 59, 60 }; Demuxer* Demuxer::instance = NULL; +static const int PESPacket_initial_size = 2000; + // PESPacket methods PESPacket::PESPacket() { - init(0); + data_size = PESPacket_initial_size; + data = (UCHAR*)malloc(data_size); + data[0] = 0x00; + data[1] = 0x00; data[2] = 0x01; + init(0); +} + +PESPacket::PESPacket(const PESPacket& packet) +{ + copyFrom(packet); +} + +PESPacket& PESPacket::operator=(const PESPacket& packet) +{ + if (this != &packet) + { + if (data) free(data); + copyFrom(packet); + } + return *this; +} + +PESPacket::~PESPacket() +{ + if (data) free(data); +} + +void PESPacket::copyFrom(const PESPacket& packet) +{ + length = packet.length; + size = packet.size; + packetType = packet.packetType; + substream = packet.substream; + seq_header = packet.seq_header; + data_size = size; + data = (UCHAR*)malloc(data_size); + memcpy(data, packet.data, data_size); } void PESPacket::init(UCHAR type, UCHAR sub) { - data.resize(6); length = 0; size = 6; + data[4] = data[5] = 0; data[3] = type; packetType = type; substream = sub; @@ -58,8 +98,15 @@ void PESPacket::truncate() int PESPacket::write(const UCHAR *buf, int len) { - if (length + len > 0xFFFA) return 0; - data.insert(data.end(), buf, buf+len); + if (size + len > 0x10000) return 0; + if (size + len > data_size) + { // Reallocate + UINT new_data_size = max(data_size + data_size / 2, data_size + len); + if (new_data_size > 0x10000) new_data_size = 0x10000; + data_size = new_data_size; + data = (UCHAR*)realloc(data, data_size); + } + memcpy(data + size, buf, len); length += len; size += len; data[4] = (length >> 8); @@ -269,7 +316,7 @@ bool Demuxer::submitPacket(PESPacket& packet) { UINT sent = 0; UCHAR packet_type = packet.getPacketType(); - const std::vector& packetdata = packet.getData(); + const UCHAR* packetdata = packet.getData(); if (packet_type >= PESTYPE_VID0 && packet_type <= PESTYPE_VIDMAX) { diff --git a/demuxer.h b/demuxer.h index ebfccaa..db5a8a6 100644 --- a/demuxer.h +++ b/demuxer.h @@ -30,7 +30,6 @@ however, no code was copied verbatim. #ifndef DEMUXER_H #define DEMUXER_H -#include #include "stream.h" #include "defines.h" @@ -42,6 +41,9 @@ class PESPacket { public: PESPacket(); + PESPacket(const PESPacket& packet); + PESPacket& operator=(const PESPacket& packet); + ~PESPacket(); void init(UCHAR type, UCHAR sub=0); void truncate(); int write(const UCHAR* buf, int len); @@ -49,7 +51,7 @@ class PESPacket UCHAR operator[] (UINT index) const; // return data[index] if in bounds, else 0 // so no proper error condition but never mind for now - const std::vector& getData() const { return data; } + const UCHAR* getData() const { return data; } UINT getLength() const { return length; } UINT getSize() const { return size; } UCHAR getPacketType() const { return packetType; } @@ -62,11 +64,12 @@ class PESPacket UINT findSeqHeader() const; static const ULLONG PTS_INVALID = (1LL << 33); protected: - std::vector data; + void copyFrom(const PESPacket& packet); + UCHAR * data; UINT length, size; + UINT data_size; UCHAR packetType; UCHAR substream; - ULLONG pts; UINT mutable seq_header; // 0 = no, 1 = unknown, else = header offset }; diff --git a/demuxervdr.cc b/demuxervdr.cc index 7f3bafc..3ac8818 100644 --- a/demuxervdr.cc +++ b/demuxervdr.cc @@ -299,7 +299,7 @@ ULONG DemuxerVDR::getFrameNumFromPTS(ULLONG pts) void DemuxerVDR::dealWithSubtitlePacket() { - const std::vector& data = packet.getData(); + const UCHAR* data = packet.getData(); UINT packetSize = packet.getSize(); if (packetSize < 9) return; UINT payloadOffset = data[8] + 9; @@ -318,7 +318,7 @@ void DemuxerVDR::dealWithSubtitlePacket() subtitlePacket.write(&data[payloadOffset+4], packetSize-payloadOffset-4); } - const std::vector& sub_data = subtitlePacket.getData(); + const UCHAR* sub_data = subtitlePacket.getData(); UINT subSize = subtitlePacket.getSize(); while (subtitlePacketPosition < subSize) { diff --git a/dvbsubtitles.cc b/dvbsubtitles.cc index 692d0a3..f1be7a8 100644 --- a/dvbsubtitles.cc +++ b/dvbsubtitles.cc @@ -511,7 +511,7 @@ void DVBSubtitles::put(const PESPacket& packet) bool DVBSubtitles::decodePacket(const PESPacket& packet) { - const std::vector& data = packet.getData(); + const UCHAR* data = packet.getData(); UINT packetSize = packet.getSize(); if (packetSize < 9) return false; UINT segmentOffset = data[8] + 11; -- 2.39.5