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