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