]> granicus.if.org Git - rtmpdump/commitdiff
Allocate the channel arrays dynamically
authorMartin Storsjo <martin@martin.st>
Wed, 30 May 2012 19:07:23 +0000 (22:07 +0300)
committerHoward Chu <hyc@highlandsun.com>
Tue, 30 Oct 2012 16:03:21 +0000 (09:03 -0700)
This avoids having to allocate space for all theoretical channels
if most of them aren't used. This drops the size of the full
RTMP struct from over 1200 KB to 16 KB (on 64 bit), and as long as
only channels with a low number are used, the amount of total
allocated memory stays far below what it was before.

librtmp/rtmp.c
librtmp/rtmp.h

index d35b58a47b091706a1a749b0d1ef107f47fd0098..6f6e97bc811d85e397b13da12c95991aedf411ba 100644 (file)
@@ -1216,7 +1216,8 @@ RTMP_GetNextMediaPacket(RTMP *r, RTMPPacket *packet)
   if (bHasMediaPacket)
     r->m_bPlaying = TRUE;
   else if (r->m_sb.sb_timedout && !r->m_pausing)
-    r->m_pauseStamp = r->m_channelTimestamp[r->m_mediaChannel];
+    r->m_pauseStamp = r->m_mediaChannel < r->m_channelsAllocatedIn ?
+                      r->m_channelTimestamp[r->m_mediaChannel] : 0;
 
   return bHasMediaPacket;
 }
@@ -1998,7 +1999,8 @@ RTMP_SendPause(RTMP *r, int DoPause, int iTime)
 int RTMP_Pause(RTMP *r, int DoPause)
 {
   if (DoPause)
-    r->m_pauseStamp = r->m_channelTimestamp[r->m_mediaChannel];
+    r->m_pauseStamp = r->m_mediaChannel < r->m_channelsAllocatedIn ?
+                      r->m_channelTimestamp[r->m_mediaChannel] : 0;
   return RTMP_SendPause(r, DoPause, r->m_pauseStamp);
 }
 
@@ -2953,7 +2955,8 @@ HandleCtrl(RTMP *r, const RTMPPacket *packet)
            break;
          if (!r->m_pausing)
            {
-             r->m_pauseStamp = r->m_channelTimestamp[r->m_mediaChannel];
+             r->m_pauseStamp = r->m_mediaChannel < r->m_channelsAllocatedIn ?
+                               r->m_channelTimestamp[r->m_mediaChannel] : 0;
              RTMP_SendPause(r, TRUE, r->m_pauseStamp);
              r->m_pausing = 1;
            }
@@ -3098,6 +3101,26 @@ RTMP_ReadPacket(RTMP *r, RTMPPacket *packet)
 
   nSize = packetSize[packet->m_headerType];
 
+  if (packet->m_nChannel >= r->m_channelsAllocatedIn)
+    {
+      int n = packet->m_nChannel + 10;
+      int *timestamp = realloc(r->m_channelTimestamp, sizeof(int) * n);
+      RTMPPacket **packets = realloc(r->m_vecChannelsIn, sizeof(RTMPPacket*) * n);
+      if (!timestamp)
+        free(r->m_channelTimestamp);
+      if (!packets)
+        free(r->m_vecChannelsIn);
+      r->m_channelTimestamp = timestamp;
+      r->m_vecChannelsIn = packets;
+      if (!timestamp || !packets) {
+        r->m_channelsAllocatedIn = 0;
+        return FALSE;
+      }
+      memset(r->m_channelTimestamp + r->m_channelsAllocatedIn, 0, sizeof(int) * (n - r->m_channelsAllocatedIn));
+      memset(r->m_vecChannelsIn + r->m_channelsAllocatedIn, 0, sizeof(RTMPPacket*) * (n - r->m_channelsAllocatedIn));
+      r->m_channelsAllocatedIn = n;
+    }
+
   if (nSize == RTMP_LARGE_HEADER_SIZE) /* if we get a full header the timestamp is absolute */
     packet->m_hasAbsTimestamp = TRUE;
 
