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