[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