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