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