rtmp: Gracefully ignore _checkbw errors by tracking them
[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           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, ++rt->nb_invokes);
630     ff_amf_write_null(&p);
631
632     return rtmp_send_packet(rt, &pkt, 1);
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     char *tracked_method = NULL;
1059     int level = AV_LOG_ERROR;
1060     uint8_t tmpstr[256];
1061     int ret;
1062
1063     if ((ret = find_tracked_method(s, pkt, 9, &tracked_method)) < 0)
1064         return ret;
1065
1066     if (!ff_amf_get_field_value(pkt->data + 9, data_end,
1067                                 "description", tmpstr, sizeof(tmpstr))) {
1068         if (tracked_method && !strcmp(tracked_method, "_checkbw")) {
1069             /* Ignore _checkbw errors. */
1070             level = AV_LOG_WARNING;
1071             ret = 0;
1072         } else
1073             ret = -1;
1074         av_log(s, level, "Server error: %s\n", tmpstr);
1075     }
1076
1077     av_free(tracked_method);
1078     return ret;
1079 }
1080
1081 static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
1082 {
1083     RTMPContext *rt = s->priv_data;
1084     char *tracked_method = NULL;
1085     int ret = 0;
1086
1087     if ((ret = find_tracked_method(s, pkt, 10, &tracked_method)) < 0)
1088         return ret;
1089
1090     if (!tracked_method) {
1091         /* Ignore this reply when the current method is not tracked. */
1092         return ret;
1093     }
1094
1095     if (!memcmp(tracked_method, "connect", 7)) {
1096         if (!rt->is_input) {
1097             if ((ret = gen_release_stream(s, rt)) < 0)
1098                 goto fail;
1099
1100             if ((ret = gen_fcpublish_stream(s, rt)) < 0)
1101                 goto fail;
1102         } else {
1103             if ((ret = gen_server_bw(s, rt)) < 0)
1104                 goto fail;
1105         }
1106
1107         if ((ret = gen_create_stream(s, rt)) < 0)
1108             goto fail;
1109
1110         if (rt->is_input) {
1111             /* Send the FCSubscribe command when the name of live
1112              * stream is defined by the user or if it's a live stream. */
1113             if (rt->subscribe) {
1114                 if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
1115                     goto fail;
1116             } else if (rt->live == -1) {
1117                 if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
1118                     goto fail;
1119             }
1120         }
1121     } else if (!memcmp(tracked_method, "createStream", 12)) {
1122         //extract a number from the result
1123         if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
1124             av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
1125         } else {
1126             rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21));
1127         }
1128
1129         if (!rt->is_input) {
1130             if ((ret = gen_publish(s, rt)) < 0)
1131                 goto fail;
1132         } else {
1133             if ((ret = gen_play(s, rt)) < 0)
1134                 goto fail;
1135             if ((ret = gen_buffer_time(s, rt)) < 0)
1136                 goto fail;
1137         }
1138     }
1139
1140 fail:
1141     av_free(tracked_method);
1142     return ret;
1143 }
1144
1145 static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
1146 {
1147     RTMPContext *rt = s->priv_data;
1148     const uint8_t *data_end = pkt->data + pkt->data_size;
1149     const uint8_t *ptr = pkt->data + 11;
1150     uint8_t tmpstr[256];
1151     int i, t;
1152
1153     for (i = 0; i < 2; i++) {
1154         t = ff_amf_tag_size(ptr, data_end);
1155         if (t < 0)
1156             return 1;
1157         ptr += t;
1158     }
1159
1160     t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
1161     if (!t && !strcmp(tmpstr, "error")) {
1162         if (!ff_amf_get_field_value(ptr, data_end,
1163                                     "description", tmpstr, sizeof(tmpstr)))
1164             av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
1165         return -1;
1166     }
1167
1168     t = ff_amf_get_field_value(ptr, data_end, "code", tmpstr, sizeof(tmpstr));
1169     if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
1170     if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
1171     if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
1172     if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
1173
1174     return 0;
1175 }
1176
1177 static int handle_invoke(URLContext *s, RTMPPacket *pkt)
1178 {
1179     RTMPContext *rt = s->priv_data;
1180     int ret = 0;
1181
1182     //TODO: check for the messages sent for wrong state?
1183     if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
1184         if ((ret = handle_invoke_error(s, pkt)) < 0)
1185             return ret;
1186     } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
1187         if ((ret = handle_invoke_result(s, pkt)) < 0)
1188             return ret;
1189     } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
1190         if ((ret = handle_invoke_status(s, pkt)) < 0)
1191             return ret;
1192     } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) {
1193         if ((ret = gen_check_bw(s, rt)) < 0)
1194             return ret;
1195     }
1196
1197     return ret;
1198 }
1199
1200 /**
1201  * Parse received packet and possibly perform some action depending on
1202  * the packet contents.
1203  * @return 0 for no errors, negative values for serious errors which prevent
1204  *         further communications, positive values for uncritical errors
1205  */
1206 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
1207 {
1208     int ret;
1209
1210 #ifdef DEBUG
1211     ff_rtmp_packet_dump(s, pkt);
1212 #endif
1213
1214     switch (pkt->type) {
1215     case RTMP_PT_BYTES_READ:
1216         av_dlog(s, "received bytes read report\n");
1217         break;
1218     case RTMP_PT_CHUNK_SIZE:
1219         if ((ret = handle_chunk_size(s, pkt)) < 0)
1220             return ret;
1221         break;
1222     case RTMP_PT_PING:
1223         if ((ret = handle_ping(s, pkt)) < 0)
1224             return ret;
1225         break;
1226     case RTMP_PT_CLIENT_BW:
1227         if ((ret = handle_client_bw(s, pkt)) < 0)
1228             return ret;
1229         break;
1230     case RTMP_PT_SERVER_BW:
1231         if ((ret = handle_server_bw(s, pkt)) < 0)
1232             return ret;
1233         break;
1234     case RTMP_PT_INVOKE:
1235         if ((ret = handle_invoke(s, pkt)) < 0)
1236             return ret;
1237         break;
1238     case RTMP_PT_VIDEO:
1239     case RTMP_PT_AUDIO:
1240     case RTMP_PT_METADATA:
1241         /* Audio, Video and Metadata packets are parsed in get_packet() */
1242         break;
1243     default:
1244         av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
1245         break;
1246     }
1247     return 0;
1248 }
1249
1250 /**
1251  * Interact with the server by receiving and sending RTMP packets until
1252  * there is some significant data (media data or expected status notification).
1253  *
1254  * @param s          reading context
1255  * @param for_header non-zero value tells function to work until it
1256  * gets notification from the server that playing has been started,
1257  * otherwise function will work until some media data is received (or
1258  * an error happens)
1259  * @return 0 for successful operation, negative value in case of error
1260  */
1261 static int get_packet(URLContext *s, int for_header)
1262 {
1263     RTMPContext *rt = s->priv_data;
1264     int ret;
1265     uint8_t *p;
1266     const uint8_t *next;
1267     uint32_t data_size;
1268     uint32_t ts, cts, pts=0;
1269
1270     if (rt->state == STATE_STOPPED)
1271         return AVERROR_EOF;
1272
1273     for (;;) {
1274         RTMPPacket rpkt = { 0 };
1275         if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
1276                                        rt->in_chunk_size, rt->prev_pkt[0])) <= 0) {
1277             if (ret == 0) {
1278                 return AVERROR(EAGAIN);
1279             } else {
1280                 return AVERROR(EIO);
1281             }
1282         }
1283         rt->bytes_read += ret;
1284         if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
1285             av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
1286             if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
1287                 return ret;
1288             rt->last_bytes_read = rt->bytes_read;
1289         }
1290
1291         ret = rtmp_parse_result(s, rt, &rpkt);
1292         if (ret < 0) {//serious error in current packet
1293             ff_rtmp_packet_destroy(&rpkt);
1294             return ret;
1295         }
1296         if (rt->state == STATE_STOPPED) {
1297             ff_rtmp_packet_destroy(&rpkt);
1298             return AVERROR_EOF;
1299         }
1300         if (for_header && (rt->state == STATE_PLAYING || rt->state == STATE_PUBLISHING)) {
1301             ff_rtmp_packet_destroy(&rpkt);
1302             return 0;
1303         }
1304         if (!rpkt.data_size || !rt->is_input) {
1305             ff_rtmp_packet_destroy(&rpkt);
1306             continue;
1307         }
1308         if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
1309            (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
1310             ts = rpkt.timestamp;
1311
1312             // generate packet header and put data into buffer for FLV demuxer
1313             rt->flv_off  = 0;
1314             rt->flv_size = rpkt.data_size + 15;
1315             rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
1316             bytestream_put_byte(&p, rpkt.type);
1317             bytestream_put_be24(&p, rpkt.data_size);
1318             bytestream_put_be24(&p, ts);
1319             bytestream_put_byte(&p, ts >> 24);
1320             bytestream_put_be24(&p, 0);
1321             bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
1322             bytestream_put_be32(&p, 0);
1323             ff_rtmp_packet_destroy(&rpkt);
1324             return 0;
1325         } else if (rpkt.type == RTMP_PT_METADATA) {
1326             // we got raw FLV data, make it available for FLV demuxer
1327             rt->flv_off  = 0;
1328             rt->flv_size = rpkt.data_size;
1329             rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
1330             /* rewrite timestamps */
1331             next = rpkt.data;
1332             ts = rpkt.timestamp;
1333             while (next - rpkt.data < rpkt.data_size - 11) {
1334                 next++;
1335                 data_size = bytestream_get_be24(&next);
1336                 p=next;
1337                 cts = bytestream_get_be24(&next);
1338                 cts |= bytestream_get_byte(&next) << 24;
1339                 if (pts==0)
1340                     pts=cts;
1341                 ts += cts - pts;
1342                 pts = cts;
1343                 bytestream_put_be24(&p, ts);
1344                 bytestream_put_byte(&p, ts >> 24);
1345                 next += data_size + 3 + 4;
1346             }
1347             memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
1348             ff_rtmp_packet_destroy(&rpkt);
1349             return 0;
1350         }
1351         ff_rtmp_packet_destroy(&rpkt);
1352     }
1353 }
1354
1355 static int rtmp_close(URLContext *h)
1356 {
1357     RTMPContext *rt = h->priv_data;
1358     int ret = 0;
1359
1360     if (!rt->is_input) {
1361         rt->flv_data = NULL;
1362         if (rt->out_pkt.data_size)
1363             ff_rtmp_packet_destroy(&rt->out_pkt);
1364         if (rt->state > STATE_FCPUBLISH)
1365             ret = gen_fcunpublish_stream(h, rt);
1366     }
1367     if (rt->state > STATE_HANDSHAKED)
1368         ret = gen_delete_stream(h, rt);
1369
1370     free_tracked_methods(rt);
1371     av_freep(&rt->flv_data);
1372     ffurl_close(rt->stream);
1373     return ret;
1374 }
1375
1376 /**
1377  * Open RTMP connection and verify that the stream can be played.
1378  *
1379  * URL syntax: rtmp://server[:port][/app][/playpath]
1380  *             where 'app' is first one or two directories in the path
1381  *             (e.g. /ondemand/, /flash/live/, etc.)
1382  *             and 'playpath' is a file name (the rest of the path,
1383  *             may be prefixed with "mp4:")
1384  */
1385 static int rtmp_open(URLContext *s, const char *uri, int flags)
1386 {
1387     RTMPContext *rt = s->priv_data;
1388     char proto[8], hostname[256], path[1024], *fname;
1389     char *old_app;
1390     uint8_t buf[2048];
1391     int port;
1392     AVDictionary *opts = NULL;
1393     int ret;
1394
1395     rt->is_input = !(flags & AVIO_FLAG_WRITE);
1396
1397     av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
1398                  path, sizeof(path), s->filename);
1399
1400     if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
1401         if (!strcmp(proto, "rtmpts"))
1402             av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
1403
1404         /* open the http tunneling connection */
1405         ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
1406     } else if (!strcmp(proto, "rtmps")) {
1407         /* open the tls connection */
1408         if (port < 0)
1409             port = RTMPS_DEFAULT_PORT;
1410         ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
1411     } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
1412         if (!strcmp(proto, "rtmpte"))
1413             av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
1414
1415         /* open the encrypted connection */
1416         ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
1417         rt->encrypted = 1;
1418     } else {
1419         /* open the tcp connection */
1420         if (port < 0)
1421             port = RTMP_DEFAULT_PORT;
1422         ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
1423     }
1424
1425     if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
1426                           &s->interrupt_callback, &opts)) < 0) {
1427         av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
1428         goto fail;
1429     }
1430
1431     rt->state = STATE_START;
1432     if ((ret = rtmp_handshake(s, rt)) < 0)
1433         goto fail;
1434
1435     rt->out_chunk_size = 128;
1436     rt->in_chunk_size  = 128; // Probably overwritten later
1437     rt->state = STATE_HANDSHAKED;
1438
1439     // Keep the application name when it has been defined by the user.
1440     old_app = rt->app;
1441
1442     rt->app = av_malloc(APP_MAX_LENGTH);
1443     if (!rt->app) {
1444         ret = AVERROR(ENOMEM);
1445         goto fail;
1446     }
1447
1448     //extract "app" part from path
1449     if (!strncmp(path, "/ondemand/", 10)) {
1450         fname = path + 10;
1451         memcpy(rt->app, "ondemand", 9);
1452     } else {
1453         char *next = *path ? path + 1 : path;
1454         char *p = strchr(next, '/');
1455         if (!p) {
1456             fname = next;
1457             rt->app[0] = '\0';
1458         } else {
1459             // make sure we do not mismatch a playpath for an application instance
1460             char *c = strchr(p + 1, ':');
1461             fname = strchr(p + 1, '/');
1462             if (!fname || (c && c < fname)) {
1463                 fname = p + 1;
1464                 av_strlcpy(rt->app, path + 1, p - path);
1465             } else {
1466                 fname++;
1467                 av_strlcpy(rt->app, path + 1, fname - path - 1);
1468             }
1469         }
1470     }
1471
1472     if (old_app) {
1473         // The name of application has been defined by the user, override it.
1474         av_free(rt->app);
1475         rt->app = old_app;
1476     }
1477
1478     if (!rt->playpath) {
1479         int len = strlen(fname);
1480
1481         rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
1482         if (!rt->playpath) {
1483             ret = AVERROR(ENOMEM);
1484             goto fail;
1485         }
1486
1487         if (!strchr(fname, ':') && len >= 4 &&
1488             (!strcmp(fname + len - 4, ".f4v") ||
1489              !strcmp(fname + len - 4, ".mp4"))) {
1490             memcpy(rt->playpath, "mp4:", 5);
1491         } else if (len >= 4 && !strcmp(fname + len - 4, ".flv")) {
1492             fname[len - 4] = '\0';
1493         } else {
1494             rt->playpath[0] = 0;
1495         }
1496         strncat(rt->playpath, fname, PLAYPATH_MAX_LENGTH - 5);
1497     }
1498
1499     if (!rt->tcurl) {
1500         rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
1501         if (!rt->tcurl) {
1502             ret = AVERROR(ENOMEM);
1503             goto fail;
1504         }
1505         ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
1506                     port, "/%s", rt->app);
1507     }
1508
1509     if (!rt->flashver) {
1510         rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
1511         if (!rt->flashver) {
1512             ret = AVERROR(ENOMEM);
1513             goto fail;
1514         }
1515         if (rt->is_input) {
1516             snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
1517                     RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
1518                     RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
1519         } else {
1520             snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
1521                     "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
1522         }
1523     }
1524
1525     rt->client_report_size = 1048576;
1526     rt->bytes_read = 0;
1527     rt->last_bytes_read = 0;
1528     rt->server_bw = 2500000;
1529
1530     av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
1531            proto, path, rt->app, rt->playpath);
1532     if ((ret = gen_connect(s, rt)) < 0)
1533         goto fail;
1534
1535     do {
1536         ret = get_packet(s, 1);
1537     } while (ret == EAGAIN);
1538     if (ret < 0)
1539         goto fail;
1540
1541     if (rt->is_input) {
1542         // generate FLV header for demuxer
1543         rt->flv_size = 13;
1544         rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
1545         rt->flv_off  = 0;
1546         memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
1547     } else {
1548         rt->flv_size = 0;
1549         rt->flv_data = NULL;
1550         rt->flv_off  = 0;
1551         rt->skip_bytes = 13;
1552     }
1553
1554     s->max_packet_size = rt->stream->max_packet_size;
1555     s->is_streamed     = 1;
1556     return 0;
1557
1558 fail:
1559     av_dict_free(&opts);
1560     rtmp_close(s);
1561     return ret;
1562 }
1563
1564 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
1565 {
1566     RTMPContext *rt = s->priv_data;
1567     int orig_size = size;
1568     int ret;
1569
1570     while (size > 0) {
1571         int data_left = rt->flv_size - rt->flv_off;
1572
1573         if (data_left >= size) {
1574             memcpy(buf, rt->flv_data + rt->flv_off, size);
1575             rt->flv_off += size;
1576             return orig_size;
1577         }
1578         if (data_left > 0) {
1579             memcpy(buf, rt->flv_data + rt->flv_off, data_left);
1580             buf  += data_left;
1581             size -= data_left;
1582             rt->flv_off = rt->flv_size;
1583             return data_left;
1584         }
1585         if ((ret = get_packet(s, 0)) < 0)
1586            return ret;
1587     }
1588     return orig_size;
1589 }
1590
1591 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
1592 {
1593     RTMPContext *rt = s->priv_data;
1594     int size_temp = size;
1595     int pktsize, pkttype;
1596     uint32_t ts;
1597     const uint8_t *buf_temp = buf;
1598     uint8_t c;
1599     int ret;
1600
1601     do {
1602         if (rt->skip_bytes) {
1603             int skip = FFMIN(rt->skip_bytes, size_temp);
1604             buf_temp       += skip;
1605             size_temp      -= skip;
1606             rt->skip_bytes -= skip;
1607             continue;
1608         }
1609
1610         if (rt->flv_header_bytes < 11) {
1611             const uint8_t *header = rt->flv_header;
1612             int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
1613             bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
1614             rt->flv_header_bytes += copy;
1615             size_temp            -= copy;
1616             if (rt->flv_header_bytes < 11)
1617                 break;
1618
1619             pkttype = bytestream_get_byte(&header);
1620             pktsize = bytestream_get_be24(&header);
1621             ts = bytestream_get_be24(&header);
1622             ts |= bytestream_get_byte(&header) << 24;
1623             bytestream_get_be24(&header);
1624             rt->flv_size = pktsize;
1625
1626             //force 12bytes header
1627             if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
1628                 pkttype == RTMP_PT_NOTIFY) {
1629                 if (pkttype == RTMP_PT_NOTIFY)
1630                     pktsize += 16;
1631                 rt->prev_pkt[1][RTMP_SOURCE_CHANNEL].channel_id = 0;
1632             }
1633
1634             //this can be a big packet, it's better to send it right here
1635             if ((ret = ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL,
1636                                              pkttype, ts, pktsize)) < 0)
1637                 return ret;
1638
1639             rt->out_pkt.extra = rt->main_channel_id;
1640             rt->flv_data = rt->out_pkt.data;
1641
1642             if (pkttype == RTMP_PT_NOTIFY)
1643                 ff_amf_write_string(&rt->flv_data, "@setDataFrame");
1644         }
1645
1646         if (rt->flv_size - rt->flv_off > size_temp) {
1647             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
1648             rt->flv_off += size_temp;
1649             size_temp = 0;
1650         } else {
1651             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
1652             size_temp   -= rt->flv_size - rt->flv_off;
1653             rt->flv_off += rt->flv_size - rt->flv_off;
1654         }
1655
1656         if (rt->flv_off == rt->flv_size) {
1657             rt->skip_bytes = 4;
1658
1659             if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
1660                 return ret;
1661             rt->flv_size = 0;
1662             rt->flv_off = 0;
1663             rt->flv_header_bytes = 0;
1664             rt->flv_nb_packets++;
1665         }
1666     } while (buf_temp - buf < size);
1667
1668     if (rt->flv_nb_packets < rt->flush_interval)
1669         return size;
1670     rt->flv_nb_packets = 0;
1671
1672     /* set stream into nonblocking mode */
1673     rt->stream->flags |= AVIO_FLAG_NONBLOCK;
1674
1675     /* try to read one byte from the stream */
1676     ret = ffurl_read(rt->stream, &c, 1);
1677
1678     /* switch the stream back into blocking mode */
1679     rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
1680
1681     if (ret == AVERROR(EAGAIN)) {
1682         /* no incoming data to handle */
1683         return size;
1684     } else if (ret < 0) {
1685         return ret;
1686     } else if (ret == 1) {
1687         RTMPPacket rpkt = { 0 };
1688
1689         if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
1690                                                 rt->in_chunk_size,
1691                                                 rt->prev_pkt[0], c)) <= 0)
1692              return ret;
1693
1694         if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
1695             return ret;
1696
1697         ff_rtmp_packet_destroy(&rpkt);
1698     }
1699
1700     return size;
1701 }
1702
1703 #define OFFSET(x) offsetof(RTMPContext, x)
1704 #define DEC AV_OPT_FLAG_DECODING_PARAM
1705 #define ENC AV_OPT_FLAG_ENCODING_PARAM
1706
1707 static const AVOption rtmp_options[] = {
1708     {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1709     {"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},
1710     {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1711     {"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},
1712     {"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},
1713     {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
1714     {"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"},
1715     {"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"},
1716     {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {0}, 0, 0, DEC, "rtmp_live"},
1717     {"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},
1718     {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1719     {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
1720     {"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},
1721     {"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},
1722     { NULL },
1723 };
1724
1725 #define RTMP_PROTOCOL(flavor)                    \
1726 static const AVClass flavor##_class = {          \
1727     .class_name = #flavor,                       \
1728     .item_name  = av_default_item_name,          \
1729     .option     = rtmp_options,                  \
1730     .version    = LIBAVUTIL_VERSION_INT,         \
1731 };                                               \
1732                                                  \
1733 URLProtocol ff_##flavor##_protocol = {           \
1734     .name           = #flavor,                   \
1735     .url_open       = rtmp_open,                 \
1736     .url_read       = rtmp_read,                 \
1737     .url_write      = rtmp_write,                \
1738     .url_close      = rtmp_close,                \
1739     .priv_data_size = sizeof(RTMPContext),       \
1740     .flags          = URL_PROTOCOL_FLAG_NETWORK, \
1741     .priv_data_class= &flavor##_class,           \
1742 };
1743
1744
1745 RTMP_PROTOCOL(rtmp)
1746 RTMP_PROTOCOL(rtmpe)
1747 RTMP_PROTOCOL(rtmps)
1748 RTMP_PROTOCOL(rtmpt)
1749 RTMP_PROTOCOL(rtmpte)
1750 RTMP_PROTOCOL(rtmpts)