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