X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Frtmpproto.c;h=ed483cf37fe62289cdc338a5d6348f6fe21a3a04;hb=6ea6ff053af2aff8a9a898292f9640efa9290c9f;hp=e3fce2e1fad853ff44e0fb4e0343d9a05e9462b1;hpb=9765caec1b9991e676d1b91db0c04a6242b65d7a;p=ffmpeg diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index e3fce2e1fad..ed483cf37fe 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -71,6 +71,9 @@ typedef struct RTMPContext { uint32_t client_report_size; ///< number of bytes after which client should report to server uint32_t bytes_read; ///< number of bytes read from server uint32_t last_bytes_read; ///< number of bytes read last reported to server + int skip_bytes; ///< number of bytes to skip from the input FLV stream in the next write call + uint8_t flv_header[11]; ///< partial incoming flv packet header + int flv_header_bytes; ///< number of initialized bytes in flv_header } RTMPContext; #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing @@ -879,6 +882,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) rt->flv_size = 0; rt->flv_data = NULL; rt->flv_off = 0; + rt->skip_bytes = 13; } s->max_packet_size = rt->stream->max_packet_size; @@ -925,25 +929,29 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) uint32_t ts; const uint8_t *buf_temp = buf; - if (size < 11) { - av_log(s, AV_LOG_DEBUG, "FLV packet too small %d\n", size); - return 0; - } - do { - if (!rt->flv_off) { - //skip flv header - if (buf_temp[0] == 'F' && buf_temp[1] == 'L' && buf_temp[2] == 'V') { - buf_temp += 9 + 4; - size_temp -= 9 + 4; - } + if (rt->skip_bytes) { + int skip = FFMIN(rt->skip_bytes, size_temp); + buf_temp += skip; + size_temp -= skip; + rt->skip_bytes -= skip; + continue; + } + + if (rt->flv_header_bytes < 11) { + const uint8_t *header = rt->flv_header; + int copy = FFMIN(11 - rt->flv_header_bytes, size_temp); + bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy); + rt->flv_header_bytes += copy; + size_temp -= copy; + if (rt->flv_header_bytes < 11) + break; - pkttype = bytestream_get_byte(&buf_temp); - pktsize = bytestream_get_be24(&buf_temp); - ts = bytestream_get_be24(&buf_temp); - ts |= bytestream_get_byte(&buf_temp) << 24; - bytestream_get_be24(&buf_temp); - size_temp -= 11; + pkttype = bytestream_get_byte(&header); + pktsize = bytestream_get_be24(&header); + ts = bytestream_get_be24(&header); + ts |= bytestream_get_byte(&header) << 24; + bytestream_get_be24(&header); rt->flv_size = pktsize; //force 12bytes header @@ -966,20 +974,23 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) if (rt->flv_size - rt->flv_off > size_temp) { bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp); rt->flv_off += size_temp; + size_temp = 0; } else { bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off); + size_temp -= rt->flv_size - rt->flv_off; rt->flv_off += rt->flv_size - rt->flv_off; } if (rt->flv_off == rt->flv_size) { - bytestream_get_be32(&buf_temp); + rt->skip_bytes = 4; ff_rtmp_packet_write(rt->stream, &rt->out_pkt, rt->chunk_size, rt->prev_pkt[1]); ff_rtmp_packet_destroy(&rt->out_pkt); rt->flv_size = 0; rt->flv_off = 0; + rt->flv_header_bytes = 0; } - } while (buf_temp - buf < size_temp); + } while (buf_temp - buf < size); return size; }