From 053386864219eccbcca1886c55f902f9555428a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 13 Jun 2012 10:51:22 +0300 Subject: rtmp: Tokenize the AMF connection parameters manually instead of using strtok_r MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes builds on platforms without strtok_r (windows). Signed-off-by: Martin Storsjö --- libavformat/rtmpproto.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'libavformat') diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 56011f1cde..2b15d80846 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -115,7 +115,7 @@ static const uint8_t rtmp_server_key[] = { static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p) { - char *field, *value, *saveptr; + char *field, *value; char type; /* The type must be B for Boolean, N for number, S for string, O for @@ -130,8 +130,12 @@ static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p) value = param + 2; } else if (param[0] == 'N' && param[1] && param[2] == ':') { type = param[1]; - field = strtok_r(param + 3, ":", &saveptr); - value = strtok_r(NULL, ":", &saveptr); + field = param + 3; + value = strchr(field, ':'); + if (!value) + goto fail; + *value = '\0'; + value++; if (!field || !value) goto fail; @@ -226,18 +230,27 @@ static int gen_connect(URLContext *s, RTMPContext *rt) ff_amf_write_object_end(&p); if (rt->conn) { - char *param, *saveptr; + char *param = rt->conn; // Write arbitrary AMF data to the Connect message. - param = strtok_r(rt->conn, " ", &saveptr); while (param != NULL) { + char *sep; + param += strspn(param, " "); + if (!*param) + break; + sep = strchr(param, ' '); + if (sep) + *sep = '\0'; if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) { // Invalid AMF parameter. ff_rtmp_packet_destroy(&pkt); return ret; } - param = strtok_r(NULL, " ", &saveptr); + if (sep) + param = sep + 1; + else + break; } } -- cgit v1.2.1 From 9ff930aace0d61a355f14e49f9fa1d95b8c0e5be Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 13 Jun 2012 14:45:57 +0200 Subject: rtmp: Display a verbose message when an unknown packet type is received MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtmpproto.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'libavformat') diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 2b15d80846..945ad49faa 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -937,6 +937,9 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) return ret; } break; + default: + av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type); + break; } return 0; } -- cgit v1.2.1 From c2d38beab2858307f76b01070e7044f2577b8600 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 13 Jun 2012 14:47:26 +0200 Subject: rtmp: Handle server bandwidth packets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtmpproto.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'libavformat') diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 945ad49faa..729e2d7af4 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -88,6 +88,7 @@ typedef struct RTMPContext { char* tcurl; ///< url of the target stream char* flashver; ///< version of the flash plugin char* swfurl; ///< url of the swf player + int server_bw; ///< server bandwidth } RTMPContext; #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing @@ -523,7 +524,7 @@ static int gen_server_bw(URLContext *s, RTMPContext *rt) return ret; p = pkt.data; - bytestream_put_be32(&p, 2500000); + bytestream_put_be32(&p, rt->server_bw); ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); ff_rtmp_packet_destroy(&pkt); @@ -851,6 +852,14 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", AV_RB32(pkt->data)); rt->client_report_size = AV_RB32(pkt->data) >> 1; break; + case RTMP_PT_SERVER_BW: + rt->server_bw = AV_RB32(pkt->data); + if (rt->server_bw <= 0) { + av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n", rt->server_bw); + return AVERROR(EINVAL); + } + av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw); + break; case RTMP_PT_INVOKE: //TODO: check for the messages sent for wrong state? if (!memcmp(pkt->data, "\002\000\006_error", 9)) { @@ -1198,6 +1207,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) rt->client_report_size = 1048576; rt->bytes_read = 0; rt->last_bytes_read = 0; + rt->server_bw = 2500000; av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n", proto, path, rt->app, rt->playpath); -- cgit v1.2.1 From 9477c035a768261e54c50404c0f3746bf023f7a4 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 13 Jun 2012 14:48:02 +0200 Subject: rtmp: Set the client buffer time to 3s instead of 0.26s MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This factorizes existing code into a new function gen_buffer_time(), which generates the client buffer time message and sends it to the server. Signed-off-by: Martin Storsjö --- libavformat/rtmpproto.c | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) (limited to 'libavformat') diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 729e2d7af4..0407ad32f8 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -89,6 +89,7 @@ typedef struct RTMPContext { char* flashver; ///< version of the flash plugin char* swfurl; ///< url of the swf player int server_bw; ///< server bandwidth + int client_buffer_time; ///< client buffer time in ms } RTMPContext; #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing @@ -407,6 +408,31 @@ static int gen_delete_stream(URLContext *s, RTMPContext *rt) return ret; } +/** + * Generate client buffer time and send it to the server. + */ +static int gen_buffer_time(URLContext *s, RTMPContext *rt) +{ + RTMPPacket pkt; + uint8_t *p; + int ret; + + if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, + 1, 10)) < 0) + return ret; + + p = pkt.data; + bytestream_put_be16(&p, 3); + bytestream_put_be32(&p, rt->main_channel_id); + bytestream_put_be32(&p, rt->client_buffer_time); + + ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, + rt->prev_pkt[1]); + ff_rtmp_packet_destroy(&pkt); + + return ret; +} + /** * Generate 'play' call and send it to the server, then ping the server * to start actual playing. @@ -436,23 +462,6 @@ static int gen_play(URLContext *s, RTMPContext *rt) rt->prev_pkt[1]); ff_rtmp_packet_destroy(&pkt); - if (ret < 0) - return ret; - - // set client buffer time disguised in ping packet - if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, - 1, 10)) < 0) - return ret; - - p = pkt.data; - bytestream_put_be16(&p, 3); - bytestream_put_be32(&p, 1); - bytestream_put_be32(&p, 256); //TODO: what is a good value here? - - ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, - rt->prev_pkt[1]); - ff_rtmp_packet_destroy(&pkt); - return ret; } @@ -910,6 +919,8 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) if (rt->is_input) { if ((ret = gen_play(s, rt)) < 0) return ret; + if ((ret = gen_buffer_time(s, rt)) < 0) + return ret; } else { if ((ret = gen_publish(s, rt)) < 0) return ret; @@ -1208,6 +1219,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) rt->bytes_read = 0; rt->last_bytes_read = 0; rt->server_bw = 2500000; + rt->client_buffer_time = 3000; av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n", proto, path, rt->app, rt->playpath); -- cgit v1.2.1 From 8517e9c476e8cf92d9ed25b6486bb43d3dc2c49d Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Wed, 13 Jun 2012 15:02:03 +0200 Subject: rtmp: Add a new option 'rtmp_buffer', for setting the client buffer time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtmpproto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libavformat') diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 0407ad32f8..e64e2a322b 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -1219,7 +1219,6 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) rt->bytes_read = 0; rt->last_bytes_read = 0; rt->server_bw = 2500000; - rt->client_buffer_time = 3000; av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n", proto, path, rt->app, rt->playpath); @@ -1366,6 +1365,7 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) static const AVOption rtmp_options[] = { {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, + {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {3000}, 0, INT_MAX, DEC|ENC}, {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, {"rtmp_flashver", "Version of the Flash plugin used to run the SWF player.", OFFSET(flashver), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"}, -- cgit v1.2.1