@@ -3373,7 +3396,7 @@ RTMP_SendChunk(RTMP *r, RTMPChunk *chunk)
 int
 RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue)
 {
-  const RTMPPacket *prevPacket = r->m_vecChannelsOut[packet->m_nChannel];
+  const RTMPPacket *prevPacket;
   uint32_t last = 0;
   int nSize;
   int hSize, cSize;
@@ -3383,6 +3406,22 @@ RTMP_SendPacket(RTMP *r, RTMPPacket *packet, int queue)
   int nChunkSize;
   int tlen;
 
+  if (packet->m_nChannel >= r->m_channelsAllocatedOut)
+    {
+      int n = packet->m_nChannel + 10;
+      RTMPPacket **packets = realloc(r->m_vecChannelsOut, sizeof(RTMPPacket*) * n);
+      if (!packets) {
+        free(r->m_vecChannelsOut);
+        r->m_vecChannelsOut = NULL;
+        r->m_channelsAllocatedOut = 0;
+        return FALSE;
+      }
+      r->m_vecChannelsOut = packets;
+      memset(r->m_vecChannelsOut + r->m_channelsAllocatedOut, 0, sizeof(RTMPPacket*) * (n - r->m_channelsAllocatedOut));
+      r->m_channelsAllocatedOut = n;
+    }
+
+  prevPacket = r->m_vecChannelsOut[packet->m_nChannel];
   if (prevPacket && packet->m_headerType != RTMP_PACKET_SIZE_LARGE)
     {
       /* compress a bit by using the prev packet's attributes */
@@ -3619,7 +3658,7 @@ RTMP_Close(RTMP *r)
   r->m_write.m_nBytesRead = 0;
   RTMPPacket_Free(&r->m_write);
 
-  for (i = 0; i < RTMP_CHANNELS; i++)
+  for (i = 0; i < r->m_channelsAllocatedIn; i++)
     {
       if (r->m_vecChannelsIn[i])
        {
@@ -3627,12 +3666,23 @@ RTMP_Close(RTMP *r)
          free(r->m_vecChannelsIn[i]);
          r->m_vecChannelsIn[i] = NULL;
        }
+    }
+  free(r->m_vecChannelsIn);
+  r->m_vecChannelsIn = NULL;
+  free(r->m_channelTimestamp);
+  r->m_channelTimestamp = NULL;
+  r->m_channelsAllocatedIn = 0;
+  for (i = 0; i < r->m_channelsAllocatedOut; i++)
+    {
       if (r->m_vecChannelsOut[i])
        {
          free(r->m_vecChannelsOut[i]);
          r->m_vecChannelsOut[i] = NULL;
        }
     }
+  free(r->m_vecChannelsOut);
+  r->m_vecChannelsOut = NULL;
+  r->m_channelsAllocatedOut = 0;
   AV_clear(r->m_methodCalls, r->m_numCalls);
   r->m_methodCalls = NULL;
   r->m_numCalls = 0;
index 76e01fd1c8b00365d1fe33046e0f0053a92a35f6..8cb6e456e45cbf9e48bf5f6baa09a826e7ecb259 100644 (file)
@@ -253,9 +253,11 @@ extern "C"
     int m_numCalls;
     RTMP_METHOD *m_methodCalls;        /* remote method calls queue */
 
-    RTMPPacket *m_vecChannelsIn[RTMP_CHANNELS];
-    RTMPPacket *m_vecChannelsOut[RTMP_CHANNELS];
-    int m_channelTimestamp[RTMP_CHANNELS];     /* abs timestamp of last packet */
+    int m_channelsAllocatedIn;
+    int m_channelsAllocatedOut;
+    RTMPPacket **m_vecChannelsIn;
+    RTMPPacket **m_vecChannelsOut;
+    int *m_channelTimestamp;   /* abs timestamp of last packet */
 
     double m_fAudioCodecs;     /* audioCodecs for the connect packet */
     double m_fVideoCodecs;     /* videoCodecs for the connect packet */