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