]> git.sesse.net Git - ffmpeg/blob - libavformat/rtmpproto.c
rtmp: Factorize the code by adding handle_chunk_size
[ffmpeg] / libavformat / rtmpproto.c
1 /*
2  * RTMP network protocol
3  * Copyright (c) 2009 Kostya Shishkov
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file
24  * RTMP protocol
25  */
26
27 #include "libavcodec/bytestream.h"
28 #include "libavutil/avstring.h"
29 #include "libavutil/intfloat.h"
30 #include "libavutil/lfg.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/sha.h"
33 #include "avformat.h"
34 #include "internal.h"
35
36 #include "network.h"
37
38 #include "flv.h"
39 #include "rtmp.h"
40 #include "rtmpcrypt.h"
41 #include "rtmppkt.h"
42 #include "url.h"
43
44 //#define DEBUG
45
46 #define APP_MAX_LENGTH 128
47 #define PLAYPATH_MAX_LENGTH 256
48 #define TCURL_MAX_LENGTH 512
49 #define FLASHVER_MAX_LENGTH 64
50
51 /** RTMP protocol handler state */
52 typedef enum {
53     STATE_START,      ///< client has not done anything yet
54     STATE_HANDSHAKED, ///< client has performed handshake
55     STATE_RELEASING,  ///< client releasing stream before publish it (for output)
56     STATE_FCPUBLISH,  ///< client FCPublishing stream (for output)
57     STATE_CONNECTING, ///< client connected to server successfully
58     STATE_READY,      ///< client has sent all needed commands and waits for server reply
59     STATE_PLAYING,    ///< client has started receiving multimedia data from server
60     STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
61     STATE_STOPPED,    ///< the broadcast has been stopped
62 } ClientState;
63
64 /** protocol handler context */
65 typedef struct RTMPContext {
66     const AVClass *class;
67     URLContext*   stream;                     ///< TCP stream used in interactions with RTMP server
68     RTMPPacket    prev_pkt[2][RTMP_CHANNELS]; ///< packet history used when reading and sending packets
69     int           chunk_size;                 ///< size of the chunks RTMP packets are divided into
70     int           is_input;                   ///< input/output flag
71     char          *playpath;                  ///< stream identifier to play (with possible "mp4:" prefix)
72     int           live;                       ///< 0: recorded, -1: live, -2: both
73     char          *app;                       ///< name of application
74     char          *conn;                      ///< append arbitrary AMF data to the Connect message
75     ClientState   state;                      ///< current state
76     int           main_channel_id;            ///< an additional channel ID which is used for some invocations
77     uint8_t*      flv_data;                   ///< buffer with data for demuxer
78     int           flv_size;                   ///< current buffer size
79     int           flv_off;                    ///< number of bytes read from current buffer
80     int           flv_nb_packets;             ///< number of flv packets published
81     RTMPPacket    out_pkt;                    ///< rtmp packet, created from flv a/v or metadata (for output)
82     uint32_t      client_report_size;         ///< number of bytes after which client should report to server
83     uint32_t      bytes_read;                 ///< number of bytes read from server
84     uint32_t      last_bytes_read;            ///< number of bytes read last reported to server
85     int           skip_bytes;                 ///< number of bytes to skip from the input FLV stream in the next write call
86     uint8_t       flv_header[11];             ///< partial incoming flv packet header
87     int           flv_header_bytes;           ///< number of initialized bytes in flv_header
88     int           nb_invokes;                 ///< keeps track of invoke messages
89     int           create_stream_invoke;       ///< invoke id for the create stream command
90     char*         tcurl;                      ///< url of the target stream
91     char*         flashver;                   ///< version of the flash plugin
92     char*         swfurl;                     ///< url of the swf player
93     char*         pageurl;                    ///< url of the web page
94     int           server_bw;                  ///< server bandwidth
95     int           client_buffer_time;         ///< client buffer time in ms
96     int           flush_interval;             ///< number of packets flushed in the same request (RTMPT only)
97     int           encrypted;                  ///< use an encrypted connection (RTMPE only)
98 } RTMPContext;
99
100 #define PLAYER_KEY_OPEN_PART_LEN 30   ///< length of partial key used for first client digest signing
101 /** Client key used for digest signing */
102 static const uint8_t rtmp_player_key[] = {
103     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
104     'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
105
106     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
107     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
108     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
109 };
110
111 #define SERVER_KEY_OPEN_PART_LEN 36   ///< length of partial key used for first server digest signing
112 /** Key used for RTMP server digest signing */
113 static const uint8_t rtmp_server_key[] = {
114     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
115     'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
116     'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
117
118     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
119     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
120     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
121 };
122
123 static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)
124 {
125     char *field, *value;
126     char type;
127
128     /* The type must be B for Boolean, N for number, S for string, O for
129      * object, or Z for null. For Booleans the data must be either 0 or 1 for
130      * FALSE or TRUE, respectively. Likewise for Objects the data must be
131      * 0 or 1 to end or begin an object, respectively. Data items in subobjects
132      * may be named, by prefixing the type with 'N' and specifying the name
133      * before the value (ie. NB:myFlag:1). This option may be used multiple times
134      * to construct arbitrary AMF sequences. */
135     if (param[0] && param[1] == ':') {
136         type = param[0];
137         value = param + 2;
138     } else if (param[0] == 'N' && param[1] && param[2] == ':') {
139         type = param[1];
140         field = param + 3;
141         value = strchr(field, ':');
142         if (!value)
143             goto fail;
144         *value = '\0';
145         value++;
146
147         if (!field || !value)
148             goto fail;
149
150         ff_amf_write_field_name(p, field);
151     } else {
152         goto fail;
153     }
154
155     switch (type) {
156     case 'B':
157         ff_amf_write_bool(p, value[0] != '0');
158         break;
159     case 'S':
160         ff_amf_write_string(p, value);
161         break;
162     case 'N':
163         ff_amf_write_number(p, strtod(value, NULL));
164         break;
165     case 'Z':
166         ff_amf_write_null(p);
167         break;
168     case 'O':
169         if (value[0] != '0')
170             ff_amf_write_object_start(p);
171         else
172             ff_amf_write_object_end(p);
173         break;
174     default:
175         goto fail;
176         break;
177     }
178
179     return 0;
180
181 fail:
182     av_log(s, AV_LOG_ERROR, "Invalid AMF parameter: %s\n", param);
183     return AVERROR(EINVAL);
184 }
185
186 /**
187  * Generate 'connect' call and send it to the server.
188  */
189 static int gen_connect(URLContext *s, RTMPContext *rt)
190 {
191     RTMPPacket pkt;
192     uint8_t *p;
193     int ret;
194
195     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
196                                      0, 4096)) < 0)
197         return ret;
198
199     p = pkt.data;
200
201     ff_amf_write_string(&p, "connect");
202     ff_amf_write_number(&p, ++rt->nb_invokes);
203     ff_amf_write_object_start(&p);
204     ff_amf_write_field_name(&p, "app");
205     ff_amf_write_string(&p, rt->app);
206
207     if (!rt->is_input) {
208         ff_amf_write_field_name(&p, "type");
209         ff_amf_write_string(&p, "nonprivate");
210     }
211     ff_amf_write_field_name(&p, "flashVer");
212     ff_amf_write_string(&p, rt->flashver);
213
214     if (rt->swfurl) {
215         ff_amf_write_field_name(&p, "swfUrl");
216         ff_amf_write_string(&p, rt->swfurl);
217     }
218
219     ff_amf_write_field_name(&p, "tcUrl");
220     ff_amf_write_string(&p, rt->tcurl);
221     if (rt->is_input) {
222         ff_amf_write_field_name(&p, "fpad");
223         ff_amf_write_bool(&p, 0);
224         ff_amf_write_field_name(&p, "capabilities");
225         ff_amf_write_number(&p, 15.0);
226
227         /* Tell the server we support all the audio codecs except
228          * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)
229          * which are unused in the RTMP protocol implementation. */
230         ff_amf_write_field_name(&p, "audioCodecs");
231         ff_amf_write_number(&p, 4071.0);
232         ff_amf_write_field_name(&p, "videoCodecs");
233         ff_amf_write_number(&p, 252.0);
234         ff_amf_write_field_name(&p, "videoFunction");
235         ff_amf_write_number(&p, 1.0);
236
237         if (rt->pageurl) {
238             ff_amf_write_field_name(&p, "pageUrl");
239             ff_amf_write_string(&p, rt->pageurl);
240         }
241     }
242     ff_amf_write_object_end(&p);
243
244     if (rt->conn) {
245         char *param = rt->conn;
246
247         // Write arbitrary AMF data to the Connect message.
248         while (param != NULL) {
249             char *sep;
250             param += strspn(param, " ");
251             if (!*param)
252                 break;
253             sep = strchr(param, ' ');
254             if (sep)
255                 *sep = '\0';
256             if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) {
257                 // Invalid AMF parameter.
258                 ff_rtmp_packet_destroy(&pkt);
259                 return ret;
260             }
261
262             if (sep)
263                 param = sep + 1;
264             else
265                 break;
266         }
267     }
268
269     pkt.data_size = p - pkt.data;
270
271     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
272                                rt->prev_pkt[1]);
273     ff_rtmp_packet_destroy(&pkt);
274
275     return ret;
276 }
277
278 /**
279  * Generate 'releaseStream' call and send it to the server. It should make
280  * the server release some channel for media streams.
281  */
282 static int gen_release_stream(URLContext *s, RTMPContext *rt)
283 {
284     RTMPPacket pkt;
285     uint8_t *p;
286     int ret;
287
288     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
289                                      0, 29 + strlen(rt->playpath))) < 0)
290         return ret;
291
292     av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
293     p = pkt.data;
294     ff_amf_write_string(&p, "releaseStream");
295     ff_amf_write_number(&p, ++rt->nb_invokes);
296     ff_amf_write_null(&p);
297     ff_amf_write_string(&p, rt->playpath);
298
299     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
300                                rt->prev_pkt[1]);
301     ff_rtmp_packet_destroy(&pkt);
302
303     return ret;
304 }
305
306 /**
307  * Generate 'FCPublish' call and send it to the server. It should make
308  * the server preapare for receiving media streams.
309  */
310 static int gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
311 {
312     RTMPPacket pkt;
313     uint8_t *p;
314     int ret;
315
316     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
317                                      0, 25 + strlen(rt->playpath))) < 0)
318         return ret;
319
320     av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
321     p = pkt.data;
322     ff_amf_write_string(&p, "FCPublish");
323     ff_amf_write_number(&p, ++rt->nb_invokes);
324     ff_amf_write_null(&p);
325     ff_amf_write_string(&p, rt->playpath);
326
327     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
328                                rt->prev_pkt[1]);
329     ff_rtmp_packet_destroy(&pkt);
330
331     return ret;
332 }
333
334 /**
335  * Generate 'FCUnpublish' call and send it to the server. It should make
336  * the server destroy stream.
337  */
338 static int gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
339 {
340     RTMPPacket pkt;
341     uint8_t *p;
342     int ret;
343
344     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
345                                      0, 27 + strlen(rt->playpath))) < 0)
346         return ret;
347
348     av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
349     p = pkt.data;
350     ff_amf_write_string(&p, "FCUnpublish");
351     ff_amf_write_number(&p, ++rt->nb_invokes);
352     ff_amf_write_null(&p);
353     ff_amf_write_string(&p, rt->playpath);
354
355     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
356                                rt->prev_pkt[1]);
357     ff_rtmp_packet_destroy(&pkt);
358
359     return ret;
360 }
361
362 /**
363  * Generate 'createStream' call and send it to the server. It should make
364  * the server allocate some channel for media streams.
365  */
366 static int gen_create_stream(URLContext *s, RTMPContext *rt)
367 {
368     RTMPPacket pkt;
369     uint8_t *p;
370     int ret;
371
372     av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
373
374     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
375                                      0, 25)) < 0)
376         return ret;
377
378     p = pkt.data;
379     ff_amf_write_string(&p, "createStream");
380     ff_amf_write_number(&p, ++rt->nb_invokes);
381     ff_amf_write_null(&p);
382     rt->create_stream_invoke = rt->nb_invokes;
383
384     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
385                                rt->prev_pkt[1]);
386     ff_rtmp_packet_destroy(&pkt);
387
388     return ret;
389 }
390
391
392 /**
393  * Generate 'deleteStream' call and send it to the server. It should make
394  * the server remove some channel for media streams.
395  */
396 static int gen_delete_stream(URLContext *s, RTMPContext *rt)
397 {
398     RTMPPacket pkt;
399     uint8_t *p;
400     int ret;
401
402     av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
403
404     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
405                                      0, 34)) < 0)
406         return ret;
407
408     p = pkt.data;
409     ff_amf_write_string(&p, "deleteStream");
410     ff_amf_write_number(&p, ++rt->nb_invokes);
411     ff_amf_write_null(&p);
412     ff_amf_write_number(&p, rt->main_channel_id);
413
414     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
415                                rt->prev_pkt[1]);
416     ff_rtmp_packet_destroy(&pkt);
417
418     return ret;
419 }
420
421 /**
422  * Generate client buffer time and send it to the server.
423  */
424 static int gen_buffer_time(URLContext *s, RTMPContext *rt)
425 {
426     RTMPPacket pkt;
427     uint8_t *p;
428     int ret;
429
430     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
431                                      1, 10)) < 0)
432         return ret;
433
434     p = pkt.data;
435     bytestream_put_be16(&p, 3);
436     bytestream_put_be32(&p, rt->main_channel_id);
437     bytestream_put_be32(&p, rt->client_buffer_time);
438
439     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
440                                rt->prev_pkt[1]);
441     ff_rtmp_packet_destroy(&pkt);
442
443     return ret;
444 }
445
446 /**
447  * Generate 'play' call and send it to the server, then ping the server
448  * to start actual playing.
449  */
450 static int gen_play(URLContext *s, RTMPContext *rt)
451 {
452     RTMPPacket pkt;
453     uint8_t *p;
454     int ret;
455
456     av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
457
458     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE,
459                                      0, 29 + strlen(rt->playpath))) < 0)
460         return ret;
461
462     pkt.extra = rt->main_channel_id;
463
464     p = pkt.data;
465     ff_amf_write_string(&p, "play");
466     ff_amf_write_number(&p, ++rt->nb_invokes);
467     ff_amf_write_null(&p);
468     ff_amf_write_string(&p, rt->playpath);
469     ff_amf_write_number(&p, rt->live);
470
471     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
472                                rt->prev_pkt[1]);
473     ff_rtmp_packet_destroy(&pkt);
474
475     return ret;
476 }
477
478 /**
479  * Generate 'publish' call and send it to the server.
480  */
481 static int gen_publish(URLContext *s, RTMPContext *rt)
482 {
483     RTMPPacket pkt;
484     uint8_t *p;
485     int ret;
486
487     av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
488
489     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
490                                      0, 30 + strlen(rt->playpath))) < 0)
491         return ret;
492
493     pkt.extra = rt->main_channel_id;
494
495     p = pkt.data;
496     ff_amf_write_string(&p, "publish");
497     ff_amf_write_number(&p, ++rt->nb_invokes);
498     ff_amf_write_null(&p);
499     ff_amf_write_string(&p, rt->playpath);
500     ff_amf_write_string(&p, "live");
501
502     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
503                                rt->prev_pkt[1]);
504     ff_rtmp_packet_destroy(&pkt);
505
506     return ret;
507 }
508
509 /**
510  * Generate ping reply and send it to the server.
511  */
512 static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
513 {
514     RTMPPacket pkt;
515     uint8_t *p;
516     int ret;
517
518     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
519                                      ppkt->timestamp + 1, 6)) < 0)
520         return ret;
521
522     p = pkt.data;
523     bytestream_put_be16(&p, 7);
524     bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
525     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
526                                rt->prev_pkt[1]);
527     ff_rtmp_packet_destroy(&pkt);
528
529     return ret;
530 }
531
532 /**
533  * Generate server bandwidth message and send it to the server.
534  */
535 static int gen_server_bw(URLContext *s, RTMPContext *rt)
536 {
537     RTMPPacket pkt;
538     uint8_t *p;
539     int ret;
540
541     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_SERVER_BW,
542                                      0, 4)) < 0)
543         return ret;
544
545     p = pkt.data;
546     bytestream_put_be32(&p, rt->server_bw);
547     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
548                                rt->prev_pkt[1]);
549     ff_rtmp_packet_destroy(&pkt);
550
551     return ret;
552 }
553
554 /**
555  * Generate check bandwidth message and send it to the server.
556  */
557 static int gen_check_bw(URLContext *s, RTMPContext *rt)
558 {
559     RTMPPacket pkt;
560     uint8_t *p;
561     int ret;
562
563     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
564                                      0, 21)) < 0)
565         return ret;
566
567     p = pkt.data;
568     ff_amf_write_string(&p, "_checkbw");
569     ff_amf_write_number(&p, ++rt->nb_invokes);
570     ff_amf_write_null(&p);
571
572     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
573                                rt->prev_pkt[1]);
574     ff_rtmp_packet_destroy(&pkt);
575
576     return ret;
577 }
578
579 /**
580  * Generate report on bytes read so far and send it to the server.
581  */
582 static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
583 {
584     RTMPPacket pkt;
585     uint8_t *p;
586     int ret;
587
588     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ,
589                                      ts, 4)) < 0)
590         return ret;
591
592     p = pkt.data;
593     bytestream_put_be32(&p, rt->bytes_read);
594     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size,
595                                rt->prev_pkt[1]);
596     ff_rtmp_packet_destroy(&pkt);
597
598     return ret;
599 }
600
601 int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap,
602                         const uint8_t *key, int keylen, uint8_t *dst)
603 {
604     struct AVSHA *sha;
605     uint8_t hmac_buf[64+32] = {0};
606     int i;
607
608     sha = av_mallocz(av_sha_size);
609     if (!sha)
610         return AVERROR(ENOMEM);
611
612     if (keylen < 64) {
613         memcpy(hmac_buf, key, keylen);
614     } else {
615         av_sha_init(sha, 256);
616         av_sha_update(sha,key, keylen);
617         av_sha_final(sha, hmac_buf);
618     }
619     for (i = 0; i < 64; i++)
620         hmac_buf[i] ^= HMAC_IPAD_VAL;
621
622     av_sha_init(sha, 256);
623     av_sha_update(sha, hmac_buf, 64);
624     if (gap <= 0) {
625         av_sha_update(sha, src, len);
626     } else { //skip 32 bytes used for storing digest
627         av_sha_update(sha, src, gap);
628         av_sha_update(sha, src + gap + 32, len - gap - 32);
629     }
630     av_sha_final(sha, hmac_buf + 64);
631
632     for (i = 0; i < 64; i++)
633         hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad
634     av_sha_init(sha, 256);
635     av_sha_update(sha, hmac_buf, 64+32);
636     av_sha_final(sha, dst);
637
638     av_free(sha);
639
640     return 0;
641 }
642
643 int ff_rtmp_calc_digest_pos(const uint8_t *buf, int off, int mod_val,
644                             int add_val)
645 {
646     int i, digest_pos = 0;
647
648     for (i = 0; i < 4; i++)
649         digest_pos += buf[i + off];
650     digest_pos = digest_pos % mod_val + add_val;
651
652     return digest_pos;
653 }
654
655 /**
656  * Put HMAC-SHA2 digest of packet data (except for the bytes where this digest
657  * will be stored) into that packet.
658  *
659  * @param buf handshake data (1536 bytes)
660  * @param encrypted use an encrypted connection (RTMPE)
661  * @return offset to the digest inside input data
662  */
663 static int rtmp_handshake_imprint_with_digest(uint8_t *buf, int encrypted)
664 {
665     int ret, digest_pos;
666
667     if (encrypted)
668         digest_pos = ff_rtmp_calc_digest_pos(buf, 772, 728, 776);
669     else
670         digest_pos = ff_rtmp_calc_digest_pos(buf, 8, 728, 12);
671
672     ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
673                               rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
674                               buf + digest_pos);
675     if (ret < 0)
676         return ret;
677
678     return digest_pos;
679 }
680
681 /**
682  * Verify that the received server response has the expected digest value.
683  *
684  * @param buf handshake data received from the server (1536 bytes)
685  * @param off position to search digest offset from
686  * @return 0 if digest is valid, digest position otherwise
687  */
688 static int rtmp_validate_digest(uint8_t *buf, int off)
689 {
690     uint8_t digest[32];
691     int ret, digest_pos;
692
693     digest_pos = ff_rtmp_calc_digest_pos(buf, off, 728, off + 4);
694
695     ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
696                               rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
697                               digest);
698     if (ret < 0)
699         return ret;
700
701     if (!memcmp(digest, buf + digest_pos, 32))
702         return digest_pos;
703     return 0;
704 }
705
706 /**
707  * Perform handshake with the server by means of exchanging pseudorandom data
708  * signed with HMAC-SHA2 digest.
709  *
710  * @return 0 if handshake succeeds, negative value otherwise
711  */
712 static int rtmp_handshake(URLContext *s, RTMPContext *rt)
713 {
714     AVLFG rnd;
715     uint8_t tosend    [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
716         3,                // unencrypted data
717         0, 0, 0, 0,       // client uptime
718         RTMP_CLIENT_VER1,
719         RTMP_CLIENT_VER2,
720         RTMP_CLIENT_VER3,
721         RTMP_CLIENT_VER4,
722     };
723     uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
724     uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
725     int i;
726     int server_pos, client_pos;
727     uint8_t digest[32], signature[32];
728     int ret, type = 0;
729
730     av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
731
732     av_lfg_init(&rnd, 0xDEADC0DE);
733     // generate handshake packet - 1536 bytes of pseudorandom data
734     for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
735         tosend[i] = av_lfg_get(&rnd) >> 24;
736
737     if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
738         /* When the client wants to use RTMPE, we have to change the command
739          * byte to 0x06 which means to use encrypted data and we have to set
740          * the flash version to at least 9.0.115.0. */
741         tosend[0] = 6;
742         tosend[5] = 128;
743         tosend[6] = 0;
744         tosend[7] = 3;
745         tosend[8] = 2;
746
747         /* Initialize the Diffie-Hellmann context and generate the public key
748          * to send to the server. */
749         if ((ret = ff_rtmpe_gen_pub_key(rt->stream, tosend + 1)) < 0)
750             return ret;
751     }
752
753     client_pos = rtmp_handshake_imprint_with_digest(tosend + 1, rt->encrypted);
754     if (client_pos < 0)
755         return client_pos;
756
757     if ((ret = ffurl_write(rt->stream, tosend,
758                            RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
759         av_log(s, AV_LOG_ERROR, "Cannot write RTMP handshake request\n");
760         return ret;
761     }
762
763     if ((ret = ffurl_read_complete(rt->stream, serverdata,
764                                    RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
765         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
766         return ret;
767     }
768
769     if ((ret = ffurl_read_complete(rt->stream, clientdata,
770                                    RTMP_HANDSHAKE_PACKET_SIZE)) < 0) {
771         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
772         return ret;
773     }
774
775     av_log(s, AV_LOG_DEBUG, "Type answer %d\n", serverdata[0]);
776     av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
777            serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
778
779     if (rt->is_input && serverdata[5] >= 3) {
780         server_pos = rtmp_validate_digest(serverdata + 1, 772);
781         if (server_pos < 0)
782             return server_pos;
783
784         if (!server_pos) {
785             type = 1;
786             server_pos = rtmp_validate_digest(serverdata + 1, 8);
787             if (server_pos < 0)
788                 return server_pos;
789
790             if (!server_pos) {
791                 av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
792                 return AVERROR(EIO);
793             }
794         }
795
796         ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
797                                   rtmp_server_key, sizeof(rtmp_server_key),
798                                   digest);
799         if (ret < 0)
800             return ret;
801
802         ret = ff_rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE - 32,
803                                   0, digest, 32, signature);
804         if (ret < 0)
805             return ret;
806
807         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
808             /* Compute the shared secret key sent by the server and initialize
809              * the RC4 encryption. */
810             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
811                                                    tosend + 1, type)) < 0)
812                 return ret;
813
814             /* Encrypt the signature received by the server. */
815             ff_rtmpe_encrypt_sig(rt->stream, signature, digest, serverdata[0]);
816         }
817
818         if (memcmp(signature, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
819             av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
820             return AVERROR(EIO);
821         }
822
823         for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
824             tosend[i] = av_lfg_get(&rnd) >> 24;
825         ret = ff_rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
826                                   rtmp_player_key, sizeof(rtmp_player_key),
827                                   digest);
828         if (ret < 0)
829             return ret;
830
831         ret = ff_rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
832                                   digest, 32,
833                                   tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
834         if (ret < 0)
835             return ret;
836
837         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
838             /* Encrypt the signature to be send to the server. */
839             ff_rtmpe_encrypt_sig(rt->stream, tosend +
840                                  RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
841                                  serverdata[0]);
842         }
843
844         // write reply back to the server
845         if ((ret = ffurl_write(rt->stream, tosend,
846                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
847             return ret;
848
849         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
850             /* Set RC4 keys for encryption and update the keystreams. */
851             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
852                 return ret;
853         }
854     } else {
855         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
856             /* Compute the shared secret key sent by the server and initialize
857              * the RC4 encryption. */
858             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
859                             tosend + 1, 1)) < 0)
860                 return ret;
861
862             if (serverdata[0] == 9) {
863                 /* Encrypt the signature received by the server. */
864                 ff_rtmpe_encrypt_sig(rt->stream, signature, digest,
865                                      serverdata[0]);
866             }
867         }
868
869         if ((ret = ffurl_write(rt->stream, serverdata + 1,
870                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
871             return ret;
872
873         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
874             /* Set RC4 keys for encryption and update the keystreams. */
875             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
876                 return ret;
877         }
878     }
879
880     return 0;
881 }
882
883 static int handle_chunk_size(URLContext *s, RTMPPacket *pkt)
884 {
885     RTMPContext *rt = s->priv_data;
886     int ret;
887
888     if (pkt->data_size != 4) {
889         av_log(s, AV_LOG_ERROR,
890                "Chunk size change packet is not 4 bytes long (%d)\n",
891                pkt->data_size);
892         return -1;
893     }
894
895     if (!rt->is_input) {
896         if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->chunk_size,
897                                         rt->prev_pkt[1])) < 0)
898             return ret;
899     }
900
901     rt->chunk_size = AV_RB32(pkt->data);
902     if (rt->chunk_size <= 0) {
903         av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n", rt->chunk_size);
904         return -1;
905     }
906     av_log(s, AV_LOG_DEBUG, "New chunk size = %d\n", rt->chunk_size);
907
908     return 0;
909 }
910
911 static int handle_ping(URLContext *s, RTMPPacket *pkt)
912 {
913     RTMPContext *rt = s->priv_data;
914     int t, ret;
915
916     t = AV_RB16(pkt->data);
917     if (t == 6) {
918         if ((ret = gen_pong(s, rt, pkt)) < 0)
919             return ret;
920     }
921
922     return 0;
923 }
924
925 static int handle_client_bw(URLContext *s, RTMPPacket *pkt)
926 {
927     RTMPContext *rt = s->priv_data;
928
929     if (pkt->data_size < 4) {
930         av_log(s, AV_LOG_ERROR,
931                "Client bandwidth report packet is less than 4 bytes long (%d)\n",
932                pkt->data_size);
933         return -1;
934     }
935     av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", AV_RB32(pkt->data));
936     rt->client_report_size = AV_RB32(pkt->data) >> 1;
937
938     return 0;
939 }
940
941 static int handle_server_bw(URLContext *s, RTMPPacket *pkt)
942 {
943     RTMPContext *rt = s->priv_data;
944
945     rt->server_bw = AV_RB32(pkt->data);
946     if (rt->server_bw <= 0) {
947         av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n",
948                rt->server_bw);
949         return AVERROR(EINVAL);
950     }
951     av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw);
952
953     return 0;
954 }
955
956 /**
957  * Parse received packet and possibly perform some action depending on
958  * the packet contents.
959  * @return 0 for no errors, negative values for serious errors which prevent
960  *         further communications, positive values for uncritical errors
961  */
962 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
963 {
964     int i, t;
965     const uint8_t *data_end = pkt->data + pkt->data_size;
966     int ret;
967
968 #ifdef DEBUG
969     ff_rtmp_packet_dump(s, pkt);
970 #endif
971
972     switch (pkt->type) {
973     case RTMP_PT_CHUNK_SIZE:
974         if ((ret = handle_chunk_size(s, pkt)) < 0)
975             return ret;
976         break;
977     case RTMP_PT_PING:
978         if ((ret = handle_ping(s, pkt)) < 0)
979             return ret;
980         break;
981     case RTMP_PT_CLIENT_BW:
982         if ((ret = handle_client_bw(s, pkt)) < 0)
983             return ret;
984         break;
985     case RTMP_PT_SERVER_BW:
986         if ((ret = handle_server_bw(s, pkt)) < 0)
987             return ret;
988         break;
989     case RTMP_PT_INVOKE:
990         //TODO: check for the messages sent for wrong state?
991         if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
992             uint8_t tmpstr[256];
993
994             if (!ff_amf_get_field_value(pkt->data + 9, data_end,
995                                         "description", tmpstr, sizeof(tmpstr)))
996                 av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
997             return -1;
998         } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
999             switch (rt->state) {
1000             case STATE_HANDSHAKED:
1001                 if (!rt->is_input) {
1002                     if ((ret = gen_release_stream(s, rt)) < 0)
1003                         return ret;
1004                     if ((ret = gen_fcpublish_stream(s, rt)) < 0)
1005                         return ret;
1006                     rt->state = STATE_RELEASING;
1007                 } else {
1008                     if ((ret = gen_server_bw(s, rt)) < 0)
1009                         return ret;
1010                     rt->state = STATE_CONNECTING;
1011                 }
1012                 if ((ret = gen_create_stream(s, rt)) < 0)
1013                     return ret;
1014                 break;
1015             case STATE_FCPUBLISH:
1016                 rt->state = STATE_CONNECTING;
1017                 break;
1018             case STATE_RELEASING:
1019                 rt->state = STATE_FCPUBLISH;
1020                 /* hack for Wowza Media Server, it does not send result for
1021                  * releaseStream and FCPublish calls */
1022                 if (!pkt->data[10]) {
1023                     int pkt_id = av_int2double(AV_RB64(pkt->data + 11));
1024                     if (pkt_id == rt->create_stream_invoke)
1025                         rt->state = STATE_CONNECTING;
1026                 }
1027                 if (rt->state != STATE_CONNECTING)
1028                     break;
1029             case STATE_CONNECTING:
1030                 //extract a number from the result
1031                 if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
1032                     av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
1033                 } else {
1034                     rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21));
1035                 }
1036                 if (rt->is_input) {
1037                     if ((ret = gen_play(s, rt)) < 0)
1038                         return ret;
1039                     if ((ret = gen_buffer_time(s, rt)) < 0)
1040                         return ret;
1041                 } else {
1042                     if ((ret = gen_publish(s, rt)) < 0)
1043                         return ret;
1044                 }
1045                 rt->state = STATE_READY;
1046                 break;
1047             }
1048         } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
1049             const uint8_t* ptr = pkt->data + 11;
1050             uint8_t tmpstr[256];
1051
1052             for (i = 0; i < 2; i++) {
1053                 t = ff_amf_tag_size(ptr, data_end);
1054                 if (t < 0)
1055                     return 1;
1056                 ptr += t;
1057             }
1058             t = ff_amf_get_field_value(ptr, data_end,
1059                                        "level", tmpstr, sizeof(tmpstr));
1060             if (!t && !strcmp(tmpstr, "error")) {
1061                 if (!ff_amf_get_field_value(ptr, data_end,
1062                                             "description", tmpstr, sizeof(tmpstr)))
1063                     av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
1064                 return -1;
1065             }
1066             t = ff_amf_get_field_value(ptr, data_end,
1067                                        "code", tmpstr, sizeof(tmpstr));
1068             if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
1069             if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
1070             if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
1071             if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
1072         } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) {
1073             if ((ret = gen_check_bw(s, rt)) < 0)
1074                 return ret;
1075         }
1076         break;
1077     case RTMP_PT_VIDEO:
1078     case RTMP_PT_AUDIO:
1079         /* Audio and Video packets are parsed in get_packet() */
1080         break;
1081     default:
1082         av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
1083         break;
1084     }
1085     return 0;
1086 }
1087
1088 /**
1089  * Interact with the server by receiving and sending RTMP packets until
1090  * there is some significant data (media data or expected status notification).
1091  *
1092  * @param s          reading context
1093  * @param for_header non-zero value tells function to work until it
1094  * gets notification from the server that playing has been started,
1095  * otherwise function will work until some media data is received (or
1096  * an error happens)
1097  * @return 0 for successful operation, negative value in case of error
1098  */
1099 static int get_packet(URLContext *s, int for_header)
1100 {
1101     RTMPContext *rt = s->priv_data;
1102     int ret;
1103     uint8_t *p;
1104     const uint8_t *next;
1105     uint32_t data_size;
1106     uint32_t ts, cts, pts=0;
1107
1108     if (rt->state == STATE_STOPPED)
1109         return AVERROR_EOF;
1110
1111     for (;;) {
1112         RTMPPacket rpkt = { 0 };
1113         if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
1114                                        rt->chunk_size, rt->prev_pkt[0])) <= 0) {
1115             if (ret == 0) {
1116                 return AVERROR(EAGAIN);
1117             } else {
1118                 return AVERROR(EIO);
1119             }
1120         }
1121         rt->bytes_read += ret;
1122         if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
1123             av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
1124             if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
1125                 return ret;
1126             rt->last_bytes_read = rt->bytes_read;
1127         }
1128
1129         ret = rtmp_parse_result(s, rt, &rpkt);
1130         if (ret < 0) {//serious error in current packet
1131             ff_rtmp_packet_destroy(&rpkt);
1132             return ret;
1133         }
1134         if (rt->state == STATE_STOPPED) {
1135             ff_rtmp_packet_destroy(&rpkt);
1136             return AVERROR_EOF;
1137         }
1138         if (for_header && (rt->state == STATE_PLAYING || rt->state == STATE_PUBLISHING)) {
1139             ff_rtmp_packet_destroy(&rpkt);
1140             return 0;
1141         }
1142         if (!rpkt.data_size || !rt->is_input) {
1143             ff_rtmp_packet_destroy(&rpkt);
1144             continue;
1145         }
1146         if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
1147            (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
1148             ts = rpkt.timestamp;
1149
1150             // generate packet header and put data into buffer for FLV demuxer
1151             rt->flv_off  = 0;
1152             rt->flv_size = rpkt.data_size + 15;
1153             rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
1154             bytestream_put_byte(&p, rpkt.type);
1155             bytestream_put_be24(&p, rpkt.data_size);
1156             bytestream_put_be24(&p, ts);
1157             bytestream_put_byte(&p, ts >> 24);
1158             bytestream_put_be24(&p, 0);
1159             bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
1160             bytestream_put_be32(&p, 0);
1161             ff_rtmp_packet_destroy(&rpkt);
1162             return 0;
1163         } else if (rpkt.type == RTMP_PT_METADATA) {
1164             // we got raw FLV data, make it available for FLV demuxer
1165             rt->flv_off  = 0;
1166             rt->flv_size = rpkt.data_size;
1167             rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
1168             /* rewrite timestamps */
1169             next = rpkt.data;
1170             ts = rpkt.timestamp;
1171             while (next - rpkt.data < rpkt.data_size - 11) {
1172                 next++;
1173                 data_size = bytestream_get_be24(&next);
1174                 p=next;
1175                 cts = bytestream_get_be24(&next);
1176                 cts |= bytestream_get_byte(&next) << 24;
1177                 if (pts==0)
1178                     pts=cts;
1179                 ts += cts - pts;
1180                 pts = cts;
1181                 bytestream_put_be24(&p, ts);
1182                 bytestream_put_byte(&p, ts >> 24);
1183                 next += data_size + 3 + 4;
1184             }
1185             memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
1186             ff_rtmp_packet_destroy(&rpkt);
1187             return 0;
1188         }
1189         ff_rtmp_packet_destroy(&rpkt);
1190     }
1191 }
1192
1193 static int rtmp_close(URLContext *h)
1194 {
1195     RTMPContext *rt = h->priv_data;
1196     int ret = 0;
1197
1198     if (!rt->is_input) {
1199         rt->flv_data = NULL;
1200         if (rt->out_pkt.data_size)
1201             ff_rtmp_packet_destroy(&rt->out_pkt);
1202         if (rt->state > STATE_FCPUBLISH)
1203             ret = gen_fcunpublish_stream(h, rt);
1204     }
1205     if (rt->state > STATE_HANDSHAKED)
1206         ret = gen_delete_stream(h, rt);
1207
1208     av_freep(&rt->flv_data);
1209     ffurl_close(rt->stream);
1210     return ret;
1211 }
1212
1213 /**
1214  * Open RTMP connection and verify that the stream can be played.
1215  *
1216  * URL syntax: rtmp://server[:port][/app][/playpath]
1217  *             where 'app' is first one or two directories in the path
1218  *             (e.g. /ondemand/, /flash/live/, etc.)
1219  *             and 'playpath' is a file name (the rest of the path,
1220  *             may be prefixed with "mp4:")
1221  */
1222 static int rtmp_open(URLContext *s, const char *uri, int flags)
1223 {
1224     RTMPContext *rt = s->priv_data;
1225     char proto[8], hostname[256], path[1024], *fname;
1226     char *old_app;
1227     uint8_t buf[2048];
1228     int port;
1229     AVDictionary *opts = NULL;
1230     int ret;
1231
1232     rt->is_input = !(flags & AVIO_FLAG_WRITE);
1233
1234     av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
1235                  path, sizeof(path), s->filename);
1236
1237     if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
1238         if (!strcmp(proto, "rtmpts"))
1239             av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
1240
1241         /* open the http tunneling connection */
1242         ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
1243     } else if (!strcmp(proto, "rtmps")) {
1244         /* open the tls connection */
1245         if (port < 0)
1246             port = RTMPS_DEFAULT_PORT;
1247         ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
1248     } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
1249         if (!strcmp(proto, "rtmpte"))
1250             av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
1251
1252         /* open the encrypted connection */
1253         ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
1254         rt->encrypted = 1;
1255     } else {
1256         /* open the tcp connection */
1257         if (port < 0)
1258             port = RTMP_DEFAULT_PORT;
1259         ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
1260     }
1261
1262     if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
1263                           &s->interrupt_callback, &opts)) < 0) {
1264         av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
1265         goto fail;
1266     }
1267
1268     rt->state = STATE_START;
1269     if ((ret = rtmp_handshake(s, rt)) < 0)
1270         goto fail;
1271
1272     rt->chunk_size = 128;
1273     rt->state = STATE_HANDSHAKED;
1274
1275     // Keep the application name when it has been defined by the user.
1276     old_app = rt->app;
1277
1278     rt->app = av_malloc(APP_MAX_LENGTH);
1279     if (!rt->app) {
1280         ret = AVERROR(ENOMEM);
1281         goto fail;
1282     }
1283
1284     //extract "app" part from path
1285     if (!strncmp(path, "/ondemand/", 10)) {
1286         fname = path + 10;
1287         memcpy(rt->app, "ondemand", 9);
1288     } else {
1289         char *next = *path ? path + 1 : path;
1290         char *p = strchr(next, '/');
1291         if (!p) {
1292             fname = next;
1293             rt->app[0] = '\0';
1294         } else {
1295             // make sure we do not mismatch a playpath for an application instance
1296             char *c = strchr(p + 1, ':');
1297             fname = strchr(p + 1, '/');
1298             if (!fname || (c && c < fname)) {
1299                 fname = p + 1;
1300                 av_strlcpy(rt->app, path + 1, p - path);
1301             } else {
1302                 fname++;
1303                 av_strlcpy(rt->app, path + 1, fname - path - 1);
1304             }
1305         }
1306     }
1307
1308     if (old_app) {
1309         // The name of application has been defined by the user, override it.
1310         av_free(rt->app);
1311         rt->app = old_app;
1312     }
1313
1314     if (!rt->playpath) {
1315         int len = strlen(fname);
1316
1317         rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
1318         if (!rt->playpath) {
1319             ret = AVERROR(ENOMEM);
1320             goto fail;
1321         }
1322
1323         if (!strchr(fname, ':') && len >= 4 &&
1324             (!strcmp(fname + len - 4, ".f4v") ||
1325              !strcmp(fname + len - 4, ".mp4"))) {
1326             memcpy(rt->playpath, "mp4:", 5);
1327         } else if (len >= 4 && !strcmp(fname + len - 4, ".flv")) {
1328             fname[len - 4] = '\0';
1329         } else {
1330             rt->playpath[0] = 0;
1331         }
1332         strncat(rt->playpath, fname, PLAYPATH_MAX_LENGTH - 5);
1333     }
1334
1335     if (!rt->tcurl) {
1336         rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
1337         if (!rt->tcurl) {
1338             ret = AVERROR(ENOMEM);
1339             goto fail;
1340         }
1341         ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
1342                     port, "/%s", rt->app);
1343     }
1344
1345     if (!rt->flashver) {
1346         rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
1347         if (!rt->flashver) {
1348             ret = AVERROR(ENOMEM);
1349             goto fail;
1350         }
1351         if (rt->is_input) {
1352             snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
1353                     RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
1354                     RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
1355         } else {
1356             snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
1357                     "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
1358         }
1359     }
1360
1361     rt->client_report_size = 1048576;
1362     rt->bytes_read = 0;
1363     rt->last_bytes_read = 0;
1364     rt->server_bw = 2500000;
1365
1366     av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
1367            proto, path, rt->app, rt->playpath);
1368     if ((ret = gen_connect(s, rt)) < 0)
1369         goto fail;
1370
1371     do {
1372         ret = get_packet(s, 1);
1373     } while (ret == EAGAIN);
1374     if (ret < 0)
1375         goto fail;
1376
1377     if (rt->is_input) {
1378         // generate FLV header for demuxer
1379         rt->flv_size = 13;
1380         rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
1381         rt->flv_off  = 0;
1382         memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
1383     } else {
1384         rt->flv_size = 0;
1385         rt->flv_data = NULL;
1386         rt->flv_off  = 0;
1387         rt->skip_bytes = 13;
1388     }
1389
1390     s->max_packet_size = rt->stream->max_packet_size;
1391     s->is_streamed     = 1;
1392     return 0;
1393
1394 fail:
1395     av_dict_free(&opts);
1396     rtmp_close(s);
1397     return ret;
1398 }
1399
1400 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
1401 {
1402     RTMPContext *rt = s->priv_data;
1403     int orig_size = size;
1404     int ret;
1405
1406     while (size > 0) {
1407         int data_left = rt->flv_size - rt->flv_off;
1408
1409         if (data_left >= size) {
1410             memcpy(buf, rt->flv_data + rt->flv_off, size);
1411             rt->flv_off += size;
1412             return orig_size;
1413         }
1414         if (data_left > 0) {
1415             memcpy(buf, rt->flv_data + rt->flv_off, data_left);
1416             buf  += data_left;
1417             size -= data_left;
1418             rt->flv_off = rt->flv_size;
1419             return data_left;
1420         }
1421         if ((ret = get_packet(s, 0)) < 0)
1422            return ret;
1423     }
1424     return orig_size;
1425 }
1426
1427 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
1428 {
1429     RTMPContext *rt = s->priv_data;
1430     int size_temp = size;
1431     int pktsize, pkttype;
1432     uint32_t ts;
1433     const uint8_t *buf_temp = buf;
1434     uint8_t c;
1435     int ret;
1436
1437     do {
1438         if (rt->skip_bytes) {
1439             int skip = FFMIN(rt->skip_bytes, size_temp);
1440             buf_temp       += skip;
1441             size_temp      -= skip;
1442             rt->skip_bytes -= skip;
1443             continue;
1444         }
1445
1446         if (rt->flv_header_bytes < 11) {
1447             const uint8_t *header = rt->flv_header;
1448             int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
1449             bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
1450             rt->flv_header_bytes += copy;
1451             size_temp            -= copy;
1452             if (rt->flv_header_bytes < 11)
1453                 break;
1454
1455             pkttype = bytestream_get_byte(&header);
1456             pktsize = bytestream_get_be24(&header);
1457             ts = bytestream_get_be24(&header);
1458             ts |= bytestream_get_byte(&header) << 24;
1459             bytestream_get_be24(&header);
1460             rt->flv_size = pktsize;
1461
1462             //force 12bytes header
1463             if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
1464                 pkttype == RTMP_PT_NOTIFY) {
1465                 if (pkttype == RTMP_PT_NOTIFY)
1466                     pktsize += 16;
1467                 rt->prev_pkt[1][RTMP_SOURCE_CHANNEL].channel_id = 0;
1468             }
1469
1470             //this can be a big packet, it's better to send it right here
1471             if ((ret = ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL,
1472                                              pkttype, ts, pktsize)) < 0)
1473                 return ret;
1474
1475             rt->out_pkt.extra = rt->main_channel_id;
1476             rt->flv_data = rt->out_pkt.data;
1477
1478             if (pkttype == RTMP_PT_NOTIFY)
1479                 ff_amf_write_string(&rt->flv_data, "@setDataFrame");
1480         }
1481
1482         if (rt->flv_size - rt->flv_off > size_temp) {
1483             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
1484             rt->flv_off += size_temp;
1485             size_temp = 0;
1486         } else {
1487             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
1488             size_temp   -= rt->flv_size - rt->flv_off;
1489             rt->flv_off += rt->flv_size - rt->flv_off;
1490         }
1491
1492         if (rt->flv_off == rt->flv_size) {
1493             rt->skip_bytes = 4;
1494
1495             if ((ret = ff_rtmp_packet_write(rt->stream, &rt->out_pkt,
1496                                             rt->chunk_size, rt->prev_pkt[1])) < 0)
1497                 return ret;
1498             ff_rtmp_packet_destroy(&rt->out_pkt);
1499             rt->flv_size = 0;
1500             rt->flv_off = 0;
1501             rt->flv_header_bytes = 0;
1502             rt->flv_nb_packets++;
1503         }
1504     } while (buf_temp - buf < size);
1505
1506     if (rt->flv_nb_packets < rt->flush_interval)
1507         return size;
1508     rt->flv_nb_packets = 0;
1509
1510     /* set stream into nonblocking mode */
1511     rt->stream->flags |= AVIO_FLAG_NONBLOCK;
1512
1513     /* try to read one byte from the stream */
1514     ret = ffurl_read(rt->stream, &c, 1);
1515
1516     /* switch the stream back into blocking mode */
1517     rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
1518
1519     if (ret == AVERROR(EAGAIN)) {
1520         /* no incoming data to handle */
1521         return size;
1522     } else if (ret < 0) {
1523         return ret;
1524     } else if (ret == 1) {
1525         RTMPPacket rpkt = { 0 };
1526
1527         if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
1528                                                 rt->chunk_size,
1529                                                 rt->prev_pkt[0], c)) <= 0)
1530              return ret;
1531
1532         if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
1533             return ret;
1534
1535         ff_rtmp_packet_destroy(&rpkt);
1536     }
1537
1538     return size;
1539 }
1540
1541 #define OFFSET(x) offsetof(RTMPContext, x)
1542 #define DEC AV_OPT_FLAG_DECODING_PARAM
1543 #define ENC AV_OPT_FLAG_ENCODING_PARAM
1544
1545 static const AVOption rtmp_options[] = {
1546     {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1547     {"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},
1548     {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1549     {"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},
1550     {"rtmp_flush_interval", "Number of packets flushed in the same request (RTMPT only).", OFFSET(flush_interval), AV_OPT_TYPE_INT, {10}, 0, INT_MAX, ENC},
1551     {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
1552     {"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"},
1553     {"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"},
1554     {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {0}, 0, 0, DEC, "rtmp_live"},
1555     {"rtmp_pageurl", "URL of the web page in which the media was embedded. By default no value will be sent.", OFFSET(pageurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
1556     {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1557     {"rtmp_swfurl", "URL of the SWF player. By default no value will be sent", OFFSET(swfurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1558     {"rtmp_tcurl", "URL of the target stream. Defaults to proto://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1559     { NULL },
1560 };
1561
1562 static const AVClass rtmp_class = {
1563     .class_name = "rtmp",
1564     .item_name  = av_default_item_name,
1565     .option     = rtmp_options,
1566     .version    = LIBAVUTIL_VERSION_INT,
1567 };
1568
1569 URLProtocol ff_rtmp_protocol = {
1570     .name           = "rtmp",
1571     .url_open       = rtmp_open,
1572     .url_read       = rtmp_read,
1573     .url_write      = rtmp_write,
1574     .url_close      = rtmp_close,
1575     .priv_data_size = sizeof(RTMPContext),
1576     .flags          = URL_PROTOCOL_FLAG_NETWORK,
1577     .priv_data_class= &rtmp_class,
1578 };
1579
1580 static const AVClass rtmpe_class = {
1581     .class_name = "rtmpe",
1582     .item_name  = av_default_item_name,
1583     .option     = rtmp_options,
1584     .version    = LIBAVUTIL_VERSION_INT,
1585 };
1586
1587 URLProtocol ff_rtmpe_protocol = {
1588     .name            = "rtmpe",
1589     .url_open        = rtmp_open,
1590     .url_read        = rtmp_read,
1591     .url_write       = rtmp_write,
1592     .url_close       = rtmp_close,
1593     .priv_data_size  = sizeof(RTMPContext),
1594     .flags           = URL_PROTOCOL_FLAG_NETWORK,
1595     .priv_data_class = &rtmpe_class,
1596 };
1597
1598 static const AVClass rtmps_class = {
1599     .class_name = "rtmps",
1600     .item_name  = av_default_item_name,
1601     .option     = rtmp_options,
1602     .version    = LIBAVUTIL_VERSION_INT,
1603 };
1604
1605 URLProtocol ff_rtmps_protocol = {
1606     .name            = "rtmps",
1607     .url_open        = rtmp_open,
1608     .url_read        = rtmp_read,
1609     .url_write       = rtmp_write,
1610     .url_close       = rtmp_close,
1611     .priv_data_size  = sizeof(RTMPContext),
1612     .flags           = URL_PROTOCOL_FLAG_NETWORK,
1613     .priv_data_class = &rtmps_class,
1614 };
1615
1616 static const AVClass rtmpt_class = {
1617     .class_name = "rtmpt",
1618     .item_name  = av_default_item_name,
1619     .option     = rtmp_options,
1620     .version    = LIBAVUTIL_VERSION_INT,
1621 };
1622
1623 URLProtocol ff_rtmpt_protocol = {
1624     .name            = "rtmpt",
1625     .url_open        = rtmp_open,
1626     .url_read        = rtmp_read,
1627     .url_write       = rtmp_write,
1628     .url_close       = rtmp_close,
1629     .priv_data_size  = sizeof(RTMPContext),
1630     .flags           = URL_PROTOCOL_FLAG_NETWORK,
1631     .priv_data_class = &rtmpt_class,
1632 };
1633
1634 static const AVClass rtmpte_class = {
1635     .class_name = "rtmpte",
1636     .item_name  = av_default_item_name,
1637     .option     = rtmp_options,
1638     .version    = LIBAVUTIL_VERSION_INT,
1639 };
1640
1641 URLProtocol ff_rtmpte_protocol = {
1642     .name            = "rtmpte",
1643     .url_open        = rtmp_open,
1644     .url_read        = rtmp_read,
1645     .url_write       = rtmp_write,
1646     .url_close       = rtmp_close,
1647     .priv_data_size  = sizeof(RTMPContext),
1648     .flags           = URL_PROTOCOL_FLAG_NETWORK,
1649     .priv_data_class = &rtmpte_class,
1650 };
1651
1652 static const AVClass rtmpts_class = {
1653     .class_name = "rtmpts",
1654     .item_name  = av_default_item_name,
1655     .option     = rtmp_options,
1656     .version    = LIBAVUTIL_VERSION_INT,
1657 };
1658
1659 URLProtocol ff_rtmpts_protocol = {
1660     .name            = "rtmpts",
1661     .url_open        = rtmp_open,
1662     .url_read        = rtmp_read,
1663     .url_write       = rtmp_write,
1664     .url_close       = rtmp_close,
1665     .priv_data_size  = sizeof(RTMPContext),
1666     .flags           = URL_PROTOCOL_FLAG_NETWORK,
1667     .priv_data_class = &rtmpts_class,
1668 };