]> git.sesse.net Git - ffmpeg/blob - libavformat/rtmpproto.c
a2efe3882fe495b1ce915fa3bde21a1402ba0711
[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 AVERROR_INVALIDDATA;
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 AVERROR_INVALIDDATA;
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 AVERROR_INVALIDDATA;
934     }
935
936     rt->client_report_size = AV_RB32(pkt->data);
937     if (rt->client_report_size <= 0) {
938         av_log(s, AV_LOG_ERROR, "Incorrect client bandwidth %d\n",
939                 rt->client_report_size);
940         return AVERROR_INVALIDDATA;
941
942     }
943     av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", rt->client_report_size);
944     rt->client_report_size >>= 1;
945
946     return 0;
947 }
948
949 static int handle_server_bw(URLContext *s, RTMPPacket *pkt)
950 {
951     RTMPContext *rt = s->priv_data;
952
953     rt->server_bw = AV_RB32(pkt->data);
954     if (rt->server_bw <= 0) {
955         av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n",
956                rt->server_bw);
957         return AVERROR_INVALIDDATA;
958     }
959     av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw);
960
961     return 0;
962 }
963
964 static int handle_invoke(URLContext *s, RTMPPacket *pkt)
965 {
966     RTMPContext *rt = s->priv_data;
967     int i, t;
968     const uint8_t *data_end = pkt->data + pkt->data_size;
969     int ret;
970
971     //TODO: check for the messages sent for wrong state?
972     if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
973         uint8_t tmpstr[256];
974
975         if (!ff_amf_get_field_value(pkt->data + 9, data_end,
976                                     "description", tmpstr, sizeof(tmpstr)))
977             av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
978         return -1;
979     } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
980         switch (rt->state) {
981             case STATE_HANDSHAKED:
982                 if (!rt->is_input) {
983                     if ((ret = gen_release_stream(s, rt)) < 0)
984                         return ret;
985                     if ((ret = gen_fcpublish_stream(s, rt)) < 0)
986                         return ret;
987                     rt->state = STATE_RELEASING;
988                 } else {
989                     if ((ret = gen_server_bw(s, rt)) < 0)
990                         return ret;
991                     rt->state = STATE_CONNECTING;
992                 }
993                 if ((ret = gen_create_stream(s, rt)) < 0)
994                     return ret;
995                 break;
996             case STATE_FCPUBLISH:
997                 rt->state = STATE_CONNECTING;
998                 break;
999             case STATE_RELEASING:
1000                 rt->state = STATE_FCPUBLISH;
1001                 /* hack for Wowza Media Server, it does not send result for
1002                  * releaseStream and FCPublish calls */
1003                 if (!pkt->data[10]) {
1004                     int pkt_id = av_int2double(AV_RB64(pkt->data + 11));
1005                     if (pkt_id == rt->create_stream_invoke)
1006                         rt->state = STATE_CONNECTING;
1007                 }
1008                 if (rt->state != STATE_CONNECTING)
1009                     break;
1010             case STATE_CONNECTING:
1011                 //extract a number from the result
1012                 if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
1013                     av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
1014                 } else {
1015                     rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21));
1016                 }
1017                 if (rt->is_input) {
1018                     if ((ret = gen_play(s, rt)) < 0)
1019                         return ret;
1020                     if ((ret = gen_buffer_time(s, rt)) < 0)
1021                         return ret;
1022                 } else {
1023                     if ((ret = gen_publish(s, rt)) < 0)
1024                         return ret;
1025                 }
1026                 rt->state = STATE_READY;
1027                 break;
1028         }
1029     } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
1030         const uint8_t* ptr = pkt->data + 11;
1031         uint8_t tmpstr[256];
1032
1033         for (i = 0; i < 2; i++) {
1034             t = ff_amf_tag_size(ptr, data_end);
1035             if (t < 0)
1036                 return 1;
1037             ptr += t;
1038         }
1039         t = ff_amf_get_field_value(ptr, data_end,
1040                                    "level", tmpstr, sizeof(tmpstr));
1041         if (!t && !strcmp(tmpstr, "error")) {
1042             if (!ff_amf_get_field_value(ptr, data_end,
1043                                         "description", tmpstr, sizeof(tmpstr)))
1044                 av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
1045             return -1;
1046         }
1047         t = ff_amf_get_field_value(ptr, data_end,
1048                 "code", tmpstr, sizeof(tmpstr));
1049         if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
1050         if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
1051         if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
1052         if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
1053     } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) {
1054         if ((ret = gen_check_bw(s, rt)) < 0)
1055             return ret;
1056     }
1057
1058     return 0;
1059 }
1060
1061 /**
1062  * Parse received packet and possibly perform some action depending on
1063  * the packet contents.
1064  * @return 0 for no errors, negative values for serious errors which prevent
1065  *         further communications, positive values for uncritical errors
1066  */
1067 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
1068 {
1069     int ret;
1070
1071 #ifdef DEBUG
1072     ff_rtmp_packet_dump(s, pkt);
1073 #endif
1074
1075     switch (pkt->type) {
1076     case RTMP_PT_CHUNK_SIZE:
1077         if ((ret = handle_chunk_size(s, pkt)) < 0)
1078             return ret;
1079         break;
1080     case RTMP_PT_PING:
1081         if ((ret = handle_ping(s, pkt)) < 0)
1082             return ret;
1083         break;
1084     case RTMP_PT_CLIENT_BW:
1085         if ((ret = handle_client_bw(s, pkt)) < 0)
1086             return ret;
1087         break;
1088     case RTMP_PT_SERVER_BW:
1089         if ((ret = handle_server_bw(s, pkt)) < 0)
1090             return ret;
1091         break;
1092     case RTMP_PT_INVOKE:
1093         if ((ret = handle_invoke(s, pkt)) < 0)
1094             return ret;
1095         break;
1096     case RTMP_PT_VIDEO:
1097     case RTMP_PT_AUDIO:
1098         /* Audio and Video packets are parsed in get_packet() */
1099         break;
1100     default:
1101         av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
1102         break;
1103     }
1104     return 0;
1105 }
1106
1107 /**
1108  * Interact with the server by receiving and sending RTMP packets until
1109  * there is some significant data (media data or expected status notification).
1110  *
1111  * @param s          reading context
1112  * @param for_header non-zero value tells function to work until it
1113  * gets notification from the server that playing has been started,
1114  * otherwise function will work until some media data is received (or
1115  * an error happens)
1116  * @return 0 for successful operation, negative value in case of error
1117  */
1118 static int get_packet(URLContext *s, int for_header)
1119 {
1120     RTMPContext *rt = s->priv_data;
1121     int ret;
1122     uint8_t *p;
1123     const uint8_t *next;
1124     uint32_t data_size;
1125     uint32_t ts, cts, pts=0;
1126
1127     if (rt->state == STATE_STOPPED)
1128         return AVERROR_EOF;
1129
1130     for (;;) {
1131         RTMPPacket rpkt = { 0 };
1132         if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
1133                                        rt->chunk_size, rt->prev_pkt[0])) <= 0) {
1134             if (ret == 0) {
1135                 return AVERROR(EAGAIN);
1136             } else {
1137                 return AVERROR(EIO);
1138             }
1139         }
1140         rt->bytes_read += ret;
1141         if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
1142             av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
1143             if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
1144                 return ret;
1145             rt->last_bytes_read = rt->bytes_read;
1146         }
1147
1148         ret = rtmp_parse_result(s, rt, &rpkt);
1149         if (ret < 0) {//serious error in current packet
1150             ff_rtmp_packet_destroy(&rpkt);
1151             return ret;
1152         }
1153         if (rt->state == STATE_STOPPED) {
1154             ff_rtmp_packet_destroy(&rpkt);
1155             return AVERROR_EOF;
1156         }
1157         if (for_header && (rt->state == STATE_PLAYING || rt->state == STATE_PUBLISHING)) {
1158             ff_rtmp_packet_destroy(&rpkt);
1159             return 0;
1160         }
1161         if (!rpkt.data_size || !rt->is_input) {
1162             ff_rtmp_packet_destroy(&rpkt);
1163             continue;
1164         }
1165         if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
1166            (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
1167             ts = rpkt.timestamp;
1168
1169             // generate packet header and put data into buffer for FLV demuxer
1170             rt->flv_off  = 0;
1171             rt->flv_size = rpkt.data_size + 15;
1172             rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
1173             bytestream_put_byte(&p, rpkt.type);
1174             bytestream_put_be24(&p, rpkt.data_size);
1175             bytestream_put_be24(&p, ts);
1176             bytestream_put_byte(&p, ts >> 24);
1177             bytestream_put_be24(&p, 0);
1178             bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
1179             bytestream_put_be32(&p, 0);
1180             ff_rtmp_packet_destroy(&rpkt);
1181             return 0;
1182         } else if (rpkt.type == RTMP_PT_METADATA) {
1183             // we got raw FLV data, make it available for FLV demuxer
1184             rt->flv_off  = 0;
1185             rt->flv_size = rpkt.data_size;
1186             rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
1187             /* rewrite timestamps */
1188             next = rpkt.data;
1189             ts = rpkt.timestamp;
1190             while (next - rpkt.data < rpkt.data_size - 11) {
1191                 next++;
1192                 data_size = bytestream_get_be24(&next);
1193                 p=next;
1194                 cts = bytestream_get_be24(&next);
1195                 cts |= bytestream_get_byte(&next) << 24;
1196                 if (pts==0)
1197                     pts=cts;
1198                 ts += cts - pts;
1199                 pts = cts;
1200                 bytestream_put_be24(&p, ts);
1201                 bytestream_put_byte(&p, ts >> 24);
1202                 next += data_size + 3 + 4;
1203             }
1204             memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
1205             ff_rtmp_packet_destroy(&rpkt);
1206             return 0;
1207         }
1208         ff_rtmp_packet_destroy(&rpkt);
1209     }
1210 }
1211
1212 static int rtmp_close(URLContext *h)
1213 {
1214     RTMPContext *rt = h->priv_data;
1215     int ret = 0;
1216
1217     if (!rt->is_input) {
1218         rt->flv_data = NULL;
1219         if (rt->out_pkt.data_size)
1220             ff_rtmp_packet_destroy(&rt->out_pkt);
1221         if (rt->state > STATE_FCPUBLISH)
1222             ret = gen_fcunpublish_stream(h, rt);
1223     }
1224     if (rt->state > STATE_HANDSHAKED)
1225         ret = gen_delete_stream(h, rt);
1226
1227     av_freep(&rt->flv_data);
1228     ffurl_close(rt->stream);
1229     return ret;
1230 }
1231
1232 /**
1233  * Open RTMP connection and verify that the stream can be played.
1234  *
1235  * URL syntax: rtmp://server[:port][/app][/playpath]
1236  *             where 'app' is first one or two directories in the path
1237  *             (e.g. /ondemand/, /flash/live/, etc.)
1238  *             and 'playpath' is a file name (the rest of the path,
1239  *             may be prefixed with "mp4:")
1240  */
1241 static int rtmp_open(URLContext *s, const char *uri, int flags)
1242 {
1243     RTMPContext *rt = s->priv_data;
1244     char proto[8], hostname[256], path[1024], *fname;
1245     char *old_app;
1246     uint8_t buf[2048];
1247     int port;
1248     AVDictionary *opts = NULL;
1249     int ret;
1250
1251     rt->is_input = !(flags & AVIO_FLAG_WRITE);
1252
1253     av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
1254                  path, sizeof(path), s->filename);
1255
1256     if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
1257         if (!strcmp(proto, "rtmpts"))
1258             av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
1259
1260         /* open the http tunneling connection */
1261         ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
1262     } else if (!strcmp(proto, "rtmps")) {
1263         /* open the tls connection */
1264         if (port < 0)
1265             port = RTMPS_DEFAULT_PORT;
1266         ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
1267     } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
1268         if (!strcmp(proto, "rtmpte"))
1269             av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
1270
1271         /* open the encrypted connection */
1272         ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
1273         rt->encrypted = 1;
1274     } else {
1275         /* open the tcp connection */
1276         if (port < 0)
1277             port = RTMP_DEFAULT_PORT;
1278         ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
1279     }
1280
1281     if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
1282                           &s->interrupt_callback, &opts)) < 0) {
1283         av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
1284         goto fail;
1285     }
1286
1287     rt->state = STATE_START;
1288     if ((ret = rtmp_handshake(s, rt)) < 0)
1289         goto fail;
1290
1291     rt->chunk_size = 128;
1292     rt->state = STATE_HANDSHAKED;
1293
1294     // Keep the application name when it has been defined by the user.
1295     old_app = rt->app;
1296
1297     rt->app = av_malloc(APP_MAX_LENGTH);
1298     if (!rt->app) {
1299         ret = AVERROR(ENOMEM);
1300         goto fail;
1301     }
1302
1303     //extract "app" part from path
1304     if (!strncmp(path, "/ondemand/", 10)) {
1305         fname = path + 10;
1306         memcpy(rt->app, "ondemand", 9);
1307     } else {
1308         char *next = *path ? path + 1 : path;
1309         char *p = strchr(next, '/');
1310         if (!p) {
1311             fname = next;
1312             rt->app[0] = '\0';
1313         } else {
1314             // make sure we do not mismatch a playpath for an application instance
1315             char *c = strchr(p + 1, ':');
1316             fname = strchr(p + 1, '/');
1317             if (!fname || (c && c < fname)) {
1318                 fname = p + 1;
1319                 av_strlcpy(rt->app, path + 1, p - path);
1320             } else {
1321                 fname++;
1322                 av_strlcpy(rt->app, path + 1, fname - path - 1);
1323             }
1324         }
1325     }
1326
1327     if (old_app) {
1328         // The name of application has been defined by the user, override it.
1329         av_free(rt->app);
1330         rt->app = old_app;
1331     }
1332
1333     if (!rt->playpath) {
1334         int len = strlen(fname);
1335
1336         rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
1337         if (!rt->playpath) {
1338             ret = AVERROR(ENOMEM);
1339             goto fail;
1340         }
1341
1342         if (!strchr(fname, ':') && len >= 4 &&
1343             (!strcmp(fname + len - 4, ".f4v") ||
1344              !strcmp(fname + len - 4, ".mp4"))) {
1345             memcpy(rt->playpath, "mp4:", 5);
1346         } else if (len >= 4 && !strcmp(fname + len - 4, ".flv")) {
1347             fname[len - 4] = '\0';
1348         } else {
1349             rt->playpath[0] = 0;
1350         }
1351         strncat(rt->playpath, fname, PLAYPATH_MAX_LENGTH - 5);
1352     }
1353
1354     if (!rt->tcurl) {
1355         rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
1356         if (!rt->tcurl) {
1357             ret = AVERROR(ENOMEM);
1358             goto fail;
1359         }
1360         ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
1361                     port, "/%s", rt->app);
1362     }
1363
1364     if (!rt->flashver) {
1365         rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
1366         if (!rt->flashver) {
1367             ret = AVERROR(ENOMEM);
1368             goto fail;
1369         }
1370         if (rt->is_input) {
1371             snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
1372                     RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
1373                     RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
1374         } else {
1375             snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
1376                     "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
1377         }
1378     }
1379
1380     rt->client_report_size = 1048576;
1381     rt->bytes_read = 0;
1382     rt->last_bytes_read = 0;
1383     rt->server_bw = 2500000;
1384
1385     av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
1386            proto, path, rt->app, rt->playpath);
1387     if ((ret = gen_connect(s, rt)) < 0)
1388         goto fail;
1389
1390     do {
1391         ret = get_packet(s, 1);
1392     } while (ret == EAGAIN);
1393     if (ret < 0)
1394         goto fail;
1395
1396     if (rt->is_input) {
1397         // generate FLV header for demuxer
1398         rt->flv_size = 13;
1399         rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
1400         rt->flv_off  = 0;
1401         memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
1402     } else {
1403         rt->flv_size = 0;
1404         rt->flv_data = NULL;
1405         rt->flv_off  = 0;
1406         rt->skip_bytes = 13;
1407     }
1408
1409     s->max_packet_size = rt->stream->max_packet_size;
1410     s->is_streamed     = 1;
1411     return 0;
1412
1413 fail:
1414     av_dict_free(&opts);
1415     rtmp_close(s);
1416     return ret;
1417 }
1418
1419 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
1420 {
1421     RTMPContext *rt = s->priv_data;
1422     int orig_size = size;
1423     int ret;
1424
1425     while (size > 0) {
1426         int data_left = rt->flv_size - rt->flv_off;
1427
1428         if (data_left >= size) {
1429             memcpy(buf, rt->flv_data + rt->flv_off, size);
1430             rt->flv_off += size;
1431             return orig_size;
1432         }
1433         if (data_left > 0) {
1434             memcpy(buf, rt->flv_data + rt->flv_off, data_left);
1435             buf  += data_left;
1436             size -= data_left;
1437             rt->flv_off = rt->flv_size;
1438             return data_left;
1439         }
1440         if ((ret = get_packet(s, 0)) < 0)
1441            return ret;
1442     }
1443     return orig_size;
1444 }
1445
1446 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
1447 {
1448     RTMPContext *rt = s->priv_data;
1449     int size_temp = size;
1450     int pktsize, pkttype;
1451     uint32_t ts;
1452     const uint8_t *buf_temp = buf;
1453     uint8_t c;
1454     int ret;
1455
1456     do {
1457         if (rt->skip_bytes) {
1458             int skip = FFMIN(rt->skip_bytes, size_temp);
1459             buf_temp       += skip;
1460             size_temp      -= skip;
1461             rt->skip_bytes -= skip;
1462             continue;
1463         }
1464
1465         if (rt->flv_header_bytes < 11) {
1466             const uint8_t *header = rt->flv_header;
1467             int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
1468             bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
1469             rt->flv_header_bytes += copy;
1470             size_temp            -= copy;
1471             if (rt->flv_header_bytes < 11)
1472                 break;
1473
1474             pkttype = bytestream_get_byte(&header);
1475             pktsize = bytestream_get_be24(&header);
1476             ts = bytestream_get_be24(&header);
1477             ts |= bytestream_get_byte(&header) << 24;
1478             bytestream_get_be24(&header);
1479             rt->flv_size = pktsize;
1480
1481             //force 12bytes header
1482             if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
1483                 pkttype == RTMP_PT_NOTIFY) {
1484                 if (pkttype == RTMP_PT_NOTIFY)
1485                     pktsize += 16;
1486                 rt->prev_pkt[1][RTMP_SOURCE_CHANNEL].channel_id = 0;
1487             }
1488
1489             //this can be a big packet, it's better to send it right here
1490             if ((ret = ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL,
1491                                              pkttype, ts, pktsize)) < 0)
1492                 return ret;
1493
1494             rt->out_pkt.extra = rt->main_channel_id;
1495             rt->flv_data = rt->out_pkt.data;
1496
1497             if (pkttype == RTMP_PT_NOTIFY)
1498                 ff_amf_write_string(&rt->flv_data, "@setDataFrame");
1499         }
1500
1501         if (rt->flv_size - rt->flv_off > size_temp) {
1502             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
1503             rt->flv_off += size_temp;
1504             size_temp = 0;
1505         } else {
1506             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
1507             size_temp   -= rt->flv_size - rt->flv_off;
1508             rt->flv_off += rt->flv_size - rt->flv_off;
1509         }
1510
1511         if (rt->flv_off == rt->flv_size) {
1512             rt->skip_bytes = 4;
1513
1514             if ((ret = ff_rtmp_packet_write(rt->stream, &rt->out_pkt,
1515                                             rt->chunk_size, rt->prev_pkt[1])) < 0)
1516                 return ret;
1517             ff_rtmp_packet_destroy(&rt->out_pkt);
1518             rt->flv_size = 0;
1519             rt->flv_off = 0;
1520             rt->flv_header_bytes = 0;
1521             rt->flv_nb_packets++;
1522         }
1523     } while (buf_temp - buf < size);
1524
1525     if (rt->flv_nb_packets < rt->flush_interval)
1526         return size;
1527     rt->flv_nb_packets = 0;
1528
1529     /* set stream into nonblocking mode */
1530     rt->stream->flags |= AVIO_FLAG_NONBLOCK;
1531
1532     /* try to read one byte from the stream */
1533     ret = ffurl_read(rt->stream, &c, 1);
1534
1535     /* switch the stream back into blocking mode */
1536     rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
1537
1538     if (ret == AVERROR(EAGAIN)) {
1539         /* no incoming data to handle */
1540         return size;
1541     } else if (ret < 0) {
1542         return ret;
1543     } else if (ret == 1) {
1544         RTMPPacket rpkt = { 0 };
1545
1546         if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
1547                                                 rt->chunk_size,
1548                                                 rt->prev_pkt[0], c)) <= 0)
1549              return ret;
1550
1551         if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
1552             return ret;
1553
1554         ff_rtmp_packet_destroy(&rpkt);
1555     }
1556
1557     return size;
1558 }
1559
1560 #define OFFSET(x) offsetof(RTMPContext, x)
1561 #define DEC AV_OPT_FLAG_DECODING_PARAM
1562 #define ENC AV_OPT_FLAG_ENCODING_PARAM
1563
1564 static const AVOption rtmp_options[] = {
1565     {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1566     {"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},
1567     {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1568     {"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},
1569     {"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},
1570     {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
1571     {"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"},
1572     {"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"},
1573     {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {0}, 0, 0, DEC, "rtmp_live"},
1574     {"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},
1575     {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1576     {"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},
1577     {"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},
1578     { NULL },
1579 };
1580
1581 static const AVClass rtmp_class = {
1582     .class_name = "rtmp",
1583     .item_name  = av_default_item_name,
1584     .option     = rtmp_options,
1585     .version    = LIBAVUTIL_VERSION_INT,
1586 };
1587
1588 URLProtocol ff_rtmp_protocol = {
1589     .name           = "rtmp",
1590     .url_open       = rtmp_open,
1591     .url_read       = rtmp_read,
1592     .url_write      = rtmp_write,
1593     .url_close      = rtmp_close,
1594     .priv_data_size = sizeof(RTMPContext),
1595     .flags          = URL_PROTOCOL_FLAG_NETWORK,
1596     .priv_data_class= &rtmp_class,
1597 };
1598
1599 static const AVClass rtmpe_class = {
1600     .class_name = "rtmpe",
1601     .item_name  = av_default_item_name,
1602     .option     = rtmp_options,
1603     .version    = LIBAVUTIL_VERSION_INT,
1604 };
1605
1606 URLProtocol ff_rtmpe_protocol = {
1607     .name            = "rtmpe",
1608     .url_open        = rtmp_open,
1609     .url_read        = rtmp_read,
1610     .url_write       = rtmp_write,
1611     .url_close       = rtmp_close,
1612     .priv_data_size  = sizeof(RTMPContext),
1613     .flags           = URL_PROTOCOL_FLAG_NETWORK,
1614     .priv_data_class = &rtmpe_class,
1615 };
1616
1617 static const AVClass rtmps_class = {
1618     .class_name = "rtmps",
1619     .item_name  = av_default_item_name,
1620     .option     = rtmp_options,
1621     .version    = LIBAVUTIL_VERSION_INT,
1622 };
1623
1624 URLProtocol ff_rtmps_protocol = {
1625     .name            = "rtmps",
1626     .url_open        = rtmp_open,
1627     .url_read        = rtmp_read,
1628     .url_write       = rtmp_write,
1629     .url_close       = rtmp_close,
1630     .priv_data_size  = sizeof(RTMPContext),
1631     .flags           = URL_PROTOCOL_FLAG_NETWORK,
1632     .priv_data_class = &rtmps_class,
1633 };
1634
1635 static const AVClass rtmpt_class = {
1636     .class_name = "rtmpt",
1637     .item_name  = av_default_item_name,
1638     .option     = rtmp_options,
1639     .version    = LIBAVUTIL_VERSION_INT,
1640 };
1641
1642 URLProtocol ff_rtmpt_protocol = {
1643     .name            = "rtmpt",
1644     .url_open        = rtmp_open,
1645     .url_read        = rtmp_read,
1646     .url_write       = rtmp_write,
1647     .url_close       = rtmp_close,
1648     .priv_data_size  = sizeof(RTMPContext),
1649     .flags           = URL_PROTOCOL_FLAG_NETWORK,
1650     .priv_data_class = &rtmpt_class,
1651 };
1652
1653 static const AVClass rtmpte_class = {
1654     .class_name = "rtmpte",
1655     .item_name  = av_default_item_name,
1656     .option     = rtmp_options,
1657     .version    = LIBAVUTIL_VERSION_INT,
1658 };
1659
1660 URLProtocol ff_rtmpte_protocol = {
1661     .name            = "rtmpte",
1662     .url_open        = rtmp_open,
1663     .url_read        = rtmp_read,
1664     .url_write       = rtmp_write,
1665     .url_close       = rtmp_close,
1666     .priv_data_size  = sizeof(RTMPContext),
1667     .flags           = URL_PROTOCOL_FLAG_NETWORK,
1668     .priv_data_class = &rtmpte_class,
1669 };
1670
1671 static const AVClass rtmpts_class = {
1672     .class_name = "rtmpts",
1673     .item_name  = av_default_item_name,
1674     .option     = rtmp_options,
1675     .version    = LIBAVUTIL_VERSION_INT,
1676 };
1677
1678 URLProtocol ff_rtmpts_protocol = {
1679     .name            = "rtmpts",
1680     .url_open        = rtmp_open,
1681     .url_read        = rtmp_read,
1682     .url_write       = rtmp_write,
1683     .url_close       = rtmp_close,
1684     .priv_data_size  = sizeof(RTMPContext),
1685     .flags           = URL_PROTOCOL_FLAG_NETWORK,
1686     .priv_data_class = &rtmpts_class,
1687 };