rtmp: Allocate the prev_pkt arrays dynamically
Normally, all channel ids are between 0 and 10, while they in uncommon cases can have values up to 64k. This avoids allocating two arrays for up to 64k entries (at a total of over 6 MB in size) each when most of them aren't used at all. Signed-off-by: Martin Storsjö <martin@martin.st>
This commit is contained in:
parent
39185ec4fa
commit
84a125c4c2
@ -129,20 +129,42 @@ int ff_amf_read_null(GetByteContext *bc)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ff_rtmp_check_alloc_array(RTMPPacket **prev_pkt, int *nb_prev_pkt,
|
||||||
|
int channel)
|
||||||
|
{
|
||||||
|
int nb_alloc;
|
||||||
|
RTMPPacket *ptr;
|
||||||
|
if (channel < *nb_prev_pkt)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
nb_alloc = channel + 16;
|
||||||
|
// This can't use the av_reallocp family of functions, since we
|
||||||
|
// would need to free each element in the array before the array
|
||||||
|
// itself is freed.
|
||||||
|
ptr = av_realloc_array(*prev_pkt, nb_alloc, sizeof(**prev_pkt));
|
||||||
|
if (!ptr)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
memset(ptr + *nb_prev_pkt, 0, (nb_alloc - *nb_prev_pkt) * sizeof(*ptr));
|
||||||
|
*prev_pkt = ptr;
|
||||||
|
*nb_prev_pkt = nb_alloc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
|
int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
|
||||||
int chunk_size, RTMPPacket *prev_pkt)
|
int chunk_size, RTMPPacket **prev_pkt, int *nb_prev_pkt)
|
||||||
{
|
{
|
||||||
uint8_t hdr;
|
uint8_t hdr;
|
||||||
|
|
||||||
if (ffurl_read(h, &hdr, 1) != 1)
|
if (ffurl_read(h, &hdr, 1) != 1)
|
||||||
return AVERROR(EIO);
|
return AVERROR(EIO);
|
||||||
|
|
||||||
return ff_rtmp_packet_read_internal(h, p, chunk_size, prev_pkt, hdr);
|
return ff_rtmp_packet_read_internal(h, p, chunk_size, prev_pkt,
|
||||||
|
nb_prev_pkt, hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p,
|
static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p,
|
||||||
int chunk_size, RTMPPacket *prev_pkt,
|
int chunk_size, RTMPPacket **prev_pkt_ptr,
|
||||||
uint8_t hdr)
|
int *nb_prev_pkt, uint8_t hdr)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint8_t buf[16];
|
uint8_t buf[16];
|
||||||
@ -151,6 +173,7 @@ static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p,
|
|||||||
enum RTMPPacketType type;
|
enum RTMPPacketType type;
|
||||||
int written = 0;
|
int written = 0;
|
||||||
int ret, toread;
|
int ret, toread;
|
||||||
|
RTMPPacket *prev_pkt;
|
||||||
|
|
||||||
written++;
|
written++;
|
||||||
channel_id = hdr & 0x3F;
|
channel_id = hdr & 0x3F;
|
||||||
@ -162,6 +185,10 @@ static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p,
|
|||||||
written += channel_id + 1;
|
written += channel_id + 1;
|
||||||
channel_id = AV_RL16(buf) + 64;
|
channel_id = AV_RL16(buf) + 64;
|
||||||
}
|
}
|
||||||
|
if ((ret = ff_rtmp_check_alloc_array(prev_pkt_ptr, nb_prev_pkt,
|
||||||
|
channel_id)) < 0)
|
||||||
|
return ret;
|
||||||
|
prev_pkt = *prev_pkt_ptr;
|
||||||
size = prev_pkt[channel_id].size;
|
size = prev_pkt[channel_id].size;
|
||||||
type = prev_pkt[channel_id].type;
|
type = prev_pkt[channel_id].type;
|
||||||
extra = prev_pkt[channel_id].extra;
|
extra = prev_pkt[channel_id].extra;
|
||||||
@ -252,10 +279,12 @@ static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
|
int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
|
||||||
RTMPPacket *prev_pkt, uint8_t hdr)
|
RTMPPacket **prev_pkt, int *nb_prev_pkt,
|
||||||
|
uint8_t hdr)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
int ret = rtmp_packet_read_one_chunk(h, p, chunk_size, prev_pkt, hdr);
|
int ret = rtmp_packet_read_one_chunk(h, p, chunk_size, prev_pkt,
|
||||||
|
nb_prev_pkt, hdr);
|
||||||
if (ret > 0 || ret != AVERROR(EAGAIN))
|
if (ret > 0 || ret != AVERROR(EAGAIN))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -265,13 +294,20 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
|
int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt,
|
||||||
int chunk_size, RTMPPacket *prev_pkt)
|
int chunk_size, RTMPPacket **prev_pkt_ptr,
|
||||||
|
int *nb_prev_pkt)
|
||||||
{
|
{
|
||||||
uint8_t pkt_hdr[16], *p = pkt_hdr;
|
uint8_t pkt_hdr[16], *p = pkt_hdr;
|
||||||
int mode = RTMP_PS_TWELVEBYTES;
|
int mode = RTMP_PS_TWELVEBYTES;
|
||||||
int off = 0;
|
int off = 0;
|
||||||
int written = 0;
|
int written = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
RTMPPacket *prev_pkt;
|
||||||
|
|
||||||
|
if ((ret = ff_rtmp_check_alloc_array(prev_pkt_ptr, nb_prev_pkt,
|
||||||
|
pkt->channel_id)) < 0)
|
||||||
|
return ret;
|
||||||
|
prev_pkt = *prev_pkt_ptr;
|
||||||
|
|
||||||
pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp;
|
pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp;
|
||||||
|
|
||||||
|
@ -114,10 +114,12 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt);
|
|||||||
* @param chunk_size current chunk size
|
* @param chunk_size current chunk size
|
||||||
* @param prev_pkt previously read packet headers for all channels
|
* @param prev_pkt previously read packet headers for all channels
|
||||||
* (may be needed for restoring incomplete packet header)
|
* (may be needed for restoring incomplete packet header)
|
||||||
|
* @param nb_prev_pkt number of allocated elements in prev_pkt
|
||||||
* @return number of bytes read on success, negative value otherwise
|
* @return number of bytes read on success, negative value otherwise
|
||||||
*/
|
*/
|
||||||
int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
|
int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
|
||||||
int chunk_size, RTMPPacket *prev_pkt);
|
int chunk_size, RTMPPacket **prev_pkt,
|
||||||
|
int *nb_prev_pkt);
|
||||||
/**
|
/**
|
||||||
* Read internal RTMP packet sent by the server.
|
* Read internal RTMP packet sent by the server.
|
||||||
*
|
*
|
||||||
@ -126,11 +128,13 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p,
|
|||||||
* @param chunk_size current chunk size
|
* @param chunk_size current chunk size
|
||||||
* @param prev_pkt previously read packet headers for all channels
|
* @param prev_pkt previously read packet headers for all channels
|
||||||
* (may be needed for restoring incomplete packet header)
|
* (may be needed for restoring incomplete packet header)
|
||||||
|
* @param nb_prev_pkt number of allocated elements in prev_pkt
|
||||||
* @param c the first byte already read
|
* @param c the first byte already read
|
||||||
* @return number of bytes read on success, negative value otherwise
|
* @return number of bytes read on success, negative value otherwise
|
||||||
*/
|
*/
|
||||||
int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
|
int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
|
||||||
RTMPPacket *prev_pkt, uint8_t c);
|
RTMPPacket **prev_pkt, int *nb_prev_pkt,
|
||||||
|
uint8_t c);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send RTMP packet to the server.
|
* Send RTMP packet to the server.
|
||||||
@ -140,10 +144,12 @@ int ff_rtmp_packet_read_internal(URLContext *h, RTMPPacket *p, int chunk_size,
|
|||||||
* @param chunk_size current chunk size
|
* @param chunk_size current chunk size
|
||||||
* @param prev_pkt previously sent packet headers for all channels
|
* @param prev_pkt previously sent packet headers for all channels
|
||||||
* (may be used for packet header compressing)
|
* (may be used for packet header compressing)
|
||||||
|
* @param nb_prev_pkt number of allocated elements in prev_pkt
|
||||||
* @return number of bytes written on success, negative value otherwise
|
* @return number of bytes written on success, negative value otherwise
|
||||||
*/
|
*/
|
||||||
int ff_rtmp_packet_write(URLContext *h, RTMPPacket *p,
|
int ff_rtmp_packet_write(URLContext *h, RTMPPacket *p,
|
||||||
int chunk_size, RTMPPacket *prev_pkt);
|
int chunk_size, RTMPPacket **prev_pkt,
|
||||||
|
int *nb_prev_pkt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print information and contents of RTMP packet.
|
* Print information and contents of RTMP packet.
|
||||||
@ -153,6 +159,16 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *p,
|
|||||||
*/
|
*/
|
||||||
void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p);
|
void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enlarge the prev_pkt array to fit the given channel
|
||||||
|
*
|
||||||
|
* @param prev_pkt array with previously sent packet headers
|
||||||
|
* @param nb_prev_pkt number of allocated elements in prev_pkt
|
||||||
|
* @param channel the channel number that needs to be allocated
|
||||||
|
*/
|
||||||
|
int ff_rtmp_check_alloc_array(RTMPPacket **prev_pkt, int *nb_prev_pkt,
|
||||||
|
int channel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name Functions used to work with the AMF format (which is also used in .flv)
|
* @name Functions used to work with the AMF format (which is also used in .flv)
|
||||||
* @see amf_* funcs in libavformat/flvdec.c
|
* @see amf_* funcs in libavformat/flvdec.c
|
||||||
|
@ -77,7 +77,8 @@ typedef struct TrackedMethod {
|
|||||||
typedef struct RTMPContext {
|
typedef struct RTMPContext {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
URLContext* stream; ///< TCP stream used in interactions with RTMP server
|
URLContext* stream; ///< TCP stream used in interactions with RTMP server
|
||||||
RTMPPacket prev_pkt[2][RTMP_CHANNELS]; ///< packet history used when reading and sending packets ([0] for reading, [1] for writing)
|
RTMPPacket *prev_pkt[2]; ///< packet history used when reading and sending packets ([0] for reading, [1] for writing)
|
||||||
|
int nb_prev_pkt[2]; ///< number of elements in prev_pkt
|
||||||
int in_chunk_size; ///< size of the chunks incoming RTMP packets are divided into
|
int in_chunk_size; ///< size of the chunks incoming RTMP packets are divided into
|
||||||
int out_chunk_size; ///< size of the chunks outgoing RTMP packets are divided into
|
int out_chunk_size; ///< size of the chunks outgoing RTMP packets are divided into
|
||||||
int is_input; ///< input/output flag
|
int is_input; ///< input/output flag
|
||||||
@ -238,7 +239,7 @@ static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
|
ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
|
||||||
rt->prev_pkt[1]);
|
&rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
|
||||||
fail:
|
fail:
|
||||||
ff_rtmp_packet_destroy(pkt);
|
ff_rtmp_packet_destroy(pkt);
|
||||||
return ret;
|
return ret;
|
||||||
@ -408,7 +409,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
|
|||||||
GetByteContext gbc;
|
GetByteContext gbc;
|
||||||
|
|
||||||
if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
|
if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
|
||||||
rt->prev_pkt[0])) < 0)
|
&rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
cp = pkt.data;
|
cp = pkt.data;
|
||||||
bytestream2_init(&gbc, cp, pkt.size);
|
bytestream2_init(&gbc, cp, pkt.size);
|
||||||
@ -444,7 +445,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
|
|||||||
bytestream_put_be32(&p, rt->server_bw);
|
bytestream_put_be32(&p, rt->server_bw);
|
||||||
pkt.size = p - pkt.data;
|
pkt.size = p - pkt.data;
|
||||||
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
||||||
rt->prev_pkt[1]);
|
&rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
|
||||||
ff_rtmp_packet_destroy(&pkt);
|
ff_rtmp_packet_destroy(&pkt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -457,7 +458,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
|
|||||||
bytestream_put_byte(&p, 2); // dynamic
|
bytestream_put_byte(&p, 2); // dynamic
|
||||||
pkt.size = p - pkt.data;
|
pkt.size = p - pkt.data;
|
||||||
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
||||||
rt->prev_pkt[1]);
|
&rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
|
||||||
ff_rtmp_packet_destroy(&pkt);
|
ff_rtmp_packet_destroy(&pkt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -471,7 +472,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
|
|||||||
bytestream_put_be16(&p, 0); // 0 -> Stream Begin
|
bytestream_put_be16(&p, 0); // 0 -> Stream Begin
|
||||||
bytestream_put_be32(&p, 0);
|
bytestream_put_be32(&p, 0);
|
||||||
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
||||||
rt->prev_pkt[1]);
|
&rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
|
||||||
ff_rtmp_packet_destroy(&pkt);
|
ff_rtmp_packet_destroy(&pkt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -484,7 +485,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
|
|||||||
p = pkt.data;
|
p = pkt.data;
|
||||||
bytestream_put_be32(&p, rt->out_chunk_size);
|
bytestream_put_be32(&p, rt->out_chunk_size);
|
||||||
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
||||||
rt->prev_pkt[1]);
|
&rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
|
||||||
ff_rtmp_packet_destroy(&pkt);
|
ff_rtmp_packet_destroy(&pkt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -519,7 +520,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
|
|||||||
|
|
||||||
pkt.size = p - pkt.data;
|
pkt.size = p - pkt.data;
|
||||||
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
||||||
rt->prev_pkt[1]);
|
&rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
|
||||||
ff_rtmp_packet_destroy(&pkt);
|
ff_rtmp_packet_destroy(&pkt);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
@ -534,7 +535,7 @@ static int read_connect(URLContext *s, RTMPContext *rt)
|
|||||||
ff_amf_write_number(&p, 8192);
|
ff_amf_write_number(&p, 8192);
|
||||||
pkt.size = p - pkt.data;
|
pkt.size = p - pkt.data;
|
||||||
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
|
||||||
rt->prev_pkt[1]);
|
&rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
|
||||||
ff_rtmp_packet_destroy(&pkt);
|
ff_rtmp_packet_destroy(&pkt);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1455,7 +1456,7 @@ static int handle_chunk_size(URLContext *s, RTMPPacket *pkt)
|
|||||||
/* Send the same chunk size change packet back to the server,
|
/* Send the same chunk size change packet back to the server,
|
||||||
* setting the outgoing chunk size to the same as the incoming one. */
|
* setting the outgoing chunk size to the same as the incoming one. */
|
||||||
if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
|
if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
|
||||||
rt->prev_pkt[1])) < 0)
|
&rt->prev_pkt[1], &rt->nb_prev_pkt[1])) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
rt->out_chunk_size = AV_RB32(pkt->data);
|
rt->out_chunk_size = AV_RB32(pkt->data);
|
||||||
}
|
}
|
||||||
@ -1784,7 +1785,7 @@ static int write_begin(URLContext *s)
|
|||||||
bytestream2_put_be32(&pbc, rt->nb_streamid);
|
bytestream2_put_be32(&pbc, rt->nb_streamid);
|
||||||
|
|
||||||
ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
|
ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
|
||||||
rt->prev_pkt[1]);
|
&rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
|
||||||
|
|
||||||
ff_rtmp_packet_destroy(&spkt);
|
ff_rtmp_packet_destroy(&spkt);
|
||||||
|
|
||||||
@ -1831,7 +1832,7 @@ static int write_status(URLContext *s, RTMPPacket *pkt,
|
|||||||
|
|
||||||
spkt.size = pp - spkt.data;
|
spkt.size = pp - spkt.data;
|
||||||
ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
|
ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
|
||||||
rt->prev_pkt[1]);
|
&rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
|
||||||
ff_rtmp_packet_destroy(&spkt);
|
ff_rtmp_packet_destroy(&spkt);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -1932,7 +1933,7 @@ static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
|
|||||||
}
|
}
|
||||||
spkt.size = pp - spkt.data;
|
spkt.size = pp - spkt.data;
|
||||||
ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
|
ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
|
||||||
rt->prev_pkt[1]);
|
&rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
|
||||||
ff_rtmp_packet_destroy(&spkt);
|
ff_rtmp_packet_destroy(&spkt);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -2262,7 +2263,8 @@ static int get_packet(URLContext *s, int for_header)
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
RTMPPacket rpkt = { 0 };
|
RTMPPacket rpkt = { 0 };
|
||||||
if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
|
if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
|
||||||
rt->in_chunk_size, rt->prev_pkt[0])) <= 0) {
|
rt->in_chunk_size, &rt->prev_pkt[0],
|
||||||
|
&rt->nb_prev_pkt[0])) <= 0) {
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
return AVERROR(EAGAIN);
|
return AVERROR(EAGAIN);
|
||||||
} else {
|
} else {
|
||||||
@ -2343,9 +2345,11 @@ static int rtmp_close(URLContext *h)
|
|||||||
}
|
}
|
||||||
if (rt->state > STATE_HANDSHAKED)
|
if (rt->state > STATE_HANDSHAKED)
|
||||||
ret = gen_delete_stream(h, rt);
|
ret = gen_delete_stream(h, rt);
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++) {
|
||||||
for (j = 0; j < RTMP_CHANNELS; j++)
|
for (j = 0; j < rt->nb_prev_pkt[i]; j++)
|
||||||
ff_rtmp_packet_destroy(&rt->prev_pkt[i][j]);
|
ff_rtmp_packet_destroy(&rt->prev_pkt[i][j]);
|
||||||
|
av_freep(&rt->prev_pkt[i]);
|
||||||
|
}
|
||||||
|
|
||||||
free_tracked_methods(rt);
|
free_tracked_methods(rt);
|
||||||
av_freep(&rt->flv_data);
|
av_freep(&rt->flv_data);
|
||||||
@ -2562,11 +2566,14 @@ reconnect:
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (rt->do_reconnect) {
|
if (rt->do_reconnect) {
|
||||||
|
int i;
|
||||||
ffurl_close(rt->stream);
|
ffurl_close(rt->stream);
|
||||||
rt->stream = NULL;
|
rt->stream = NULL;
|
||||||
rt->do_reconnect = 0;
|
rt->do_reconnect = 0;
|
||||||
rt->nb_invokes = 0;
|
rt->nb_invokes = 0;
|
||||||
memset(rt->prev_pkt, 0, sizeof(rt->prev_pkt));
|
for (i = 0; i < 2; i++)
|
||||||
|
memset(rt->prev_pkt[i], 0,
|
||||||
|
sizeof(**rt->prev_pkt) * rt->nb_prev_pkt[i]);
|
||||||
free_tracked_methods(rt);
|
free_tracked_methods(rt);
|
||||||
goto reconnect;
|
goto reconnect;
|
||||||
}
|
}
|
||||||
@ -2687,6 +2694,10 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
|
|||||||
pkttype == RTMP_PT_NOTIFY) {
|
pkttype == RTMP_PT_NOTIFY) {
|
||||||
if (pkttype == RTMP_PT_NOTIFY)
|
if (pkttype == RTMP_PT_NOTIFY)
|
||||||
pktsize += 16;
|
pktsize += 16;
|
||||||
|
if ((ret = ff_rtmp_check_alloc_array(&rt->prev_pkt[1],
|
||||||
|
&rt->nb_prev_pkt[1],
|
||||||
|
channel)) < 0)
|
||||||
|
return ret;
|
||||||
rt->prev_pkt[1][channel].channel_id = 0;
|
rt->prev_pkt[1][channel].channel_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2747,7 +2758,8 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
|
|||||||
|
|
||||||
if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
|
if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
|
||||||
rt->in_chunk_size,
|
rt->in_chunk_size,
|
||||||
rt->prev_pkt[0], c)) <= 0)
|
&rt->prev_pkt[0],
|
||||||
|
&rt->nb_prev_pkt[0], c)) <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
|
if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user