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