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