[rtmpdump] branch master updated. a928232 Allocate the channel arrays dynamically

gitolite gil at avcodec.org
Tue Oct 30 17:06:49 CET 2012


The branch, master has been updated
       via  a9282329c3be3bb95f31137867fad9920b682d6d (commit)
       via  0fb1d9936fb25f0755bb8b4afc95db048efe4526 (commit)
       via  4a08069f086b68e99f33e931583148f4090960a3 (commit)
       via  91921dda7002ea8ffed9dfb74ad2913dfdd0b1ed (commit)
       via  4ded9e053744e54286ab9af4e9657f5926a79a2c (commit)
       via  895392a7161ceb37ac32b3fb4a910b350361b13f (commit)
       via  8e527f61afbcb72eb7d8ae1f507765cdc2df2785 (commit)
      from  002ef6f6be2bbdf852ff64ab6981d709435a9045 (commit)


- Log -----------------------------------------------------------------
commit a9282329c3be3bb95f31137867fad9920b682d6d
Author:     Martin Storsjo <martin at martin.st>
AuthorDate: Wed May 30 22:07:23 2012 +0300
Commit:     Howard Chu <hyc at highlandsun.com>
CommitDate: Tue Oct 30 09:03:21 2012 -0700

    Allocate the channel arrays dynamically
    
    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.

diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
index d35b58a..6f6e97b 100644
--- a/librtmp/rtmp.c
+++ b/librtmp/rtmp.c
@@ -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;
diff --git a/librtmp/rtmp.h b/librtmp/rtmp.h
index 76e01fd..8cb6e45 100644
--- a/librtmp/rtmp.h
+++ b/librtmp/rtmp.h
@@ -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 */

commit 0fb1d9936fb25f0755bb8b4afc95db048efe4526
Author:     Martin Storsjo <martin at martin.st>
AuthorDate: Wed May 30 22:06:57 2012 +0300
Commit:     Howard Chu <hyc at highlandsun.com>
CommitDate: Tue Oct 30 09:02:56 2012 -0700

    Free skipped packets in RTMP_GetNextMediaPacket

diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
index ab52c49..d35b58a 100644
--- a/librtmp/rtmp.c
+++ b/librtmp/rtmp.c
@@ -1206,6 +1206,7 @@ RTMP_GetNextMediaPacket(RTMP *r, RTMPPacket *packet)
 		  packet->m_nTimeStamp, packet->m_hasAbsTimestamp,
 		  r->m_mediaStamp);
 #endif
+	      RTMPPacket_Free(packet);
 	      continue;
 	    }
 	  r->m_pausing = 0;

commit 4a08069f086b68e99f33e931583148f4090960a3
Author:     Martin Storsjo <martin at martin.st>
AuthorDate: Mon May 21 23:52:11 2012 +0300
Commit:     Howard Chu <hyc at highlandsun.com>
CommitDate: Tue Oct 30 09:02:12 2012 -0700

    Use CRLF newlines consistently for all HTTP POST headers

diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
index 6183d20..ab52c49 100644
--- a/librtmp/rtmp.c
+++ b/librtmp/rtmp.c
@@ -3835,8 +3835,8 @@ HTTP_Post(RTMP *r, RTMPTCmd cmd, const char *buf, int len)
   int hlen = snprintf(hbuf, sizeof(hbuf), "POST /%s%s/%d HTTP/1.1\r\n"
     "Host: %.*s:%d\r\n"
     "Accept: */*\r\n"
-    "User-Agent: Shockwave Flash\n"
-    "Connection: Keep-Alive\n"
+    "User-Agent: Shockwave Flash\r\n"
+    "Connection: Keep-Alive\r\n"
     "Cache-Control: no-cache\r\n"
     "Content-type: application/x-fcs\r\n"
     "Content-length: %d\r\n\r\n", RTMPT_cmds[cmd],

commit 91921dda7002ea8ffed9dfb74ad2913dfdd0b1ed
Author:     Martin Storsjo <martin at martin.st>
AuthorDate: Mon May 21 18:17:32 2012 +0300
Commit:     Howard Chu <hyc at highlandsun.com>
CommitDate: Tue Oct 30 09:01:51 2012 -0700

    Refill if HTTP_read indicated it needs more data
    
    HTTP_read wants to skip past the first payload byte, so
    it actually needs to have at least 144 + 1 bytes buffered.
    
    This also avoids relying on the magic 144 byte constant altogether,
    which could easily break if servers include less reply headers.

diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
index 21e2c18..6183d20 100644
--- a/librtmp/rtmp.c
+++ b/librtmp/rtmp.c
@@ -1403,9 +1403,11 @@ ReadN(RTMP *r, char *buffer, int n)
       int nBytes = 0, nRead;
       if (r->Link.protocol & RTMP_FEATURE_HTTP)
         {
+	  int refill = 0;
 	  while (!r->m_resplen)
 	    {
-	      if (r->m_sb.sb_size < 144)
+	      int ret;
+	      if (r->m_sb.sb_size < 13 || refill)
 	        {
 		  if (!r->m_unackd)
 		    HTTP_Post(r, RTMPT_IDLE, "", 1);
@@ -1416,12 +1418,20 @@ ReadN(RTMP *r, char *buffer, int n)
 		      return 0;
 		    }
 		}
-	      if (HTTP_read(r, 0) == -1)
+	      if ((ret = HTTP_read(r, 0)) == -1)
 		{
 		  RTMP_Log(RTMP_LOGDEBUG, "%s, No valid HTTP response found", __FUNCTION__);
 		  RTMP_Close(r);
 		  return 0;
 		}
+              else if (ret == -2)
+                {
+                  refill = 1;
+                }
+              else
+                {
+                  refill = 0;
+                }
 	    }
 	  if (r->m_resplen && !r->m_sb.sb_size)
 	    RTMPSockBuf_Fill(&r->m_sb);

commit 4ded9e053744e54286ab9af4e9657f5926a79a2c
Author:     Martin Storsjo <martin at martin.st>
AuthorDate: Mon May 21 18:17:31 2012 +0300
Commit:     Howard Chu <hyc at highlandsun.com>
CommitDate: Tue Oct 30 09:01:34 2012 -0700

    Don't require 144 bytes to be buffered before proceeding with HTTP_read
    
    This makes the code more flexible, if servers were to use
    smaller headers.

diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
index 0d28666..21e2c18 100644
--- a/librtmp/rtmp.c
+++ b/librtmp/rtmp.c
@@ -3849,11 +3849,20 @@ HTTP_read(RTMP *r, int fill)
 restart:
   if (fill)
     RTMPSockBuf_Fill(&r->m_sb);
-  if (r->m_sb.sb_size < 144)
+  if (r->m_sb.sb_size < 13) {
+    if (fill)
+      goto restart;
     return -2;
+  }
   if (strncmp(r->m_sb.sb_start, "HTTP/1.1 200 ", 13))
     return -1;
   r->m_sb.sb_start[r->m_sb.sb_size] = '\0';
+  if (!strstr(r->m_sb.sb_start, "\r\n\r\n")) {
+    if (fill)
+      goto restart;
+    return -2;
+  }
+
   ptr = r->m_sb.sb_start + sizeof("HTTP/1.1 200");
   while ((ptr = strstr(ptr, "Content-"))) {
     if (!strncasecmp(ptr+8, "length:", 7)) break;

commit 895392a7161ceb37ac32b3fb4a910b350361b13f
Author:     Martin Storsjo <martin at martin.st>
AuthorDate: Mon May 21 18:17:30 2012 +0300
Commit:     Howard Chu <hyc at highlandsun.com>
CommitDate: Tue Oct 30 09:01:01 2012 -0700

    Buffer more data before returning successfully from HTTP_read, if needed
    
    This fixes issues if the http header and the payload data
    are sent in separate packets (as they normally are), and the
    buffer contains the full header but none of the payload.

diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
index 83f3247..0d28666 100644
--- a/librtmp/rtmp.c
+++ b/librtmp/rtmp.c
@@ -3846,6 +3846,7 @@ HTTP_read(RTMP *r, int fill)
   char *ptr;
   int hlen;
 
+restart:
   if (fill)
     RTMPSockBuf_Fill(&r->m_sb);
   if (r->m_sb.sb_size < 144)
@@ -3865,6 +3866,12 @@ HTTP_read(RTMP *r, int fill)
   if (!ptr)
     return -1;
   ptr += 4;
+  if (ptr + (r->m_clientID.av_val ? 1 : hlen) > r->m_sb.sb_start + r->m_sb.sb_size)
+    {
+      if (fill)
+        goto restart;
+      return -2;
+    }
   r->m_sb.sb_size -= ptr - r->m_sb.sb_start;
   r->m_sb.sb_start = ptr;
   r->m_unackd--;

commit 8e527f61afbcb72eb7d8ae1f507765cdc2df2785
Author:     Martin Storsjo <martin at martin.st>
AuthorDate: Mon May 21 18:17:29 2012 +0300
Commit:     Howard Chu <hyc at highlandsun.com>
CommitDate: Tue Oct 30 09:00:40 2012 -0700

    Add null termination to buffers before using strstr

diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
index cba8b6c..83f3247 100644
--- a/librtmp/rtmp.c
+++ b/librtmp/rtmp.c
@@ -3673,7 +3673,7 @@ RTMPSockBuf_Fill(RTMPSockBuf *sb)
 
   while (1)
     {
-      nBytes = sizeof(sb->sb_buf) - sb->sb_size - (sb->sb_start - sb->sb_buf);
+      nBytes = sizeof(sb->sb_buf) - 1 - sb->sb_size - (sb->sb_start - sb->sb_buf);
 #if defined(CRYPTO) && !defined(NO_SSL)
       if (sb->sb_ssl)
 	{
@@ -3852,6 +3852,7 @@ HTTP_read(RTMP *r, int fill)
     return -2;
   if (strncmp(r->m_sb.sb_start, "HTTP/1.1 200 ", 13))
     return -1;
+  r->m_sb.sb_start[r->m_sb.sb_size] = '\0';
   ptr = r->m_sb.sb_start + sizeof("HTTP/1.1 200");
   while ((ptr = strstr(ptr, "Content-"))) {
     if (!strncasecmp(ptr+8, "length:", 7)) break;

-----------------------------------------------------------------------

Summary of changes:
 librtmp/rtmp.c |  100 +++++++++++++++++++++++++++++++++++++++++++++++++------
 librtmp/rtmp.h |    8 +++--
 2 files changed, 94 insertions(+), 14 deletions(-)


hooks/post-receive
-- 



More information about the rtmpdump mailing list