rtmpproto: Pass the 'live' parameter in the right unit
[ffmpeg.git] / libavformat / rtmpproto.c
1 /*
2  * RTMP network protocol
3  * Copyright (c) 2009 Konstantin 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/base64.h"
30 #include "libavutil/intfloat.h"
31 #include "libavutil/lfg.h"
32 #include "libavutil/md5.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/random_seed.h"
35 #include "libavutil/sha.h"
36 #include "avformat.h"
37 #include "internal.h"
38
39 #include "network.h"
40
41 #include "flv.h"
42 #include "rtmp.h"
43 #include "rtmpcrypt.h"
44 #include "rtmppkt.h"
45 #include "url.h"
46
47 #if CONFIG_ZLIB
48 #include <zlib.h>
49 #endif
50
51 #define APP_MAX_LENGTH 128
52 #define PLAYPATH_MAX_LENGTH 256
53 #define TCURL_MAX_LENGTH 512
54 #define FLASHVER_MAX_LENGTH 64
55 #define RTMP_PKTDATA_DEFAULT_SIZE 4096
56 #define RTMP_HEADER 11
57
58 /** RTMP protocol handler state */
59 typedef enum {
60     STATE_START,      ///< client has not done anything yet
61     STATE_HANDSHAKED, ///< client has performed handshake
62     STATE_FCPUBLISH,  ///< client FCPublishing stream (for output)
63     STATE_PLAYING,    ///< client has started receiving multimedia data from server
64     STATE_SEEKING,    ///< client has started the seek operation. Back on STATE_PLAYING when the time comes
65     STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
66     STATE_RECEIVING,  ///< received a publish command (for input)
67     STATE_SENDING,    ///< received a play command (for output)
68     STATE_STOPPED,    ///< the broadcast has been stopped
69 } ClientState;
70
71 typedef struct TrackedMethod {
72     char *name;
73     int id;
74 } TrackedMethod;
75
76 /** protocol handler context */
77 typedef struct RTMPContext {
78     const AVClass *class;
79     URLContext*   stream;                     ///< TCP stream used in interactions with RTMP server
80     RTMPPacket    prev_pkt[2][RTMP_CHANNELS]; ///< packet history used when reading and sending packets ([0] for reading, [1] for writing)
81     int           in_chunk_size;              ///< size of the chunks incoming RTMP packets are divided into
82     int           out_chunk_size;             ///< size of the chunks outgoing RTMP packets are divided into
83     int           is_input;                   ///< input/output flag
84     char          *playpath;                  ///< stream identifier to play (with possible "mp4:" prefix)
85     int           live;                       ///< 0: recorded, -1: live, -2: both
86     char          *app;                       ///< name of application
87     char          *conn;                      ///< append arbitrary AMF data to the Connect message
88     ClientState   state;                      ///< current state
89     int           stream_id;                  ///< ID assigned by the server for the stream
90     uint8_t*      flv_data;                   ///< buffer with data for demuxer
91     int           flv_size;                   ///< current buffer size
92     int           flv_off;                    ///< number of bytes read from current buffer
93     int           flv_nb_packets;             ///< number of flv packets published
94     RTMPPacket    out_pkt;                    ///< rtmp packet, created from flv a/v or metadata (for output)
95     uint32_t      client_report_size;         ///< number of bytes after which client should report to server
96     uint32_t      bytes_read;                 ///< number of bytes read from server
97     uint32_t      last_bytes_read;            ///< number of bytes read last reported to server
98     int           skip_bytes;                 ///< number of bytes to skip from the input FLV stream in the next write call
99     uint8_t       flv_header[RTMP_HEADER];    ///< partial incoming flv packet header
100     int           flv_header_bytes;           ///< number of initialized bytes in flv_header
101     int           nb_invokes;                 ///< keeps track of invoke messages
102     char*         tcurl;                      ///< url of the target stream
103     char*         flashver;                   ///< version of the flash plugin
104     char*         swfhash;                    ///< SHA256 hash of the decompressed SWF file (32 bytes)
105     int           swfhash_len;                ///< length of the SHA256 hash
106     int           swfsize;                    ///< size of the decompressed SWF file
107     char*         swfurl;                     ///< url of the swf player
108     char*         swfverify;                  ///< URL to player swf file, compute hash/size automatically
109     char          swfverification[42];        ///< hash of the SWF verification
110     char*         pageurl;                    ///< url of the web page
111     char*         subscribe;                  ///< name of live stream to subscribe
112     int           server_bw;                  ///< server bandwidth
113     int           client_buffer_time;         ///< client buffer time in ms
114     int           flush_interval;             ///< number of packets flushed in the same request (RTMPT only)
115     int           encrypted;                  ///< use an encrypted connection (RTMPE only)
116     TrackedMethod*tracked_methods;            ///< tracked methods buffer
117     int           nb_tracked_methods;         ///< number of tracked methods
118     int           tracked_methods_size;       ///< size of the tracked methods buffer
119     int           listen;                     ///< listen mode flag
120     int           listen_timeout;             ///< listen timeout to wait for new connections
121     int           nb_streamid;                ///< The next stream id to return on createStream calls
122     char          username[50];
123     char          password[50];
124     char          auth_params[500];
125     int           do_reconnect;
126     int           auth_tried;
127 } RTMPContext;
128
129 #define PLAYER_KEY_OPEN_PART_LEN 30   ///< length of partial key used for first client digest signing
130 /** Client key used for digest signing */
131 static const uint8_t rtmp_player_key[] = {
132     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
133     'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
134
135     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
136     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
137     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
138 };
139
140 #define SERVER_KEY_OPEN_PART_LEN 36   ///< length of partial key used for first server digest signing
141 /** Key used for RTMP server digest signing */
142 static const uint8_t rtmp_server_key[] = {
143     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
144     'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
145     'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
146
147     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
148     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
149     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
150 };
151
152 static int add_tracked_method(RTMPContext *rt, const char *name, int id)
153 {
154     int err;
155
156     if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
157         rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
158         if ((err = av_reallocp(&rt->tracked_methods, rt->tracked_methods_size *
159                                sizeof(*rt->tracked_methods))) < 0) {
160             rt->nb_tracked_methods = 0;
161             rt->tracked_methods_size = 0;
162             return err;
163         }
164     }
165
166     rt->tracked_methods[rt->nb_tracked_methods].name = av_strdup(name);
167     if (!rt->tracked_methods[rt->nb_tracked_methods].name)
168         return AVERROR(ENOMEM);
169     rt->tracked_methods[rt->nb_tracked_methods].id = id;
170     rt->nb_tracked_methods++;
171
172     return 0;
173 }
174
175 static void del_tracked_method(RTMPContext *rt, int index)
176 {
177     memmove(&rt->tracked_methods[index], &rt->tracked_methods[index + 1],
178             sizeof(*rt->tracked_methods) * (rt->nb_tracked_methods - index - 1));
179     rt->nb_tracked_methods--;
180 }
181
182 static int find_tracked_method(URLContext *s, RTMPPacket *pkt, int offset,
183                                char **tracked_method)
184 {
185     RTMPContext *rt = s->priv_data;
186     GetByteContext gbc;
187     double pkt_id;
188     int ret;
189     int i;
190
191     bytestream2_init(&gbc, pkt->data + offset, pkt->size - offset);
192     if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
193         return ret;
194
195     for (i = 0; i < rt->nb_tracked_methods; i++) {
196         if (rt->tracked_methods[i].id != pkt_id)
197             continue;
198
199         *tracked_method = rt->tracked_methods[i].name;
200         del_tracked_method(rt, i);
201         break;
202     }
203
204     return 0;
205 }
206
207 static void free_tracked_methods(RTMPContext *rt)
208 {
209     int i;
210
211     for (i = 0; i < rt->nb_tracked_methods; i ++)
212         av_free(rt->tracked_methods[i].name);
213     av_free(rt->tracked_methods);
214     rt->tracked_methods      = NULL;
215     rt->tracked_methods_size = 0;
216     rt->nb_tracked_methods   = 0;
217 }
218
219 static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
220 {
221     int ret;
222
223     if (pkt->type == RTMP_PT_INVOKE && track) {
224         GetByteContext gbc;
225         char name[128];
226         double pkt_id;
227         int len;
228
229         bytestream2_init(&gbc, pkt->data, pkt->size);
230         if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0)
231             goto fail;
232
233         if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
234             goto fail;
235
236         if ((ret = add_tracked_method(rt, name, pkt_id)) < 0)
237             goto fail;
238     }
239
240     ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
241                                rt->prev_pkt[1]);
242 fail:
243     ff_rtmp_packet_destroy(pkt);
244     return ret;
245 }
246
247 static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)
248 {
249     char *field, *value;
250     char type;
251
252     /* The type must be B for Boolean, N for number, S for string, O for
253      * object, or Z for null. For Booleans the data must be either 0 or 1 for
254      * FALSE or TRUE, respectively. Likewise for Objects the data must be
255      * 0 or 1 to end or begin an object, respectively. Data items in subobjects
256      * may be named, by prefixing the type with 'N' and specifying the name
257      * before the value (ie. NB:myFlag:1). This option may be used multiple times
258      * to construct arbitrary AMF sequences. */
259     if (param[0] && param[1] == ':') {
260         type = param[0];
261         value = param + 2;
262     } else if (param[0] == 'N' && param[1] && param[2] == ':') {
263         type = param[1];
264         field = param + 3;
265         value = strchr(field, ':');
266         if (!value)
267             goto fail;
268         *value = '\0';
269         value++;
270
271         if (!field || !value)
272             goto fail;
273
274         ff_amf_write_field_name(p, field);
275     } else {
276         goto fail;
277     }
278
279     switch (type) {
280     case 'B':
281         ff_amf_write_bool(p, value[0] != '0');
282         break;
283     case 'S':
284         ff_amf_write_string(p, value);
285         break;
286     case 'N':
287         ff_amf_write_number(p, strtod(value, NULL));
288         break;
289     case 'Z':
290         ff_amf_write_null(p);
291         break;
292     case 'O':
293         if (value[0] != '0')
294             ff_amf_write_object_start(p);
295         else
296             ff_amf_write_object_end(p);
297         break;
298     default:
299         goto fail;
300         break;
301     }
302
303     return 0;
304
305 fail:
306     av_log(s, AV_LOG_ERROR, "Invalid AMF parameter: %s\n", param);
307     return AVERROR(EINVAL);
308 }
309
310 /**
311  * Generate 'connect' call and send it to the server.
312  */
313 static int gen_connect(URLContext *s, RTMPContext *rt)
314 {
315     RTMPPacket pkt;
316     uint8_t *p;
317     int ret;
318
319     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
320                                      0, 4096)) < 0)
321         return ret;
322
323     p = pkt.data;
324
325     ff_amf_write_string(&p, "connect");
326     ff_amf_write_number(&p, ++rt->nb_invokes);
327     ff_amf_write_object_start(&p);
328     ff_amf_write_field_name(&p, "app");
329     ff_amf_write_string2(&p, rt->app, rt->auth_params);
330
331     if (!rt->is_input) {
332         ff_amf_write_field_name(&p, "type");
333         ff_amf_write_string(&p, "nonprivate");
334     }
335     ff_amf_write_field_name(&p, "flashVer");
336     ff_amf_write_string(&p, rt->flashver);
337
338     if (rt->swfurl) {
339         ff_amf_write_field_name(&p, "swfUrl");
340         ff_amf_write_string(&p, rt->swfurl);
341     }
342
343     ff_amf_write_field_name(&p, "tcUrl");
344     ff_amf_write_string2(&p, rt->tcurl, rt->auth_params);
345     if (rt->is_input) {
346         ff_amf_write_field_name(&p, "fpad");
347         ff_amf_write_bool(&p, 0);
348         ff_amf_write_field_name(&p, "capabilities");
349         ff_amf_write_number(&p, 15.0);
350
351         /* Tell the server we support all the audio codecs except
352          * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)
353          * which are unused in the RTMP protocol implementation. */
354         ff_amf_write_field_name(&p, "audioCodecs");
355         ff_amf_write_number(&p, 4071.0);
356         ff_amf_write_field_name(&p, "videoCodecs");
357         ff_amf_write_number(&p, 252.0);
358         ff_amf_write_field_name(&p, "videoFunction");
359         ff_amf_write_number(&p, 1.0);
360
361         if (rt->pageurl) {
362             ff_amf_write_field_name(&p, "pageUrl");
363             ff_amf_write_string(&p, rt->pageurl);
364         }
365     }
366     ff_amf_write_object_end(&p);
367
368     if (rt->conn) {
369         char *param = rt->conn;
370
371         // Write arbitrary AMF data to the Connect message.
372         while (param != NULL) {
373             char *sep;
374             param += strspn(param, " ");
375             if (!*param)
376                 break;
377             sep = strchr(param, ' ');
378             if (sep)
379                 *sep = '\0';
380             if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) {
381                 // Invalid AMF parameter.
382                 ff_rtmp_packet_destroy(&pkt);
383                 return ret;
384             }
385
386             if (sep)
387                 param = sep + 1;
388             else
389                 break;
390         }
391     }
392
393     pkt.size = p - pkt.data;
394
395     return rtmp_send_packet(rt, &pkt, 1);
396 }
397
398 static int read_connect(URLContext *s, RTMPContext *rt)
399 {
400     RTMPPacket pkt = { 0 };
401     uint8_t *p;
402     const uint8_t *cp;
403     int ret;
404     char command[64];
405     int stringlen;
406     double seqnum;
407     uint8_t tmpstr[256];
408     GetByteContext gbc;
409
410     if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
411                                    rt->prev_pkt[0])) < 0)
412         return ret;
413     cp = pkt.data;
414     bytestream2_init(&gbc, cp, pkt.size);
415     if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) {
416         av_log(s, AV_LOG_ERROR, "Unable to read command string\n");
417         ff_rtmp_packet_destroy(&pkt);
418         return AVERROR_INVALIDDATA;
419     }
420     if (strcmp(command, "connect")) {
421         av_log(s, AV_LOG_ERROR, "Expecting connect, got %s\n", command);
422         ff_rtmp_packet_destroy(&pkt);
423         return AVERROR_INVALIDDATA;
424     }
425     ret = ff_amf_read_number(&gbc, &seqnum);
426     if (ret)
427         av_log(s, AV_LOG_WARNING, "SeqNum not found\n");
428     /* Here one could parse an AMF Object with data as flashVers and others. */
429     ret = ff_amf_get_field_value(gbc.buffer,
430                                  gbc.buffer + bytestream2_get_bytes_left(&gbc),
431                                  "app", tmpstr, sizeof(tmpstr));
432     if (ret)
433         av_log(s, AV_LOG_WARNING, "App field not found in connect\n");
434     if (!ret && strcmp(tmpstr, rt->app))
435         av_log(s, AV_LOG_WARNING, "App field don't match up: %s <-> %s\n",
436                tmpstr, rt->app);
437     ff_rtmp_packet_destroy(&pkt);
438
439     // Send Window Acknowledgement Size (as defined in speficication)
440     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
441                                      RTMP_PT_SERVER_BW, 0, 4)) < 0)
442         return ret;
443     p = pkt.data;
444     bytestream_put_be32(&p, rt->server_bw);
445     pkt.size = p - pkt.data;
446     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
447                                rt->prev_pkt[1]);
448     ff_rtmp_packet_destroy(&pkt);
449     if (ret < 0)
450         return ret;
451     // Send Peer Bandwidth
452     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
453                                      RTMP_PT_CLIENT_BW, 0, 5)) < 0)
454         return ret;
455     p = pkt.data;
456     bytestream_put_be32(&p, rt->server_bw);
457     bytestream_put_byte(&p, 2); // dynamic
458     pkt.size = p - pkt.data;
459     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
460                                rt->prev_pkt[1]);
461     ff_rtmp_packet_destroy(&pkt);
462     if (ret < 0)
463         return ret;
464
465     // Ping request
466     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
467                                      RTMP_PT_PING, 0, 6)) < 0)
468         return ret;
469
470     p = pkt.data;
471     bytestream_put_be16(&p, 0); // 0 -> Stream Begin
472     bytestream_put_be32(&p, 0);
473     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
474                                rt->prev_pkt[1]);
475     ff_rtmp_packet_destroy(&pkt);
476     if (ret < 0)
477         return ret;
478
479     // Chunk size
480     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
481                                      RTMP_PT_CHUNK_SIZE, 0, 4)) < 0)
482         return ret;
483
484     p = pkt.data;
485     bytestream_put_be32(&p, rt->out_chunk_size);
486     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
487                                rt->prev_pkt[1]);
488     ff_rtmp_packet_destroy(&pkt);
489     if (ret < 0)
490         return ret;
491
492     // Send result_ NetConnection.Connect.Success to connect
493     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
494                                      RTMP_PT_INVOKE, 0,
495                                      RTMP_PKTDATA_DEFAULT_SIZE)) < 0)
496         return ret;
497
498     p = pkt.data;
499     ff_amf_write_string(&p, "_result");
500     ff_amf_write_number(&p, seqnum);
501
502     ff_amf_write_object_start(&p);
503     ff_amf_write_field_name(&p, "fmsVer");
504     ff_amf_write_string(&p, "FMS/3,0,1,123");
505     ff_amf_write_field_name(&p, "capabilities");
506     ff_amf_write_number(&p, 31);
507     ff_amf_write_object_end(&p);
508
509     ff_amf_write_object_start(&p);
510     ff_amf_write_field_name(&p, "level");
511     ff_amf_write_string(&p, "status");
512     ff_amf_write_field_name(&p, "code");
513     ff_amf_write_string(&p, "NetConnection.Connect.Success");
514     ff_amf_write_field_name(&p, "description");
515     ff_amf_write_string(&p, "Connection succeeded.");
516     ff_amf_write_field_name(&p, "objectEncoding");
517     ff_amf_write_number(&p, 0);
518     ff_amf_write_object_end(&p);
519
520     pkt.size = p - pkt.data;
521     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
522                                rt->prev_pkt[1]);
523     ff_rtmp_packet_destroy(&pkt);
524     if (ret < 0)
525         return ret;
526
527     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
528                                      RTMP_PT_INVOKE, 0, 30)) < 0)
529         return ret;
530     p = pkt.data;
531     ff_amf_write_string(&p, "onBWDone");
532     ff_amf_write_number(&p, 0);
533     ff_amf_write_null(&p);
534     ff_amf_write_number(&p, 8192);
535     pkt.size = p - pkt.data;
536     ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
537                                rt->prev_pkt[1]);
538     ff_rtmp_packet_destroy(&pkt);
539
540     return ret;
541 }
542
543 /**
544  * Generate 'releaseStream' call and send it to the server. It should make
545  * the server release some channel for media streams.
546  */
547 static int gen_release_stream(URLContext *s, RTMPContext *rt)
548 {
549     RTMPPacket pkt;
550     uint8_t *p;
551     int ret;
552
553     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
554                                      0, 29 + strlen(rt->playpath))) < 0)
555         return ret;
556
557     av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
558     p = pkt.data;
559     ff_amf_write_string(&p, "releaseStream");
560     ff_amf_write_number(&p, ++rt->nb_invokes);
561     ff_amf_write_null(&p);
562     ff_amf_write_string(&p, rt->playpath);
563
564     return rtmp_send_packet(rt, &pkt, 1);
565 }
566
567 /**
568  * Generate 'FCPublish' call and send it to the server. It should make
569  * the server preapare for receiving media streams.
570  */
571 static int gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
572 {
573     RTMPPacket pkt;
574     uint8_t *p;
575     int ret;
576
577     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
578                                      0, 25 + strlen(rt->playpath))) < 0)
579         return ret;
580
581     av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
582     p = pkt.data;
583     ff_amf_write_string(&p, "FCPublish");
584     ff_amf_write_number(&p, ++rt->nb_invokes);
585     ff_amf_write_null(&p);
586     ff_amf_write_string(&p, rt->playpath);
587
588     return rtmp_send_packet(rt, &pkt, 1);
589 }
590
591 /**
592  * Generate 'FCUnpublish' call and send it to the server. It should make
593  * the server destroy stream.
594  */
595 static int gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
596 {
597     RTMPPacket pkt;
598     uint8_t *p;
599     int ret;
600
601     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
602                                      0, 27 + strlen(rt->playpath))) < 0)
603         return ret;
604
605     av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
606     p = pkt.data;
607     ff_amf_write_string(&p, "FCUnpublish");
608     ff_amf_write_number(&p, ++rt->nb_invokes);
609     ff_amf_write_null(&p);
610     ff_amf_write_string(&p, rt->playpath);
611
612     return rtmp_send_packet(rt, &pkt, 0);
613 }
614
615 /**
616  * Generate 'createStream' call and send it to the server. It should make
617  * the server allocate some channel for media streams.
618  */
619 static int gen_create_stream(URLContext *s, RTMPContext *rt)
620 {
621     RTMPPacket pkt;
622     uint8_t *p;
623     int ret;
624
625     av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
626
627     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
628                                      0, 25)) < 0)
629         return ret;
630
631     p = pkt.data;
632     ff_amf_write_string(&p, "createStream");
633     ff_amf_write_number(&p, ++rt->nb_invokes);
634     ff_amf_write_null(&p);
635
636     return rtmp_send_packet(rt, &pkt, 1);
637 }
638
639
640 /**
641  * Generate 'deleteStream' call and send it to the server. It should make
642  * the server remove some channel for media streams.
643  */
644 static int gen_delete_stream(URLContext *s, RTMPContext *rt)
645 {
646     RTMPPacket pkt;
647     uint8_t *p;
648     int ret;
649
650     av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
651
652     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
653                                      0, 34)) < 0)
654         return ret;
655
656     p = pkt.data;
657     ff_amf_write_string(&p, "deleteStream");
658     ff_amf_write_number(&p, ++rt->nb_invokes);
659     ff_amf_write_null(&p);
660     ff_amf_write_number(&p, rt->stream_id);
661
662     return rtmp_send_packet(rt, &pkt, 0);
663 }
664
665 /**
666  * Generate client buffer time and send it to the server.
667  */
668 static int gen_buffer_time(URLContext *s, RTMPContext *rt)
669 {
670     RTMPPacket pkt;
671     uint8_t *p;
672     int ret;
673
674     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
675                                      1, 10)) < 0)
676         return ret;
677
678     p = pkt.data;
679     bytestream_put_be16(&p, 3);
680     bytestream_put_be32(&p, rt->stream_id);
681     bytestream_put_be32(&p, rt->client_buffer_time);
682
683     return rtmp_send_packet(rt, &pkt, 0);
684 }
685
686 /**
687  * Generate 'play' call and send it to the server, then ping the server
688  * to start actual playing.
689  */
690 static int gen_play(URLContext *s, RTMPContext *rt)
691 {
692     RTMPPacket pkt;
693     uint8_t *p;
694     int ret;
695
696     av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
697
698     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
699                                      0, 29 + strlen(rt->playpath))) < 0)
700         return ret;
701
702     pkt.extra = rt->stream_id;
703
704     p = pkt.data;
705     ff_amf_write_string(&p, "play");
706     ff_amf_write_number(&p, ++rt->nb_invokes);
707     ff_amf_write_null(&p);
708     ff_amf_write_string(&p, rt->playpath);
709     ff_amf_write_number(&p, rt->live * 1000);
710
711     return rtmp_send_packet(rt, &pkt, 1);
712 }
713
714 static int gen_seek(URLContext *s, RTMPContext *rt, int64_t timestamp)
715 {
716     RTMPPacket pkt;
717     uint8_t *p;
718     int ret;
719
720     av_log(s, AV_LOG_DEBUG, "Sending seek command for timestamp %"PRId64"\n",
721            timestamp);
722
723     if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 26)) < 0)
724         return ret;
725
726     pkt.extra = rt->stream_id;
727
728     p = pkt.data;
729     ff_amf_write_string(&p, "seek");
730     ff_amf_write_number(&p, 0); //no tracking back responses
731     ff_amf_write_null(&p); //as usual, the first null param
732     ff_amf_write_number(&p, timestamp); //where we want to jump
733
734     return rtmp_send_packet(rt, &pkt, 1);
735 }
736
737 /**
738  * Generate 'publish' call and send it to the server.
739  */
740 static int gen_publish(URLContext *s, RTMPContext *rt)
741 {
742     RTMPPacket pkt;
743     uint8_t *p;
744     int ret;
745
746     av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
747
748     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
749                                      0, 30 + strlen(rt->playpath))) < 0)
750         return ret;
751
752     pkt.extra = rt->stream_id;
753
754     p = pkt.data;
755     ff_amf_write_string(&p, "publish");
756     ff_amf_write_number(&p, ++rt->nb_invokes);
757     ff_amf_write_null(&p);
758     ff_amf_write_string(&p, rt->playpath);
759     ff_amf_write_string(&p, "live");
760
761     return rtmp_send_packet(rt, &pkt, 1);
762 }
763
764 /**
765  * Generate ping reply and send it to the server.
766  */
767 static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
768 {
769     RTMPPacket pkt;
770     uint8_t *p;
771     int ret;
772
773     if (ppkt->size < 6) {
774         av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
775                ppkt->size);
776         return AVERROR_INVALIDDATA;
777     }
778
779     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
780                                      ppkt->timestamp + 1, 6)) < 0)
781         return ret;
782
783     p = pkt.data;
784     bytestream_put_be16(&p, 7);
785     bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
786
787     return rtmp_send_packet(rt, &pkt, 0);
788 }
789
790 /**
791  * Generate SWF verification message and send it to the server.
792  */
793 static int gen_swf_verification(URLContext *s, RTMPContext *rt)
794 {
795     RTMPPacket pkt;
796     uint8_t *p;
797     int ret;
798
799     av_log(s, AV_LOG_DEBUG, "Sending SWF verification...\n");
800     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
801                                      0, 44)) < 0)
802         return ret;
803
804     p = pkt.data;
805     bytestream_put_be16(&p, 27);
806     memcpy(p, rt->swfverification, 42);
807
808     return rtmp_send_packet(rt, &pkt, 0);
809 }
810
811 /**
812  * Generate server bandwidth message and send it to the server.
813  */
814 static int gen_server_bw(URLContext *s, RTMPContext *rt)
815 {
816     RTMPPacket pkt;
817     uint8_t *p;
818     int ret;
819
820     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_SERVER_BW,
821                                      0, 4)) < 0)
822         return ret;
823
824     p = pkt.data;
825     bytestream_put_be32(&p, rt->server_bw);
826
827     return rtmp_send_packet(rt, &pkt, 0);
828 }
829
830 /**
831  * Generate check bandwidth message and send it to the server.
832  */
833 static int gen_check_bw(URLContext *s, RTMPContext *rt)
834 {
835     RTMPPacket pkt;
836     uint8_t *p;
837     int ret;
838
839     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
840                                      0, 21)) < 0)
841         return ret;
842
843     p = pkt.data;
844     ff_amf_write_string(&p, "_checkbw");
845     ff_amf_write_number(&p, ++rt->nb_invokes);
846     ff_amf_write_null(&p);
847
848     return rtmp_send_packet(rt, &pkt, 1);
849 }
850
851 /**
852  * Generate report on bytes read so far and send it to the server.
853  */
854 static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
855 {
856     RTMPPacket pkt;
857     uint8_t *p;
858     int ret;
859
860     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ,
861                                      ts, 4)) < 0)
862         return ret;
863
864     p = pkt.data;
865     bytestream_put_be32(&p, rt->bytes_read);
866
867     return rtmp_send_packet(rt, &pkt, 0);
868 }
869
870 static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt,
871                                   const char *subscribe)
872 {
873     RTMPPacket pkt;
874     uint8_t *p;
875     int ret;
876
877     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
878                                      0, 27 + strlen(subscribe))) < 0)
879         return ret;
880
881     p = pkt.data;
882     ff_amf_write_string(&p, "FCSubscribe");
883     ff_amf_write_number(&p, ++rt->nb_invokes);
884     ff_amf_write_null(&p);
885     ff_amf_write_string(&p, subscribe);
886
887     return rtmp_send_packet(rt, &pkt, 1);
888 }
889
890 int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap,
891                         const uint8_t *key, int keylen, uint8_t *dst)
892 {
893     struct AVSHA *sha;
894     uint8_t hmac_buf[64+32] = {0};
895     int i;
896
897     sha = av_sha_alloc();
898     if (!sha)
899         return AVERROR(ENOMEM);
900
901     if (keylen < 64) {
902         memcpy(hmac_buf, key, keylen);
903     } else {
904         av_sha_init(sha, 256);
905         av_sha_update(sha,key, keylen);
906         av_sha_final(sha, hmac_buf);
907     }
908     for (i = 0; i < 64; i++)
909         hmac_buf[i] ^= HMAC_IPAD_VAL;
910
911     av_sha_init(sha, 256);
912     av_sha_update(sha, hmac_buf, 64);
913     if (gap <= 0) {
914         av_sha_update(sha, src, len);
915     } else { //skip 32 bytes used for storing digest
916         av_sha_update(sha, src, gap);
917         av_sha_update(sha, src + gap + 32, len - gap - 32);
918     }
919     av_sha_final(sha, hmac_buf + 64);
920
921     for (i = 0; i < 64; i++)
922         hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad
923     av_sha_init(sha, 256);
924     av_sha_update(sha, hmac_buf, 64+32);
925     av_sha_final(sha, dst);
926
927     av_free(sha);
928
929     return 0;
930 }
931
932 int ff_rtmp_calc_digest_pos(const uint8_t *buf, int off, int mod_val,
933                             int add_val)
934 {
935     int i, digest_pos = 0;
936
937     for (i = 0; i < 4; i++)
938         digest_pos += buf[i + off];
939     digest_pos = digest_pos % mod_val + add_val;
940
941     return digest_pos;
942 }
943
944 /**
945  * Put HMAC-SHA2 digest of packet data (except for the bytes where this digest
946  * will be stored) into that packet.
947  *
948  * @param buf handshake data (1536 bytes)
949  * @param encrypted use an encrypted connection (RTMPE)
950  * @return offset to the digest inside input data
951  */
952 static int rtmp_handshake_imprint_with_digest(uint8_t *buf, int encrypted)
953 {
954     int ret, digest_pos;
955
956     if (encrypted)
957         digest_pos = ff_rtmp_calc_digest_pos(buf, 772, 728, 776);
958     else
959         digest_pos = ff_rtmp_calc_digest_pos(buf, 8, 728, 12);
960
961     ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
962                               rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
963                               buf + digest_pos);
964     if (ret < 0)
965         return ret;
966
967     return digest_pos;
968 }
969
970 /**
971  * Verify that the received server response has the expected digest value.
972  *
973  * @param buf handshake data received from the server (1536 bytes)
974  * @param off position to search digest offset from
975  * @return 0 if digest is valid, digest position otherwise
976  */
977 static int rtmp_validate_digest(uint8_t *buf, int off)
978 {
979     uint8_t digest[32];
980     int ret, digest_pos;
981
982     digest_pos = ff_rtmp_calc_digest_pos(buf, off, 728, off + 4);
983
984     ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
985                               rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
986                               digest);
987     if (ret < 0)
988         return ret;
989
990     if (!memcmp(digest, buf + digest_pos, 32))
991         return digest_pos;
992     return 0;
993 }
994
995 static int rtmp_calc_swf_verification(URLContext *s, RTMPContext *rt,
996                                       uint8_t *buf)
997 {
998     uint8_t *p;
999     int ret;
1000
1001     if (rt->swfhash_len != 32) {
1002         av_log(s, AV_LOG_ERROR,
1003                "Hash of the decompressed SWF file is not 32 bytes long.\n");
1004         return AVERROR(EINVAL);
1005     }
1006
1007     p = &rt->swfverification[0];
1008     bytestream_put_byte(&p, 1);
1009     bytestream_put_byte(&p, 1);
1010     bytestream_put_be32(&p, rt->swfsize);
1011     bytestream_put_be32(&p, rt->swfsize);
1012
1013     if ((ret = ff_rtmp_calc_digest(rt->swfhash, 32, 0, buf, 32, p)) < 0)
1014         return ret;
1015
1016     return 0;
1017 }
1018
1019 #if CONFIG_ZLIB
1020 static int rtmp_uncompress_swfplayer(uint8_t *in_data, int64_t in_size,
1021                                      uint8_t **out_data, int64_t *out_size)
1022 {
1023     z_stream zs = { 0 };
1024     void *ptr;
1025     int size;
1026     int ret = 0;
1027
1028     zs.avail_in = in_size;
1029     zs.next_in  = in_data;
1030     ret = inflateInit(&zs);
1031     if (ret != Z_OK)
1032         return AVERROR_UNKNOWN;
1033
1034     do {
1035         uint8_t tmp_buf[16384];
1036
1037         zs.avail_out = sizeof(tmp_buf);
1038         zs.next_out  = tmp_buf;
1039
1040         ret = inflate(&zs, Z_NO_FLUSH);
1041         if (ret != Z_OK && ret != Z_STREAM_END) {
1042             ret = AVERROR_UNKNOWN;
1043             goto fail;
1044         }
1045
1046         size = sizeof(tmp_buf) - zs.avail_out;
1047         if (!(ptr = av_realloc(*out_data, *out_size + size))) {
1048             ret = AVERROR(ENOMEM);
1049             goto fail;
1050         }
1051         *out_data = ptr;
1052
1053         memcpy(*out_data + *out_size, tmp_buf, size);
1054         *out_size += size;
1055     } while (zs.avail_out == 0);
1056
1057 fail:
1058     inflateEnd(&zs);
1059     return ret;
1060 }
1061 #endif
1062
1063 static int rtmp_calc_swfhash(URLContext *s)
1064 {
1065     RTMPContext *rt = s->priv_data;
1066     uint8_t *in_data = NULL, *out_data = NULL, *swfdata;
1067     int64_t in_size, out_size;
1068     URLContext *stream;
1069     char swfhash[32];
1070     int swfsize;
1071     int ret = 0;
1072
1073     /* Get the SWF player file. */
1074     if ((ret = ffurl_open(&stream, rt->swfverify, AVIO_FLAG_READ,
1075                           &s->interrupt_callback, NULL)) < 0) {
1076         av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify);
1077         goto fail;
1078     }
1079
1080     if ((in_size = ffurl_seek(stream, 0, AVSEEK_SIZE)) < 0) {
1081         ret = AVERROR(EIO);
1082         goto fail;
1083     }
1084
1085     if (!(in_data = av_malloc(in_size))) {
1086         ret = AVERROR(ENOMEM);
1087         goto fail;
1088     }
1089
1090     if ((ret = ffurl_read_complete(stream, in_data, in_size)) < 0)
1091         goto fail;
1092
1093     if (in_size < 3) {
1094         ret = AVERROR_INVALIDDATA;
1095         goto fail;
1096     }
1097
1098     if (!memcmp(in_data, "CWS", 3)) {
1099         /* Decompress the SWF player file using Zlib. */
1100         if (!(out_data = av_malloc(8))) {
1101             ret = AVERROR(ENOMEM);
1102             goto fail;
1103         }
1104         *in_data = 'F'; // magic stuff
1105         memcpy(out_data, in_data, 8);
1106         out_size = 8;
1107
1108 #if CONFIG_ZLIB
1109         if ((ret = rtmp_uncompress_swfplayer(in_data + 8, in_size - 8,
1110                                              &out_data, &out_size)) < 0)
1111             goto fail;
1112 #else
1113         av_log(s, AV_LOG_ERROR,
1114                "Zlib is required for decompressing the SWF player file.\n");
1115         ret = AVERROR(EINVAL);
1116         goto fail;
1117 #endif
1118         swfsize = out_size;
1119         swfdata = out_data;
1120     } else {
1121         swfsize = in_size;
1122         swfdata = in_data;
1123     }
1124
1125     /* Compute the SHA256 hash of the SWF player file. */
1126     if ((ret = ff_rtmp_calc_digest(swfdata, swfsize, 0,
1127                                    "Genuine Adobe Flash Player 001", 30,
1128                                    swfhash)) < 0)
1129         goto fail;
1130
1131     /* Set SWFVerification parameters. */
1132     av_opt_set_bin(rt, "rtmp_swfhash", swfhash, 32, 0);
1133     rt->swfsize = swfsize;
1134
1135 fail:
1136     av_freep(&in_data);
1137     av_freep(&out_data);
1138     ffurl_close(stream);
1139     return ret;
1140 }
1141
1142 /**
1143  * Perform handshake with the server by means of exchanging pseudorandom data
1144  * signed with HMAC-SHA2 digest.
1145  *
1146  * @return 0 if handshake succeeds, negative value otherwise
1147  */
1148 static int rtmp_handshake(URLContext *s, RTMPContext *rt)
1149 {
1150     AVLFG rnd;
1151     uint8_t tosend    [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
1152         3,                // unencrypted data
1153         0, 0, 0, 0,       // client uptime
1154         RTMP_CLIENT_VER1,
1155         RTMP_CLIENT_VER2,
1156         RTMP_CLIENT_VER3,
1157         RTMP_CLIENT_VER4,
1158     };
1159     uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
1160     uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
1161     int i;
1162     int server_pos, client_pos;
1163     uint8_t digest[32], signature[32];
1164     int ret, type = 0;
1165
1166     av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
1167
1168     av_lfg_init(&rnd, 0xDEADC0DE);
1169     // generate handshake packet - 1536 bytes of pseudorandom data
1170     for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
1171         tosend[i] = av_lfg_get(&rnd) >> 24;
1172
1173     if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1174         /* When the client wants to use RTMPE, we have to change the command
1175          * byte to 0x06 which means to use encrypted data and we have to set
1176          * the flash version to at least 9.0.115.0. */
1177         tosend[0] = 6;
1178         tosend[5] = 128;
1179         tosend[6] = 0;
1180         tosend[7] = 3;
1181         tosend[8] = 2;
1182
1183         /* Initialize the Diffie-Hellmann context and generate the public key
1184          * to send to the server. */
1185         if ((ret = ff_rtmpe_gen_pub_key(rt->stream, tosend + 1)) < 0)
1186             return ret;
1187     }
1188
1189     client_pos = rtmp_handshake_imprint_with_digest(tosend + 1, rt->encrypted);
1190     if (client_pos < 0)
1191         return client_pos;
1192
1193     if ((ret = ffurl_write(rt->stream, tosend,
1194                            RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1195         av_log(s, AV_LOG_ERROR, "Cannot write RTMP handshake request\n");
1196         return ret;
1197     }
1198
1199     if ((ret = ffurl_read_complete(rt->stream, serverdata,
1200                                    RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1201         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1202         return ret;
1203     }
1204
1205     if ((ret = ffurl_read_complete(rt->stream, clientdata,
1206                                    RTMP_HANDSHAKE_PACKET_SIZE)) < 0) {
1207         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1208         return ret;
1209     }
1210
1211     av_log(s, AV_LOG_DEBUG, "Type answer %d\n", serverdata[0]);
1212     av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
1213            serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
1214
1215     if (rt->is_input && serverdata[5] >= 3) {
1216         server_pos = rtmp_validate_digest(serverdata + 1, 772);
1217         if (server_pos < 0)
1218             return server_pos;
1219
1220         if (!server_pos) {
1221             type = 1;
1222             server_pos = rtmp_validate_digest(serverdata + 1, 8);
1223             if (server_pos < 0)
1224                 return server_pos;
1225
1226             if (!server_pos) {
1227                 av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
1228                 return AVERROR(EIO);
1229             }
1230         }
1231
1232         /* Generate SWFVerification token (SHA256 HMAC hash of decompressed SWF,
1233          * key are the last 32 bytes of the server handshake. */
1234         if (rt->swfsize) {
1235             if ((ret = rtmp_calc_swf_verification(s, rt, serverdata + 1 +
1236                                                   RTMP_HANDSHAKE_PACKET_SIZE - 32)) < 0)
1237                 return ret;
1238         }
1239
1240         ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
1241                                   rtmp_server_key, sizeof(rtmp_server_key),
1242                                   digest);
1243         if (ret < 0)
1244             return ret;
1245
1246         ret = ff_rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE - 32,
1247                                   0, digest, 32, signature);
1248         if (ret < 0)
1249             return ret;
1250
1251         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1252             /* Compute the shared secret key sent by the server and initialize
1253              * the RC4 encryption. */
1254             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1255                                                    tosend + 1, type)) < 0)
1256                 return ret;
1257
1258             /* Encrypt the signature received by the server. */
1259             ff_rtmpe_encrypt_sig(rt->stream, signature, digest, serverdata[0]);
1260         }
1261
1262         if (memcmp(signature, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
1263             av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
1264             return AVERROR(EIO);
1265         }
1266
1267         for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
1268             tosend[i] = av_lfg_get(&rnd) >> 24;
1269         ret = ff_rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
1270                                   rtmp_player_key, sizeof(rtmp_player_key),
1271                                   digest);
1272         if (ret < 0)
1273             return ret;
1274
1275         ret = ff_rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
1276                                   digest, 32,
1277                                   tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
1278         if (ret < 0)
1279             return ret;
1280
1281         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1282             /* Encrypt the signature to be send to the server. */
1283             ff_rtmpe_encrypt_sig(rt->stream, tosend +
1284                                  RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
1285                                  serverdata[0]);
1286         }
1287
1288         // write reply back to the server
1289         if ((ret = ffurl_write(rt->stream, tosend,
1290                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1291             return ret;
1292
1293         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1294             /* Set RC4 keys for encryption and update the keystreams. */
1295             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1296                 return ret;
1297         }
1298     } else {
1299         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1300             /* Compute the shared secret key sent by the server and initialize
1301              * the RC4 encryption. */
1302             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1303                             tosend + 1, 1)) < 0)
1304                 return ret;
1305
1306             if (serverdata[0] == 9) {
1307                 /* Encrypt the signature received by the server. */
1308                 ff_rtmpe_encrypt_sig(rt->stream, signature, digest,
1309                                      serverdata[0]);
1310             }
1311         }
1312
1313         if ((ret = ffurl_write(rt->stream, serverdata + 1,
1314                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1315             return ret;
1316
1317         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1318             /* Set RC4 keys for encryption and update the keystreams. */
1319             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1320                 return ret;
1321         }
1322     }
1323
1324     return 0;
1325 }
1326
1327 static int rtmp_receive_hs_packet(RTMPContext* rt, uint32_t *first_int,
1328                                   uint32_t *second_int, char *arraydata,
1329                                   int size)
1330 {
1331     int inoutsize;
1332
1333     inoutsize = ffurl_read_complete(rt->stream, arraydata,
1334                                     RTMP_HANDSHAKE_PACKET_SIZE);
1335     if (inoutsize <= 0)
1336         return AVERROR(EIO);
1337     if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1338         av_log(rt, AV_LOG_ERROR, "Erroneous Message size %d"
1339                " not following standard\n", (int)inoutsize);
1340         return AVERROR(EINVAL);
1341     }
1342
1343     *first_int  = AV_RB32(arraydata);
1344     *second_int = AV_RB32(arraydata + 4);
1345     return 0;
1346 }
1347
1348 static int rtmp_send_hs_packet(RTMPContext* rt, uint32_t first_int,
1349                                uint32_t second_int, char *arraydata, int size)
1350 {
1351     int inoutsize;
1352
1353     AV_WB32(arraydata, first_int);
1354     AV_WB32(arraydata + 4, second_int);
1355     inoutsize = ffurl_write(rt->stream, arraydata,
1356                             RTMP_HANDSHAKE_PACKET_SIZE);
1357     if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1358         av_log(rt, AV_LOG_ERROR, "Unable to write answer\n");
1359         return AVERROR(EIO);
1360     }
1361
1362     return 0;
1363 }
1364
1365 /**
1366  * rtmp handshake server side
1367  */
1368 static int rtmp_server_handshake(URLContext *s, RTMPContext *rt)
1369 {
1370     uint8_t buffer[RTMP_HANDSHAKE_PACKET_SIZE];
1371     uint32_t hs_epoch;
1372     uint32_t hs_my_epoch;
1373     uint8_t hs_c1[RTMP_HANDSHAKE_PACKET_SIZE];
1374     uint8_t hs_s1[RTMP_HANDSHAKE_PACKET_SIZE];
1375     uint32_t zeroes;
1376     uint32_t temp       = 0;
1377     int randomidx       = 0;
1378     int inoutsize       = 0;
1379     int ret;
1380
1381     inoutsize = ffurl_read_complete(rt->stream, buffer, 1);       // Receive C0
1382     if (inoutsize <= 0) {
1383         av_log(s, AV_LOG_ERROR, "Unable to read handshake\n");
1384         return AVERROR(EIO);
1385     }
1386     // Check Version
1387     if (buffer[0] != 3) {
1388         av_log(s, AV_LOG_ERROR, "RTMP protocol version mismatch\n");
1389         return AVERROR(EIO);
1390     }
1391     if (ffurl_write(rt->stream, buffer, 1) <= 0) {                 // Send S0
1392         av_log(s, AV_LOG_ERROR,
1393                "Unable to write answer - RTMP S0\n");
1394         return AVERROR(EIO);
1395     }
1396     /* Receive C1 */
1397     ret = rtmp_receive_hs_packet(rt, &hs_epoch, &zeroes, hs_c1,
1398                                  RTMP_HANDSHAKE_PACKET_SIZE);
1399     if (ret) {
1400         av_log(s, AV_LOG_ERROR, "RTMP Handshake C1 Error\n");
1401         return ret;
1402     }
1403     /* Send S1 */
1404     /* By now same epoch will be sent */
1405     hs_my_epoch = hs_epoch;
1406     /* Generate random */
1407     for (randomidx = 8; randomidx < (RTMP_HANDSHAKE_PACKET_SIZE);
1408          randomidx += 4)
1409         AV_WB32(hs_s1 + randomidx, av_get_random_seed());
1410
1411     ret = rtmp_send_hs_packet(rt, hs_my_epoch, 0, hs_s1,
1412                               RTMP_HANDSHAKE_PACKET_SIZE);
1413     if (ret) {
1414         av_log(s, AV_LOG_ERROR, "RTMP Handshake S1 Error\n");
1415         return ret;
1416     }
1417     /* Send S2 */
1418     ret = rtmp_send_hs_packet(rt, hs_epoch, 0, hs_c1,
1419                               RTMP_HANDSHAKE_PACKET_SIZE);
1420     if (ret) {
1421         av_log(s, AV_LOG_ERROR, "RTMP Handshake S2 Error\n");
1422         return ret;
1423     }
1424     /* Receive C2 */
1425     ret = rtmp_receive_hs_packet(rt, &temp, &zeroes, buffer,
1426                                  RTMP_HANDSHAKE_PACKET_SIZE);
1427     if (ret) {
1428         av_log(s, AV_LOG_ERROR, "RTMP Handshake C2 Error\n");
1429         return ret;
1430     }
1431     if (temp != hs_my_epoch)
1432         av_log(s, AV_LOG_WARNING,
1433                "Erroneous C2 Message epoch does not match up with C1 epoch\n");
1434     if (memcmp(buffer + 8, hs_s1 + 8,
1435                RTMP_HANDSHAKE_PACKET_SIZE - 8))
1436         av_log(s, AV_LOG_WARNING,
1437                "Erroneous C2 Message random does not match up\n");
1438
1439     return 0;
1440 }
1441
1442 static int handle_chunk_size(URLContext *s, RTMPPacket *pkt)
1443 {
1444     RTMPContext *rt = s->priv_data;
1445     int ret;
1446
1447     if (pkt->size < 4) {
1448         av_log(s, AV_LOG_ERROR,
1449                "Too short chunk size change packet (%d)\n",
1450                pkt->size);
1451         return AVERROR_INVALIDDATA;
1452     }
1453
1454     if (!rt->is_input) {
1455         /* Send the same chunk size change packet back to the server,
1456          * setting the outgoing chunk size to the same as the incoming one. */
1457         if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
1458                                         rt->prev_pkt[1])) < 0)
1459             return ret;
1460         rt->out_chunk_size = AV_RB32(pkt->data);
1461     }
1462
1463     rt->in_chunk_size = AV_RB32(pkt->data);
1464     if (rt->in_chunk_size <= 0) {
1465         av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n",
1466                rt->in_chunk_size);
1467         return AVERROR_INVALIDDATA;
1468     }
1469     av_log(s, AV_LOG_DEBUG, "New incoming chunk size = %d\n",
1470            rt->in_chunk_size);
1471
1472     return 0;
1473 }
1474
1475 static int handle_ping(URLContext *s, RTMPPacket *pkt)
1476 {
1477     RTMPContext *rt = s->priv_data;
1478     int t, ret;
1479
1480     if (pkt->size < 2) {
1481         av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
1482                pkt->size);
1483         return AVERROR_INVALIDDATA;
1484     }
1485
1486     t = AV_RB16(pkt->data);
1487     if (t == 6) {
1488         if ((ret = gen_pong(s, rt, pkt)) < 0)
1489             return ret;
1490     } else if (t == 26) {
1491         if (rt->swfsize) {
1492             if ((ret = gen_swf_verification(s, rt)) < 0)
1493                 return ret;
1494         } else {
1495             av_log(s, AV_LOG_WARNING, "Ignoring SWFVerification request.\n");
1496         }
1497     }
1498
1499     return 0;
1500 }
1501
1502 static int handle_client_bw(URLContext *s, RTMPPacket *pkt)
1503 {
1504     RTMPContext *rt = s->priv_data;
1505
1506     if (pkt->size < 4) {
1507         av_log(s, AV_LOG_ERROR,
1508                "Client bandwidth report packet is less than 4 bytes long (%d)\n",
1509                pkt->size);
1510         return AVERROR_INVALIDDATA;
1511     }
1512
1513     rt->client_report_size = AV_RB32(pkt->data);
1514     if (rt->client_report_size <= 0) {
1515         av_log(s, AV_LOG_ERROR, "Incorrect client bandwidth %d\n",
1516                 rt->client_report_size);
1517         return AVERROR_INVALIDDATA;
1518
1519     }
1520     av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", rt->client_report_size);
1521     rt->client_report_size >>= 1;
1522
1523     return 0;
1524 }
1525
1526 static int handle_server_bw(URLContext *s, RTMPPacket *pkt)
1527 {
1528     RTMPContext *rt = s->priv_data;
1529
1530     if (pkt->size < 4) {
1531         av_log(s, AV_LOG_ERROR,
1532                "Too short server bandwidth report packet (%d)\n",
1533                pkt->size);
1534         return AVERROR_INVALIDDATA;
1535     }
1536
1537     rt->server_bw = AV_RB32(pkt->data);
1538     if (rt->server_bw <= 0) {
1539         av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n",
1540                rt->server_bw);
1541         return AVERROR_INVALIDDATA;
1542     }
1543     av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw);
1544
1545     return 0;
1546 }
1547
1548 static int do_adobe_auth(RTMPContext *rt, const char *user, const char *salt,
1549                          const char *opaque, const char *challenge)
1550 {
1551     uint8_t hash[16];
1552     char hashstr[AV_BASE64_SIZE(sizeof(hash))], challenge2[10];
1553     struct AVMD5 *md5 = av_md5_alloc();
1554     if (!md5)
1555         return AVERROR(ENOMEM);
1556
1557     snprintf(challenge2, sizeof(challenge2), "%08x", av_get_random_seed());
1558
1559     av_md5_init(md5);
1560     av_md5_update(md5, user, strlen(user));
1561     av_md5_update(md5, salt, strlen(salt));
1562     av_md5_update(md5, rt->password, strlen(rt->password));
1563     av_md5_final(md5, hash);
1564     av_base64_encode(hashstr, sizeof(hashstr), hash,
1565                      sizeof(hash));
1566     av_md5_init(md5);
1567     av_md5_update(md5, hashstr, strlen(hashstr));
1568     if (opaque)
1569         av_md5_update(md5, opaque, strlen(opaque));
1570     else if (challenge)
1571         av_md5_update(md5, challenge, strlen(challenge));
1572     av_md5_update(md5, challenge2, strlen(challenge2));
1573     av_md5_final(md5, hash);
1574     av_base64_encode(hashstr, sizeof(hashstr), hash,
1575                      sizeof(hash));
1576     snprintf(rt->auth_params, sizeof(rt->auth_params),
1577              "?authmod=%s&user=%s&challenge=%s&response=%s",
1578              "adobe", user, challenge2, hashstr);
1579     if (opaque)
1580         av_strlcatf(rt->auth_params, sizeof(rt->auth_params),
1581                     "&opaque=%s", opaque);
1582
1583     av_free(md5);
1584     return 0;
1585 }
1586
1587 static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)
1588 {
1589     uint8_t hash[16];
1590     char hashstr1[33], hashstr2[33];
1591     const char *realm = "live";
1592     const char *method = "publish";
1593     const char *qop = "auth";
1594     const char *nc = "00000001";
1595     char cnonce[10];
1596     struct AVMD5 *md5 = av_md5_alloc();
1597     if (!md5)
1598         return AVERROR(ENOMEM);
1599
1600     snprintf(cnonce, sizeof(cnonce), "%08x", av_get_random_seed());
1601
1602     av_md5_init(md5);
1603     av_md5_update(md5, user, strlen(user));
1604     av_md5_update(md5, ":", 1);
1605     av_md5_update(md5, realm, strlen(realm));
1606     av_md5_update(md5, ":", 1);
1607     av_md5_update(md5, rt->password, strlen(rt->password));
1608     av_md5_final(md5, hash);
1609     ff_data_to_hex(hashstr1, hash, 16, 1);
1610     hashstr1[32] = '\0';
1611
1612     av_md5_init(md5);
1613     av_md5_update(md5, method, strlen(method));
1614     av_md5_update(md5, ":/", 2);
1615     av_md5_update(md5, rt->app, strlen(rt->app));
1616     if (!strchr(rt->app, '/'))
1617         av_md5_update(md5, "/_definst_", strlen("/_definst_"));
1618     av_md5_final(md5, hash);
1619     ff_data_to_hex(hashstr2, hash, 16, 1);
1620     hashstr2[32] = '\0';
1621
1622     av_md5_init(md5);
1623     av_md5_update(md5, hashstr1, strlen(hashstr1));
1624     av_md5_update(md5, ":", 1);
1625     if (nonce)
1626         av_md5_update(md5, nonce, strlen(nonce));
1627     av_md5_update(md5, ":", 1);
1628     av_md5_update(md5, nc, strlen(nc));
1629     av_md5_update(md5, ":", 1);
1630     av_md5_update(md5, cnonce, strlen(cnonce));
1631     av_md5_update(md5, ":", 1);
1632     av_md5_update(md5, qop, strlen(qop));
1633     av_md5_update(md5, ":", 1);
1634     av_md5_update(md5, hashstr2, strlen(hashstr2));
1635     av_md5_final(md5, hash);
1636     ff_data_to_hex(hashstr1, hash, 16, 1);
1637
1638     snprintf(rt->auth_params, sizeof(rt->auth_params),
1639              "?authmod=%s&user=%s&nonce=%s&cnonce=%s&nc=%s&response=%s",
1640              "llnw", user, nonce, cnonce, nc, hashstr1);
1641
1642     av_free(md5);
1643     return 0;
1644 }
1645
1646 static int handle_connect_error(URLContext *s, const char *desc)
1647 {
1648     RTMPContext *rt = s->priv_data;
1649     char buf[300], *ptr, authmod[15];
1650     int i = 0, ret = 0;
1651     const char *user = "", *salt = "", *opaque = NULL,
1652                *challenge = NULL, *cptr = NULL, *nonce = NULL;
1653
1654     if (!(cptr = strstr(desc, "authmod=adobe")) &&
1655         !(cptr = strstr(desc, "authmod=llnw"))) {
1656         av_log(s, AV_LOG_ERROR,
1657                "Unknown connect error (unsupported authentication method?)\n");
1658         return AVERROR_UNKNOWN;
1659     }
1660     cptr += strlen("authmod=");
1661     while (*cptr && *cptr != ' ' && i < sizeof(authmod) - 1)
1662         authmod[i++] = *cptr++;
1663     authmod[i] = '\0';
1664
1665     if (!rt->username[0] || !rt->password[0]) {
1666         av_log(s, AV_LOG_ERROR, "No credentials set\n");
1667         return AVERROR_UNKNOWN;
1668     }
1669
1670     if (strstr(desc, "?reason=authfailed")) {
1671         av_log(s, AV_LOG_ERROR, "Incorrect username/password\n");
1672         return AVERROR_UNKNOWN;
1673     } else if (strstr(desc, "?reason=nosuchuser")) {
1674         av_log(s, AV_LOG_ERROR, "Incorrect username\n");
1675         return AVERROR_UNKNOWN;
1676     }
1677
1678     if (rt->auth_tried) {
1679         av_log(s, AV_LOG_ERROR, "Authentication failed\n");
1680         return AVERROR_UNKNOWN;
1681     }
1682
1683     rt->auth_params[0] = '\0';
1684
1685     if (strstr(desc, "code=403 need auth")) {
1686         snprintf(rt->auth_params, sizeof(rt->auth_params),
1687                  "?authmod=%s&user=%s", authmod, rt->username);
1688         return 0;
1689     }
1690
1691     if (!(cptr = strstr(desc, "?reason=needauth"))) {
1692         av_log(s, AV_LOG_ERROR, "No auth parameters found\n");
1693         return AVERROR_UNKNOWN;
1694     }
1695
1696     av_strlcpy(buf, cptr + 1, sizeof(buf));
1697     ptr = buf;
1698
1699     while (ptr) {
1700         char *next  = strchr(ptr, '&');
1701         char *value = strchr(ptr, '=');
1702         if (next)
1703             *next++ = '\0';
1704         if (value)
1705             *value++ = '\0';
1706         if (!strcmp(ptr, "user")) {
1707             user = value;
1708         } else if (!strcmp(ptr, "salt")) {
1709             salt = value;
1710         } else if (!strcmp(ptr, "opaque")) {
1711             opaque = value;
1712         } else if (!strcmp(ptr, "challenge")) {
1713             challenge = value;
1714         } else if (!strcmp(ptr, "nonce")) {
1715             nonce = value;
1716         }
1717         ptr = next;
1718     }
1719
1720     if (!strcmp(authmod, "adobe")) {
1721         if ((ret = do_adobe_auth(rt, user, salt, opaque, challenge)) < 0)
1722             return ret;
1723     } else {
1724         if ((ret = do_llnw_auth(rt, user, nonce)) < 0)
1725             return ret;
1726     }
1727
1728     rt->auth_tried = 1;
1729     return 0;
1730 }
1731
1732 static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
1733 {
1734     RTMPContext *rt = s->priv_data;
1735     const uint8_t *data_end = pkt->data + pkt->size;
1736     char *tracked_method = NULL;
1737     int level = AV_LOG_ERROR;
1738     uint8_t tmpstr[256];
1739     int ret;
1740
1741     if ((ret = find_tracked_method(s, pkt, 9, &tracked_method)) < 0)
1742         return ret;
1743
1744     if (!ff_amf_get_field_value(pkt->data + 9, data_end,
1745                                 "description", tmpstr, sizeof(tmpstr))) {
1746         if (tracked_method && (!strcmp(tracked_method, "_checkbw")      ||
1747                                !strcmp(tracked_method, "releaseStream") ||
1748                                !strcmp(tracked_method, "FCSubscribe")   ||
1749                                !strcmp(tracked_method, "FCPublish"))) {
1750             /* Gracefully ignore Adobe-specific historical artifact errors. */
1751             level = AV_LOG_WARNING;
1752             ret = 0;
1753         } else if (tracked_method && !strcmp(tracked_method, "connect")) {
1754             ret = handle_connect_error(s, tmpstr);
1755             if (!ret) {
1756                 rt->do_reconnect = 1;
1757                 level = AV_LOG_VERBOSE;
1758             }
1759         } else
1760             ret = AVERROR_UNKNOWN;
1761         av_log(s, level, "Server error: %s\n", tmpstr);
1762     }
1763
1764     av_free(tracked_method);
1765     return ret;
1766 }
1767
1768 static int write_begin(URLContext *s)
1769 {
1770     RTMPContext *rt = s->priv_data;
1771     PutByteContext pbc;
1772     RTMPPacket spkt = { 0 };
1773     int ret;
1774
1775     // Send Stream Begin 1
1776     if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
1777                                      RTMP_PT_PING, 0, 6)) < 0) {
1778         av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1779         return ret;
1780     }
1781
1782     bytestream2_init_writer(&pbc, spkt.data, spkt.size);
1783     bytestream2_put_be16(&pbc, 0);          // 0 -> Stream Begin
1784     bytestream2_put_be32(&pbc, rt->nb_streamid);
1785
1786     ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1787                                rt->prev_pkt[1]);
1788
1789     ff_rtmp_packet_destroy(&spkt);
1790
1791     return ret;
1792 }
1793
1794 static int write_status(URLContext *s, RTMPPacket *pkt,
1795                         const char *status, const char *filename)
1796 {
1797     RTMPContext *rt = s->priv_data;
1798     RTMPPacket spkt = { 0 };
1799     char statusmsg[128];
1800     uint8_t *pp;
1801     int ret;
1802
1803     if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1804                                      RTMP_PT_INVOKE, 0,
1805                                      RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1806         av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1807         return ret;
1808     }
1809
1810     pp = spkt.data;
1811     spkt.extra = pkt->extra;
1812     ff_amf_write_string(&pp, "onStatus");
1813     ff_amf_write_number(&pp, 0);
1814     ff_amf_write_null(&pp);
1815
1816     ff_amf_write_object_start(&pp);
1817     ff_amf_write_field_name(&pp, "level");
1818     ff_amf_write_string(&pp, "status");
1819     ff_amf_write_field_name(&pp, "code");
1820     ff_amf_write_string(&pp, status);
1821     ff_amf_write_field_name(&pp, "description");
1822     snprintf(statusmsg, sizeof(statusmsg),
1823              "%s is now published", filename);
1824     ff_amf_write_string(&pp, statusmsg);
1825     ff_amf_write_field_name(&pp, "details");
1826     ff_amf_write_string(&pp, filename);
1827     ff_amf_write_field_name(&pp, "clientid");
1828     snprintf(statusmsg, sizeof(statusmsg), "%s", LIBAVFORMAT_IDENT);
1829     ff_amf_write_string(&pp, statusmsg);
1830     ff_amf_write_object_end(&pp);
1831
1832     spkt.size = pp - spkt.data;
1833     ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1834                                rt->prev_pkt[1]);
1835     ff_rtmp_packet_destroy(&spkt);
1836
1837     return ret;
1838 }
1839
1840 static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
1841 {
1842     RTMPContext *rt = s->priv_data;
1843     double seqnum;
1844     char filename[64];
1845     char command[64];
1846     int stringlen;
1847     char *pchar;
1848     const uint8_t *p = pkt->data;
1849     uint8_t *pp      = NULL;
1850     RTMPPacket spkt  = { 0 };
1851     GetByteContext gbc;
1852     int ret;
1853
1854     bytestream2_init(&gbc, p, pkt->size);
1855     if (ff_amf_read_string(&gbc, command, sizeof(command),
1856                            &stringlen)) {
1857         av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n");
1858         return AVERROR_INVALIDDATA;
1859     }
1860
1861     ret = ff_amf_read_number(&gbc, &seqnum);
1862     if (ret)
1863         return ret;
1864     ret = ff_amf_read_null(&gbc);
1865     if (ret)
1866         return ret;
1867     if (!strcmp(command, "FCPublish") ||
1868         !strcmp(command, "publish")) {
1869         ret = ff_amf_read_string(&gbc, filename,
1870                                  sizeof(filename), &stringlen);
1871         // check with url
1872         if (s->filename) {
1873             pchar = strrchr(s->filename, '/');
1874             if (!pchar) {
1875                 av_log(s, AV_LOG_WARNING,
1876                        "Unable to find / in url %s, bad format\n",
1877                        s->filename);
1878                 pchar = s->filename;
1879             }
1880             pchar++;
1881             if (strcmp(pchar, filename))
1882                 av_log(s, AV_LOG_WARNING, "Unexpected stream %s, expecting"
1883                        " %s\n", filename, pchar);
1884         }
1885         rt->state = STATE_RECEIVING;
1886     }
1887
1888     if (!strcmp(command, "FCPublish")) {
1889         if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1890                                          RTMP_PT_INVOKE, 0,
1891                                          RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1892             av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1893             return ret;
1894         }
1895         pp = spkt.data;
1896         ff_amf_write_string(&pp, "onFCPublish");
1897     } else if (!strcmp(command, "publish")) {
1898         ret = write_begin(s);
1899         if (ret < 0)
1900             return ret;
1901
1902         // Send onStatus(NetStream.Publish.Start)
1903         return write_status(s, pkt, "NetStream.Publish.Start",
1904                            filename);
1905     } else if (!strcmp(command, "play")) {
1906         ret = write_begin(s);
1907         if (ret < 0)
1908             return ret;
1909         rt->state = STATE_SENDING;
1910         return write_status(s, pkt, "NetStream.Play.Start",
1911                             filename);
1912     } else {
1913         if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1914                                          RTMP_PT_INVOKE, 0,
1915                                          RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1916             av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1917             return ret;
1918         }
1919         pp = spkt.data;
1920         ff_amf_write_string(&pp, "_result");
1921         ff_amf_write_number(&pp, seqnum);
1922         ff_amf_write_null(&pp);
1923         if (!strcmp(command, "createStream")) {
1924             rt->nb_streamid++;
1925             if (rt->nb_streamid == 0 || rt->nb_streamid == 2)
1926                 rt->nb_streamid++; /* Values 0 and 2 are reserved */
1927             ff_amf_write_number(&pp, rt->nb_streamid);
1928             /* By now we don't control which streams are removed in
1929              * deleteStream. There is no stream creation control
1930              * if a client creates more than 2^32 - 2 streams. */
1931         }
1932     }
1933     spkt.size = pp - spkt.data;
1934     ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1935                                rt->prev_pkt[1]);
1936     ff_rtmp_packet_destroy(&spkt);
1937     return ret;
1938 }
1939
1940 static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
1941 {
1942     RTMPContext *rt = s->priv_data;
1943     char *tracked_method = NULL;
1944     int ret = 0;
1945
1946     if ((ret = find_tracked_method(s, pkt, 10, &tracked_method)) < 0)
1947         return ret;
1948
1949     if (!tracked_method) {
1950         /* Ignore this reply when the current method is not tracked. */
1951         return ret;
1952     }
1953
1954     if (!strcmp(tracked_method, "connect")) {
1955         if (!rt->is_input) {
1956             if ((ret = gen_release_stream(s, rt)) < 0)
1957                 goto fail;
1958
1959             if ((ret = gen_fcpublish_stream(s, rt)) < 0)
1960                 goto fail;
1961         } else {
1962             if ((ret = gen_server_bw(s, rt)) < 0)
1963                 goto fail;
1964         }
1965
1966         if ((ret = gen_create_stream(s, rt)) < 0)
1967             goto fail;
1968
1969         if (rt->is_input) {
1970             /* Send the FCSubscribe command when the name of live
1971              * stream is defined by the user or if it's a live stream. */
1972             if (rt->subscribe) {
1973                 if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
1974                     goto fail;
1975             } else if (rt->live == -1) {
1976                 if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
1977                     goto fail;
1978             }
1979         }
1980     } else if (!strcmp(tracked_method, "createStream")) {
1981         //extract a number from the result
1982         if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
1983             av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
1984         } else {
1985             rt->stream_id = av_int2double(AV_RB64(pkt->data + 21));
1986         }
1987
1988         if (!rt->is_input) {
1989             if ((ret = gen_publish(s, rt)) < 0)
1990                 goto fail;
1991         } else {
1992             if ((ret = gen_play(s, rt)) < 0)
1993                 goto fail;
1994             if ((ret = gen_buffer_time(s, rt)) < 0)
1995                 goto fail;
1996         }
1997     }
1998
1999 fail:
2000     av_free(tracked_method);
2001     return ret;
2002 }
2003
2004 static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
2005 {
2006     RTMPContext *rt = s->priv_data;
2007     const uint8_t *data_end = pkt->data + pkt->size;
2008     const uint8_t *ptr = pkt->data + RTMP_HEADER;
2009     uint8_t tmpstr[256];
2010     int i, t;
2011
2012     for (i = 0; i < 2; i++) {
2013         t = ff_amf_tag_size(ptr, data_end);
2014         if (t < 0)
2015             return 1;
2016         ptr += t;
2017     }
2018
2019     t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
2020     if (!t && !strcmp(tmpstr, "error")) {
2021         t = ff_amf_get_field_value(ptr, data_end,
2022                                    "description", tmpstr, sizeof(tmpstr));
2023         if (t || !tmpstr[0])
2024             t = ff_amf_get_field_value(ptr, data_end, "code",
2025                                        tmpstr, sizeof(tmpstr));
2026         if (!t)
2027             av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
2028         return -1;
2029     }
2030
2031     t = ff_amf_get_field_value(ptr, data_end, "code", tmpstr, sizeof(tmpstr));
2032     if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
2033     if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
2034     if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
2035     if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
2036     if (!t && !strcmp(tmpstr, "NetStream.Seek.Notify")) rt->state = STATE_PLAYING;
2037
2038     return 0;
2039 }
2040
2041 static int handle_invoke(URLContext *s, RTMPPacket *pkt)
2042 {
2043     RTMPContext *rt = s->priv_data;
2044     int ret = 0;
2045
2046     //TODO: check for the messages sent for wrong state?
2047     if (ff_amf_match_string(pkt->data, pkt->size, "_error")) {
2048         if ((ret = handle_invoke_error(s, pkt)) < 0)
2049             return ret;
2050     } else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) {
2051         if ((ret = handle_invoke_result(s, pkt)) < 0)
2052             return ret;
2053     } else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) {
2054         if ((ret = handle_invoke_status(s, pkt)) < 0)
2055             return ret;
2056     } else if (ff_amf_match_string(pkt->data, pkt->size, "onBWDone")) {
2057         if ((ret = gen_check_bw(s, rt)) < 0)
2058             return ret;
2059     } else if (ff_amf_match_string(pkt->data, pkt->size, "releaseStream") ||
2060                ff_amf_match_string(pkt->data, pkt->size, "FCPublish")     ||
2061                ff_amf_match_string(pkt->data, pkt->size, "publish")       ||
2062                ff_amf_match_string(pkt->data, pkt->size, "play")          ||
2063                ff_amf_match_string(pkt->data, pkt->size, "_checkbw")      ||
2064                ff_amf_match_string(pkt->data, pkt->size, "createStream")) {
2065         if ((ret = send_invoke_response(s, pkt)) < 0)
2066             return ret;
2067     }
2068
2069     return ret;
2070 }
2071
2072 static int update_offset(RTMPContext *rt, int size)
2073 {
2074     int old_flv_size;
2075
2076     // generate packet header and put data into buffer for FLV demuxer
2077     if (rt->flv_off < rt->flv_size) {
2078         // There is old unread data in the buffer, thus append at the end
2079         old_flv_size  = rt->flv_size;
2080         rt->flv_size += size + 15;
2081     } else {
2082         // All data has been read, write the new data at the start of the buffer
2083         old_flv_size = 0;
2084         rt->flv_size = size + 15;
2085         rt->flv_off  = 0;
2086     }
2087
2088     return old_flv_size;
2089 }
2090
2091 static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)
2092 {
2093     int old_flv_size, ret;
2094     PutByteContext pbc;
2095     const uint8_t *data = pkt->data + skip;
2096     const int size      = pkt->size - skip;
2097     uint32_t ts         = pkt->timestamp;
2098
2099     old_flv_size = update_offset(rt, size);
2100
2101     if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
2102         return ret;
2103     bytestream2_init_writer(&pbc, rt->flv_data, rt->flv_size);
2104     bytestream2_skip_p(&pbc, old_flv_size);
2105     bytestream2_put_byte(&pbc, pkt->type);
2106     bytestream2_put_be24(&pbc, size);
2107     bytestream2_put_be24(&pbc, ts);
2108     bytestream2_put_byte(&pbc, ts >> 24);
2109     bytestream2_put_be24(&pbc, 0);
2110     bytestream2_put_buffer(&pbc, data, size);
2111     bytestream2_put_be32(&pbc, 0);
2112
2113     return 0;
2114 }
2115
2116 static int handle_notify(URLContext *s, RTMPPacket *pkt)
2117 {
2118     RTMPContext *rt  = s->priv_data;
2119     uint8_t commandbuffer[64];
2120     char statusmsg[128];
2121     int stringlen, ret, skip = 0;
2122     GetByteContext gbc;
2123
2124     bytestream2_init(&gbc, pkt->data, pkt->size);
2125     if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
2126                            &stringlen))
2127         return AVERROR_INVALIDDATA;
2128
2129     // Skip the @setDataFrame string and validate it is a notification
2130     if (!strcmp(commandbuffer, "@setDataFrame")) {
2131         skip = gbc.buffer - pkt->data;
2132         ret = ff_amf_read_string(&gbc, statusmsg,
2133                                  sizeof(statusmsg), &stringlen);
2134         if (ret < 0)
2135             return AVERROR_INVALIDDATA;
2136     }
2137
2138     return append_flv_data(rt, pkt, skip);
2139 }
2140
2141 /**
2142  * Parse received packet and possibly perform some action depending on
2143  * the packet contents.
2144  * @return 0 for no errors, negative values for serious errors which prevent
2145  *         further communications, positive values for uncritical errors
2146  */
2147 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
2148 {
2149     int ret;
2150
2151 #ifdef DEBUG
2152     ff_rtmp_packet_dump(s, pkt);
2153 #endif
2154
2155     switch (pkt->type) {
2156     case RTMP_PT_BYTES_READ:
2157         av_dlog(s, "received bytes read report\n");
2158         break;
2159     case RTMP_PT_CHUNK_SIZE:
2160         if ((ret = handle_chunk_size(s, pkt)) < 0)
2161             return ret;
2162         break;
2163     case RTMP_PT_PING:
2164         if ((ret = handle_ping(s, pkt)) < 0)
2165             return ret;
2166         break;
2167     case RTMP_PT_CLIENT_BW:
2168         if ((ret = handle_client_bw(s, pkt)) < 0)
2169             return ret;
2170         break;
2171     case RTMP_PT_SERVER_BW:
2172         if ((ret = handle_server_bw(s, pkt)) < 0)
2173             return ret;
2174         break;
2175     case RTMP_PT_INVOKE:
2176         if ((ret = handle_invoke(s, pkt)) < 0)
2177             return ret;
2178         break;
2179     case RTMP_PT_VIDEO:
2180     case RTMP_PT_AUDIO:
2181     case RTMP_PT_METADATA:
2182     case RTMP_PT_NOTIFY:
2183         /* Audio, Video and Metadata packets are parsed in get_packet() */
2184         break;
2185     default:
2186         av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
2187         break;
2188     }
2189     return 0;
2190 }
2191
2192 static int handle_metadata(RTMPContext *rt, RTMPPacket *pkt)
2193 {
2194     int ret, old_flv_size, type;
2195     const uint8_t *next;
2196     uint8_t *p;
2197     uint32_t size;
2198     uint32_t ts, cts, pts = 0;
2199
2200     old_flv_size = update_offset(rt, pkt->size);
2201
2202     if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
2203         return ret;
2204
2205     next = pkt->data;
2206     p    = rt->flv_data + old_flv_size;
2207
2208     /* copy data while rewriting timestamps */
2209     ts = pkt->timestamp;
2210
2211     while (next - pkt->data < pkt->size - RTMP_HEADER) {
2212         type = bytestream_get_byte(&next);
2213         size = bytestream_get_be24(&next);
2214         cts  = bytestream_get_be24(&next);
2215         cts |= bytestream_get_byte(&next) << 24;
2216         if (!pts)
2217             pts = cts;
2218         ts += cts - pts;
2219         pts = cts;
2220         bytestream_put_byte(&p, type);
2221         bytestream_put_be24(&p, size);
2222         bytestream_put_be24(&p, ts);
2223         bytestream_put_byte(&p, ts >> 24);
2224         memcpy(p, next, size + 3 + 4);
2225         next += size + 3 + 4;
2226         p    += size + 3 + 4;
2227     }
2228     memcpy(p, next, RTMP_HEADER);
2229
2230     return 0;
2231 }
2232
2233 /**
2234  * Interact with the server by receiving and sending RTMP packets until
2235  * there is some significant data (media data or expected status notification).
2236  *
2237  * @param s          reading context
2238  * @param for_header non-zero value tells function to work until it
2239  * gets notification from the server that playing has been started,
2240  * otherwise function will work until some media data is received (or
2241  * an error happens)
2242  * @return 0 for successful operation, negative value in case of error
2243  */
2244 static int get_packet(URLContext *s, int for_header)
2245 {
2246     RTMPContext *rt = s->priv_data;
2247     int ret;
2248
2249     if (rt->state == STATE_STOPPED)
2250         return AVERROR_EOF;
2251
2252     for (;;) {
2253         RTMPPacket rpkt = { 0 };
2254         if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
2255                                        rt->in_chunk_size, rt->prev_pkt[0])) <= 0) {
2256             if (ret == 0) {
2257                 return AVERROR(EAGAIN);
2258             } else {
2259                 return AVERROR(EIO);
2260             }
2261         }
2262         rt->bytes_read += ret;
2263         if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
2264             av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
2265             if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
2266                 return ret;
2267             rt->last_bytes_read = rt->bytes_read;
2268         }
2269
2270         ret = rtmp_parse_result(s, rt, &rpkt);
2271
2272         // At this point we must check if we are in the seek state and continue
2273         // with the next packet. handle_invoke will get us out of this state
2274         // when the right message is encountered
2275         if (rt->state == STATE_SEEKING) {
2276             ff_rtmp_packet_destroy(&rpkt);
2277             // We continue, let the natural flow of things happen:
2278             // AVERROR(EAGAIN) or handle_invoke gets us out of here
2279             continue;
2280         }
2281
2282         if (ret < 0) {//serious error in current packet
2283             ff_rtmp_packet_destroy(&rpkt);
2284             return ret;
2285         }
2286         if (rt->do_reconnect && for_header) {
2287             ff_rtmp_packet_destroy(&rpkt);
2288             return 0;
2289         }
2290         if (rt->state == STATE_STOPPED) {
2291             ff_rtmp_packet_destroy(&rpkt);
2292             return AVERROR_EOF;
2293         }
2294         if (for_header && (rt->state == STATE_PLAYING    ||
2295                            rt->state == STATE_PUBLISHING ||
2296                            rt->state == STATE_SENDING    ||
2297                            rt->state == STATE_RECEIVING)) {
2298             ff_rtmp_packet_destroy(&rpkt);
2299             return 0;
2300         }
2301         if (!rpkt.size || !rt->is_input) {
2302             ff_rtmp_packet_destroy(&rpkt);
2303             continue;
2304         }
2305         if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO) {
2306             ret = append_flv_data(rt, &rpkt, 0);
2307             ff_rtmp_packet_destroy(&rpkt);
2308             return ret;
2309         } else if (rpkt.type == RTMP_PT_NOTIFY) {
2310             ret = handle_notify(s, &rpkt);
2311             ff_rtmp_packet_destroy(&rpkt);
2312             return ret;
2313         } else if (rpkt.type == RTMP_PT_METADATA) {
2314             ret = handle_metadata(rt, &rpkt);
2315             ff_rtmp_packet_destroy(&rpkt);
2316             return 0;
2317         }
2318         ff_rtmp_packet_destroy(&rpkt);
2319     }
2320 }
2321
2322 static int rtmp_close(URLContext *h)
2323 {
2324     RTMPContext *rt = h->priv_data;
2325     int ret = 0, i, j;
2326
2327     if (!rt->is_input) {
2328         rt->flv_data = NULL;
2329         if (rt->out_pkt.size)
2330             ff_rtmp_packet_destroy(&rt->out_pkt);
2331         if (rt->state > STATE_FCPUBLISH)
2332             ret = gen_fcunpublish_stream(h, rt);
2333     }
2334     if (rt->state > STATE_HANDSHAKED)
2335         ret = gen_delete_stream(h, rt);
2336     for (i = 0; i < 2; i++)
2337         for (j = 0; j < RTMP_CHANNELS; j++)
2338             ff_rtmp_packet_destroy(&rt->prev_pkt[i][j]);
2339
2340     free_tracked_methods(rt);
2341     av_freep(&rt->flv_data);
2342     ffurl_close(rt->stream);
2343     return ret;
2344 }
2345
2346 /**
2347  * Open RTMP connection and verify that the stream can be played.
2348  *
2349  * URL syntax: rtmp://server[:port][/app][/playpath]
2350  *             where 'app' is first one or two directories in the path
2351  *             (e.g. /ondemand/, /flash/live/, etc.)
2352  *             and 'playpath' is a file name (the rest of the path,
2353  *             may be prefixed with "mp4:")
2354  */
2355 static int rtmp_open(URLContext *s, const char *uri, int flags)
2356 {
2357     RTMPContext *rt = s->priv_data;
2358     char proto[8], hostname[256], path[1024], auth[100], *fname;
2359     char *old_app;
2360     uint8_t buf[2048];
2361     int port;
2362     AVDictionary *opts = NULL;
2363     int ret;
2364
2365     if (rt->listen_timeout > 0)
2366         rt->listen = 1;
2367
2368     rt->is_input = !(flags & AVIO_FLAG_WRITE);
2369
2370     av_url_split(proto, sizeof(proto), auth, sizeof(auth),
2371                  hostname, sizeof(hostname), &port,
2372                  path, sizeof(path), s->filename);
2373
2374     if (strchr(path, ' ')) {
2375         av_log(s, AV_LOG_WARNING,
2376                "Detected librtmp style URL parameters, these aren't supported "
2377                "by the libavformat internal RTMP handler currently enabled. "
2378                "See the documentation for the correct way to pass parameters.\n");
2379     }
2380
2381     if (auth[0]) {
2382         char *ptr = strchr(auth, ':');
2383         if (ptr) {
2384             *ptr = '\0';
2385             av_strlcpy(rt->username, auth, sizeof(rt->username));
2386             av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
2387         }
2388     }
2389
2390     if (rt->listen && strcmp(proto, "rtmp")) {
2391         av_log(s, AV_LOG_ERROR, "rtmp_listen not available for %s\n",
2392                proto);
2393         return AVERROR(EINVAL);
2394     }
2395     if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
2396         if (!strcmp(proto, "rtmpts"))
2397             av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
2398
2399         /* open the http tunneling connection */
2400         ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
2401     } else if (!strcmp(proto, "rtmps")) {
2402         /* open the tls connection */
2403         if (port < 0)
2404             port = RTMPS_DEFAULT_PORT;
2405         ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
2406     } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
2407         if (!strcmp(proto, "rtmpte"))
2408             av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
2409
2410         /* open the encrypted connection */
2411         ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
2412         rt->encrypted = 1;
2413     } else {
2414         /* open the tcp connection */
2415         if (port < 0)
2416             port = RTMP_DEFAULT_PORT;
2417         if (rt->listen)
2418             ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port,
2419                         "?listen&listen_timeout=%d",
2420                         rt->listen_timeout * 1000);
2421         else
2422             ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
2423     }
2424
2425 reconnect:
2426     if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
2427                           &s->interrupt_callback, &opts)) < 0) {
2428         av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
2429         goto fail;
2430     }
2431
2432     if (rt->swfverify) {
2433         if ((ret = rtmp_calc_swfhash(s)) < 0)
2434             goto fail;
2435     }
2436
2437     rt->state = STATE_START;
2438     if (!rt->listen && (ret = rtmp_handshake(s, rt)) < 0)
2439         goto fail;
2440     if (rt->listen && (ret = rtmp_server_handshake(s, rt)) < 0)
2441         goto fail;
2442
2443     rt->out_chunk_size = 128;
2444     rt->in_chunk_size  = 128; // Probably overwritten later
2445     rt->state = STATE_HANDSHAKED;
2446
2447     // Keep the application name when it has been defined by the user.
2448     old_app = rt->app;
2449
2450     rt->app = av_malloc(APP_MAX_LENGTH);
2451     if (!rt->app) {
2452         ret = AVERROR(ENOMEM);
2453         goto fail;
2454     }
2455
2456     //extract "app" part from path
2457     if (!strncmp(path, "/ondemand/", 10)) {
2458         fname = path + 10;
2459         memcpy(rt->app, "ondemand", 9);
2460     } else {
2461         char *next = *path ? path + 1 : path;
2462         char *p = strchr(next, '/');
2463         if (!p) {
2464             fname = next;
2465             rt->app[0] = '\0';
2466         } else {
2467             // make sure we do not mismatch a playpath for an application instance
2468             char *c = strchr(p + 1, ':');
2469             fname = strchr(p + 1, '/');
2470             if (!fname || (c && c < fname)) {
2471                 fname = p + 1;
2472                 av_strlcpy(rt->app, path + 1, p - path);
2473             } else {
2474                 fname++;
2475                 av_strlcpy(rt->app, path + 1, fname - path - 1);
2476             }
2477         }
2478     }
2479
2480     if (old_app) {
2481         // The name of application has been defined by the user, override it.
2482         av_free(rt->app);
2483         rt->app = old_app;
2484     }
2485
2486     if (!rt->playpath) {
2487         int len = strlen(fname);
2488
2489         rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
2490         if (!rt->playpath) {
2491             ret = AVERROR(ENOMEM);
2492             goto fail;
2493         }
2494
2495         if (!strchr(fname, ':') && len >= 4 &&
2496             (!strcmp(fname + len - 4, ".f4v") ||
2497              !strcmp(fname + len - 4, ".mp4"))) {
2498             memcpy(rt->playpath, "mp4:", 5);
2499         } else if (len >= 4 && !strcmp(fname + len - 4, ".flv")) {
2500             fname[len - 4] = '\0';
2501         } else {
2502             rt->playpath[0] = 0;
2503         }
2504         av_strlcat(rt->playpath, fname, PLAYPATH_MAX_LENGTH);
2505     }
2506
2507     if (!rt->tcurl) {
2508         rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
2509         if (!rt->tcurl) {
2510             ret = AVERROR(ENOMEM);
2511             goto fail;
2512         }
2513         ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
2514                     port, "/%s", rt->app);
2515     }
2516
2517     if (!rt->flashver) {
2518         rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
2519         if (!rt->flashver) {
2520             ret = AVERROR(ENOMEM);
2521             goto fail;
2522         }
2523         if (rt->is_input) {
2524             snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
2525                     RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
2526                     RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
2527         } else {
2528             snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
2529                     "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
2530         }
2531     }
2532
2533     rt->client_report_size = 1048576;
2534     rt->bytes_read = 0;
2535     rt->last_bytes_read = 0;
2536     rt->server_bw = 2500000;
2537
2538     av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
2539            proto, path, rt->app, rt->playpath);
2540     if (!rt->listen) {
2541         if ((ret = gen_connect(s, rt)) < 0)
2542             goto fail;
2543     } else {
2544         if (read_connect(s, s->priv_data) < 0)
2545             goto fail;
2546     }
2547
2548     do {
2549         ret = get_packet(s, 1);
2550     } while (ret == AVERROR(EAGAIN));
2551     if (ret < 0)
2552         goto fail;
2553
2554     if (rt->do_reconnect) {
2555         ffurl_close(rt->stream);
2556         rt->stream       = NULL;
2557         rt->do_reconnect = 0;
2558         rt->nb_invokes   = 0;
2559         memset(rt->prev_pkt, 0, sizeof(rt->prev_pkt));
2560         free_tracked_methods(rt);
2561         goto reconnect;
2562     }
2563
2564     if (rt->is_input) {
2565         int err;
2566         // generate FLV header for demuxer
2567         rt->flv_size = 13;
2568         if ((err = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
2569             return err;
2570         rt->flv_off  = 0;
2571         memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
2572     } else {
2573         rt->flv_size = 0;
2574         rt->flv_data = NULL;
2575         rt->flv_off  = 0;
2576         rt->skip_bytes = 13;
2577     }
2578
2579     s->max_packet_size = rt->stream->max_packet_size;
2580     s->is_streamed     = 1;
2581     return 0;
2582
2583 fail:
2584     av_dict_free(&opts);
2585     rtmp_close(s);
2586     return ret;
2587 }
2588
2589 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
2590 {
2591     RTMPContext *rt = s->priv_data;
2592     int orig_size = size;
2593     int ret;
2594
2595     while (size > 0) {
2596         int data_left = rt->flv_size - rt->flv_off;
2597
2598         if (data_left >= size) {
2599             memcpy(buf, rt->flv_data + rt->flv_off, size);
2600             rt->flv_off += size;
2601             return orig_size;
2602         }
2603         if (data_left > 0) {
2604             memcpy(buf, rt->flv_data + rt->flv_off, data_left);
2605             buf  += data_left;
2606             size -= data_left;
2607             rt->flv_off = rt->flv_size;
2608             return data_left;
2609         }
2610         if ((ret = get_packet(s, 0)) < 0)
2611            return ret;
2612     }
2613     return orig_size;
2614 }
2615
2616 static int64_t rtmp_seek(URLContext *s, int stream_index, int64_t timestamp,
2617                          int flags)
2618 {
2619     RTMPContext *rt = s->priv_data;
2620     int ret;
2621     av_log(s, AV_LOG_DEBUG,
2622            "Seek on stream index %d at timestamp %"PRId64" with flags %08x\n",
2623            stream_index, timestamp, flags);
2624     if ((ret = gen_seek(s, rt, timestamp)) < 0) {
2625         av_log(s, AV_LOG_ERROR,
2626                "Unable to send seek command on stream index %d at timestamp "
2627                "%"PRId64" with flags %08x\n",
2628                stream_index, timestamp, flags);
2629         return ret;
2630     }
2631     rt->flv_off = rt->flv_size;
2632     rt->state = STATE_SEEKING;
2633     return timestamp;
2634 }
2635
2636 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
2637 {
2638     RTMPContext *rt = s->priv_data;
2639     int size_temp = size;
2640     int pktsize, pkttype;
2641     uint32_t ts;
2642     const uint8_t *buf_temp = buf;
2643     uint8_t c;
2644     int ret;
2645
2646     do {
2647         if (rt->skip_bytes) {
2648             int skip = FFMIN(rt->skip_bytes, size_temp);
2649             buf_temp       += skip;
2650             size_temp      -= skip;
2651             rt->skip_bytes -= skip;
2652             continue;
2653         }
2654
2655         if (rt->flv_header_bytes < RTMP_HEADER) {
2656             const uint8_t *header = rt->flv_header;
2657             int copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp);
2658             int channel = RTMP_AUDIO_CHANNEL;
2659             bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
2660             rt->flv_header_bytes += copy;
2661             size_temp            -= copy;
2662             if (rt->flv_header_bytes < RTMP_HEADER)
2663                 break;
2664
2665             pkttype = bytestream_get_byte(&header);
2666             pktsize = bytestream_get_be24(&header);
2667             ts = bytestream_get_be24(&header);
2668             ts |= bytestream_get_byte(&header) << 24;
2669             bytestream_get_be24(&header);
2670             rt->flv_size = pktsize;
2671
2672             if (pkttype == RTMP_PT_VIDEO)
2673                 channel = RTMP_VIDEO_CHANNEL;
2674
2675             //force 12bytes header
2676             if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
2677                 pkttype == RTMP_PT_NOTIFY) {
2678                 if (pkttype == RTMP_PT_NOTIFY)
2679                     pktsize += 16;
2680                 rt->prev_pkt[1][channel].channel_id = 0;
2681             }
2682
2683             //this can be a big packet, it's better to send it right here
2684             if ((ret = ff_rtmp_packet_create(&rt->out_pkt, channel,
2685                                              pkttype, ts, pktsize)) < 0)
2686                 return ret;
2687
2688             rt->out_pkt.extra = rt->stream_id;
2689             rt->flv_data = rt->out_pkt.data;
2690
2691             if (pkttype == RTMP_PT_NOTIFY)
2692                 ff_amf_write_string(&rt->flv_data, "@setDataFrame");
2693         }
2694
2695         if (rt->flv_size - rt->flv_off > size_temp) {
2696             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
2697             rt->flv_off += size_temp;
2698             size_temp = 0;
2699         } else {
2700             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
2701             size_temp   -= rt->flv_size - rt->flv_off;
2702             rt->flv_off += rt->flv_size - rt->flv_off;
2703         }
2704
2705         if (rt->flv_off == rt->flv_size) {
2706             rt->skip_bytes = 4;
2707
2708             if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
2709                 return ret;
2710             rt->flv_size = 0;
2711             rt->flv_off = 0;
2712             rt->flv_header_bytes = 0;
2713             rt->flv_nb_packets++;
2714         }
2715     } while (buf_temp - buf < size);
2716
2717     if (rt->flv_nb_packets < rt->flush_interval)
2718         return size;
2719     rt->flv_nb_packets = 0;
2720
2721     /* set stream into nonblocking mode */
2722     rt->stream->flags |= AVIO_FLAG_NONBLOCK;
2723
2724     /* try to read one byte from the stream */
2725     ret = ffurl_read(rt->stream, &c, 1);
2726
2727     /* switch the stream back into blocking mode */
2728     rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
2729
2730     if (ret == AVERROR(EAGAIN)) {
2731         /* no incoming data to handle */
2732         return size;
2733     } else if (ret < 0) {
2734         return ret;
2735     } else if (ret == 1) {
2736         RTMPPacket rpkt = { 0 };
2737
2738         if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
2739                                                 rt->in_chunk_size,
2740                                                 rt->prev_pkt[0], c)) <= 0)
2741              return ret;
2742
2743         if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
2744             return ret;
2745
2746         ff_rtmp_packet_destroy(&rpkt);
2747     }
2748
2749     return size;
2750 }
2751
2752 #define OFFSET(x) offsetof(RTMPContext, x)
2753 #define DEC AV_OPT_FLAG_DECODING_PARAM
2754 #define ENC AV_OPT_FLAG_ENCODING_PARAM
2755
2756 static const AVOption rtmp_options[] = {
2757     {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2758     {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {.i64 = 3000}, 0, INT_MAX, DEC|ENC},
2759     {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2760     {"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},
2761     {"rtmp_flush_interval", "Number of packets flushed in the same request (RTMPT only).", OFFSET(flush_interval), AV_OPT_TYPE_INT, {.i64 = 10}, 0, INT_MAX, ENC},
2762     {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {.i64 = -2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
2763     {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
2764     {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
2765     {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
2766     {"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},
2767     {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2768     {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2769     {"rtmp_swfhash", "SHA256 hash of the decompressed SWF file (32 bytes).", OFFSET(swfhash), AV_OPT_TYPE_BINARY, .flags = DEC},
2770     {"rtmp_swfsize", "Size of the decompressed SWF file, required for SWFVerification.", OFFSET(swfsize), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC},
2771     {"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},
2772     {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically.", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2773     {"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},
2774     {"rtmp_listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2775     {"listen",      "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2776     {"timeout", "Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies -rtmp_listen 1",  OFFSET(listen_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2777     { NULL },
2778 };
2779
2780 #define RTMP_PROTOCOL(flavor)                    \
2781 static const AVClass flavor##_class = {          \
2782     .class_name = #flavor,                       \
2783     .item_name  = av_default_item_name,          \
2784     .option     = rtmp_options,                  \
2785     .version    = LIBAVUTIL_VERSION_INT,         \
2786 };                                               \
2787                                                  \
2788 URLProtocol ff_##flavor##_protocol = {           \
2789     .name           = #flavor,                   \
2790     .url_open       = rtmp_open,                 \
2791     .url_read       = rtmp_read,                 \
2792     .url_read_seek  = rtmp_seek,                 \
2793     .url_write      = rtmp_write,                \
2794     .url_close      = rtmp_close,                \
2795     .priv_data_size = sizeof(RTMPContext),       \
2796     .flags          = URL_PROTOCOL_FLAG_NETWORK, \
2797     .priv_data_class= &flavor##_class,           \
2798 };
2799
2800
2801 RTMP_PROTOCOL(rtmp)
2802 RTMP_PROTOCOL(rtmpe)
2803 RTMP_PROTOCOL(rtmps)
2804 RTMP_PROTOCOL(rtmpt)
2805 RTMP_PROTOCOL(rtmpte)
2806 RTMP_PROTOCOL(rtmpts)