mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-31 04:26:37 +08:00 
			
		
		
		
	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:
		| @@ -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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Martin Storsjö
					Martin Storsjö