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