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