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