Eliminate STL vector from PESPacket class (performance problems)
authorMark Calderbank <mark@vomp.tv>
Fri, 12 Dec 2008 18:12:29 +0000 (18:12 +0000)
committerMark Calderbank <mark@vomp.tv>
Fri, 12 Dec 2008 18:12:29 +0000 (18:12 +0000)
demuxer.cc
demuxer.h
demuxervdr.cc
dvbsubtitles.cc

index 21a6eb677b6345ccac41735ddc1937cd5b890781..398a737d21c226015b1c18fb1c1c24e4a4f68e64 100644 (file)
@@ -25,6 +25,8 @@
 #include "dvbsubtitles.h"
 #include "log.h"
 
+#include <cstdlib>
+
 #define DEMUXER_SEQ_HEAD 0x000001B3
 #define DEMUXER_PIC_HEAD 0x00000101
 #define SEEK_THRESHOLD 150000 // About 1.5 seconds
 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<UCHAR>& packetdata = packet.getData();
+  const UCHAR* packetdata = packet.getData();
 
   if (packet_type >= PESTYPE_VID0 && packet_type <= PESTYPE_VIDMAX)
   {
index ebfccaa5643cc2afa4983dd23bf4978ac1df6293..db5a8a6f4ec36e99bceafdba9e6b2ddf36ba5a68 100644 (file)
--- a/demuxer.h
+++ b/demuxer.h
@@ -30,7 +30,6 @@ however, no code was copied verbatim.
 #ifndef DEMUXER_H
 #define DEMUXER_H
 
-#include <vector>
 #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<UCHAR>& 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<UCHAR> 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
 };
 
index 7f3bafc43b47a29accb17a81415f2909293e2cc0..3ac8818b699e816355df735b419514b2dbf66f2c 100644 (file)
@@ -299,7 +299,7 @@ ULONG DemuxerVDR::getFrameNumFromPTS(ULLONG pts)
 
 void DemuxerVDR::dealWithSubtitlePacket()
 {
-  const std::vector<UCHAR>& 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<UCHAR>& sub_data = subtitlePacket.getData();
+  const UCHAR* sub_data = subtitlePacket.getData();
   UINT subSize = subtitlePacket.getSize();
   while (subtitlePacketPosition < subSize)
   {
index 692d0a3a9a8650f7f91513bcaaf0b12be0794dc7..f1be7a80399e73cb5cb9abf5e8be5ae0db5bbf0c 100644 (file)
@@ -511,7 +511,7 @@ void DVBSubtitles::put(const PESPacket& packet)
 
 bool DVBSubtitles::decodePacket(const PESPacket& packet)
 {
-  const std::vector<UCHAR>& data = packet.getData();
+  const UCHAR* data = packet.getData();
   UINT packetSize = packet.getSize();
   if (packetSize < 9) return false;
   UINT segmentOffset = data[8] + 11;