]> git.sesse.net Git - ffmpeg/blob - libavformat/rtmpproto.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / 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_BYTES_READ:
1204         av_dlog(s, "received bytes read report\n");
1205         break;
1206     case RTMP_PT_CHUNK_SIZE:
1207         if ((ret = handle_chunk_size(s, pkt)) < 0)
1208             return ret;
1209         break;
1210     case RTMP_PT_PING:
1211         if ((ret = handle_ping(s, pkt)) < 0)
1212             return ret;
1213         break;
1214     case RTMP_PT_CLIENT_BW:
1215         if ((ret = handle_client_bw(s, pkt)) < 0)
1216             return ret;
1217         break;
1218     case RTMP_PT_SERVER_BW:
1219         if ((ret = handle_server_bw(s, pkt)) < 0)
1220             return ret;
1221         break;
1222     case RTMP_PT_INVOKE:
1223         if ((ret = handle_invoke(s, pkt)) < 0)
1224             return ret;
1225         break;
1226     case RTMP_PT_VIDEO:
1227     case RTMP_PT_AUDIO:
1228     case RTMP_PT_METADATA:
1229         /* Audio, Video and Metadata packets are parsed in get_packet() */
1230         break;
1231     default:
1232         av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
1233         break;
1234     }
1235     return 0;
1236 }
1237
1238 /**
1239  * Interact with the server by receiving and sending RTMP packets until
1240  * there is some significant data (media data or expected status notification).
1241  *
1242  * @param s          reading context
1243  * @param for_header non-zero value tells function to work until it
1244  * gets notification from the server that playing has been started,
1245  * otherwise function will work until some media data is received (or
1246  * an error happens)
1247  * @return 0 for successful operation, negative value in case of error
1248  */
1249 static int get_packet(URLContext *s, int for_header)
1250 {
1251     RTMPContext *rt = s->priv_data;
1252     int ret;
1253     uint8_t *p;
1254     const uint8_t *next;
1255     uint32_t data_size;
1256     uint32_t ts, cts, pts=0;
1257
1258     if (rt->state == STATE_STOPPED)
1259         return AVERROR_EOF;
1260
1261     for (;;) {
1262         RTMPPacket rpkt = { 0 };
1263         if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
1264                                        rt->in_chunk_size, rt->prev_pkt[0])) <= 0) {
1265             if (ret == 0) {
1266                 return AVERROR(EAGAIN);
1267             } else {
1268                 return AVERROR(EIO);
1269             }
1270         }
1271         rt->bytes_read += ret;
1272         if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) {
1273             av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
1274             if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
1275                 return ret;
1276             rt->last_bytes_read = rt->bytes_read;
1277         }
1278
1279         ret = rtmp_parse_result(s, rt, &rpkt);
1280         if (ret < 0) {//serious error in current packet
1281             ff_rtmp_packet_destroy(&rpkt);
1282             return ret;
1283         }
1284         if (rt->state == STATE_STOPPED) {
1285             ff_rtmp_packet_destroy(&rpkt);
1286             return AVERROR_EOF;
1287         }
1288         if (for_header && (rt->state == STATE_PLAYING || rt->state == STATE_PUBLISHING)) {
1289             ff_rtmp_packet_destroy(&rpkt);
1290             return 0;
1291         }
1292         if (!rpkt.data_size || !rt->is_input) {
1293             ff_rtmp_packet_destroy(&rpkt);
1294             continue;
1295         }
1296         if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
1297            (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
1298             ts = rpkt.timestamp;
1299
1300             // generate packet header and put data into buffer for FLV demuxer
1301             rt->flv_off  = 0;
1302             rt->flv_size = rpkt.data_size + 15;
1303             rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
1304             bytestream_put_byte(&p, rpkt.type);
1305             bytestream_put_be24(&p, rpkt.data_size);
1306             bytestream_put_be24(&p, ts);
1307             bytestream_put_byte(&p, ts >> 24);
1308             bytestream_put_be24(&p, 0);
1309             bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
1310             bytestream_put_be32(&p, 0);
1311             ff_rtmp_packet_destroy(&rpkt);
1312             return 0;
1313         } else if (rpkt.type == RTMP_PT_METADATA) {
1314             // we got raw FLV data, make it available for FLV demuxer
1315             rt->flv_off  = 0;
1316             rt->flv_size = rpkt.data_size;
1317             rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
1318             /* rewrite timestamps */
1319             next = rpkt.data;
1320             ts = rpkt.timestamp;
1321             while (next - rpkt.data < rpkt.data_size - 11) {
1322                 next++;
1323                 data_size = bytestream_get_be24(&next);
1324                 p=next;
1325                 cts = bytestream_get_be24(&next);
1326                 cts |= bytestream_get_byte(&next) << 24;
1327                 if (pts==0)
1328                     pts=cts;
1329                 ts += cts - pts;
1330                 pts = cts;
1331                 bytestream_put_be24(&p, ts);
1332                 bytestream_put_byte(&p, ts >> 24);
1333                 next += data_size + 3 + 4;
1334             }
1335             memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
1336             ff_rtmp_packet_destroy(&rpkt);
1337             return 0;
1338         }
1339         ff_rtmp_packet_destroy(&rpkt);
1340     }
1341 }
1342
1343 static int rtmp_close(URLContext *h)
1344 {
1345     RTMPContext *rt = h->priv_data;
1346     int ret = 0;
1347
1348     if (!rt->is_input) {
1349         rt->flv_data = NULL;
1350         if (rt->out_pkt.data_size)
1351             ff_rtmp_packet_destroy(&rt->out_pkt);
1352         if (rt->state > STATE_FCPUBLISH)
1353             ret = gen_fcunpublish_stream(h, rt);
1354     }
1355     if (rt->state > STATE_HANDSHAKED)
1356         ret = gen_delete_stream(h, rt);
1357
1358     free_tracked_methods(rt);
1359     av_freep(&rt->flv_data);
1360     ffurl_close(rt->stream);
1361     return ret;
1362 }
1363
1364 /**
1365  * Open RTMP connection and verify that the stream can be played.
1366  *
1367  * URL syntax: rtmp://server[:port][/app][/playpath]
1368  *             where 'app' is first one or two directories in the path
1369  *             (e.g. /ondemand/, /flash/live/, etc.)
1370  *             and 'playpath' is a file name (the rest of the path,
1371  *             may be prefixed with "mp4:")
1372  */
1373 static int rtmp_open(URLContext *s, const char *uri, int flags)
1374 {
1375     RTMPContext *rt = s->priv_data;
1376     char proto[8], hostname[256], path[1024], *fname;
1377     char *old_app;
1378     uint8_t buf[2048];
1379     int port;
1380     AVDictionary *opts = NULL;
1381     int ret;
1382
1383     rt->is_input = !(flags & AVIO_FLAG_WRITE);
1384
1385     av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
1386                  path, sizeof(path), s->filename);
1387
1388     if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
1389         if (!strcmp(proto, "rtmpts"))
1390             av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
1391
1392         /* open the http tunneling connection */
1393         ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
1394     } else if (!strcmp(proto, "rtmps")) {
1395         /* open the tls connection */
1396         if (port < 0)
1397             port = RTMPS_DEFAULT_PORT;
1398         ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
1399     } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
1400         if (!strcmp(proto, "rtmpte"))
1401             av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
1402
1403         /* open the encrypted connection */
1404         ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
1405         rt->encrypted = 1;
1406     } else {
1407         /* open the tcp connection */
1408         if (port < 0)
1409             port = RTMP_DEFAULT_PORT;
1410         ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
1411     }
1412
1413     if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
1414                           &s->interrupt_callback, &opts)) < 0) {
1415         av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
1416         goto fail;
1417     }
1418
1419     rt->state = STATE_START;
1420     if ((ret = rtmp_handshake(s, rt)) < 0)
1421         goto fail;
1422
1423     rt->out_chunk_size = 128;
1424     rt->in_chunk_size  = 128; // Probably overwritten later
1425     rt->state = STATE_HANDSHAKED;
1426
1427     // Keep the application name when it has been defined by the user.
1428     old_app = rt->app;
1429
1430     rt->app = av_malloc(APP_MAX_LENGTH);
1431     if (!rt->app) {
1432         ret = AVERROR(ENOMEM);
1433         goto fail;
1434     }
1435
1436     //extract "app" part from path
1437     if (!strncmp(path, "/ondemand/", 10)) {
1438         fname = path + 10;
1439         memcpy(rt->app, "ondemand", 9);
1440     } else {
1441         char *next = *path ? path + 1 : path;
1442         char *p = strchr(next, '/');
1443         if (!p) {
1444             fname = next;
1445             rt->app[0] = '\0';
1446         } else {
1447             // make sure we do not mismatch a playpath for an application instance
1448             char *c = strchr(p + 1, ':');
1449             fname = strchr(p + 1, '/');
1450             if (!fname || (c && c < fname)) {
1451                 fname = p + 1;
1452                 av_strlcpy(rt->app, path + 1, p - path);
1453             } else {
1454                 fname++;
1455                 av_strlcpy(rt->app, path + 1, fname - path - 1);
1456             }
1457         }
1458     }
1459
1460     if (old_app) {
1461         // The name of application has been defined by the user, override it.
1462         av_free(rt->app);
1463         rt->app = old_app;
1464     }
1465
1466     if (!rt->playpath) {
1467         int len = strlen(fname);
1468
1469         rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
1470         if (!rt->playpath) {
1471             ret = AVERROR(ENOMEM);
1472             goto fail;
1473         }
1474
1475         if (!strchr(fname, ':') && len >= 4 &&
1476             (!strcmp(fname + len - 4, ".f4v") ||
1477              !strcmp(fname + len - 4, ".mp4"))) {
1478             memcpy(rt->playpath, "mp4:", 5);
1479         } else if (len >= 4 && !strcmp(fname + len - 4, ".flv")) {
1480             fname[len - 4] = '\0';
1481         } else {
1482             rt->playpath[0] = 0;
1483         }
1484         strncat(rt->playpath, fname, PLAYPATH_MAX_LENGTH - 5);
1485     }
1486
1487     if (!rt->tcurl) {
1488         rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
1489         if (!rt->tcurl) {
1490             ret = AVERROR(ENOMEM);
1491             goto fail;
1492         }
1493         ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
1494                     port, "/%s", rt->app);
1495     }
1496
1497     if (!rt->flashver) {
1498         rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
1499         if (!rt->flashver) {
1500             ret = AVERROR(ENOMEM);
1501             goto fail;
1502         }
1503         if (rt->is_input) {
1504             snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
1505                     RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
1506                     RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
1507         } else {
1508             snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
1509                     "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
1510         }
1511     }
1512
1513     rt->client_report_size = 1048576;
1514     rt->bytes_read = 0;
1515     rt->last_bytes_read = 0;
1516     rt->server_bw = 2500000;
1517
1518     av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
1519            proto, path, rt->app, rt->playpath);
1520     if ((ret = gen_connect(s, rt)) < 0)
1521         goto fail;
1522
1523     do {
1524         ret = get_packet(s, 1);
1525     } while (ret == EAGAIN);
1526     if (ret < 0)
1527         goto fail;
1528
1529     if (rt->is_input) {
1530         // generate FLV header for demuxer
1531         rt->flv_size = 13;
1532         rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
1533         rt->flv_off  = 0;
1534         memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
1535     } else {
1536         rt->flv_size = 0;
1537         rt->flv_data = NULL;
1538         rt->flv_off  = 0;
1539         rt->skip_bytes = 13;
1540     }
1541
1542     s->max_packet_size = rt->stream->max_packet_size;
1543     s->is_streamed     = 1;
1544     return 0;
1545
1546 fail:
1547     av_dict_free(&opts);
1548     rtmp_close(s);
1549     return ret;
1550 }
1551
1552 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
1553 {
1554     RTMPContext *rt = s->priv_data;
1555     int orig_size = size;
1556     int ret;
1557
1558     while (size > 0) {
1559         int data_left = rt->flv_size - rt->flv_off;
1560
1561         if (data_left >= size) {
1562             memcpy(buf, rt->flv_data + rt->flv_off, size);
1563             rt->flv_off += size;
1564             return orig_size;
1565         }
1566         if (data_left > 0) {
1567             memcpy(buf, rt->flv_data + rt->flv_off, data_left);
1568             buf  += data_left;
1569             size -= data_left;
1570             rt->flv_off = rt->flv_size;
1571             return data_left;
1572         }
1573         if ((ret = get_packet(s, 0)) < 0)
1574            return ret;
1575     }
1576     return orig_size;
1577 }
1578
1579 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
1580 {
1581     RTMPContext *rt = s->priv_data;
1582     int size_temp = size;
1583     int pktsize, pkttype;
1584     uint32_t ts;
1585     const uint8_t *buf_temp = buf;
1586     uint8_t c;
1587     int ret;
1588
1589     do {
1590         if (rt->skip_bytes) {
1591             int skip = FFMIN(rt->skip_bytes, size_temp);
1592             buf_temp       += skip;
1593             size_temp      -= skip;
1594             rt->skip_bytes -= skip;
1595             continue;
1596         }
1597
1598         if (rt->flv_header_bytes < 11) {
1599             const uint8_t *header = rt->flv_header;
1600             int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
1601             bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
1602             rt->flv_header_bytes += copy;
1603             size_temp            -= copy;
1604             if (rt->flv_header_bytes < 11)
1605                 break;
1606
1607             pkttype = bytestream_get_byte(&header);
1608             pktsize = bytestream_get_be24(&header);
1609             ts = bytestream_get_be24(&header);
1610             ts |= bytestream_get_byte(&header) << 24;
1611             bytestream_get_be24(&header);
1612             rt->flv_size = pktsize;
1613
1614             //force 12bytes header
1615             if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
1616                 pkttype == RTMP_PT_NOTIFY) {
1617                 if (pkttype == RTMP_PT_NOTIFY)
1618                     pktsize += 16;
1619                 rt->prev_pkt[1][RTMP_SOURCE_CHANNEL].channel_id = 0;
1620             }
1621
1622             //this can be a big packet, it's better to send it right here
1623             if ((ret = ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL,
1624                                              pkttype, ts, pktsize)) < 0)
1625                 return ret;
1626
1627             rt->out_pkt.extra = rt->main_channel_id;
1628             rt->flv_data = rt->out_pkt.data;
1629
1630             if (pkttype == RTMP_PT_NOTIFY)
1631                 ff_amf_write_string(&rt->flv_data, "@setDataFrame");
1632         }
1633
1634         if (rt->flv_size - rt->flv_off > size_temp) {
1635             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
1636             rt->flv_off += size_temp;
1637             size_temp = 0;
1638         } else {
1639             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
1640             size_temp   -= rt->flv_size - rt->flv_off;
1641             rt->flv_off += rt->flv_size - rt->flv_off;
1642         }
1643
1644         if (rt->flv_off == rt->flv_size) {
1645             rt->skip_bytes = 4;
1646
1647             if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
1648                 return ret;
1649             rt->flv_size = 0;
1650             rt->flv_off = 0;
1651             rt->flv_header_bytes = 0;
1652             rt->flv_nb_packets++;
1653         }
1654     } while (buf_temp - buf < size);
1655
1656     if (rt->flv_nb_packets < rt->flush_interval)
1657         return size;
1658     rt->flv_nb_packets = 0;
1659
1660     /* set stream into nonblocking mode */
1661     rt->stream->flags |= AVIO_FLAG_NONBLOCK;
1662
1663     /* try to read one byte from the stream */
1664     ret = ffurl_read(rt->stream, &c, 1);
1665
1666     /* switch the stream back into blocking mode */
1667     rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
1668
1669     if (ret == AVERROR(EAGAIN)) {
1670         /* no incoming data to handle */
1671         return size;
1672     } else if (ret < 0) {
1673         return ret;
1674     } else if (ret == 1) {
1675         RTMPPacket rpkt = { 0 };
1676
1677         if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
1678                                                 rt->in_chunk_size,
1679                                                 rt->prev_pkt[0], c)) <= 0)
1680              return ret;
1681
1682         if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
1683             return ret;
1684
1685         ff_rtmp_packet_destroy(&rpkt);
1686     }
1687
1688     return size;
1689 }
1690
1691 #define OFFSET(x) offsetof(RTMPContext, x)
1692 #define DEC AV_OPT_FLAG_DECODING_PARAM
1693 #define ENC AV_OPT_FLAG_ENCODING_PARAM
1694
1695 static const AVOption rtmp_options[] = {
1696     {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1697     {"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},
1698     {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1699     {"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},
1700     {"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},
1701     {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
1702     {"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"},
1703     {"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"},
1704     {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {0}, 0, 0, DEC, "rtmp_live"},
1705     {"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},
1706     {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1707     {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
1708     {"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},
1709     {"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},
1710     { NULL },
1711 };
1712
1713 #define RTMP_PROTOCOL(flavor)                    \
1714 static const AVClass flavor##_class = {          \
1715     .class_name = #flavor,                       \
1716     .item_name  = av_default_item_name,          \
1717     .option     = rtmp_options,                  \
1718     .version    = LIBAVUTIL_VERSION_INT,         \
1719 };                                               \
1720                                                  \
1721 URLProtocol ff_##flavor##_protocol = {           \
1722     .name           = #flavor,                   \
1723     .url_open       = rtmp_open,                 \
1724     .url_read       = rtmp_read,                 \
1725     .url_write      = rtmp_write,                \
1726     .url_close      = rtmp_close,                \
1727     .priv_data_size = sizeof(RTMPContext),       \
1728     .flags          = URL_PROTOCOL_FLAG_NETWORK, \
1729     .priv_data_class= &flavor##_class,           \
1730 };
1731
1732
1733 RTMP_PROTOCOL(rtmp)
1734 RTMP_PROTOCOL(rtmpe)
1735 RTMP_PROTOCOL(rtmps)
1736 RTMP_PROTOCOL(rtmpt)
1737 RTMP_PROTOCOL(rtmpte)
1738 RTMP_PROTOCOL(rtmpts)