rtmp: Factorize the code by adding find_tracked_method
[ffmpeg.git] / 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/intfloat.h"
30 #include "libavutil/lfg.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/sha.h"
33 #include "avformat.h"
34 #include "internal.h"
35
36 #include "network.h"
37
38 #include "flv.h"
39 #include "rtmp.h"
40 #include "rtmpcrypt.h"
41 #include "rtmppkt.h"
42 #include "url.h"
43
44 //#define DEBUG
45
46 #define APP_MAX_LENGTH 128
47 #define PLAYPATH_MAX_LENGTH 256
48 #define TCURL_MAX_LENGTH 512
49 #define FLASHVER_MAX_LENGTH 64
50
51 /** RTMP protocol handler state */
52 typedef enum {
53     STATE_START,      ///< client has not done anything yet
54     STATE_HANDSHAKED, ///< client has performed handshake
55     STATE_FCPUBLISH,  ///< client FCPublishing stream (for output)
56     STATE_PLAYING,    ///< client has started receiving multimedia data from server
57     STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
58     STATE_STOPPED,    ///< the broadcast has been stopped
59 } ClientState;
60
61 typedef struct TrackedMethod {
62     char *name;
63     int id;
64 } TrackedMethod;
65
66 /** protocol handler context */
67 typedef struct RTMPContext {
68     const AVClass *class;
69     URLContext*   stream;                     ///< TCP stream used in interactions with RTMP server
70     RTMPPacket    prev_pkt[2][RTMP_CHANNELS]; ///< packet history used when reading and sending packets
71     int           chunk_size;                 ///< size of the chunks RTMP packets are divided into
72     int           is_input;                   ///< input/output flag
73     char          *playpath;                  ///< stream identifier to play (with possible "mp4:" prefix)
74     int           live;                       ///< 0: recorded, -1: live, -2: both
75     char          *app;                       ///< name of application
76     char          *conn;                      ///< append arbitrary AMF data to the Connect message
77     ClientState   state;                      ///< current state
78     int           main_channel_id;            ///< an additional channel ID which is used for some invocations
79     uint8_t*      flv_data;                   ///< buffer with data for demuxer
80     int           flv_size;                   ///< current buffer size
81     int           flv_off;                    ///< number of bytes read from current buffer
82     int           flv_nb_packets;             ///< number of flv packets published
83     RTMPPacket    out_pkt;                    ///< rtmp packet, created from flv a/v or metadata (for output)
84     uint32_t      client_report_size;         ///< number of bytes after which client should report to server
85     uint32_t      bytes_read;                 ///< number of bytes read from server
86     uint32_t      last_bytes_read;            ///< number of bytes read last reported to server
87     int           skip_bytes;                 ///< number of bytes to skip from the input FLV stream in the next write call
88     uint8_t       flv_header[11];             ///< partial incoming flv packet header
89     int           flv_header_bytes;           ///< number of initialized bytes in flv_header
90     int           nb_invokes;                 ///< keeps track of invoke messages
91     char*         tcurl;                      ///< url of the target stream
92     char*         flashver;                   ///< version of the flash plugin
93     char*         swfurl;                     ///< url of the swf player
94     char*         pageurl;                    ///< url of the web page
95     char*         subscribe;                  ///< name of live stream to subscribe
96     int           server_bw;                  ///< server bandwidth
97     int           client_buffer_time;         ///< client buffer time in ms
98     int           flush_interval;             ///< number of packets flushed in the same request (RTMPT only)
99     int           encrypted;                  ///< use an encrypted connection (RTMPE only)
100     TrackedMethod*tracked_methods;            ///< tracked methods buffer
101     int           nb_tracked_methods;         ///< number of tracked methods
102     int           tracked_methods_size;       ///< size of the tracked methods buffer
103 } RTMPContext;
104
105 #define PLAYER_KEY_OPEN_PART_LEN 30   ///< length of partial key used for first client digest signing
106 /** Client key used for digest signing */
107 static const uint8_t rtmp_player_key[] = {
108     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
109     'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
110
111     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
112     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
113     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
114 };
115
116 #define SERVER_KEY_OPEN_PART_LEN 36   ///< length of partial key used for first server digest signing
117 /** Key used for RTMP server digest signing */
118 static const uint8_t rtmp_server_key[] = {
119     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
120     'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
121     'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
122
123     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
124     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
125     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
126 };
127
128 static int add_tracked_method(RTMPContext *rt, const char *name, int id)
129 {
130     void *ptr;
131
132     if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
133         rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
134         ptr = av_realloc(rt->tracked_methods,
135                          rt->tracked_methods_size * sizeof(*rt->tracked_methods));
136         if (!ptr)
137             return AVERROR(ENOMEM);
138         rt->tracked_methods = ptr;
139     }
140
141     rt->tracked_methods[rt->nb_tracked_methods].name = av_strdup(name);
142     if (!rt->tracked_methods[rt->nb_tracked_methods].name)
143         return AVERROR(ENOMEM);
144     rt->tracked_methods[rt->nb_tracked_methods].id = id;
145     rt->nb_tracked_methods++;
146
147     return 0;
148 }
149
150 static void del_tracked_method(RTMPContext *rt, int index)
151 {
152     memmove(&rt->tracked_methods[index], &rt->tracked_methods[index + 1],
153             sizeof(*rt->tracked_methods) * (rt->nb_tracked_methods - index - 1));
154     rt->nb_tracked_methods--;
155 }
156
157 static int find_tracked_method(URLContext *s, RTMPPacket *pkt, int offset,
158                                char **tracked_method)
159 {
160     RTMPContext *rt = s->priv_data;
161     GetByteContext gbc;
162     double pkt_id;
163     int ret;
164     int i;
165
166     bytestream2_init(&gbc, pkt->data + offset, pkt->data_size - offset);
167     if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
168         return ret;
169
170     for (i = 0; i < rt->nb_tracked_methods; i++) {
171         if (rt->tracked_methods[i].id != pkt_id)
172             continue;
173
174         *tracked_method = rt->tracked_methods[i].name;
175         del_tracked_method(rt, i);
176         break;
177     }
178
179     return 0;
180 }
181
182 static void free_tracked_methods(RTMPContext *rt)
183 {
184     int i;
185
186     for (i = 0; i < rt->nb_tracked_methods; i ++)
187         av_free(rt->tracked_methods[i].name);
188     av_free(rt->tracked_methods);
189 }
190
191 static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
192 {
193     int ret;
194
195     if (pkt->type == RTMP_PT_INVOKE && track) {
196         GetByteContext gbc;
197         char name[128];
198         double pkt_id;
199         int len;
200
201         bytestream2_init(&gbc, pkt->data, pkt->data_size);
202         if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0)
203             goto fail;
204
205         if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
206             goto fail;
207
208         if ((ret = add_tracked_method(rt, name, pkt_id)) < 0)
209             goto fail;
210     }
211
212     ret = ff_rtmp_packet_write(rt->stream, pkt, rt->chunk_size,
213                                rt->prev_pkt[1]);
214 fail:
215     ff_rtmp_packet_destroy(pkt);
216     return ret;
217 }
218
219 static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)
220 {
221     char *field, *value;
222     char type;
223
224     /* The type must be B for Boolean, N for number, S for string, O for
225      * object, or Z for null. For Booleans the data must be either 0 or 1 for
226      * FALSE or TRUE, respectively. Likewise for Objects the data must be
227      * 0 or 1 to end or begin an object, respectively. Data items in subobjects
228      * may be named, by prefixing the type with 'N' and specifying the name
229      * before the value (ie. NB:myFlag:1). This option may be used multiple times
230      * to construct arbitrary AMF sequences. */
231     if (param[0] && param[1] == ':') {
232         type = param[0];
233         value = param + 2;
234     } else if (param[0] == 'N' && param[1] && param[2] == ':') {
235         type = param[1];
236         field = param + 3;
237         value = strchr(field, ':');
238         if (!value)
239             goto fail;
240         *value = '\0';
241         value++;
242
243         if (!field || !value)
244             goto fail;
245
246         ff_amf_write_field_name(p, field);
247     } else {
248         goto fail;
249     }
250
251     switch (type) {
252     case 'B':
253         ff_amf_write_bool(p, value[0] != '0');
254         break;
255     case 'S':
256         ff_amf_write_string(p, value);
257         break;
258     case 'N':
259         ff_amf_write_number(p, strtod(value, NULL));
260         break;
261     case 'Z':
262         ff_amf_write_null(p);
263         break;
264     case 'O':
265         if (value[0] != '0')
266             ff_amf_write_object_start(p);
267         else
268             ff_amf_write_object_end(p);
269         break;
270     default:
271         goto fail;
272         break;
273     }
274
275     return 0;
276
277 fail:
278     av_log(s, AV_LOG_ERROR, "Invalid AMF parameter: %s\n", param);
279     return AVERROR(EINVAL);
280 }
281
282 /**
283  * Generate 'connect' call and send it to the server.
284  */
285 static int gen_connect(URLContext *s, RTMPContext *rt)
286 {
287     RTMPPacket pkt;
288     uint8_t *p;
289     int ret;
290
291     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
292                                      0, 4096)) < 0)
293         return ret;
294
295     p = pkt.data;
296
297     ff_amf_write_string(&p, "connect");
298     ff_amf_write_number(&p, ++rt->nb_invokes);
299     ff_amf_write_object_start(&p);
300     ff_amf_write_field_name(&p, "app");
301     ff_amf_write_string(&p, rt->app);
302
303     if (!rt->is_input) {
304         ff_amf_write_field_name(&p, "type");
305         ff_amf_write_string(&p, "nonprivate");
306     }
307     ff_amf_write_field_name(&p, "flashVer");
308     ff_amf_write_string(&p, rt->flashver);
309
310     if (rt->swfurl) {
311         ff_amf_write_field_name(&p, "swfUrl");
312         ff_amf_write_string(&p, rt->swfurl);
313     }
314
315     ff_amf_write_field_name(&p, "tcUrl");
316     ff_amf_write_string(&p, rt->tcurl);
317     if (rt->is_input) {
318         ff_amf_write_field_name(&p, "fpad");
319         ff_amf_write_bool(&p, 0);
320         ff_amf_write_field_name(&p, "capabilities");
321         ff_amf_write_number(&p, 15.0);
322
323         /* Tell the server we support all the audio codecs except
324          * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)
325          * which are unused in the RTMP protocol implementation. */
326         ff_amf_write_field_name(&p, "audioCodecs");
327         ff_amf_write_number(&p, 4071.0);
328         ff_amf_write_field_name(&p, "videoCodecs");
329         ff_amf_write_number(&p, 252.0);
330         ff_amf_write_field_name(&p, "videoFunction");
331         ff_amf_write_number(&p, 1.0);
332
333         if (rt->pageurl) {
334             ff_amf_write_field_name(&p, "pageUrl");
335             ff_amf_write_string(&p, rt->pageurl);
336         }
337     }
338     ff_amf_write_object_end(&p);
339
340     if (rt->conn) {
341         char *param = rt->conn;
342
343         // Write arbitrary AMF data to the Connect message.
344         while (param != NULL) {
345             char *sep;
346             param += strspn(param, " ");
347             if (!*param)
348                 break;
349             sep = strchr(param, ' ');
350             if (sep)
351                 *sep = '\0';
352             if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) {
353                 // Invalid AMF parameter.
354                 ff_rtmp_packet_destroy(&pkt);
355                 return ret;
356             }
357
358             if (sep)
359                 param = sep + 1;
360             else
361                 break;
362         }
363     }
364
365     pkt.data_size = p - pkt.data;
366
367     return rtmp_send_packet(rt, &pkt, 1);
368 }
369
370 /**
371  * Generate 'releaseStream' call and send it to the server. It should make
372  * the server release some channel for media streams.
373  */
374 static int gen_release_stream(URLContext *s, RTMPContext *rt)
375 {
376     RTMPPacket pkt;
377     uint8_t *p;
378     int ret;
379
380     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
381                                      0, 29 + strlen(rt->playpath))) < 0)
382         return ret;
383
384     av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
385     p = pkt.data;
386     ff_amf_write_string(&p, "releaseStream");
387     ff_amf_write_number(&p, ++rt->nb_invokes);
388     ff_amf_write_null(&p);
389     ff_amf_write_string(&p, rt->playpath);
390
391     return rtmp_send_packet(rt, &pkt, 0);
392 }
393
394 /**
395  * Generate 'FCPublish' call and send it to the server. It should make
396  * the server preapare for receiving media streams.
397  */
398 static int gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
399 {
400     RTMPPacket pkt;
401     uint8_t *p;
402     int ret;
403
404     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
405                                      0, 25 + strlen(rt->playpath))) < 0)
406         return ret;
407
408     av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
409     p = pkt.data;
410     ff_amf_write_string(&p, "FCPublish");
411     ff_amf_write_number(&p, ++rt->nb_invokes);
412     ff_amf_write_null(&p);
413     ff_amf_write_string(&p, rt->playpath);
414
415     return rtmp_send_packet(rt, &pkt, 0);
416 }
417
418 /**
419  * Generate 'FCUnpublish' call and send it to the server. It should make
420  * the server destroy stream.
421  */
422 static int gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
423 {
424     RTMPPacket pkt;
425     uint8_t *p;
426     int ret;
427
428     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
429                                      0, 27 + strlen(rt->playpath))) < 0)
430         return ret;
431
432     av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
433     p = pkt.data;
434     ff_amf_write_string(&p, "FCUnpublish");
435     ff_amf_write_number(&p, ++rt->nb_invokes);
436     ff_amf_write_null(&p);
437     ff_amf_write_string(&p, rt->playpath);
438
439     return rtmp_send_packet(rt, &pkt, 0);
440 }
441
442 /**
443  * Generate 'createStream' call and send it to the server. It should make
444  * the server allocate some channel for media streams.
445  */
446 static int gen_create_stream(URLContext *s, RTMPContext *rt)
447 {
448     RTMPPacket pkt;
449     uint8_t *p;
450     int ret;
451
452     av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
453
454     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
455                                      0, 25)) < 0)
456         return ret;
457
458     p = pkt.data;
459     ff_amf_write_string(&p, "createStream");
460     ff_amf_write_number(&p, ++rt->nb_invokes);
461     ff_amf_write_null(&p);
462
463     return rtmp_send_packet(rt, &pkt, 1);
464 }
465
466
467 /**
468  * Generate 'deleteStream' call and send it to the server. It should make
469  * the server remove some channel for media streams.
470  */
471 static int gen_delete_stream(URLContext *s, RTMPContext *rt)
472 {
473     RTMPPacket pkt;
474     uint8_t *p;
475     int ret;
476
477     av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
478
479     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
480                                      0, 34)) < 0)
481         return ret;
482
483     p = pkt.data;
484     ff_amf_write_string(&p, "deleteStream");
485     ff_amf_write_number(&p, ++rt->nb_invokes);
486     ff_amf_write_null(&p);
487     ff_amf_write_number(&p, rt->main_channel_id);
488
489     return rtmp_send_packet(rt, &pkt, 0);
490 }
491
492 /**
493  * Generate client buffer time and send it to the server.
494  */
495 static int gen_buffer_time(URLContext *s, RTMPContext *rt)
496 {
497     RTMPPacket pkt;
498     uint8_t *p;
499     int ret;
500
501     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
502                                      1, 10)) < 0)
503         return ret;
504
505     p = pkt.data;
506     bytestream_put_be16(&p, 3);
507     bytestream_put_be32(&p, rt->main_channel_id);
508     bytestream_put_be32(&p, rt->client_buffer_time);
509
510     return rtmp_send_packet(rt, &pkt, 0);
511 }
512
513 /**
514  * Generate 'play' call and send it to the server, then ping the server
515  * to start actual playing.
516  */
517 static int gen_play(URLContext *s, RTMPContext *rt)
518 {
519     RTMPPacket pkt;
520     uint8_t *p;
521     int ret;
522
523     av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
524
525     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE,
526                                      0, 29 + strlen(rt->playpath))) < 0)
527         return ret;
528
529     pkt.extra = rt->main_channel_id;
530
531     p = pkt.data;
532     ff_amf_write_string(&p, "play");
533     ff_amf_write_number(&p, ++rt->nb_invokes);
534     ff_amf_write_null(&p);
535     ff_amf_write_string(&p, rt->playpath);
536     ff_amf_write_number(&p, rt->live);
537
538     return rtmp_send_packet(rt, &pkt, 1);
539 }
540
541 /**
542  * Generate 'publish' call and send it to the server.
543  */
544 static int gen_publish(URLContext *s, RTMPContext *rt)
545 {
546     RTMPPacket pkt;
547     uint8_t *p;
548     int ret;
549
550     av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
551
552     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
553                                      0, 30 + strlen(rt->playpath))) < 0)
554         return ret;
555
556     pkt.extra = rt->main_channel_id;
557
558     p = pkt.data;
559     ff_amf_write_string(&p, "publish");
560     ff_amf_write_number(&p, ++rt->nb_invokes);
561     ff_amf_write_null(&p);
562     ff_amf_write_string(&p, rt->playpath);
563     ff_amf_write_string(&p, "live");
564
565     return rtmp_send_packet(rt, &pkt, 1);
566 }
567
568 /**
569  * Generate ping reply and send it to the server.
570  */
571 static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
572 {
573     RTMPPacket pkt;
574     uint8_t *p;
575     int ret;
576
577     if (ppkt->data_size < 6) {
578         av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
579                ppkt->data_size);
580         return AVERROR_INVALIDDATA;
581     }
582
583     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
584                                      ppkt->timestamp + 1, 6)) < 0)
585         return ret;
586
587     p = pkt.data;
588     bytestream_put_be16(&p, 7);
589     bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
590
591     return rtmp_send_packet(rt, &pkt, 0);
592 }
593
594 /**
595  * Generate server bandwidth message and send it to the server.
596  */
597 static int gen_server_bw(URLContext *s, RTMPContext *rt)
598 {
599     RTMPPacket pkt;
600     uint8_t *p;
601     int ret;
602
603     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_SERVER_BW,
604                                      0, 4)) < 0)
605         return ret;
606
607     p = pkt.data;
608     bytestream_put_be32(&p, rt->server_bw);
609
610     return rtmp_send_packet(rt, &pkt, 0);
611 }
612
613 /**
614  * Generate check bandwidth message and send it to the server.
615  */
616 static int gen_check_bw(URLContext *s, RTMPContext *rt)
617 {
618     RTMPPacket pkt;
619     uint8_t *p;
620     int ret;
621
622     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
623                                      0, 21)) < 0)
624         return ret;
625
626     p = pkt.data;
627     ff_amf_write_string(&p, "_checkbw");
628     ff_amf_write_number(&p, RTMP_NOTIFICATION);
629     ff_amf_write_null(&p);
630
631     return rtmp_send_packet(rt, &pkt, 0);
632 }
633
634 /**
635  * Generate report on bytes read so far and send it to the server.
636  */
637 static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
638 {
639     RTMPPacket pkt;
640     uint8_t *p;
641     int ret;
642
643     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ,
644                                      ts, 4)) < 0)
645         return ret;
646
647     p = pkt.data;
648     bytestream_put_be32(&p, rt->bytes_read);
649
650     return rtmp_send_packet(rt, &pkt, 0);
651 }
652
653 static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt,
654                                   const char *subscribe)
655 {
656     RTMPPacket pkt;
657     uint8_t *p;
658     int ret;
659
660     if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
661                                      0, 27 + strlen(subscribe))) < 0)
662         return ret;
663
664     p = pkt.data;
665     ff_amf_write_string(&p, "FCSubscribe");
666     ff_amf_write_number(&p, ++rt->nb_invokes);
667     ff_amf_write_null(&p);
668     ff_amf_write_string(&p, subscribe);
669
670     return rtmp_send_packet(rt, &pkt, 1);
671 }
672
673 int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap,
674                         const uint8_t *key, int keylen, uint8_t *dst)
675 {
676     struct AVSHA *sha;
677     uint8_t hmac_buf[64+32] = {0};
678     int i;
679
680     sha = av_mallocz(av_sha_size);
681     if (!sha)
682         return AVERROR(ENOMEM);
683
684     if (keylen < 64) {
685         memcpy(hmac_buf, key, keylen);
686     } else {
687         av_sha_init(sha, 256);
688         av_sha_update(sha,key, keylen);
689         av_sha_final(sha, hmac_buf);
690     }
691     for (i = 0; i < 64; i++)
692         hmac_buf[i] ^= HMAC_IPAD_VAL;
693
694     av_sha_init(sha, 256);
695     av_sha_update(sha, hmac_buf, 64);
696     if (gap <= 0) {
697         av_sha_update(sha, src, len);
698     } else { //skip 32 bytes used for storing digest
699         av_sha_update(sha, src, gap);
700         av_sha_update(sha, src + gap + 32, len - gap - 32);
701     }
702     av_sha_final(sha, hmac_buf + 64);
703
704     for (i = 0; i < 64; i++)
705         hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad
706     av_sha_init(sha, 256);
707     av_sha_update(sha, hmac_buf, 64+32);
708     av_sha_final(sha, dst);
709
710     av_free(sha);
711
712     return 0;
713 }
714
715 int ff_rtmp_calc_digest_pos(const uint8_t *buf, int off, int mod_val,
716                             int add_val)
717 {
718     int i, digest_pos = 0;
719
720     for (i = 0; i < 4; i++)
721         digest_pos += buf[i + off];
722     digest_pos = digest_pos % mod_val + add_val;
723
724     return digest_pos;
725 }
726
727 /**
728  * Put HMAC-SHA2 digest of packet data (except for the bytes where this digest
729  * will be stored) into that packet.
730  *
731  * @param buf handshake data (1536 bytes)
732  * @param encrypted use an encrypted connection (RTMPE)
733  * @return offset to the digest inside input data
734  */
735 static int rtmp_handshake_imprint_with_digest(uint8_t *buf, int encrypted)
736 {
737     int ret, digest_pos;
738
739     if (encrypted)
740         digest_pos = ff_rtmp_calc_digest_pos(buf, 772, 728, 776);
741     else
742         digest_pos = ff_rtmp_calc_digest_pos(buf, 8, 728, 12);
743
744     ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
745                               rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
746                               buf + digest_pos);
747     if (ret < 0)
748         return ret;
749
750     return digest_pos;
751 }
752
753 /**
754  * Verify that the received server response has the expected digest value.
755  *
756  * @param buf handshake data received from the server (1536 bytes)
757  * @param off position to search digest offset from
758  * @return 0 if digest is valid, digest position otherwise
759  */
760 static int rtmp_validate_digest(uint8_t *buf, int off)
761 {
762     uint8_t digest[32];
763     int ret, digest_pos;
764
765     digest_pos = ff_rtmp_calc_digest_pos(buf, off, 728, off + 4);
766
767     ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
768                               rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
769                               digest);
770     if (ret < 0)
771         return ret;
772
773     if (!memcmp(digest, buf + digest_pos, 32))
774         return digest_pos;
775     return 0;
776 }
777
778 /**
779  * Perform handshake with the server by means of exchanging pseudorandom data
780  * signed with HMAC-SHA2 digest.
781  *
782  * @return 0 if handshake succeeds, negative value otherwise
783  */
784 static int rtmp_handshake(URLContext *s, RTMPContext *rt)
785 {
786     AVLFG rnd;
787     uint8_t tosend    [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
788         3,                // unencrypted data
789         0, 0, 0, 0,       // client uptime
790         RTMP_CLIENT_VER1,
791         RTMP_CLIENT_VER2,
792         RTMP_CLIENT_VER3,
793         RTMP_CLIENT_VER4,
794     };
795     uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
796     uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
797     int i;
798     int server_pos, client_pos;
799     uint8_t digest[32], signature[32];
800     int ret, type = 0;
801
802     av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
803
804     av_lfg_init(&rnd, 0xDEADC0DE);
805     // generate handshake packet - 1536 bytes of pseudorandom data
806     for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
807         tosend[i] = av_lfg_get(&rnd) >> 24;
808
809     if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
810         /* When the client wants to use RTMPE, we have to change the command
811          * byte to 0x06 which means to use encrypted data and we have to set
812          * the flash version to at least 9.0.115.0. */
813         tosend[0] = 6;
814         tosend[5] = 128;
815         tosend[6] = 0;
816         tosend[7] = 3;
817         tosend[8] = 2;
818
819         /* Initialize the Diffie-Hellmann context and generate the public key
820          * to send to the server. */
821         if ((ret = ff_rtmpe_gen_pub_key(rt->stream, tosend + 1)) < 0)
822             return ret;
823     }
824
825     client_pos = rtmp_handshake_imprint_with_digest(tosend + 1, rt->encrypted);
826     if (client_pos < 0)
827         return client_pos;
828
829     if ((ret = ffurl_write(rt->stream, tosend,
830                            RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
831         av_log(s, AV_LOG_ERROR, "Cannot write RTMP handshake request\n");
832         return ret;
833     }
834
835     if ((ret = ffurl_read_complete(rt->stream, serverdata,
836                                    RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
837         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
838         return ret;
839     }
840
841     if ((ret = ffurl_read_complete(rt->stream, clientdata,
842                                    RTMP_HANDSHAKE_PACKET_SIZE)) < 0) {
843         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
844         return ret;
845     }
846
847     av_log(s, AV_LOG_DEBUG, "Type answer %d\n", serverdata[0]);
848     av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
849            serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
850
851     if (rt->is_input && serverdata[5] >= 3) {
852         server_pos = rtmp_validate_digest(serverdata + 1, 772);
853         if (server_pos < 0)
854             return server_pos;
855
856         if (!server_pos) {
857             type = 1;
858             server_pos = rtmp_validate_digest(serverdata + 1, 8);
859             if (server_pos < 0)
860                 return server_pos;
861
862             if (!server_pos) {
863                 av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
864                 return AVERROR(EIO);
865             }
866         }
867
868         ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
869                                   rtmp_server_key, sizeof(rtmp_server_key),
870                                   digest);
871         if (ret < 0)
872             return ret;
873
874         ret = ff_rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE - 32,
875                                   0, digest, 32, signature);
876         if (ret < 0)
877             return ret;
878
879         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
880             /* Compute the shared secret key sent by the server and initialize
881              * the RC4 encryption. */
882             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
883                                                    tosend + 1, type)) < 0)
884                 return ret;
885
886             /* Encrypt the signature received by the server. */
887             ff_rtmpe_encrypt_sig(rt->stream, signature, digest, serverdata[0]);
888         }
889
890         if (memcmp(signature, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
891             av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
892             return AVERROR(EIO);
893         }
894
895         for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
896             tosend[i] = av_lfg_get(&rnd) >> 24;
897         ret = ff_rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
898                                   rtmp_player_key, sizeof(rtmp_player_key),
899                                   digest);
900         if (ret < 0)
901             return ret;
902
903         ret = ff_rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
904                                   digest, 32,
905                                   tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
906         if (ret < 0)
907             return ret;
908
909         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
910             /* Encrypt the signature to be send to the server. */
911             ff_rtmpe_encrypt_sig(rt->stream, tosend +
912                                  RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
913                                  serverdata[0]);
914         }
915
916         // write reply back to the server
917         if ((ret = ffurl_write(rt->stream, tosend,
918                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
919             return ret;
920
921         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
922             /* Set RC4 keys for encryption and update the keystreams. */
923             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
924                 return ret;
925         }
926     } else {
927         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
928             /* Compute the shared secret key sent by the server and initialize
929              * the RC4 encryption. */
930             if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
931                             tosend + 1, 1)) < 0)
932                 return ret;
933
934             if (serverdata[0] == 9) {
935                 /* Encrypt the signature received by the server. */
936                 ff_rtmpe_encrypt_sig(rt->stream, signature, digest,
937                                      serverdata[0]);
938             }
939         }
940
941         if ((ret = ffurl_write(rt->stream, serverdata + 1,
942                                RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
943             return ret;
944
945         if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
946             /* Set RC4 keys for encryption and update the keystreams. */
947             if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
948                 return ret;
949         }
950     }
951
952     return 0;
953 }
954
955 static int handle_chunk_size(URLContext *s, RTMPPacket *pkt)
956 {
957     RTMPContext *rt = s->priv_data;
958     int ret;
959
960     if (pkt->data_size < 4) {
961         av_log(s, AV_LOG_ERROR,
962                "Too short chunk size change packet (%d)\n",
963                pkt->data_size);
964         return AVERROR_INVALIDDATA;
965     }
966
967     if (!rt->is_input) {
968         if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->chunk_size,
969                                         rt->prev_pkt[1])) < 0)
970             return ret;
971     }
972
973     rt->chunk_size = AV_RB32(pkt->data);
974     if (rt->chunk_size <= 0) {
975         av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n", rt->chunk_size);
976         return AVERROR_INVALIDDATA;
977     }
978     av_log(s, AV_LOG_DEBUG, "New chunk size = %d\n", rt->chunk_size);
979
980     return 0;
981 }
982
983 static int handle_ping(URLContext *s, RTMPPacket *pkt)
984 {
985     RTMPContext *rt = s->priv_data;
986     int t, ret;
987
988     if (pkt->data_size < 2) {
989         av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
990                pkt->data_size);
991         return AVERROR_INVALIDDATA;
992     }
993
994     t = AV_RB16(pkt->data);
995     if (t == 6) {
996         if ((ret = gen_pong(s, rt, pkt)) < 0)
997             return ret;
998     }
999
1000     return 0;
1001 }
1002
1003 static int handle_client_bw(URLContext *s, RTMPPacket *pkt)
1004 {
1005     RTMPContext *rt = s->priv_data;
1006
1007     if (pkt->data_size < 4) {
1008         av_log(s, AV_LOG_ERROR,
1009                "Client bandwidth report packet is less than 4 bytes long (%d)\n",
1010                pkt->data_size);
1011         return AVERROR_INVALIDDATA;
1012     }
1013
1014     rt->client_report_size = AV_RB32(pkt->data);
1015     if (rt->client_report_size <= 0) {
1016         av_log(s, AV_LOG_ERROR, "Incorrect client bandwidth %d\n",
1017                 rt->client_report_size);
1018         return AVERROR_INVALIDDATA;
1019
1020     }
1021     av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", rt->client_report_size);
1022     rt->client_report_size >>= 1;
1023
1024     return 0;
1025 }
1026
1027 static int handle_server_bw(URLContext *s, RTMPPacket *pkt)
1028 {
1029     RTMPContext *rt = s->priv_data;
1030
1031     if (pkt->data_size < 4) {
1032         av_log(s, AV_LOG_ERROR,
1033                "Too short server bandwidth report packet (%d)\n",
1034                pkt->data_size);
1035         return AVERROR_INVALIDDATA;
1036     }
1037
1038     rt->server_bw = AV_RB32(pkt->data);
1039     if (rt->server_bw <= 0) {
1040         av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n",
1041                rt->server_bw);
1042         return AVERROR_INVALIDDATA;
1043     }
1044     av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw);
1045
1046     return 0;
1047 }
1048
1049 static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
1050 {
1051     const uint8_t *data_end = pkt->data + pkt->data_size;
1052     uint8_t tmpstr[256];
1053
1054     if (!ff_amf_get_field_value(pkt->data + 9, data_end,
1055                                 "description", tmpstr, sizeof(tmpstr))) {
1056         av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
1057         return -1;
1058     }
1059
1060     return 0;
1061 }
1062
1063 static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
1064 {
1065     RTMPContext *rt = s->priv_data;
1066     char *tracked_method = NULL;
1067     int ret = 0;
1068
1069     if ((ret = find_tracked_method(s, pkt, 10, &tracked_method)) < 0)
1070         return ret;
1071
1072     if (!tracked_method) {
1073         /* Ignore this reply when the current method is not tracked. */
1074         return ret;
1075     }
1076
1077     if (!memcmp(tracked_method, "connect", 7)) {
1078         if (!rt->is_input) {
1079             if ((ret = gen_release_stream(s, rt)) < 0)
1080                 goto fail;
1081
1082             if ((ret = gen_fcpublish_stream(s, rt)) < 0)
1083                 goto fail;
1084         } else {
1085             if ((ret = gen_server_bw(s, rt)) < 0)
1086                 goto fail;
1087         }
1088
1089         if ((ret = gen_create_stream(s, rt)) < 0)
1090             goto fail;
1091
1092         if (rt->is_input) {
1093             /* Send the FCSubscribe command when the name of live
1094              * stream is defined by the user or if it's a live stream. */
1095             if (rt->subscribe) {
1096                 if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
1097                     goto fail;
1098             } else if (rt->live == -1) {
1099                 if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
1100                     goto fail;
1101             }
1102         }
1103     } else if (!memcmp(tracked_method, "createStream", 12)) {
1104         //extract a number from the result
1105         if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
1106             av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
1107         } else {
1108             rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21));
1109         }
1110
1111         if (!rt->is_input) {
1112             if ((ret = gen_publish(s, rt)) < 0)
1113                 goto fail;
1114         } else {
1115             if ((ret = gen_play(s, rt)) < 0)
1116                 goto fail;
1117             if ((ret = gen_buffer_time(s, rt)) < 0)
1118                 goto fail;
1119         }
1120     }
1121
1122 fail:
1123     av_free(tracked_method);
1124     return ret;
1125 }
1126
1127 static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
1128 {
1129     RTMPContext *rt = s->priv_data;
1130     const uint8_t *data_end = pkt->data + pkt->data_size;
1131     const uint8_t *ptr = pkt->data + 11;
1132     uint8_t tmpstr[256];
1133     int i, t;
1134
1135     for (i = 0; i < 2; i++) {
1136         t = ff_amf_tag_size(ptr, data_end);
1137         if (t < 0)
1138             return 1;
1139         ptr += t;
1140     }
1141
1142     t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
1143     if (!t && !strcmp(tmpstr, "error")) {
1144         if (!ff_amf_get_field_value(ptr, data_end,
1145                                     "description", tmpstr, sizeof(tmpstr)))
1146             av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
1147         return -1;
1148     }
1149
1150     t = ff_amf_get_field_value(ptr, data_end, "code", tmpstr, sizeof(tmpstr));
1151     if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
1152     if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
1153     if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
1154     if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
1155
1156     return 0;
1157 }
1158
1159 static int handle_invoke(URLContext *s, RTMPPacket *pkt)
1160 {
1161     RTMPContext *rt = s->priv_data;
1162     int ret = 0;
1163
1164     //TODO: check for the messages sent for wrong state?
1165     if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
1166         if ((ret = handle_invoke_error(s, pkt)) < 0)
1167             return ret;
1168     } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
1169         if ((ret = handle_invoke_result(s, pkt)) < 0)
1170             return ret;
1171     } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
1172         if ((ret = handle_invoke_status(s, pkt)) < 0)
1173             return ret;
1174     } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) {
1175         if ((ret = gen_check_bw(s, rt)) < 0)
1176             return ret;
1177     }
1178
1179     return ret;
1180 }
1181
1182 /**
1183  * Parse received packet and possibly perform some action depending on
1184  * the packet contents.
1185  * @return 0 for no errors, negative values for serious errors which prevent
1186  *         further communications, positive values for uncritical errors
1187  */
1188 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
1189 {
1190     int ret;
1191
1192 #ifdef DEBUG
1193     ff_rtmp_packet_dump(s, pkt);
1194 #endif
1195
1196     switch (pkt->type) {
1197     case RTMP_PT_CHUNK_SIZE:
1198         if ((ret = handle_chunk_size(s, pkt)) < 0)
1199             return ret;
1200         break;
1201     case RTMP_PT_PING:
1202         if ((ret = handle_ping(s, pkt)) < 0)
1203             return ret;
1204         break;
1205     case RTMP_PT_CLIENT_BW:
1206         if ((ret = handle_client_bw(s, pkt)) < 0)
1207             return ret;
1208         break;
1209     case RTMP_PT_SERVER_BW:
1210         if ((ret = handle_server_bw(s, pkt)) < 0)
1211             return ret;
1212         break;
1213     case RTMP_PT_INVOKE:
1214         if ((ret = handle_invoke(s, pkt)) < 0)
1215             return ret;
1216         break;
1217     case RTMP_PT_VIDEO:
1218     case RTMP_PT_AUDIO:
1219     case RTMP_PT_METADATA:
1220         /* Audio, Video and Metadata packets are parsed in get_packet() */
1221         break;
1222     default:
1223         av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
1224         break;
1225     }
1226     return 0;
1227 }
1228
1229 /**
1230  * Interact with the server by receiving and sending RTMP packets until
1231  * there is some significant data (media data or expected status notification).
1232  *
1233  * @param s          reading context
1234  * @param for_header non-zero value tells function to work until it
1235  * gets notification from the server that playing has been started,
1236  * otherwise function will work until some media data is received (or
1237  * an error happens)
1238  * @return 0 for successful operation, negative value in case of error
1239  */
1240 static int get_packet(URLContext *s, int for_header)
1241 {
1242     RTMPContext *rt = s->priv_data;
1243     int ret;
1244     uint8_t *p;
1245     const uint8_t *next;
1246     uint32_t data_size;
1247     uint32_t ts, cts, pts=0;
1248
1249     if (rt->state == STATE_STOPPED)
1250         return AVERROR_EOF;
1251
1252     for (;;) {
1253         RTMPPacket rpkt = { 0 };
1254         if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
1255                                        rt->chunk_size, rt->prev_pkt[0])) <= 0) {
1256             if (ret == 0) {
1257                 return AVERROR(EAGAIN);
1258             } else {
1259                 return AVERROR(EIO);
1260             }
1261         }
1262         rt->bytes_read += ret;
1263         if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
1264             av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
1265             if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
1266                 return ret;
1267             rt->last_bytes_read = rt->bytes_read;
1268         }
1269
1270         ret = rtmp_parse_result(s, rt, &rpkt);
1271         if (ret < 0) {//serious error in current packet
1272             ff_rtmp_packet_destroy(&rpkt);
1273             return ret;
1274         }
1275         if (rt->state == STATE_STOPPED) {
1276             ff_rtmp_packet_destroy(&rpkt);
1277             return AVERROR_EOF;
1278         }
1279         if (for_header && (rt->state == STATE_PLAYING || rt->state == STATE_PUBLISHING)) {
1280             ff_rtmp_packet_destroy(&rpkt);
1281             return 0;
1282         }
1283         if (!rpkt.data_size || !rt->is_input) {
1284             ff_rtmp_packet_destroy(&rpkt);
1285             continue;
1286         }
1287         if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
1288            (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
1289             ts = rpkt.timestamp;
1290
1291             // generate packet header and put data into buffer for FLV demuxer
1292             rt->flv_off  = 0;
1293             rt->flv_size = rpkt.data_size + 15;
1294             rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
1295             bytestream_put_byte(&p, rpkt.type);
1296             bytestream_put_be24(&p, rpkt.data_size);
1297             bytestream_put_be24(&p, ts);
1298             bytestream_put_byte(&p, ts >> 24);
1299             bytestream_put_be24(&p, 0);
1300             bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
1301             bytestream_put_be32(&p, 0);
1302             ff_rtmp_packet_destroy(&rpkt);
1303             return 0;
1304         } else if (rpkt.type == RTMP_PT_METADATA) {
1305             // we got raw FLV data, make it available for FLV demuxer
1306             rt->flv_off  = 0;
1307             rt->flv_size = rpkt.data_size;
1308             rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
1309             /* rewrite timestamps */
1310             next = rpkt.data;
1311             ts = rpkt.timestamp;
1312             while (next - rpkt.data < rpkt.data_size - 11) {
1313                 next++;
1314                 data_size = bytestream_get_be24(&next);
1315                 p=next;
1316                 cts = bytestream_get_be24(&next);
1317                 cts |= bytestream_get_byte(&next) << 24;
1318                 if (pts==0)
1319                     pts=cts;
1320                 ts += cts - pts;
1321                 pts = cts;
1322                 bytestream_put_be24(&p, ts);
1323                 bytestream_put_byte(&p, ts >> 24);
1324                 next += data_size + 3 + 4;
1325             }
1326             memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
1327             ff_rtmp_packet_destroy(&rpkt);
1328             return 0;
1329         }
1330         ff_rtmp_packet_destroy(&rpkt);
1331     }
1332 }
1333
1334 static int rtmp_close(URLContext *h)
1335 {
1336     RTMPContext *rt = h->priv_data;
1337     int ret = 0;
1338
1339     if (!rt->is_input) {
1340         rt->flv_data = NULL;
1341         if (rt->out_pkt.data_size)
1342             ff_rtmp_packet_destroy(&rt->out_pkt);
1343         if (rt->state > STATE_FCPUBLISH)
1344             ret = gen_fcunpublish_stream(h, rt);
1345     }
1346     if (rt->state > STATE_HANDSHAKED)
1347         ret = gen_delete_stream(h, rt);
1348
1349     free_tracked_methods(rt);
1350     av_freep(&rt->flv_data);
1351     ffurl_close(rt->stream);
1352     return ret;
1353 }
1354
1355 /**
1356  * Open RTMP connection and verify that the stream can be played.
1357  *
1358  * URL syntax: rtmp://server[:port][/app][/playpath]
1359  *             where 'app' is first one or two directories in the path
1360  *             (e.g. /ondemand/, /flash/live/, etc.)
1361  *             and 'playpath' is a file name (the rest of the path,
1362  *             may be prefixed with "mp4:")
1363  */
1364 static int rtmp_open(URLContext *s, const char *uri, int flags)
1365 {
1366     RTMPContext *rt = s->priv_data;
1367     char proto[8], hostname[256], path[1024], *fname;
1368     char *old_app;
1369     uint8_t buf[2048];
1370     int port;
1371     AVDictionary *opts = NULL;
1372     int ret;
1373
1374     rt->is_input = !(flags & AVIO_FLAG_WRITE);
1375
1376     av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
1377                  path, sizeof(path), s->filename);
1378
1379     if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
1380         if (!strcmp(proto, "rtmpts"))
1381             av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
1382
1383         /* open the http tunneling connection */
1384         ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
1385     } else if (!strcmp(proto, "rtmps")) {
1386         /* open the tls connection */
1387         if (port < 0)
1388             port = RTMPS_DEFAULT_PORT;
1389         ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
1390     } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
1391         if (!strcmp(proto, "rtmpte"))
1392             av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
1393
1394         /* open the encrypted connection */
1395         ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
1396         rt->encrypted = 1;
1397     } else {
1398         /* open the tcp connection */
1399         if (port < 0)
1400             port = RTMP_DEFAULT_PORT;
1401         ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
1402     }
1403
1404     if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
1405                           &s->interrupt_callback, &opts)) < 0) {
1406         av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
1407         goto fail;
1408     }
1409
1410     rt->state = STATE_START;
1411     if ((ret = rtmp_handshake(s, rt)) < 0)
1412         goto fail;
1413
1414     rt->chunk_size = 128;
1415     rt->state = STATE_HANDSHAKED;
1416
1417     // Keep the application name when it has been defined by the user.
1418     old_app = rt->app;
1419
1420     rt->app = av_malloc(APP_MAX_LENGTH);
1421     if (!rt->app) {
1422         ret = AVERROR(ENOMEM);
1423         goto fail;
1424     }
1425
1426     //extract "app" part from path
1427     if (!strncmp(path, "/ondemand/", 10)) {
1428         fname = path + 10;
1429         memcpy(rt->app, "ondemand", 9);
1430     } else {
1431         char *next = *path ? path + 1 : path;
1432         char *p = strchr(next, '/');
1433         if (!p) {
1434             fname = next;
1435             rt->app[0] = '\0';
1436         } else {
1437             // make sure we do not mismatch a playpath for an application instance
1438             char *c = strchr(p + 1, ':');
1439             fname = strchr(p + 1, '/');
1440             if (!fname || (c && c < fname)) {
1441                 fname = p + 1;
1442                 av_strlcpy(rt->app, path + 1, p - path);
1443             } else {
1444                 fname++;
1445                 av_strlcpy(rt->app, path + 1, fname - path - 1);
1446             }
1447         }
1448     }
1449
1450     if (old_app) {
1451         // The name of application has been defined by the user, override it.
1452         av_free(rt->app);
1453         rt->app = old_app;
1454     }
1455
1456     if (!rt->playpath) {
1457         int len = strlen(fname);
1458
1459         rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
1460         if (!rt->playpath) {
1461             ret = AVERROR(ENOMEM);
1462             goto fail;
1463         }
1464
1465         if (!strchr(fname, ':') && len >= 4 &&
1466             (!strcmp(fname + len - 4, ".f4v") ||
1467              !strcmp(fname + len - 4, ".mp4"))) {
1468             memcpy(rt->playpath, "mp4:", 5);
1469         } else if (len >= 4 && !strcmp(fname + len - 4, ".flv")) {
1470             fname[len - 4] = '\0';
1471         } else {
1472             rt->playpath[0] = 0;
1473         }
1474         strncat(rt->playpath, fname, PLAYPATH_MAX_LENGTH - 5);
1475     }
1476
1477     if (!rt->tcurl) {
1478         rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
1479         if (!rt->tcurl) {
1480             ret = AVERROR(ENOMEM);
1481             goto fail;
1482         }
1483         ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
1484                     port, "/%s", rt->app);
1485     }
1486
1487     if (!rt->flashver) {
1488         rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
1489         if (!rt->flashver) {
1490             ret = AVERROR(ENOMEM);
1491             goto fail;
1492         }
1493         if (rt->is_input) {
1494             snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
1495                     RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
1496                     RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
1497         } else {
1498             snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
1499                     "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
1500         }
1501     }
1502
1503     rt->client_report_size = 1048576;
1504     rt->bytes_read = 0;
1505     rt->last_bytes_read = 0;
1506     rt->server_bw = 2500000;
1507
1508     av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
1509            proto, path, rt->app, rt->playpath);
1510     if ((ret = gen_connect(s, rt)) < 0)
1511         goto fail;
1512
1513     do {
1514         ret = get_packet(s, 1);
1515     } while (ret == EAGAIN);
1516     if (ret < 0)
1517         goto fail;
1518
1519     if (rt->is_input) {
1520         // generate FLV header for demuxer
1521         rt->flv_size = 13;
1522         rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
1523         rt->flv_off  = 0;
1524         memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
1525     } else {
1526         rt->flv_size = 0;
1527         rt->flv_data = NULL;
1528         rt->flv_off  = 0;
1529         rt->skip_bytes = 13;
1530     }
1531
1532     s->max_packet_size = rt->stream->max_packet_size;
1533     s->is_streamed     = 1;
1534     return 0;
1535
1536 fail:
1537     av_dict_free(&opts);
1538     rtmp_close(s);
1539     return ret;
1540 }
1541
1542 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
1543 {
1544     RTMPContext *rt = s->priv_data;
1545     int orig_size = size;
1546     int ret;
1547
1548     while (size > 0) {
1549         int data_left = rt->flv_size - rt->flv_off;
1550
1551         if (data_left >= size) {
1552             memcpy(buf, rt->flv_data + rt->flv_off, size);
1553             rt->flv_off += size;
1554             return orig_size;
1555         }
1556         if (data_left > 0) {
1557             memcpy(buf, rt->flv_data + rt->flv_off, data_left);
1558             buf  += data_left;
1559             size -= data_left;
1560             rt->flv_off = rt->flv_size;
1561             return data_left;
1562         }
1563         if ((ret = get_packet(s, 0)) < 0)
1564            return ret;
1565     }
1566     return orig_size;
1567 }
1568
1569 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
1570 {
1571     RTMPContext *rt = s->priv_data;
1572     int size_temp = size;
1573     int pktsize, pkttype;
1574     uint32_t ts;
1575     const uint8_t *buf_temp = buf;
1576     uint8_t c;
1577     int ret;
1578
1579     do {
1580         if (rt->skip_bytes) {
1581             int skip = FFMIN(rt->skip_bytes, size_temp);
1582             buf_temp       += skip;
1583             size_temp      -= skip;
1584             rt->skip_bytes -= skip;
1585             continue;
1586         }
1587
1588         if (rt->flv_header_bytes < 11) {
1589             const uint8_t *header = rt->flv_header;
1590             int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
1591             bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
1592             rt->flv_header_bytes += copy;
1593             size_temp            -= copy;
1594             if (rt->flv_header_bytes < 11)
1595                 break;
1596
1597             pkttype = bytestream_get_byte(&header);
1598             pktsize = bytestream_get_be24(&header);
1599             ts = bytestream_get_be24(&header);
1600             ts |= bytestream_get_byte(&header) << 24;
1601             bytestream_get_be24(&header);
1602             rt->flv_size = pktsize;
1603
1604             //force 12bytes header
1605             if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
1606                 pkttype == RTMP_PT_NOTIFY) {
1607                 if (pkttype == RTMP_PT_NOTIFY)
1608                     pktsize += 16;
1609                 rt->prev_pkt[1][RTMP_SOURCE_CHANNEL].channel_id = 0;
1610             }
1611
1612             //this can be a big packet, it's better to send it right here
1613             if ((ret = ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL,
1614                                              pkttype, ts, pktsize)) < 0)
1615                 return ret;
1616
1617             rt->out_pkt.extra = rt->main_channel_id;
1618             rt->flv_data = rt->out_pkt.data;
1619
1620             if (pkttype == RTMP_PT_NOTIFY)
1621                 ff_amf_write_string(&rt->flv_data, "@setDataFrame");
1622         }
1623
1624         if (rt->flv_size - rt->flv_off > size_temp) {
1625             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
1626             rt->flv_off += size_temp;
1627             size_temp = 0;
1628         } else {
1629             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
1630             size_temp   -= rt->flv_size - rt->flv_off;
1631             rt->flv_off += rt->flv_size - rt->flv_off;
1632         }
1633
1634         if (rt->flv_off == rt->flv_size) {
1635             rt->skip_bytes = 4;
1636
1637             if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
1638                 return ret;
1639             rt->flv_size = 0;
1640             rt->flv_off = 0;
1641             rt->flv_header_bytes = 0;
1642             rt->flv_nb_packets++;
1643         }
1644     } while (buf_temp - buf < size);
1645
1646     if (rt->flv_nb_packets < rt->flush_interval)
1647         return size;
1648     rt->flv_nb_packets = 0;
1649
1650     /* set stream into nonblocking mode */
1651     rt->stream->flags |= AVIO_FLAG_NONBLOCK;
1652
1653     /* try to read one byte from the stream */
1654     ret = ffurl_read(rt->stream, &c, 1);
1655
1656     /* switch the stream back into blocking mode */
1657     rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
1658
1659     if (ret == AVERROR(EAGAIN)) {
1660         /* no incoming data to handle */
1661         return size;
1662     } else if (ret < 0) {
1663         return ret;
1664     } else if (ret == 1) {
1665         RTMPPacket rpkt = { 0 };
1666
1667         if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
1668                                                 rt->chunk_size,
1669                                                 rt->prev_pkt[0], c)) <= 0)
1670              return ret;
1671
1672         if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
1673             return ret;
1674
1675         ff_rtmp_packet_destroy(&rpkt);
1676     }
1677
1678     return size;
1679 }
1680
1681 #define OFFSET(x) offsetof(RTMPContext, x)
1682 #define DEC AV_OPT_FLAG_DECODING_PARAM
1683 #define ENC AV_OPT_FLAG_ENCODING_PARAM
1684
1685 static const AVOption rtmp_options[] = {
1686     {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1687     {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {3000}, 0, INT_MAX, DEC|ENC},
1688     {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1689     {"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},
1690     {"rtmp_flush_interval", "Number of packets flushed in the same request (RTMPT only).", OFFSET(flush_interval), AV_OPT_TYPE_INT, {10}, 0, INT_MAX, ENC},
1691     {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
1692     {"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"},
1693     {"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"},
1694     {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {0}, 0, 0, DEC, "rtmp_live"},
1695     {"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},
1696     {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1697     {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
1698     {"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},
1699     {"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},
1700     { NULL },
1701 };
1702
1703 #define RTMP_PROTOCOL(flavor)                    \
1704 static const AVClass flavor##_class = {          \
1705     .class_name = #flavor,                       \
1706     .item_name  = av_default_item_name,          \
1707     .option     = rtmp_options,                  \
1708     .version    = LIBAVUTIL_VERSION_INT,         \
1709 };                                               \
1710                                                  \
1711 URLProtocol ff_##flavor##_protocol = {           \
1712     .name           = #flavor,                   \
1713     .url_open       = rtmp_open,                 \
1714     .url_read       = rtmp_read,                 \
1715     .url_write      = rtmp_write,                \
1716     .url_close      = rtmp_close,                \
1717     .priv_data_size = sizeof(RTMPContext),       \
1718     .flags          = URL_PROTOCOL_FLAG_NETWORK, \
1719     .priv_data_class= &flavor##_class,           \
1720 };
1721
1722
1723 RTMP_PROTOCOL(rtmp)
1724 RTMP_PROTOCOL(rtmpe)
1725 RTMP_PROTOCOL(rtmps)
1726 RTMP_PROTOCOL(rtmpt)
1727 RTMP_PROTOCOL(rtmpte)
1728 RTMP_PROTOCOL(rtmpts)