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