[rtmpdump] [PATCH] Allocate the channel arrays dynamically

Howard Chu hyc at highlandsun.com
Wed May 30 23:05:31 CEST 2012


Martin Storsjo wrote:
> 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.

Wasted effort. Most commercial sites now use a channel number > 512 anyway, to 
trip a bug in old freeware RTMP implementations that didn't handle multi-byte 
channel numbers.

> ---
>   librtmp/rtmp.c |   60 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
>   librtmp/rtmp.h |    8 +++++---
>   2 files changed, 60 insertions(+), 8 deletions(-)
>
> diff --git a/librtmp/rtmp.c b/librtmp/rtmp.c
> index 37a05ad..74d5552 100644
> --- a/librtmp/rtmp.c
> +++ b/librtmp/rtmp.c
> @@ -1101,7 +1101,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;
>   }
> @@ -1873,7 +1874,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);
>   }
>
> @@ -2828,7 +2830,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;
>   	    }
> @@ -2973,6 +2976,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;
>
> @@ -3248,7 +3271,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;
> @@ -3258,6 +3281,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 */
> @@ -3494,7 +3533,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])
>   	{
> @@ -3502,12 +3541,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 6b2ae5b..558e0ac 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 */


More information about the rtmpdump mailing list