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