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