rtmp: Support 'rtmp_swfurl', an option which specifies the URL of the SWF player.
[ffmpeg.git] / libavformat / rtmpproto.c
1 /*
2  * RTMP network protocol
3  * Copyright (c) 2009 Kostya Shishkov
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file
24  * RTMP protocol
25  */
26
27 #include "libavcodec/bytestream.h"
28 #include "libavutil/avstring.h"
29 #include "libavutil/intfloat.h"
30 #include "libavutil/lfg.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/sha.h"
33 #include "avformat.h"
34 #include "internal.h"
35
36 #include "network.h"
37
38 #include "flv.h"
39 #include "rtmp.h"
40 #include "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     ClientState   state;                      ///< current state
74     int           main_channel_id;            ///< an additional channel ID which is used for some invocations
75     uint8_t*      flv_data;                   ///< buffer with data for demuxer
76     int           flv_size;                   ///< current buffer size
77     int           flv_off;                    ///< number of bytes read from current buffer
78     RTMPPacket    out_pkt;                    ///< rtmp packet, created from flv a/v or metadata (for output)
79     uint32_t      client_report_size;         ///< number of bytes after which client should report to server
80     uint32_t      bytes_read;                 ///< number of bytes read from server
81     uint32_t      last_bytes_read;            ///< number of bytes read last reported to server
82     int           skip_bytes;                 ///< number of bytes to skip from the input FLV stream in the next write call
83     uint8_t       flv_header[11];             ///< partial incoming flv packet header
84     int           flv_header_bytes;           ///< number of initialized bytes in flv_header
85     int           nb_invokes;                 ///< keeps track of invoke messages
86     int           create_stream_invoke;       ///< invoke id for the create stream command
87     char*         tcurl;                      ///< url of the target stream
88     char*         flashver;                   ///< version of the flash plugin
89     char*         swfurl;                     ///< url of the swf player
90 } RTMPContext;
91
92 #define PLAYER_KEY_OPEN_PART_LEN 30   ///< length of partial key used for first client digest signing
93 /** Client key used for digest signing */
94 static const uint8_t rtmp_player_key[] = {
95     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
96     'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
97
98     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
99     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
100     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
101 };
102
103 #define SERVER_KEY_OPEN_PART_LEN 36   ///< length of partial key used for first server digest signing
104 /** Key used for RTMP server digest signing */
105 static const uint8_t rtmp_server_key[] = {
106     'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
107     'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
108     'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
109
110     0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
111     0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
112     0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
113 };
114
115 /**
116  * Generate 'connect' call and send it to the server.
117  */
118 static void gen_connect(URLContext *s, RTMPContext *rt)
119 {
120     RTMPPacket pkt;
121     uint8_t *p;
122
123     ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 4096);
124     p = pkt.data;
125
126     ff_amf_write_string(&p, "connect");
127     ff_amf_write_number(&p, ++rt->nb_invokes);
128     ff_amf_write_object_start(&p);
129     ff_amf_write_field_name(&p, "app");
130     ff_amf_write_string(&p, rt->app);
131
132     if (!rt->is_input) {
133         ff_amf_write_field_name(&p, "type");
134         ff_amf_write_string(&p, "nonprivate");
135     }
136     ff_amf_write_field_name(&p, "flashVer");
137     ff_amf_write_string(&p, rt->flashver);
138
139     if (rt->swfurl) {
140         ff_amf_write_field_name(&p, "swfUrl");
141         ff_amf_write_string(&p, rt->swfurl);
142     }
143
144     ff_amf_write_field_name(&p, "tcUrl");
145     ff_amf_write_string(&p, rt->tcurl);
146     if (rt->is_input) {
147         ff_amf_write_field_name(&p, "fpad");
148         ff_amf_write_bool(&p, 0);
149         ff_amf_write_field_name(&p, "capabilities");
150         ff_amf_write_number(&p, 15.0);
151
152         /* Tell the server we support all the audio codecs except
153          * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)
154          * which are unused in the RTMP protocol implementation. */
155         ff_amf_write_field_name(&p, "audioCodecs");
156         ff_amf_write_number(&p, 4071.0);
157         ff_amf_write_field_name(&p, "videoCodecs");
158         ff_amf_write_number(&p, 252.0);
159         ff_amf_write_field_name(&p, "videoFunction");
160         ff_amf_write_number(&p, 1.0);
161     }
162     ff_amf_write_object_end(&p);
163
164     pkt.data_size = p - pkt.data;
165
166     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
167     ff_rtmp_packet_destroy(&pkt);
168 }
169
170 /**
171  * Generate 'releaseStream' call and send it to the server. It should make
172  * the server release some channel for media streams.
173  */
174 static void gen_release_stream(URLContext *s, RTMPContext *rt)
175 {
176     RTMPPacket pkt;
177     uint8_t *p;
178
179     ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0,
180                           29 + strlen(rt->playpath));
181
182     av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
183     p = pkt.data;
184     ff_amf_write_string(&p, "releaseStream");
185     ff_amf_write_number(&p, ++rt->nb_invokes);
186     ff_amf_write_null(&p);
187     ff_amf_write_string(&p, rt->playpath);
188
189     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
190     ff_rtmp_packet_destroy(&pkt);
191 }
192
193 /**
194  * Generate 'FCPublish' call and send it to the server. It should make
195  * the server preapare for receiving media streams.
196  */
197 static void gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
198 {
199     RTMPPacket pkt;
200     uint8_t *p;
201
202     ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0,
203                           25 + strlen(rt->playpath));
204
205     av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
206     p = pkt.data;
207     ff_amf_write_string(&p, "FCPublish");
208     ff_amf_write_number(&p, ++rt->nb_invokes);
209     ff_amf_write_null(&p);
210     ff_amf_write_string(&p, rt->playpath);
211
212     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
213     ff_rtmp_packet_destroy(&pkt);
214 }
215
216 /**
217  * Generate 'FCUnpublish' call and send it to the server. It should make
218  * the server destroy stream.
219  */
220 static void gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
221 {
222     RTMPPacket pkt;
223     uint8_t *p;
224
225     ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0,
226                           27 + strlen(rt->playpath));
227
228     av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
229     p = pkt.data;
230     ff_amf_write_string(&p, "FCUnpublish");
231     ff_amf_write_number(&p, ++rt->nb_invokes);
232     ff_amf_write_null(&p);
233     ff_amf_write_string(&p, rt->playpath);
234
235     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
236     ff_rtmp_packet_destroy(&pkt);
237 }
238
239 /**
240  * Generate 'createStream' call and send it to the server. It should make
241  * the server allocate some channel for media streams.
242  */
243 static void gen_create_stream(URLContext *s, RTMPContext *rt)
244 {
245     RTMPPacket pkt;
246     uint8_t *p;
247
248     av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
249     ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 25);
250
251     p = pkt.data;
252     ff_amf_write_string(&p, "createStream");
253     ff_amf_write_number(&p, ++rt->nb_invokes);
254     ff_amf_write_null(&p);
255     rt->create_stream_invoke = rt->nb_invokes;
256
257     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
258     ff_rtmp_packet_destroy(&pkt);
259 }
260
261
262 /**
263  * Generate 'deleteStream' call and send it to the server. It should make
264  * the server remove some channel for media streams.
265  */
266 static void gen_delete_stream(URLContext *s, RTMPContext *rt)
267 {
268     RTMPPacket pkt;
269     uint8_t *p;
270
271     av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
272     ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 34);
273
274     p = pkt.data;
275     ff_amf_write_string(&p, "deleteStream");
276     ff_amf_write_number(&p, ++rt->nb_invokes);
277     ff_amf_write_null(&p);
278     ff_amf_write_number(&p, rt->main_channel_id);
279
280     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
281     ff_rtmp_packet_destroy(&pkt);
282 }
283
284 /**
285  * Generate 'play' call and send it to the server, then ping the server
286  * to start actual playing.
287  */
288 static void gen_play(URLContext *s, RTMPContext *rt)
289 {
290     RTMPPacket pkt;
291     uint8_t *p;
292
293     av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
294     ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE, 0,
295                           29 + strlen(rt->playpath));
296     pkt.extra = rt->main_channel_id;
297
298     p = pkt.data;
299     ff_amf_write_string(&p, "play");
300     ff_amf_write_number(&p, ++rt->nb_invokes);
301     ff_amf_write_null(&p);
302     ff_amf_write_string(&p, rt->playpath);
303     ff_amf_write_number(&p, rt->live);
304
305     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
306     ff_rtmp_packet_destroy(&pkt);
307
308     // set client buffer time disguised in ping packet
309     ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, 1, 10);
310
311     p = pkt.data;
312     bytestream_put_be16(&p, 3);
313     bytestream_put_be32(&p, 1);
314     bytestream_put_be32(&p, 256); //TODO: what is a good value here?
315
316     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
317     ff_rtmp_packet_destroy(&pkt);
318 }
319
320 /**
321  * Generate 'publish' call and send it to the server.
322  */
323 static void gen_publish(URLContext *s, RTMPContext *rt)
324 {
325     RTMPPacket pkt;
326     uint8_t *p;
327
328     av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
329     ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE, 0,
330                           30 + strlen(rt->playpath));
331     pkt.extra = rt->main_channel_id;
332
333     p = pkt.data;
334     ff_amf_write_string(&p, "publish");
335     ff_amf_write_number(&p, ++rt->nb_invokes);
336     ff_amf_write_null(&p);
337     ff_amf_write_string(&p, rt->playpath);
338     ff_amf_write_string(&p, "live");
339
340     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
341     ff_rtmp_packet_destroy(&pkt);
342 }
343
344 /**
345  * Generate ping reply and send it to the server.
346  */
347 static void gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
348 {
349     RTMPPacket pkt;
350     uint8_t *p;
351
352     ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING, ppkt->timestamp + 1, 6);
353     p = pkt.data;
354     bytestream_put_be16(&p, 7);
355     bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
356     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
357     ff_rtmp_packet_destroy(&pkt);
358 }
359
360 /**
361  * Generate server bandwidth message and send it to the server.
362  */
363 static void gen_server_bw(URLContext *s, RTMPContext *rt)
364 {
365     RTMPPacket pkt;
366     uint8_t *p;
367
368     ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_SERVER_BW, 0, 4);
369     p = pkt.data;
370     bytestream_put_be32(&p, 2500000);
371     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
372     ff_rtmp_packet_destroy(&pkt);
373 }
374
375 /**
376  * Generate report on bytes read so far and send it to the server.
377  */
378 static void gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
379 {
380     RTMPPacket pkt;
381     uint8_t *p;
382
383     ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ, ts, 4);
384     p = pkt.data;
385     bytestream_put_be32(&p, rt->bytes_read);
386     ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);
387     ff_rtmp_packet_destroy(&pkt);
388 }
389
390 //TODO: Move HMAC code somewhere. Eventually.
391 #define HMAC_IPAD_VAL 0x36
392 #define HMAC_OPAD_VAL 0x5C
393
394 /**
395  * Calculate HMAC-SHA2 digest for RTMP handshake packets.
396  *
397  * @param src    input buffer
398  * @param len    input buffer length (should be 1536)
399  * @param gap    offset in buffer where 32 bytes should not be taken into account
400  *               when calculating digest (since it will be used to store that digest)
401  * @param key    digest key
402  * @param keylen digest key length
403  * @param dst    buffer where calculated digest will be stored (32 bytes)
404  */
405 static void rtmp_calc_digest(const uint8_t *src, int len, int gap,
406                              const uint8_t *key, int keylen, uint8_t *dst)
407 {
408     struct AVSHA *sha;
409     uint8_t hmac_buf[64+32] = {0};
410     int i;
411
412     sha = av_mallocz(av_sha_size);
413
414     if (keylen < 64) {
415         memcpy(hmac_buf, key, keylen);
416     } else {
417         av_sha_init(sha, 256);
418         av_sha_update(sha,key, keylen);
419         av_sha_final(sha, hmac_buf);
420     }
421     for (i = 0; i < 64; i++)
422         hmac_buf[i] ^= HMAC_IPAD_VAL;
423
424     av_sha_init(sha, 256);
425     av_sha_update(sha, hmac_buf, 64);
426     if (gap <= 0) {
427         av_sha_update(sha, src, len);
428     } else { //skip 32 bytes used for storing digest
429         av_sha_update(sha, src, gap);
430         av_sha_update(sha, src + gap + 32, len - gap - 32);
431     }
432     av_sha_final(sha, hmac_buf + 64);
433
434     for (i = 0; i < 64; i++)
435         hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad
436     av_sha_init(sha, 256);
437     av_sha_update(sha, hmac_buf, 64+32);
438     av_sha_final(sha, dst);
439
440     av_free(sha);
441 }
442
443 /**
444  * Put HMAC-SHA2 digest of packet data (except for the bytes where this digest
445  * will be stored) into that packet.
446  *
447  * @param buf handshake data (1536 bytes)
448  * @return offset to the digest inside input data
449  */
450 static int rtmp_handshake_imprint_with_digest(uint8_t *buf)
451 {
452     int i, digest_pos = 0;
453
454     for (i = 8; i < 12; i++)
455         digest_pos += buf[i];
456     digest_pos = (digest_pos % 728) + 12;
457
458     rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
459                      rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
460                      buf + digest_pos);
461     return digest_pos;
462 }
463
464 /**
465  * Verify that the received server response has the expected digest value.
466  *
467  * @param buf handshake data received from the server (1536 bytes)
468  * @param off position to search digest offset from
469  * @return 0 if digest is valid, digest position otherwise
470  */
471 static int rtmp_validate_digest(uint8_t *buf, int off)
472 {
473     int i, digest_pos = 0;
474     uint8_t digest[32];
475
476     for (i = 0; i < 4; i++)
477         digest_pos += buf[i + off];
478     digest_pos = (digest_pos % 728) + off + 4;
479
480     rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
481                      rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
482                      digest);
483     if (!memcmp(digest, buf + digest_pos, 32))
484         return digest_pos;
485     return 0;
486 }
487
488 /**
489  * Perform handshake with the server by means of exchanging pseudorandom data
490  * signed with HMAC-SHA2 digest.
491  *
492  * @return 0 if handshake succeeds, negative value otherwise
493  */
494 static int rtmp_handshake(URLContext *s, RTMPContext *rt)
495 {
496     AVLFG rnd;
497     uint8_t tosend    [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
498         3,                // unencrypted data
499         0, 0, 0, 0,       // client uptime
500         RTMP_CLIENT_VER1,
501         RTMP_CLIENT_VER2,
502         RTMP_CLIENT_VER3,
503         RTMP_CLIENT_VER4,
504     };
505     uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
506     uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
507     int i;
508     int server_pos, client_pos;
509     uint8_t digest[32];
510
511     av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
512
513     av_lfg_init(&rnd, 0xDEADC0DE);
514     // generate handshake packet - 1536 bytes of pseudorandom data
515     for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
516         tosend[i] = av_lfg_get(&rnd) >> 24;
517     client_pos = rtmp_handshake_imprint_with_digest(tosend + 1);
518
519     ffurl_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE + 1);
520     i = ffurl_read_complete(rt->stream, serverdata, RTMP_HANDSHAKE_PACKET_SIZE + 1);
521     if (i != RTMP_HANDSHAKE_PACKET_SIZE + 1) {
522         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
523         return -1;
524     }
525     i = ffurl_read_complete(rt->stream, clientdata, RTMP_HANDSHAKE_PACKET_SIZE);
526     if (i != RTMP_HANDSHAKE_PACKET_SIZE) {
527         av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
528         return -1;
529     }
530
531     av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
532            serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
533
534     if (rt->is_input && serverdata[5] >= 3) {
535         server_pos = rtmp_validate_digest(serverdata + 1, 772);
536         if (!server_pos) {
537             server_pos = rtmp_validate_digest(serverdata + 1, 8);
538             if (!server_pos) {
539                 av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
540                 return -1;
541             }
542         }
543
544         rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
545                          rtmp_server_key, sizeof(rtmp_server_key),
546                          digest);
547         rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE-32, 0,
548                          digest, 32,
549                          digest);
550         if (memcmp(digest, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
551             av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
552             return -1;
553         }
554
555         for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
556             tosend[i] = av_lfg_get(&rnd) >> 24;
557         rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
558                          rtmp_player_key, sizeof(rtmp_player_key),
559                          digest);
560         rtmp_calc_digest(tosend,  RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
561                          digest, 32,
562                          tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
563
564         // write reply back to the server
565         ffurl_write(rt->stream, tosend, RTMP_HANDSHAKE_PACKET_SIZE);
566     } else {
567         ffurl_write(rt->stream, serverdata+1, RTMP_HANDSHAKE_PACKET_SIZE);
568     }
569
570     return 0;
571 }
572
573 /**
574  * Parse received packet and possibly perform some action depending on
575  * the packet contents.
576  * @return 0 for no errors, negative values for serious errors which prevent
577  *         further communications, positive values for uncritical errors
578  */
579 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
580 {
581     int i, t;
582     const uint8_t *data_end = pkt->data + pkt->data_size;
583
584 #ifdef DEBUG
585     ff_rtmp_packet_dump(s, pkt);
586 #endif
587
588     switch (pkt->type) {
589     case RTMP_PT_CHUNK_SIZE:
590         if (pkt->data_size != 4) {
591             av_log(s, AV_LOG_ERROR,
592                    "Chunk size change packet is not 4 bytes long (%d)\n", pkt->data_size);
593             return -1;
594         }
595         if (!rt->is_input)
596             ff_rtmp_packet_write(rt->stream, pkt, rt->chunk_size, rt->prev_pkt[1]);
597         rt->chunk_size = AV_RB32(pkt->data);
598         if (rt->chunk_size <= 0) {
599             av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n", rt->chunk_size);
600             return -1;
601         }
602         av_log(s, AV_LOG_DEBUG, "New chunk size = %d\n", rt->chunk_size);
603         break;
604     case RTMP_PT_PING:
605         t = AV_RB16(pkt->data);
606         if (t == 6)
607             gen_pong(s, rt, pkt);
608         break;
609     case RTMP_PT_CLIENT_BW:
610         if (pkt->data_size < 4) {
611             av_log(s, AV_LOG_ERROR,
612                    "Client bandwidth report packet is less than 4 bytes long (%d)\n",
613                    pkt->data_size);
614             return -1;
615         }
616         av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", AV_RB32(pkt->data));
617         rt->client_report_size = AV_RB32(pkt->data) >> 1;
618         break;
619     case RTMP_PT_INVOKE:
620         //TODO: check for the messages sent for wrong state?
621         if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
622             uint8_t tmpstr[256];
623
624             if (!ff_amf_get_field_value(pkt->data + 9, data_end,
625                                         "description", tmpstr, sizeof(tmpstr)))
626                 av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
627             return -1;
628         } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
629             switch (rt->state) {
630             case STATE_HANDSHAKED:
631                 if (!rt->is_input) {
632                     gen_release_stream(s, rt);
633                     gen_fcpublish_stream(s, rt);
634                     rt->state = STATE_RELEASING;
635                 } else {
636                     gen_server_bw(s, rt);
637                     rt->state = STATE_CONNECTING;
638                 }
639                 gen_create_stream(s, rt);
640                 break;
641             case STATE_FCPUBLISH:
642                 rt->state = STATE_CONNECTING;
643                 break;
644             case STATE_RELEASING:
645                 rt->state = STATE_FCPUBLISH;
646                 /* hack for Wowza Media Server, it does not send result for
647                  * releaseStream and FCPublish calls */
648                 if (!pkt->data[10]) {
649                     int pkt_id = av_int2double(AV_RB64(pkt->data + 11));
650                     if (pkt_id == rt->create_stream_invoke)
651                         rt->state = STATE_CONNECTING;
652                 }
653                 if (rt->state != STATE_CONNECTING)
654                     break;
655             case STATE_CONNECTING:
656                 //extract a number from the result
657                 if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
658                     av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
659                 } else {
660                     rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21));
661                 }
662                 if (rt->is_input) {
663                     gen_play(s, rt);
664                 } else {
665                     gen_publish(s, rt);
666                 }
667                 rt->state = STATE_READY;
668                 break;
669             }
670         } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
671             const uint8_t* ptr = pkt->data + 11;
672             uint8_t tmpstr[256];
673
674             for (i = 0; i < 2; i++) {
675                 t = ff_amf_tag_size(ptr, data_end);
676                 if (t < 0)
677                     return 1;
678                 ptr += t;
679             }
680             t = ff_amf_get_field_value(ptr, data_end,
681                                        "level", tmpstr, sizeof(tmpstr));
682             if (!t && !strcmp(tmpstr, "error")) {
683                 if (!ff_amf_get_field_value(ptr, data_end,
684                                             "description", tmpstr, sizeof(tmpstr)))
685                     av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr);
686                 return -1;
687             }
688             t = ff_amf_get_field_value(ptr, data_end,
689                                        "code", tmpstr, sizeof(tmpstr));
690             if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
691             if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
692             if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
693             if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
694         }
695         break;
696     }
697     return 0;
698 }
699
700 /**
701  * Interact with the server by receiving and sending RTMP packets until
702  * there is some significant data (media data or expected status notification).
703  *
704  * @param s          reading context
705  * @param for_header non-zero value tells function to work until it
706  * gets notification from the server that playing has been started,
707  * otherwise function will work until some media data is received (or
708  * an error happens)
709  * @return 0 for successful operation, negative value in case of error
710  */
711 static int get_packet(URLContext *s, int for_header)
712 {
713     RTMPContext *rt = s->priv_data;
714     int ret;
715     uint8_t *p;
716     const uint8_t *next;
717     uint32_t data_size;
718     uint32_t ts, cts, pts=0;
719
720     if (rt->state == STATE_STOPPED)
721         return AVERROR_EOF;
722
723     for (;;) {
724         RTMPPacket rpkt = { 0 };
725         if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
726                                        rt->chunk_size, rt->prev_pkt[0])) <= 0) {
727             if (ret == 0) {
728                 return AVERROR(EAGAIN);
729             } else {
730                 return AVERROR(EIO);
731             }
732         }
733         rt->bytes_read += ret;
734         if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
735             av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
736             gen_bytes_read(s, rt, rpkt.timestamp + 1);
737             rt->last_bytes_read = rt->bytes_read;
738         }
739
740         ret = rtmp_parse_result(s, rt, &rpkt);
741         if (ret < 0) {//serious error in current packet
742             ff_rtmp_packet_destroy(&rpkt);
743             return -1;
744         }
745         if (rt->state == STATE_STOPPED) {
746             ff_rtmp_packet_destroy(&rpkt);
747             return AVERROR_EOF;
748         }
749         if (for_header && (rt->state == STATE_PLAYING || rt->state == STATE_PUBLISHING)) {
750             ff_rtmp_packet_destroy(&rpkt);
751             return 0;
752         }
753         if (!rpkt.data_size || !rt->is_input) {
754             ff_rtmp_packet_destroy(&rpkt);
755             continue;
756         }
757         if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
758            (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
759             ts = rpkt.timestamp;
760
761             // generate packet header and put data into buffer for FLV demuxer
762             rt->flv_off  = 0;
763             rt->flv_size = rpkt.data_size + 15;
764             rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
765             bytestream_put_byte(&p, rpkt.type);
766             bytestream_put_be24(&p, rpkt.data_size);
767             bytestream_put_be24(&p, ts);
768             bytestream_put_byte(&p, ts >> 24);
769             bytestream_put_be24(&p, 0);
770             bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
771             bytestream_put_be32(&p, 0);
772             ff_rtmp_packet_destroy(&rpkt);
773             return 0;
774         } else if (rpkt.type == RTMP_PT_METADATA) {
775             // we got raw FLV data, make it available for FLV demuxer
776             rt->flv_off  = 0;
777             rt->flv_size = rpkt.data_size;
778             rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
779             /* rewrite timestamps */
780             next = rpkt.data;
781             ts = rpkt.timestamp;
782             while (next - rpkt.data < rpkt.data_size - 11) {
783                 next++;
784                 data_size = bytestream_get_be24(&next);
785                 p=next;
786                 cts = bytestream_get_be24(&next);
787                 cts |= bytestream_get_byte(&next) << 24;
788                 if (pts==0)
789                     pts=cts;
790                 ts += cts - pts;
791                 pts = cts;
792                 bytestream_put_be24(&p, ts);
793                 bytestream_put_byte(&p, ts >> 24);
794                 next += data_size + 3 + 4;
795             }
796             memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
797             ff_rtmp_packet_destroy(&rpkt);
798             return 0;
799         }
800         ff_rtmp_packet_destroy(&rpkt);
801     }
802 }
803
804 static int rtmp_close(URLContext *h)
805 {
806     RTMPContext *rt = h->priv_data;
807
808     if (!rt->is_input) {
809         rt->flv_data = NULL;
810         if (rt->out_pkt.data_size)
811             ff_rtmp_packet_destroy(&rt->out_pkt);
812         if (rt->state > STATE_FCPUBLISH)
813             gen_fcunpublish_stream(h, rt);
814     }
815     if (rt->state > STATE_HANDSHAKED)
816         gen_delete_stream(h, rt);
817
818     av_freep(&rt->flv_data);
819     ffurl_close(rt->stream);
820     return 0;
821 }
822
823 /**
824  * Open RTMP connection and verify that the stream can be played.
825  *
826  * URL syntax: rtmp://server[:port][/app][/playpath]
827  *             where 'app' is first one or two directories in the path
828  *             (e.g. /ondemand/, /flash/live/, etc.)
829  *             and 'playpath' is a file name (the rest of the path,
830  *             may be prefixed with "mp4:")
831  */
832 static int rtmp_open(URLContext *s, const char *uri, int flags)
833 {
834     RTMPContext *rt = s->priv_data;
835     char proto[8], hostname[256], path[1024], *fname;
836     char *old_app;
837     uint8_t buf[2048];
838     int port;
839     int ret;
840
841     rt->is_input = !(flags & AVIO_FLAG_WRITE);
842
843     av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
844                  path, sizeof(path), s->filename);
845
846     if (port < 0)
847         port = RTMP_DEFAULT_PORT;
848     ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
849
850     if (ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
851                    &s->interrupt_callback, NULL) < 0) {
852         av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
853         goto fail;
854     }
855
856     rt->state = STATE_START;
857     if (rtmp_handshake(s, rt))
858         goto fail;
859
860     rt->chunk_size = 128;
861     rt->state = STATE_HANDSHAKED;
862
863     // Keep the application name when it has been defined by the user.
864     old_app = rt->app;
865
866     rt->app = av_malloc(APP_MAX_LENGTH);
867     if (!rt->app) {
868         rtmp_close(s);
869         return AVERROR(ENOMEM);
870     }
871
872     //extract "app" part from path
873     if (!strncmp(path, "/ondemand/", 10)) {
874         fname = path + 10;
875         memcpy(rt->app, "ondemand", 9);
876     } else {
877         char *p = strchr(path + 1, '/');
878         if (!p) {
879             fname = path + 1;
880             rt->app[0] = '\0';
881         } else {
882             char *c = strchr(p + 1, ':');
883             fname = strchr(p + 1, '/');
884             if (!fname || c < fname) {
885                 fname = p + 1;
886                 av_strlcpy(rt->app, path + 1, p - path);
887             } else {
888                 fname++;
889                 av_strlcpy(rt->app, path + 1, fname - path - 1);
890             }
891         }
892     }
893
894     if (old_app) {
895         // The name of application has been defined by the user, override it.
896         av_free(rt->app);
897         rt->app = old_app;
898     }
899
900     if (!rt->playpath) {
901         rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
902         if (!rt->playpath) {
903             rtmp_close(s);
904             return AVERROR(ENOMEM);
905         }
906
907         if (!strchr(fname, ':') &&
908             (!strcmp(fname + strlen(fname) - 4, ".f4v") ||
909              !strcmp(fname + strlen(fname) - 4, ".mp4"))) {
910             memcpy(rt->playpath, "mp4:", 5);
911         } else {
912             rt->playpath[0] = 0;
913         }
914         strncat(rt->playpath, fname, PLAYPATH_MAX_LENGTH - 5);
915     }
916
917     if (!rt->tcurl) {
918         rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
919         ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
920                     port, "/%s", rt->app);
921     }
922
923     if (!rt->flashver) {
924         rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
925         if (rt->is_input) {
926             snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
927                     RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
928                     RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
929         } else {
930             snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
931                     "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
932         }
933     }
934
935     rt->client_report_size = 1048576;
936     rt->bytes_read = 0;
937     rt->last_bytes_read = 0;
938
939     av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
940            proto, path, rt->app, rt->playpath);
941     gen_connect(s, rt);
942
943     do {
944         ret = get_packet(s, 1);
945     } while (ret == EAGAIN);
946     if (ret < 0)
947         goto fail;
948
949     if (rt->is_input) {
950         // generate FLV header for demuxer
951         rt->flv_size = 13;
952         rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
953         rt->flv_off  = 0;
954         memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
955     } else {
956         rt->flv_size = 0;
957         rt->flv_data = NULL;
958         rt->flv_off  = 0;
959         rt->skip_bytes = 13;
960     }
961
962     s->max_packet_size = rt->stream->max_packet_size;
963     s->is_streamed     = 1;
964     return 0;
965
966 fail:
967     rtmp_close(s);
968     return AVERROR(EIO);
969 }
970
971 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
972 {
973     RTMPContext *rt = s->priv_data;
974     int orig_size = size;
975     int ret;
976
977     while (size > 0) {
978         int data_left = rt->flv_size - rt->flv_off;
979
980         if (data_left >= size) {
981             memcpy(buf, rt->flv_data + rt->flv_off, size);
982             rt->flv_off += size;
983             return orig_size;
984         }
985         if (data_left > 0) {
986             memcpy(buf, rt->flv_data + rt->flv_off, data_left);
987             buf  += data_left;
988             size -= data_left;
989             rt->flv_off = rt->flv_size;
990             return data_left;
991         }
992         if ((ret = get_packet(s, 0)) < 0)
993            return ret;
994     }
995     return orig_size;
996 }
997
998 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
999 {
1000     RTMPContext *rt = s->priv_data;
1001     int size_temp = size;
1002     int pktsize, pkttype;
1003     uint32_t ts;
1004     const uint8_t *buf_temp = buf;
1005
1006     do {
1007         if (rt->skip_bytes) {
1008             int skip = FFMIN(rt->skip_bytes, size_temp);
1009             buf_temp       += skip;
1010             size_temp      -= skip;
1011             rt->skip_bytes -= skip;
1012             continue;
1013         }
1014
1015         if (rt->flv_header_bytes < 11) {
1016             const uint8_t *header = rt->flv_header;
1017             int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
1018             bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
1019             rt->flv_header_bytes += copy;
1020             size_temp            -= copy;
1021             if (rt->flv_header_bytes < 11)
1022                 break;
1023
1024             pkttype = bytestream_get_byte(&header);
1025             pktsize = bytestream_get_be24(&header);
1026             ts = bytestream_get_be24(&header);
1027             ts |= bytestream_get_byte(&header) << 24;
1028             bytestream_get_be24(&header);
1029             rt->flv_size = pktsize;
1030
1031             //force 12bytes header
1032             if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
1033                 pkttype == RTMP_PT_NOTIFY) {
1034                 if (pkttype == RTMP_PT_NOTIFY)
1035                     pktsize += 16;
1036                 rt->prev_pkt[1][RTMP_SOURCE_CHANNEL].channel_id = 0;
1037             }
1038
1039             //this can be a big packet, it's better to send it right here
1040             ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL, pkttype, ts, pktsize);
1041             rt->out_pkt.extra = rt->main_channel_id;
1042             rt->flv_data = rt->out_pkt.data;
1043
1044             if (pkttype == RTMP_PT_NOTIFY)
1045                 ff_amf_write_string(&rt->flv_data, "@setDataFrame");
1046         }
1047
1048         if (rt->flv_size - rt->flv_off > size_temp) {
1049             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
1050             rt->flv_off += size_temp;
1051             size_temp = 0;
1052         } else {
1053             bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
1054             size_temp   -= rt->flv_size - rt->flv_off;
1055             rt->flv_off += rt->flv_size - rt->flv_off;
1056         }
1057
1058         if (rt->flv_off == rt->flv_size) {
1059             rt->skip_bytes = 4;
1060
1061             ff_rtmp_packet_write(rt->stream, &rt->out_pkt, rt->chunk_size, rt->prev_pkt[1]);
1062             ff_rtmp_packet_destroy(&rt->out_pkt);
1063             rt->flv_size = 0;
1064             rt->flv_off = 0;
1065             rt->flv_header_bytes = 0;
1066         }
1067     } while (buf_temp - buf < size);
1068     return size;
1069 }
1070
1071 #define OFFSET(x) offsetof(RTMPContext, x)
1072 #define DEC AV_OPT_FLAG_DECODING_PARAM
1073 #define ENC AV_OPT_FLAG_ENCODING_PARAM
1074
1075 static const AVOption rtmp_options[] = {
1076     {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1077     {"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},
1078     {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
1079     {"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"},
1080     {"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"},
1081     {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {0}, 0, 0, DEC, "rtmp_live"},
1082     {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
1083     {"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},
1084     {"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},
1085     { NULL },
1086 };
1087
1088 static const AVClass rtmp_class = {
1089     .class_name = "rtmp",
1090     .item_name  = av_default_item_name,
1091     .option     = rtmp_options,
1092     .version    = LIBAVUTIL_VERSION_INT,
1093 };
1094
1095 URLProtocol ff_rtmp_protocol = {
1096     .name           = "rtmp",
1097     .url_open       = rtmp_open,
1098     .url_read       = rtmp_read,
1099     .url_write      = rtmp_write,
1100     .url_close      = rtmp_close,
1101     .priv_data_size = sizeof(RTMPContext),
1102     .flags          = URL_PROTOCOL_FLAG_NETWORK,
1103     .priv_data_class= &rtmp_class,
1104 };