Remove commented-out debug #define cruft
[libav.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/base64.h"
30 #include "libavutil/intfloat.h"
31 #include "libavutil/lfg.h"
32 #include "libavutil/md5.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/random_seed.h"
35 #include "libavutil/sha.h"
36 #include "avformat.h"
37 #include "internal.h"
38
39 #include "network.h"
40
41 #include "flv.h"
42 #include "rtmp.h"
43 #include "rtmpcrypt.h"
44 #include "rtmppkt.h"
45 #include "url.h"
46
47 #if CONFIG_ZLIB
48 #include <zlib.h>
49 #endif
50
51 #define APP_MAX_LENGTH 128
52 #define PLAYPATH_MAX_LENGTH 256
53 #define TCURL_MAX_LENGTH 512
54 #define FLASHVER_MAX_LENGTH 64
55 #define RTMP_PKTDATA_DEFAULT_SIZE 4096
56
57 /** RTMP protocol handler state */
58 typedef enum {
59 STATE_START, ///< client has not done anything yet
60 STATE_HANDSHAKED, ///< client has performed handshake
61 STATE_FCPUBLISH, ///< client FCPublishing stream (for output)
62 STATE_PLAYING, ///< client has started receiving multimedia data from server
63 STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
64 STATE_RECEIVING, ///< received a publish command (for input)
65 STATE_STOPPED, ///< the broadcast has been stopped
66 } ClientState;
67
68 typedef struct TrackedMethod {
69 char *name;
70 int id;
71 } TrackedMethod;
72
73 /** protocol handler context */
74 typedef struct RTMPContext {
75 const AVClass *class;
76 URLContext* stream; ///< TCP stream used in interactions with RTMP server
77 RTMPPacket prev_pkt[2][RTMP_CHANNELS]; ///< packet history used when reading and sending packets
78 int in_chunk_size; ///< size of the chunks incoming RTMP packets are divided into
79 int out_chunk_size; ///< size of the chunks outgoing RTMP packets are divided into
80 int is_input; ///< input/output flag
81 char *playpath; ///< stream identifier to play (with possible "mp4:" prefix)
82 int live; ///< 0: recorded, -1: live, -2: both
83 char *app; ///< name of application
84 char *conn; ///< append arbitrary AMF data to the Connect message
85 ClientState state; ///< current state
86 int main_channel_id; ///< an additional channel ID which is used for some invocations
87 uint8_t* flv_data; ///< buffer with data for demuxer
88 int flv_size; ///< current buffer size
89 int flv_off; ///< number of bytes read from current buffer
90 int flv_nb_packets; ///< number of flv packets published
91 RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output)
92 uint32_t client_report_size; ///< number of bytes after which client should report to server
93 uint32_t bytes_read; ///< number of bytes read from server
94 uint32_t last_bytes_read; ///< number of bytes read last reported to server
95 int skip_bytes; ///< number of bytes to skip from the input FLV stream in the next write call
96 uint8_t flv_header[11]; ///< partial incoming flv packet header
97 int flv_header_bytes; ///< number of initialized bytes in flv_header
98 int nb_invokes; ///< keeps track of invoke messages
99 char* tcurl; ///< url of the target stream
100 char* flashver; ///< version of the flash plugin
101 char* swfhash; ///< SHA256 hash of the decompressed SWF file (32 bytes)
102 int swfhash_len; ///< length of the SHA256 hash
103 int swfsize; ///< size of the decompressed SWF file
104 char* swfurl; ///< url of the swf player
105 char* swfverify; ///< URL to player swf file, compute hash/size automatically
106 char swfverification[42]; ///< hash of the SWF verification
107 char* pageurl; ///< url of the web page
108 char* subscribe; ///< name of live stream to subscribe
109 int server_bw; ///< server bandwidth
110 int client_buffer_time; ///< client buffer time in ms
111 int flush_interval; ///< number of packets flushed in the same request (RTMPT only)
112 int encrypted; ///< use an encrypted connection (RTMPE only)
113 TrackedMethod*tracked_methods; ///< tracked methods buffer
114 int nb_tracked_methods; ///< number of tracked methods
115 int tracked_methods_size; ///< size of the tracked methods buffer
116 int listen; ///< listen mode flag
117 int listen_timeout; ///< listen timeout to wait for new connections
118 int nb_streamid; ///< The next stream id to return on createStream calls
119 char username[50];
120 char password[50];
121 char auth_params[500];
122 int do_reconnect;
123 int auth_tried;
124 } RTMPContext;
125
126 #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing
127 /** Client key used for digest signing */
128 static const uint8_t rtmp_player_key[] = {
129 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
130 'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
131
132 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
133 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
134 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
135 };
136
137 #define SERVER_KEY_OPEN_PART_LEN 36 ///< length of partial key used for first server digest signing
138 /** Key used for RTMP server digest signing */
139 static const uint8_t rtmp_server_key[] = {
140 'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
141 'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
142 'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
143
144 0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
145 0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
146 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
147 };
148
149 static int add_tracked_method(RTMPContext *rt, const char *name, int id)
150 {
151 void *ptr;
152
153 if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
154 rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
155 ptr = av_realloc(rt->tracked_methods,
156 rt->tracked_methods_size * sizeof(*rt->tracked_methods));
157 if (!ptr)
158 return AVERROR(ENOMEM);
159 rt->tracked_methods = ptr;
160 }
161
162 rt->tracked_methods[rt->nb_tracked_methods].name = av_strdup(name);
163 if (!rt->tracked_methods[rt->nb_tracked_methods].name)
164 return AVERROR(ENOMEM);
165 rt->tracked_methods[rt->nb_tracked_methods].id = id;
166 rt->nb_tracked_methods++;
167
168 return 0;
169 }
170
171 static void del_tracked_method(RTMPContext *rt, int index)
172 {
173 memmove(&rt->tracked_methods[index], &rt->tracked_methods[index + 1],
174 sizeof(*rt->tracked_methods) * (rt->nb_tracked_methods - index - 1));
175 rt->nb_tracked_methods--;
176 }
177
178 static int find_tracked_method(URLContext *s, RTMPPacket *pkt, int offset,
179 char **tracked_method)
180 {
181 RTMPContext *rt = s->priv_data;
182 GetByteContext gbc;
183 double pkt_id;
184 int ret;
185 int i;
186
187 bytestream2_init(&gbc, pkt->data + offset, pkt->data_size - offset);
188 if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
189 return ret;
190
191 for (i = 0; i < rt->nb_tracked_methods; i++) {
192 if (rt->tracked_methods[i].id != pkt_id)
193 continue;
194
195 *tracked_method = rt->tracked_methods[i].name;
196 del_tracked_method(rt, i);
197 break;
198 }
199
200 return 0;
201 }
202
203 static void free_tracked_methods(RTMPContext *rt)
204 {
205 int i;
206
207 for (i = 0; i < rt->nb_tracked_methods; i ++)
208 av_free(rt->tracked_methods[i].name);
209 av_free(rt->tracked_methods);
210 rt->tracked_methods = NULL;
211 rt->tracked_methods_size = 0;
212 rt->nb_tracked_methods = 0;
213 }
214
215 static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
216 {
217 int ret;
218
219 if (pkt->type == RTMP_PT_INVOKE && track) {
220 GetByteContext gbc;
221 char name[128];
222 double pkt_id;
223 int len;
224
225 bytestream2_init(&gbc, pkt->data, pkt->data_size);
226 if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0)
227 goto fail;
228
229 if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
230 goto fail;
231
232 if ((ret = add_tracked_method(rt, name, pkt_id)) < 0)
233 goto fail;
234 }
235
236 ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
237 rt->prev_pkt[1]);
238 fail:
239 ff_rtmp_packet_destroy(pkt);
240 return ret;
241 }
242
243 static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)
244 {
245 char *field, *value;
246 char type;
247
248 /* The type must be B for Boolean, N for number, S for string, O for
249 * object, or Z for null. For Booleans the data must be either 0 or 1 for
250 * FALSE or TRUE, respectively. Likewise for Objects the data must be
251 * 0 or 1 to end or begin an object, respectively. Data items in subobjects
252 * may be named, by prefixing the type with 'N' and specifying the name
253 * before the value (ie. NB:myFlag:1). This option may be used multiple times
254 * to construct arbitrary AMF sequences. */
255 if (param[0] && param[1] == ':') {
256 type = param[0];
257 value = param + 2;
258 } else if (param[0] == 'N' && param[1] && param[2] == ':') {
259 type = param[1];
260 field = param + 3;
261 value = strchr(field, ':');
262 if (!value)
263 goto fail;
264 *value = '\0';
265 value++;
266
267 if (!field || !value)
268 goto fail;
269
270 ff_amf_write_field_name(p, field);
271 } else {
272 goto fail;
273 }
274
275 switch (type) {
276 case 'B':
277 ff_amf_write_bool(p, value[0] != '0');
278 break;
279 case 'S':
280 ff_amf_write_string(p, value);
281 break;
282 case 'N':
283 ff_amf_write_number(p, strtod(value, NULL));
284 break;
285 case 'Z':
286 ff_amf_write_null(p);
287 break;
288 case 'O':
289 if (value[0] != '0')
290 ff_amf_write_object_start(p);
291 else
292 ff_amf_write_object_end(p);
293 break;
294 default:
295 goto fail;
296 break;
297 }
298
299 return 0;
300
301 fail:
302 av_log(s, AV_LOG_ERROR, "Invalid AMF parameter: %s\n", param);
303 return AVERROR(EINVAL);
304 }
305
306 /**
307 * Generate 'connect' call and send it to the server.
308 */
309 static int gen_connect(URLContext *s, RTMPContext *rt)
310 {
311 RTMPPacket pkt;
312 uint8_t *p;
313 int ret;
314
315 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
316 0, 4096)) < 0)
317 return ret;
318
319 p = pkt.data;
320
321 ff_amf_write_string(&p, "connect");
322 ff_amf_write_number(&p, ++rt->nb_invokes);
323 ff_amf_write_object_start(&p);
324 ff_amf_write_field_name(&p, "app");
325 ff_amf_write_string2(&p, rt->app, rt->auth_params);
326
327 if (!rt->is_input) {
328 ff_amf_write_field_name(&p, "type");
329 ff_amf_write_string(&p, "nonprivate");
330 }
331 ff_amf_write_field_name(&p, "flashVer");
332 ff_amf_write_string(&p, rt->flashver);
333
334 if (rt->swfurl) {
335 ff_amf_write_field_name(&p, "swfUrl");
336 ff_amf_write_string(&p, rt->swfurl);
337 }
338
339 ff_amf_write_field_name(&p, "tcUrl");
340 ff_amf_write_string2(&p, rt->tcurl, rt->auth_params);
341 if (rt->is_input) {
342 ff_amf_write_field_name(&p, "fpad");
343 ff_amf_write_bool(&p, 0);
344 ff_amf_write_field_name(&p, "capabilities");
345 ff_amf_write_number(&p, 15.0);
346
347 /* Tell the server we support all the audio codecs except
348 * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)
349 * which are unused in the RTMP protocol implementation. */
350 ff_amf_write_field_name(&p, "audioCodecs");
351 ff_amf_write_number(&p, 4071.0);
352 ff_amf_write_field_name(&p, "videoCodecs");
353 ff_amf_write_number(&p, 252.0);
354 ff_amf_write_field_name(&p, "videoFunction");
355 ff_amf_write_number(&p, 1.0);
356
357 if (rt->pageurl) {
358 ff_amf_write_field_name(&p, "pageUrl");
359 ff_amf_write_string(&p, rt->pageurl);
360 }
361 }
362 ff_amf_write_object_end(&p);
363
364 if (rt->conn) {
365 char *param = rt->conn;
366
367 // Write arbitrary AMF data to the Connect message.
368 while (param != NULL) {
369 char *sep;
370 param += strspn(param, " ");
371 if (!*param)
372 break;
373 sep = strchr(param, ' ');
374 if (sep)
375 *sep = '\0';
376 if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) {
377 // Invalid AMF parameter.
378 ff_rtmp_packet_destroy(&pkt);
379 return ret;
380 }
381
382 if (sep)
383 param = sep + 1;
384 else
385 break;
386 }
387 }
388
389 pkt.data_size = p - pkt.data;
390
391 return rtmp_send_packet(rt, &pkt, 1);
392 }
393
394 static int read_connect(URLContext *s, RTMPContext *rt)
395 {
396 RTMPPacket pkt = { 0 };
397 uint8_t *p;
398 const uint8_t *cp;
399 int ret;
400 char command[64];
401 int stringlen;
402 double seqnum;
403 uint8_t tmpstr[256];
404 GetByteContext gbc;
405
406 if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
407 rt->prev_pkt[1])) < 0)
408 return ret;
409 cp = pkt.data;
410 bytestream2_init(&gbc, cp, pkt.data_size);
411 if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) {
412 av_log(s, AV_LOG_ERROR, "Unable to read command string\n");
413 ff_rtmp_packet_destroy(&pkt);
414 return AVERROR_INVALIDDATA;
415 }
416 if (strcmp(command, "connect")) {
417 av_log(s, AV_LOG_ERROR, "Expecting connect, got %s\n", command);
418 ff_rtmp_packet_destroy(&pkt);
419 return AVERROR_INVALIDDATA;
420 }
421 ret = ff_amf_read_number(&gbc, &seqnum);
422 if (ret)
423 av_log(s, AV_LOG_WARNING, "SeqNum not found\n");
424 /* Here one could parse an AMF Object with data as flashVers and others. */
425 ret = ff_amf_get_field_value(gbc.buffer,
426 gbc.buffer + bytestream2_get_bytes_left(&gbc),
427 "app", tmpstr, sizeof(tmpstr));
428 if (ret)
429 av_log(s, AV_LOG_WARNING, "App field not found in connect\n");
430 if (!ret && strcmp(tmpstr, rt->app))
431 av_log(s, AV_LOG_WARNING, "App field don't match up: %s <-> %s\n",
432 tmpstr, rt->app);
433 ff_rtmp_packet_destroy(&pkt);
434
435 // Send Window Acknowledgement Size (as defined in speficication)
436 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
437 RTMP_PT_SERVER_BW, 0, 4)) < 0)
438 return ret;
439 p = pkt.data;
440 bytestream_put_be32(&p, rt->server_bw);
441 pkt.data_size = p - pkt.data;
442 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
443 rt->prev_pkt[1]);
444 ff_rtmp_packet_destroy(&pkt);
445 if (ret < 0)
446 return ret;
447 // Send Peer Bandwidth
448 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
449 RTMP_PT_CLIENT_BW, 0, 5)) < 0)
450 return ret;
451 p = pkt.data;
452 bytestream_put_be32(&p, rt->server_bw);
453 bytestream_put_byte(&p, 2); // dynamic
454 pkt.data_size = p - pkt.data;
455 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
456 rt->prev_pkt[1]);
457 ff_rtmp_packet_destroy(&pkt);
458 if (ret < 0)
459 return ret;
460
461 // Ping request
462 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL,
463 RTMP_PT_PING, 0, 6)) < 0)
464 return ret;
465
466 p = pkt.data;
467 bytestream_put_be16(&p, 0); // 0 -> Stream Begin
468 bytestream_put_be32(&p, 0);
469 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
470 rt->prev_pkt[1]);
471 ff_rtmp_packet_destroy(&pkt);
472 if (ret < 0)
473 return ret;
474
475 // Chunk size
476 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
477 RTMP_PT_CHUNK_SIZE, 0, 4)) < 0)
478 return ret;
479
480 p = pkt.data;
481 bytestream_put_be32(&p, rt->out_chunk_size);
482 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
483 rt->prev_pkt[1]);
484 ff_rtmp_packet_destroy(&pkt);
485 if (ret < 0)
486 return ret;
487
488 // Send result_ NetConnection.Connect.Success to connect
489 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
490 RTMP_PT_INVOKE, 0,
491 RTMP_PKTDATA_DEFAULT_SIZE)) < 0)
492 return ret;
493
494 p = pkt.data;
495 ff_amf_write_string(&p, "_result");
496 ff_amf_write_number(&p, seqnum);
497
498 ff_amf_write_object_start(&p);
499 ff_amf_write_field_name(&p, "fmsVer");
500 ff_amf_write_string(&p, "FMS/3,0,1,123");
501 ff_amf_write_field_name(&p, "capabilities");
502 ff_amf_write_number(&p, 31);
503 ff_amf_write_object_end(&p);
504
505 ff_amf_write_object_start(&p);
506 ff_amf_write_field_name(&p, "level");
507 ff_amf_write_string(&p, "status");
508 ff_amf_write_field_name(&p, "code");
509 ff_amf_write_string(&p, "NetConnection.Connect.Success");
510 ff_amf_write_field_name(&p, "description");
511 ff_amf_write_string(&p, "Connection succeeded.");
512 ff_amf_write_field_name(&p, "objectEncoding");
513 ff_amf_write_number(&p, 0);
514 ff_amf_write_object_end(&p);
515
516 pkt.data_size = p - pkt.data;
517 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
518 rt->prev_pkt[1]);
519 ff_rtmp_packet_destroy(&pkt);
520 if (ret < 0)
521 return ret;
522
523 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL,
524 RTMP_PT_INVOKE, 0, 30)) < 0)
525 return ret;
526 p = pkt.data;
527 ff_amf_write_string(&p, "onBWDone");
528 ff_amf_write_number(&p, 0);
529 ff_amf_write_null(&p);
530 ff_amf_write_number(&p, 8192);
531 pkt.data_size = p - pkt.data;
532 ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
533 rt->prev_pkt[1]);
534 ff_rtmp_packet_destroy(&pkt);
535
536 return ret;
537 }
538
539 /**
540 * Generate 'releaseStream' call and send it to the server. It should make
541 * the server release some channel for media streams.
542 */
543 static int gen_release_stream(URLContext *s, RTMPContext *rt)
544 {
545 RTMPPacket pkt;
546 uint8_t *p;
547 int ret;
548
549 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
550 0, 29 + strlen(rt->playpath))) < 0)
551 return ret;
552
553 av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
554 p = pkt.data;
555 ff_amf_write_string(&p, "releaseStream");
556 ff_amf_write_number(&p, ++rt->nb_invokes);
557 ff_amf_write_null(&p);
558 ff_amf_write_string(&p, rt->playpath);
559
560 return rtmp_send_packet(rt, &pkt, 1);
561 }
562
563 /**
564 * Generate 'FCPublish' call and send it to the server. It should make
565 * the server preapare for receiving media streams.
566 */
567 static int gen_fcpublish_stream(URLContext *s, RTMPContext *rt)
568 {
569 RTMPPacket pkt;
570 uint8_t *p;
571 int ret;
572
573 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
574 0, 25 + strlen(rt->playpath))) < 0)
575 return ret;
576
577 av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
578 p = pkt.data;
579 ff_amf_write_string(&p, "FCPublish");
580 ff_amf_write_number(&p, ++rt->nb_invokes);
581 ff_amf_write_null(&p);
582 ff_amf_write_string(&p, rt->playpath);
583
584 return rtmp_send_packet(rt, &pkt, 1);
585 }
586
587 /**
588 * Generate 'FCUnpublish' call and send it to the server. It should make
589 * the server destroy stream.
590 */
591 static int gen_fcunpublish_stream(URLContext *s, RTMPContext *rt)
592 {
593 RTMPPacket pkt;
594 uint8_t *p;
595 int ret;
596
597 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
598 0, 27 + strlen(rt->playpath))) < 0)
599 return ret;
600
601 av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
602 p = pkt.data;
603 ff_amf_write_string(&p, "FCUnpublish");
604 ff_amf_write_number(&p, ++rt->nb_invokes);
605 ff_amf_write_null(&p);
606 ff_amf_write_string(&p, rt->playpath);
607
608 return rtmp_send_packet(rt, &pkt, 0);
609 }
610
611 /**
612 * Generate 'createStream' call and send it to the server. It should make
613 * the server allocate some channel for media streams.
614 */
615 static int gen_create_stream(URLContext *s, RTMPContext *rt)
616 {
617 RTMPPacket pkt;
618 uint8_t *p;
619 int ret;
620
621 av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
622
623 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
624 0, 25)) < 0)
625 return ret;
626
627 p = pkt.data;
628 ff_amf_write_string(&p, "createStream");
629 ff_amf_write_number(&p, ++rt->nb_invokes);
630 ff_amf_write_null(&p);
631
632 return rtmp_send_packet(rt, &pkt, 1);
633 }
634
635
636 /**
637 * Generate 'deleteStream' call and send it to the server. It should make
638 * the server remove some channel for media streams.
639 */
640 static int gen_delete_stream(URLContext *s, RTMPContext *rt)
641 {
642 RTMPPacket pkt;
643 uint8_t *p;
644 int ret;
645
646 av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
647
648 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
649 0, 34)) < 0)
650 return ret;
651
652 p = pkt.data;
653 ff_amf_write_string(&p, "deleteStream");
654 ff_amf_write_number(&p, ++rt->nb_invokes);
655 ff_amf_write_null(&p);
656 ff_amf_write_number(&p, rt->main_channel_id);
657
658 return rtmp_send_packet(rt, &pkt, 0);
659 }
660
661 /**
662 * Generate client buffer time and send it to the server.
663 */
664 static int gen_buffer_time(URLContext *s, RTMPContext *rt)
665 {
666 RTMPPacket pkt;
667 uint8_t *p;
668 int ret;
669
670 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
671 1, 10)) < 0)
672 return ret;
673
674 p = pkt.data;
675 bytestream_put_be16(&p, 3);
676 bytestream_put_be32(&p, rt->main_channel_id);
677 bytestream_put_be32(&p, rt->client_buffer_time);
678
679 return rtmp_send_packet(rt, &pkt, 0);
680 }
681
682 /**
683 * Generate 'play' call and send it to the server, then ping the server
684 * to start actual playing.
685 */
686 static int gen_play(URLContext *s, RTMPContext *rt)
687 {
688 RTMPPacket pkt;
689 uint8_t *p;
690 int ret;
691
692 av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
693
694 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_VIDEO_CHANNEL, RTMP_PT_INVOKE,
695 0, 29 + strlen(rt->playpath))) < 0)
696 return ret;
697
698 pkt.extra = rt->main_channel_id;
699
700 p = pkt.data;
701 ff_amf_write_string(&p, "play");
702 ff_amf_write_number(&p, ++rt->nb_invokes);
703 ff_amf_write_null(&p);
704 ff_amf_write_string(&p, rt->playpath);
705 ff_amf_write_number(&p, rt->live);
706
707 return rtmp_send_packet(rt, &pkt, 1);
708 }
709
710 /**
711 * Generate 'publish' call and send it to the server.
712 */
713 static int gen_publish(URLContext *s, RTMPContext *rt)
714 {
715 RTMPPacket pkt;
716 uint8_t *p;
717 int ret;
718
719 av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
720
721 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SOURCE_CHANNEL, RTMP_PT_INVOKE,
722 0, 30 + strlen(rt->playpath))) < 0)
723 return ret;
724
725 pkt.extra = rt->main_channel_id;
726
727 p = pkt.data;
728 ff_amf_write_string(&p, "publish");
729 ff_amf_write_number(&p, ++rt->nb_invokes);
730 ff_amf_write_null(&p);
731 ff_amf_write_string(&p, rt->playpath);
732 ff_amf_write_string(&p, "live");
733
734 return rtmp_send_packet(rt, &pkt, 1);
735 }
736
737 /**
738 * Generate ping reply and send it to the server.
739 */
740 static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
741 {
742 RTMPPacket pkt;
743 uint8_t *p;
744 int ret;
745
746 if (ppkt->data_size < 6) {
747 av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
748 ppkt->data_size);
749 return AVERROR_INVALIDDATA;
750 }
751
752 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
753 ppkt->timestamp + 1, 6)) < 0)
754 return ret;
755
756 p = pkt.data;
757 bytestream_put_be16(&p, 7);
758 bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
759
760 return rtmp_send_packet(rt, &pkt, 0);
761 }
762
763 /**
764 * Generate SWF verification message and send it to the server.
765 */
766 static int gen_swf_verification(URLContext *s, RTMPContext *rt)
767 {
768 RTMPPacket pkt;
769 uint8_t *p;
770 int ret;
771
772 av_log(s, AV_LOG_DEBUG, "Sending SWF verification...\n");
773 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_PING,
774 0, 44)) < 0)
775 return ret;
776
777 p = pkt.data;
778 bytestream_put_be16(&p, 27);
779 memcpy(p, rt->swfverification, 42);
780
781 return rtmp_send_packet(rt, &pkt, 0);
782 }
783
784 /**
785 * Generate server bandwidth message and send it to the server.
786 */
787 static int gen_server_bw(URLContext *s, RTMPContext *rt)
788 {
789 RTMPPacket pkt;
790 uint8_t *p;
791 int ret;
792
793 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_SERVER_BW,
794 0, 4)) < 0)
795 return ret;
796
797 p = pkt.data;
798 bytestream_put_be32(&p, rt->server_bw);
799
800 return rtmp_send_packet(rt, &pkt, 0);
801 }
802
803 /**
804 * Generate check bandwidth message and send it to the server.
805 */
806 static int gen_check_bw(URLContext *s, RTMPContext *rt)
807 {
808 RTMPPacket pkt;
809 uint8_t *p;
810 int ret;
811
812 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
813 0, 21)) < 0)
814 return ret;
815
816 p = pkt.data;
817 ff_amf_write_string(&p, "_checkbw");
818 ff_amf_write_number(&p, ++rt->nb_invokes);
819 ff_amf_write_null(&p);
820
821 return rtmp_send_packet(rt, &pkt, 1);
822 }
823
824 /**
825 * Generate report on bytes read so far and send it to the server.
826 */
827 static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
828 {
829 RTMPPacket pkt;
830 uint8_t *p;
831 int ret;
832
833 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_NETWORK_CHANNEL, RTMP_PT_BYTES_READ,
834 ts, 4)) < 0)
835 return ret;
836
837 p = pkt.data;
838 bytestream_put_be32(&p, rt->bytes_read);
839
840 return rtmp_send_packet(rt, &pkt, 0);
841 }
842
843 static int gen_fcsubscribe_stream(URLContext *s, RTMPContext *rt,
844 const char *subscribe)
845 {
846 RTMPPacket pkt;
847 uint8_t *p;
848 int ret;
849
850 if ((ret = ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE,
851 0, 27 + strlen(subscribe))) < 0)
852 return ret;
853
854 p = pkt.data;
855 ff_amf_write_string(&p, "FCSubscribe");
856 ff_amf_write_number(&p, ++rt->nb_invokes);
857 ff_amf_write_null(&p);
858 ff_amf_write_string(&p, subscribe);
859
860 return rtmp_send_packet(rt, &pkt, 1);
861 }
862
863 int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap,
864 const uint8_t *key, int keylen, uint8_t *dst)
865 {
866 struct AVSHA *sha;
867 uint8_t hmac_buf[64+32] = {0};
868 int i;
869
870 sha = av_sha_alloc();
871 if (!sha)
872 return AVERROR(ENOMEM);
873
874 if (keylen < 64) {
875 memcpy(hmac_buf, key, keylen);
876 } else {
877 av_sha_init(sha, 256);
878 av_sha_update(sha,key, keylen);
879 av_sha_final(sha, hmac_buf);
880 }
881 for (i = 0; i < 64; i++)
882 hmac_buf[i] ^= HMAC_IPAD_VAL;
883
884 av_sha_init(sha, 256);
885 av_sha_update(sha, hmac_buf, 64);
886 if (gap <= 0) {
887 av_sha_update(sha, src, len);
888 } else { //skip 32 bytes used for storing digest
889 av_sha_update(sha, src, gap);
890 av_sha_update(sha, src + gap + 32, len - gap - 32);
891 }
892 av_sha_final(sha, hmac_buf + 64);
893
894 for (i = 0; i < 64; i++)
895 hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad
896 av_sha_init(sha, 256);
897 av_sha_update(sha, hmac_buf, 64+32);
898 av_sha_final(sha, dst);
899
900 av_free(sha);
901
902 return 0;
903 }
904
905 int ff_rtmp_calc_digest_pos(const uint8_t *buf, int off, int mod_val,
906 int add_val)
907 {
908 int i, digest_pos = 0;
909
910 for (i = 0; i < 4; i++)
911 digest_pos += buf[i + off];
912 digest_pos = digest_pos % mod_val + add_val;
913
914 return digest_pos;
915 }
916
917 /**
918 * Put HMAC-SHA2 digest of packet data (except for the bytes where this digest
919 * will be stored) into that packet.
920 *
921 * @param buf handshake data (1536 bytes)
922 * @param encrypted use an encrypted connection (RTMPE)
923 * @return offset to the digest inside input data
924 */
925 static int rtmp_handshake_imprint_with_digest(uint8_t *buf, int encrypted)
926 {
927 int ret, digest_pos;
928
929 if (encrypted)
930 digest_pos = ff_rtmp_calc_digest_pos(buf, 772, 728, 776);
931 else
932 digest_pos = ff_rtmp_calc_digest_pos(buf, 8, 728, 12);
933
934 ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
935 rtmp_player_key, PLAYER_KEY_OPEN_PART_LEN,
936 buf + digest_pos);
937 if (ret < 0)
938 return ret;
939
940 return digest_pos;
941 }
942
943 /**
944 * Verify that the received server response has the expected digest value.
945 *
946 * @param buf handshake data received from the server (1536 bytes)
947 * @param off position to search digest offset from
948 * @return 0 if digest is valid, digest position otherwise
949 */
950 static int rtmp_validate_digest(uint8_t *buf, int off)
951 {
952 uint8_t digest[32];
953 int ret, digest_pos;
954
955 digest_pos = ff_rtmp_calc_digest_pos(buf, off, 728, off + 4);
956
957 ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
958 rtmp_server_key, SERVER_KEY_OPEN_PART_LEN,
959 digest);
960 if (ret < 0)
961 return ret;
962
963 if (!memcmp(digest, buf + digest_pos, 32))
964 return digest_pos;
965 return 0;
966 }
967
968 static int rtmp_calc_swf_verification(URLContext *s, RTMPContext *rt,
969 uint8_t *buf)
970 {
971 uint8_t *p;
972 int ret;
973
974 if (rt->swfhash_len != 32) {
975 av_log(s, AV_LOG_ERROR,
976 "Hash of the decompressed SWF file is not 32 bytes long.\n");
977 return AVERROR(EINVAL);
978 }
979
980 p = &rt->swfverification[0];
981 bytestream_put_byte(&p, 1);
982 bytestream_put_byte(&p, 1);
983 bytestream_put_be32(&p, rt->swfsize);
984 bytestream_put_be32(&p, rt->swfsize);
985
986 if ((ret = ff_rtmp_calc_digest(rt->swfhash, 32, 0, buf, 32, p)) < 0)
987 return ret;
988
989 return 0;
990 }
991
992 #if CONFIG_ZLIB
993 static int rtmp_uncompress_swfplayer(uint8_t *in_data, int64_t in_size,
994 uint8_t **out_data, int64_t *out_size)
995 {
996 z_stream zs = { 0 };
997 void *ptr;
998 int size;
999 int ret = 0;
1000
1001 zs.avail_in = in_size;
1002 zs.next_in = in_data;
1003 ret = inflateInit(&zs);
1004 if (ret != Z_OK)
1005 return AVERROR_UNKNOWN;
1006
1007 do {
1008 uint8_t tmp_buf[16384];
1009
1010 zs.avail_out = sizeof(tmp_buf);
1011 zs.next_out = tmp_buf;
1012
1013 ret = inflate(&zs, Z_NO_FLUSH);
1014 if (ret != Z_OK && ret != Z_STREAM_END) {
1015 ret = AVERROR_UNKNOWN;
1016 goto fail;
1017 }
1018
1019 size = sizeof(tmp_buf) - zs.avail_out;
1020 if (!(ptr = av_realloc(*out_data, *out_size + size))) {
1021 ret = AVERROR(ENOMEM);
1022 goto fail;
1023 }
1024 *out_data = ptr;
1025
1026 memcpy(*out_data + *out_size, tmp_buf, size);
1027 *out_size += size;
1028 } while (zs.avail_out == 0);
1029
1030 fail:
1031 inflateEnd(&zs);
1032 return ret;
1033 }
1034 #endif
1035
1036 static int rtmp_calc_swfhash(URLContext *s)
1037 {
1038 RTMPContext *rt = s->priv_data;
1039 uint8_t *in_data = NULL, *out_data = NULL, *swfdata;
1040 int64_t in_size, out_size;
1041 URLContext *stream;
1042 char swfhash[32];
1043 int swfsize;
1044 int ret = 0;
1045
1046 /* Get the SWF player file. */
1047 if ((ret = ffurl_open(&stream, rt->swfverify, AVIO_FLAG_READ,
1048 &s->interrupt_callback, NULL)) < 0) {
1049 av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify);
1050 goto fail;
1051 }
1052
1053 if ((in_size = ffurl_seek(stream, 0, AVSEEK_SIZE)) < 0) {
1054 ret = AVERROR(EIO);
1055 goto fail;
1056 }
1057
1058 if (!(in_data = av_malloc(in_size))) {
1059 ret = AVERROR(ENOMEM);
1060 goto fail;
1061 }
1062
1063 if ((ret = ffurl_read_complete(stream, in_data, in_size)) < 0)
1064 goto fail;
1065
1066 if (in_size < 3) {
1067 ret = AVERROR_INVALIDDATA;
1068 goto fail;
1069 }
1070
1071 if (!memcmp(in_data, "CWS", 3)) {
1072 /* Decompress the SWF player file using Zlib. */
1073 if (!(out_data = av_malloc(8))) {
1074 ret = AVERROR(ENOMEM);
1075 goto fail;
1076 }
1077 *in_data = 'F'; // magic stuff
1078 memcpy(out_data, in_data, 8);
1079 out_size = 8;
1080
1081 #if CONFIG_ZLIB
1082 if ((ret = rtmp_uncompress_swfplayer(in_data + 8, in_size - 8,
1083 &out_data, &out_size)) < 0)
1084 goto fail;
1085 #else
1086 av_log(s, AV_LOG_ERROR,
1087 "Zlib is required for decompressing the SWF player file.\n");
1088 ret = AVERROR(EINVAL);
1089 goto fail;
1090 #endif
1091 swfsize = out_size;
1092 swfdata = out_data;
1093 } else {
1094 swfsize = in_size;
1095 swfdata = in_data;
1096 }
1097
1098 /* Compute the SHA256 hash of the SWF player file. */
1099 if ((ret = ff_rtmp_calc_digest(swfdata, swfsize, 0,
1100 "Genuine Adobe Flash Player 001", 30,
1101 swfhash)) < 0)
1102 goto fail;
1103
1104 /* Set SWFVerification parameters. */
1105 av_opt_set_bin(rt, "rtmp_swfhash", swfhash, 32, 0);
1106 rt->swfsize = swfsize;
1107
1108 fail:
1109 av_freep(&in_data);
1110 av_freep(&out_data);
1111 ffurl_close(stream);
1112 return ret;
1113 }
1114
1115 /**
1116 * Perform handshake with the server by means of exchanging pseudorandom data
1117 * signed with HMAC-SHA2 digest.
1118 *
1119 * @return 0 if handshake succeeds, negative value otherwise
1120 */
1121 static int rtmp_handshake(URLContext *s, RTMPContext *rt)
1122 {
1123 AVLFG rnd;
1124 uint8_t tosend [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
1125 3, // unencrypted data
1126 0, 0, 0, 0, // client uptime
1127 RTMP_CLIENT_VER1,
1128 RTMP_CLIENT_VER2,
1129 RTMP_CLIENT_VER3,
1130 RTMP_CLIENT_VER4,
1131 };
1132 uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
1133 uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
1134 int i;
1135 int server_pos, client_pos;
1136 uint8_t digest[32], signature[32];
1137 int ret, type = 0;
1138
1139 av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
1140
1141 av_lfg_init(&rnd, 0xDEADC0DE);
1142 // generate handshake packet - 1536 bytes of pseudorandom data
1143 for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
1144 tosend[i] = av_lfg_get(&rnd) >> 24;
1145
1146 if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1147 /* When the client wants to use RTMPE, we have to change the command
1148 * byte to 0x06 which means to use encrypted data and we have to set
1149 * the flash version to at least 9.0.115.0. */
1150 tosend[0] = 6;
1151 tosend[5] = 128;
1152 tosend[6] = 0;
1153 tosend[7] = 3;
1154 tosend[8] = 2;
1155
1156 /* Initialize the Diffie-Hellmann context and generate the public key
1157 * to send to the server. */
1158 if ((ret = ff_rtmpe_gen_pub_key(rt->stream, tosend + 1)) < 0)
1159 return ret;
1160 }
1161
1162 client_pos = rtmp_handshake_imprint_with_digest(tosend + 1, rt->encrypted);
1163 if (client_pos < 0)
1164 return client_pos;
1165
1166 if ((ret = ffurl_write(rt->stream, tosend,
1167 RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1168 av_log(s, AV_LOG_ERROR, "Cannot write RTMP handshake request\n");
1169 return ret;
1170 }
1171
1172 if ((ret = ffurl_read_complete(rt->stream, serverdata,
1173 RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1174 av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1175 return ret;
1176 }
1177
1178 if ((ret = ffurl_read_complete(rt->stream, clientdata,
1179 RTMP_HANDSHAKE_PACKET_SIZE)) < 0) {
1180 av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1181 return ret;
1182 }
1183
1184 av_log(s, AV_LOG_DEBUG, "Type answer %d\n", serverdata[0]);
1185 av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
1186 serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
1187
1188 if (rt->is_input && serverdata[5] >= 3) {
1189 server_pos = rtmp_validate_digest(serverdata + 1, 772);
1190 if (server_pos < 0)
1191 return server_pos;
1192
1193 if (!server_pos) {
1194 type = 1;
1195 server_pos = rtmp_validate_digest(serverdata + 1, 8);
1196 if (server_pos < 0)
1197 return server_pos;
1198
1199 if (!server_pos) {
1200 av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
1201 return AVERROR(EIO);
1202 }
1203 }
1204
1205 /* Generate SWFVerification token (SHA256 HMAC hash of decompressed SWF,
1206 * key are the last 32 bytes of the server handshake. */
1207 if (rt->swfsize) {
1208 if ((ret = rtmp_calc_swf_verification(s, rt, serverdata + 1 +
1209 RTMP_HANDSHAKE_PACKET_SIZE - 32)) < 0)
1210 return ret;
1211 }
1212
1213 ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
1214 rtmp_server_key, sizeof(rtmp_server_key),
1215 digest);
1216 if (ret < 0)
1217 return ret;
1218
1219 ret = ff_rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE - 32,
1220 0, digest, 32, signature);
1221 if (ret < 0)
1222 return ret;
1223
1224 if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1225 /* Compute the shared secret key sent by the server and initialize
1226 * the RC4 encryption. */
1227 if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1228 tosend + 1, type)) < 0)
1229 return ret;
1230
1231 /* Encrypt the signature received by the server. */
1232 ff_rtmpe_encrypt_sig(rt->stream, signature, digest, serverdata[0]);
1233 }
1234
1235 if (memcmp(signature, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
1236 av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
1237 return AVERROR(EIO);
1238 }
1239
1240 for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
1241 tosend[i] = av_lfg_get(&rnd) >> 24;
1242 ret = ff_rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
1243 rtmp_player_key, sizeof(rtmp_player_key),
1244 digest);
1245 if (ret < 0)
1246 return ret;
1247
1248 ret = ff_rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
1249 digest, 32,
1250 tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
1251 if (ret < 0)
1252 return ret;
1253
1254 if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1255 /* Encrypt the signature to be send to the server. */
1256 ff_rtmpe_encrypt_sig(rt->stream, tosend +
1257 RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
1258 serverdata[0]);
1259 }
1260
1261 // write reply back to the server
1262 if ((ret = ffurl_write(rt->stream, tosend,
1263 RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1264 return ret;
1265
1266 if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1267 /* Set RC4 keys for encryption and update the keystreams. */
1268 if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1269 return ret;
1270 }
1271 } else {
1272 if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1273 /* Compute the shared secret key sent by the server and initialize
1274 * the RC4 encryption. */
1275 if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1276 tosend + 1, 1)) < 0)
1277 return ret;
1278
1279 if (serverdata[0] == 9) {
1280 /* Encrypt the signature received by the server. */
1281 ff_rtmpe_encrypt_sig(rt->stream, signature, digest,
1282 serverdata[0]);
1283 }
1284 }
1285
1286 if ((ret = ffurl_write(rt->stream, serverdata + 1,
1287 RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1288 return ret;
1289
1290 if (rt->encrypted && CONFIG_FFRTMPCRYPT_PROTOCOL) {
1291 /* Set RC4 keys for encryption and update the keystreams. */
1292 if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1293 return ret;
1294 }
1295 }
1296
1297 return 0;
1298 }
1299
1300 static int rtmp_receive_hs_packet(RTMPContext* rt, uint32_t *first_int,
1301 uint32_t *second_int, char *arraydata,
1302 int size)
1303 {
1304 int inoutsize;
1305
1306 inoutsize = ffurl_read_complete(rt->stream, arraydata,
1307 RTMP_HANDSHAKE_PACKET_SIZE);
1308 if (inoutsize <= 0)
1309 return AVERROR(EIO);
1310 if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1311 av_log(rt, AV_LOG_ERROR, "Erroneous Message size %d"
1312 " not following standard\n", (int)inoutsize);
1313 return AVERROR(EINVAL);
1314 }
1315
1316 *first_int = AV_RB32(arraydata);
1317 *second_int = AV_RB32(arraydata + 4);
1318 return 0;
1319 }
1320
1321 static int rtmp_send_hs_packet(RTMPContext* rt, uint32_t first_int,
1322 uint32_t second_int, char *arraydata, int size)
1323 {
1324 int inoutsize;
1325
1326 AV_WB32(arraydata, first_int);
1327 AV_WB32(arraydata + 4, first_int);
1328 inoutsize = ffurl_write(rt->stream, arraydata,
1329 RTMP_HANDSHAKE_PACKET_SIZE);
1330 if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1331 av_log(rt, AV_LOG_ERROR, "Unable to write answer\n");
1332 return AVERROR(EIO);
1333 }
1334
1335 return 0;
1336 }
1337
1338 /**
1339 * rtmp handshake server side
1340 */
1341 static int rtmp_server_handshake(URLContext *s, RTMPContext *rt)
1342 {
1343 uint8_t buffer[RTMP_HANDSHAKE_PACKET_SIZE];
1344 uint32_t hs_epoch;
1345 uint32_t hs_my_epoch;
1346 uint8_t hs_c1[RTMP_HANDSHAKE_PACKET_SIZE];
1347 uint8_t hs_s1[RTMP_HANDSHAKE_PACKET_SIZE];
1348 uint32_t zeroes;
1349 uint32_t temp = 0;
1350 int randomidx = 0;
1351 int inoutsize = 0;
1352 int ret;
1353
1354 inoutsize = ffurl_read_complete(rt->stream, buffer, 1); // Receive C0
1355 if (inoutsize <= 0) {
1356 av_log(s, AV_LOG_ERROR, "Unable to read handshake\n");
1357 return AVERROR(EIO);
1358 }
1359 // Check Version
1360 if (buffer[0] != 3) {
1361 av_log(s, AV_LOG_ERROR, "RTMP protocol version mismatch\n");
1362 return AVERROR(EIO);
1363 }
1364 if (ffurl_write(rt->stream, buffer, 1) <= 0) { // Send S0
1365 av_log(s, AV_LOG_ERROR,
1366 "Unable to write answer - RTMP S0\n");
1367 return AVERROR(EIO);
1368 }
1369 /* Receive C1 */
1370 ret = rtmp_receive_hs_packet(rt, &hs_epoch, &zeroes, hs_c1,
1371 RTMP_HANDSHAKE_PACKET_SIZE);
1372 if (ret) {
1373 av_log(s, AV_LOG_ERROR, "RTMP Handshake C1 Error\n");
1374 return ret;
1375 }
1376 if (zeroes)
1377 av_log(s, AV_LOG_WARNING, "Erroneous C1 Message zero != 0\n");
1378 /* Send S1 */
1379 /* By now same epoch will be sent */
1380 hs_my_epoch = hs_epoch;
1381 /* Generate random */
1382 for (randomidx = 8; randomidx < (RTMP_HANDSHAKE_PACKET_SIZE);
1383 randomidx += 4)
1384 AV_WB32(hs_s1 + randomidx, av_get_random_seed());
1385
1386 ret = rtmp_send_hs_packet(rt, hs_my_epoch, 0, hs_s1,
1387 RTMP_HANDSHAKE_PACKET_SIZE);
1388 if (ret) {
1389 av_log(s, AV_LOG_ERROR, "RTMP Handshake S1 Error\n");
1390 return ret;
1391 }
1392 /* Send S2 */
1393 ret = rtmp_send_hs_packet(rt, hs_epoch, 0, hs_c1,
1394 RTMP_HANDSHAKE_PACKET_SIZE);
1395 if (ret) {
1396 av_log(s, AV_LOG_ERROR, "RTMP Handshake S2 Error\n");
1397 return ret;
1398 }
1399 /* Receive C2 */
1400 ret = rtmp_receive_hs_packet(rt, &temp, &zeroes, buffer,
1401 RTMP_HANDSHAKE_PACKET_SIZE);
1402 if (ret) {
1403 av_log(s, AV_LOG_ERROR, "RTMP Handshake C2 Error\n");
1404 return ret;
1405 }
1406 if (temp != hs_my_epoch)
1407 av_log(s, AV_LOG_WARNING,
1408 "Erroneous C2 Message epoch does not match up with C1 epoch\n");
1409 if (memcmp(buffer + 8, hs_s1 + 8,
1410 RTMP_HANDSHAKE_PACKET_SIZE - 8))
1411 av_log(s, AV_LOG_WARNING,
1412 "Erroneous C2 Message random does not match up\n");
1413
1414 return 0;
1415 }
1416
1417 static int handle_chunk_size(URLContext *s, RTMPPacket *pkt)
1418 {
1419 RTMPContext *rt = s->priv_data;
1420 int ret;
1421
1422 if (pkt->data_size < 4) {
1423 av_log(s, AV_LOG_ERROR,
1424 "Too short chunk size change packet (%d)\n",
1425 pkt->data_size);
1426 return AVERROR_INVALIDDATA;
1427 }
1428
1429 if (!rt->is_input) {
1430 /* Send the same chunk size change packet back to the server,
1431 * setting the outgoing chunk size to the same as the incoming one. */
1432 if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
1433 rt->prev_pkt[1])) < 0)
1434 return ret;
1435 rt->out_chunk_size = AV_RB32(pkt->data);
1436 }
1437
1438 rt->in_chunk_size = AV_RB32(pkt->data);
1439 if (rt->in_chunk_size <= 0) {
1440 av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n",
1441 rt->in_chunk_size);
1442 return AVERROR_INVALIDDATA;
1443 }
1444 av_log(s, AV_LOG_DEBUG, "New incoming chunk size = %d\n",
1445 rt->in_chunk_size);
1446
1447 return 0;
1448 }
1449
1450 static int handle_ping(URLContext *s, RTMPPacket *pkt)
1451 {
1452 RTMPContext *rt = s->priv_data;
1453 int t, ret;
1454
1455 if (pkt->data_size < 2) {
1456 av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
1457 pkt->data_size);
1458 return AVERROR_INVALIDDATA;
1459 }
1460
1461 t = AV_RB16(pkt->data);
1462 if (t == 6) {
1463 if ((ret = gen_pong(s, rt, pkt)) < 0)
1464 return ret;
1465 } else if (t == 26) {
1466 if (rt->swfsize) {
1467 if ((ret = gen_swf_verification(s, rt)) < 0)
1468 return ret;
1469 } else {
1470 av_log(s, AV_LOG_WARNING, "Ignoring SWFVerification request.\n");
1471 }
1472 }
1473
1474 return 0;
1475 }
1476
1477 static int handle_client_bw(URLContext *s, RTMPPacket *pkt)
1478 {
1479 RTMPContext *rt = s->priv_data;
1480
1481 if (pkt->data_size < 4) {
1482 av_log(s, AV_LOG_ERROR,
1483 "Client bandwidth report packet is less than 4 bytes long (%d)\n",
1484 pkt->data_size);
1485 return AVERROR_INVALIDDATA;
1486 }
1487
1488 rt->client_report_size = AV_RB32(pkt->data);
1489 if (rt->client_report_size <= 0) {
1490 av_log(s, AV_LOG_ERROR, "Incorrect client bandwidth %d\n",
1491 rt->client_report_size);
1492 return AVERROR_INVALIDDATA;
1493
1494 }
1495 av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", rt->client_report_size);
1496 rt->client_report_size >>= 1;
1497
1498 return 0;
1499 }
1500
1501 static int handle_server_bw(URLContext *s, RTMPPacket *pkt)
1502 {
1503 RTMPContext *rt = s->priv_data;
1504
1505 if (pkt->data_size < 4) {
1506 av_log(s, AV_LOG_ERROR,
1507 "Too short server bandwidth report packet (%d)\n",
1508 pkt->data_size);
1509 return AVERROR_INVALIDDATA;
1510 }
1511
1512 rt->server_bw = AV_RB32(pkt->data);
1513 if (rt->server_bw <= 0) {
1514 av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n",
1515 rt->server_bw);
1516 return AVERROR_INVALIDDATA;
1517 }
1518 av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw);
1519
1520 return 0;
1521 }
1522
1523 static int do_adobe_auth(RTMPContext *rt, const char *user, const char *salt,
1524 const char *opaque, const char *challenge)
1525 {
1526 uint8_t hash[16];
1527 char hashstr[AV_BASE64_SIZE(sizeof(hash))], challenge2[10];
1528 struct AVMD5 *md5 = av_md5_alloc();
1529 if (!md5)
1530 return AVERROR(ENOMEM);
1531
1532 snprintf(challenge2, sizeof(challenge2), "%08x", av_get_random_seed());
1533
1534 av_md5_init(md5);
1535 av_md5_update(md5, user, strlen(user));
1536 av_md5_update(md5, salt, strlen(salt));
1537 av_md5_update(md5, rt->password, strlen(rt->password));
1538 av_md5_final(md5, hash);
1539 av_base64_encode(hashstr, sizeof(hashstr), hash,
1540 sizeof(hash));
1541 av_md5_init(md5);
1542 av_md5_update(md5, hashstr, strlen(hashstr));
1543 if (opaque)
1544 av_md5_update(md5, opaque, strlen(opaque));
1545 else if (challenge)
1546 av_md5_update(md5, challenge, strlen(challenge));
1547 av_md5_update(md5, challenge2, strlen(challenge2));
1548 av_md5_final(md5, hash);
1549 av_base64_encode(hashstr, sizeof(hashstr), hash,
1550 sizeof(hash));
1551 snprintf(rt->auth_params, sizeof(rt->auth_params),
1552 "?authmod=%s&user=%s&challenge=%s&response=%s",
1553 "adobe", user, challenge2, hashstr);
1554 if (opaque)
1555 av_strlcatf(rt->auth_params, sizeof(rt->auth_params),
1556 "&opaque=%s", opaque);
1557
1558 av_free(md5);
1559 return 0;
1560 }
1561
1562 static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)
1563 {
1564 uint8_t hash[16];
1565 char hashstr1[33], hashstr2[33];
1566 const char *realm = "live";
1567 const char *method = "publish";
1568 const char *qop = "auth";
1569 const char *nc = "00000001";
1570 char cnonce[10];
1571 struct AVMD5 *md5 = av_md5_alloc();
1572 if (!md5)
1573 return AVERROR(ENOMEM);
1574
1575 snprintf(cnonce, sizeof(cnonce), "%08x", av_get_random_seed());
1576
1577 av_md5_init(md5);
1578 av_md5_update(md5, user, strlen(user));
1579 av_md5_update(md5, ":", 1);
1580 av_md5_update(md5, realm, strlen(realm));
1581 av_md5_update(md5, ":", 1);
1582 av_md5_update(md5, rt->password, strlen(rt->password));
1583 av_md5_final(md5, hash);
1584 ff_data_to_hex(hashstr1, hash, 16, 1);
1585 hashstr1[32] = '\0';
1586
1587 av_md5_init(md5);
1588 av_md5_update(md5, method, strlen(method));
1589 av_md5_update(md5, ":/", 2);
1590 av_md5_update(md5, rt->app, strlen(rt->app));
1591 av_md5_final(md5, hash);
1592 ff_data_to_hex(hashstr2, hash, 16, 1);
1593 hashstr2[32] = '\0';
1594
1595 av_md5_init(md5);
1596 av_md5_update(md5, hashstr1, strlen(hashstr1));
1597 av_md5_update(md5, ":", 1);
1598 if (nonce)
1599 av_md5_update(md5, nonce, strlen(nonce));
1600 av_md5_update(md5, ":", 1);
1601 av_md5_update(md5, nc, strlen(nc));
1602 av_md5_update(md5, ":", 1);
1603 av_md5_update(md5, cnonce, strlen(cnonce));
1604 av_md5_update(md5, ":", 1);
1605 av_md5_update(md5, qop, strlen(qop));
1606 av_md5_update(md5, ":", 1);
1607 av_md5_update(md5, hashstr2, strlen(hashstr2));
1608 av_md5_final(md5, hash);
1609 ff_data_to_hex(hashstr1, hash, 16, 1);
1610
1611 snprintf(rt->auth_params, sizeof(rt->auth_params),
1612 "?authmod=%s&user=%s&nonce=%s&cnonce=%s&nc=%s&response=%s",
1613 "llnw", user, nonce, cnonce, nc, hashstr1);
1614
1615 av_free(md5);
1616 return 0;
1617 }
1618
1619 static int handle_connect_error(URLContext *s, const char *desc)
1620 {
1621 RTMPContext *rt = s->priv_data;
1622 char buf[300], *ptr, authmod[15];
1623 int i = 0, ret = 0;
1624 const char *user = "", *salt = "", *opaque = NULL,
1625 *challenge = NULL, *cptr = NULL, *nonce = NULL;
1626
1627 if (!(cptr = strstr(desc, "authmod=adobe")) &&
1628 !(cptr = strstr(desc, "authmod=llnw"))) {
1629 av_log(s, AV_LOG_ERROR,
1630 "Unknown connect error (unsupported authentication method?)\n");
1631 return AVERROR_UNKNOWN;
1632 }
1633 cptr += strlen("authmod=");
1634 while (*cptr && *cptr != ' ' && i < sizeof(authmod) - 1)
1635 authmod[i++] = *cptr++;
1636 authmod[i] = '\0';
1637
1638 if (!rt->username[0] || !rt->password[0]) {
1639 av_log(s, AV_LOG_ERROR, "No credentials set\n");
1640 return AVERROR_UNKNOWN;
1641 }
1642
1643 if (strstr(desc, "?reason=authfailed")) {
1644 av_log(s, AV_LOG_ERROR, "Incorrect username/password\n");
1645 return AVERROR_UNKNOWN;
1646 } else if (strstr(desc, "?reason=nosuchuser")) {
1647 av_log(s, AV_LOG_ERROR, "Incorrect username\n");
1648 return AVERROR_UNKNOWN;
1649 }
1650
1651 if (rt->auth_tried) {
1652 av_log(s, AV_LOG_ERROR, "Authentication failed\n");
1653 return AVERROR_UNKNOWN;
1654 }
1655
1656 rt->auth_params[0] = '\0';
1657
1658 if (strstr(desc, "code=403 need auth")) {
1659 snprintf(rt->auth_params, sizeof(rt->auth_params),
1660 "?authmod=%s&user=%s", authmod, rt->username);
1661 return 0;
1662 }
1663
1664 if (!(cptr = strstr(desc, "?reason=needauth"))) {
1665 av_log(s, AV_LOG_ERROR, "No auth parameters found\n");
1666 return AVERROR_UNKNOWN;
1667 }
1668
1669 av_strlcpy(buf, cptr + 1, sizeof(buf));
1670 ptr = buf;
1671
1672 while (ptr) {
1673 char *next = strchr(ptr, '&');
1674 char *value = strchr(ptr, '=');
1675 if (next)
1676 *next++ = '\0';
1677 if (value)
1678 *value++ = '\0';
1679 if (!strcmp(ptr, "user")) {
1680 user = value;
1681 } else if (!strcmp(ptr, "salt")) {
1682 salt = value;
1683 } else if (!strcmp(ptr, "opaque")) {
1684 opaque = value;
1685 } else if (!strcmp(ptr, "challenge")) {
1686 challenge = value;
1687 } else if (!strcmp(ptr, "nonce")) {
1688 nonce = value;
1689 }
1690 ptr = next;
1691 }
1692
1693 if (!strcmp(authmod, "adobe")) {
1694 if ((ret = do_adobe_auth(rt, user, salt, opaque, challenge)) < 0)
1695 return ret;
1696 } else {
1697 if ((ret = do_llnw_auth(rt, user, nonce)) < 0)
1698 return ret;
1699 }
1700
1701 rt->auth_tried = 1;
1702 return 0;
1703 }
1704
1705 static int handle_invoke_error(URLContext *s, RTMPPacket *pkt)
1706 {
1707 RTMPContext *rt = s->priv_data;
1708 const uint8_t *data_end = pkt->data + pkt->data_size;
1709 char *tracked_method = NULL;
1710 int level = AV_LOG_ERROR;
1711 uint8_t tmpstr[256];
1712 int ret;
1713
1714 if ((ret = find_tracked_method(s, pkt, 9, &tracked_method)) < 0)
1715 return ret;
1716
1717 if (!ff_amf_get_field_value(pkt->data + 9, data_end,
1718 "description", tmpstr, sizeof(tmpstr))) {
1719 if (tracked_method && (!strcmp(tracked_method, "_checkbw") ||
1720 !strcmp(tracked_method, "releaseStream") ||
1721 !strcmp(tracked_method, "FCSubscribe") ||
1722 !strcmp(tracked_method, "FCPublish"))) {
1723 /* Gracefully ignore Adobe-specific historical artifact errors. */
1724 level = AV_LOG_WARNING;
1725 ret = 0;
1726 } else if (tracked_method && !strcmp(tracked_method, "connect")) {
1727 ret = handle_connect_error(s, tmpstr);
1728 if (!ret) {
1729 rt->do_reconnect = 1;
1730 level = AV_LOG_VERBOSE;
1731 }
1732 } else
1733 ret = AVERROR_UNKNOWN;
1734 av_log(s, level, "Server error: %s\n", tmpstr);
1735 }
1736
1737 av_free(tracked_method);
1738 return ret;
1739 }
1740
1741 static int send_invoke_response(URLContext *s, RTMPPacket *pkt)
1742 {
1743 RTMPContext *rt = s->priv_data;
1744 double seqnum;
1745 char filename[64];
1746 char command[64];
1747 char statusmsg[128];
1748 int stringlen;
1749 char *pchar;
1750 const uint8_t *p = pkt->data;
1751 uint8_t *pp = NULL;
1752 RTMPPacket spkt = { 0 };
1753 GetByteContext gbc;
1754 int ret;
1755
1756 bytestream2_init(&gbc, p, pkt->data_size);
1757 if (ff_amf_read_string(&gbc, command, sizeof(command),
1758 &stringlen)) {
1759 av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n");
1760 return AVERROR_INVALIDDATA;
1761 }
1762
1763 ret = ff_amf_read_number(&gbc, &seqnum);
1764 if (ret)
1765 return ret;
1766 ret = ff_amf_read_null(&gbc);
1767 if (ret)
1768 return ret;
1769 if (!strcmp(command, "FCPublish") ||
1770 !strcmp(command, "publish")) {
1771 ret = ff_amf_read_string(&gbc, filename,
1772 sizeof(filename), &stringlen);
1773 // check with url
1774 if (s->filename) {
1775 pchar = strrchr(s->filename, '/');
1776 if (!pchar) {
1777 av_log(s, AV_LOG_WARNING,
1778 "Unable to find / in url %s, bad format\n",
1779 s->filename);
1780 pchar = s->filename;
1781 }
1782 pchar++;
1783 if (strcmp(pchar, filename))
1784 av_log(s, AV_LOG_WARNING, "Unexpected stream %s, expecting"
1785 " %s\n", filename, pchar);
1786 }
1787 rt->state = STATE_RECEIVING;
1788 }
1789
1790 if (!strcmp(command, "FCPublish")) {
1791 if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1792 RTMP_PT_INVOKE, 0,
1793 RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1794 av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1795 return ret;
1796 }
1797 pp = spkt.data;
1798 ff_amf_write_string(&pp, "onFCPublish");
1799 } else if (!strcmp(command, "publish")) {
1800 PutByteContext pbc;
1801 // Send Stream Begin 1
1802 if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
1803 RTMP_PT_PING, 0, 6)) < 0) {
1804 av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1805 return ret;
1806 }
1807 pp = spkt.data;
1808 bytestream2_init_writer(&pbc, pp, spkt.data_size);
1809 bytestream2_put_be16(&pbc, 0); // 0 -> Stream Begin
1810 bytestream2_put_be32(&pbc, rt->nb_streamid);
1811 ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1812 rt->prev_pkt[1]);
1813 ff_rtmp_packet_destroy(&spkt);
1814 if (ret < 0)
1815 return ret;
1816
1817 // Send onStatus(NetStream.Publish.Start)
1818 if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1819 RTMP_PT_INVOKE, 0,
1820 RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1821 av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1822 return ret;
1823 }
1824 spkt.extra = pkt->extra;
1825 pp = spkt.data;
1826 ff_amf_write_string(&pp, "onStatus");
1827 ff_amf_write_number(&pp, 0);
1828 ff_amf_write_null(&pp);
1829
1830 ff_amf_write_object_start(&pp);
1831 ff_amf_write_field_name(&pp, "level");
1832 ff_amf_write_string(&pp, "status");
1833 ff_amf_write_field_name(&pp, "code");
1834 ff_amf_write_string(&pp, "NetStream.Publish.Start");
1835 ff_amf_write_field_name(&pp, "description");
1836 snprintf(statusmsg, sizeof(statusmsg),
1837 "%s is now published", filename);
1838 ff_amf_write_string(&pp, statusmsg);
1839 ff_amf_write_field_name(&pp, "details");
1840 ff_amf_write_string(&pp, filename);
1841 ff_amf_write_field_name(&pp, "clientid");
1842 snprintf(statusmsg, sizeof(statusmsg), "%s", LIBAVFORMAT_IDENT);
1843 ff_amf_write_string(&pp, statusmsg);
1844 ff_amf_write_object_end(&pp);
1845
1846 } else {
1847 if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1848 RTMP_PT_INVOKE, 0,
1849 RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1850 av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1851 return ret;
1852 }
1853 pp = spkt.data;
1854 ff_amf_write_string(&pp, "_result");
1855 ff_amf_write_number(&pp, seqnum);
1856 ff_amf_write_null(&pp);
1857 if (!strcmp(command, "createStream")) {
1858 rt->nb_streamid++;
1859 if (rt->nb_streamid == 0 || rt->nb_streamid == 2)
1860 rt->nb_streamid++; /* Values 0 and 2 are reserved */
1861 ff_amf_write_number(&pp, rt->nb_streamid);
1862 /* By now we don't control which streams are removed in
1863 * deleteStream. There is no stream creation control
1864 * if a client creates more than 2^32 - 2 streams. */
1865 }
1866 }
1867 spkt.data_size = pp - spkt.data;
1868 ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1869 rt->prev_pkt[1]);
1870 ff_rtmp_packet_destroy(&spkt);
1871 return ret;
1872 }
1873
1874 static int handle_invoke_result(URLContext *s, RTMPPacket *pkt)
1875 {
1876 RTMPContext *rt = s->priv_data;
1877 char *tracked_method = NULL;
1878 int ret = 0;
1879
1880 if ((ret = find_tracked_method(s, pkt, 10, &tracked_method)) < 0)
1881 return ret;
1882
1883 if (!tracked_method) {
1884 /* Ignore this reply when the current method is not tracked. */
1885 return ret;
1886 }
1887
1888 if (!memcmp(tracked_method, "connect", 7)) {
1889 if (!rt->is_input) {
1890 if ((ret = gen_release_stream(s, rt)) < 0)
1891 goto fail;
1892
1893 if ((ret = gen_fcpublish_stream(s, rt)) < 0)
1894 goto fail;
1895 } else {
1896 if ((ret = gen_server_bw(s, rt)) < 0)
1897 goto fail;
1898 }
1899
1900 if ((ret = gen_create_stream(s, rt)) < 0)
1901 goto fail;
1902
1903 if (rt->is_input) {
1904 /* Send the FCSubscribe command when the name of live
1905 * stream is defined by the user or if it's a live stream. */
1906 if (rt->subscribe) {
1907 if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
1908 goto fail;
1909 } else if (rt->live == -1) {
1910 if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
1911 goto fail;
1912 }
1913 }
1914 } else if (!memcmp(tracked_method, "createStream", 12)) {
1915 //extract a number from the result
1916 if (pkt->data[10] || pkt->data[19] != 5 || pkt->data[20]) {
1917 av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
1918 } else {
1919 rt->main_channel_id = av_int2double(AV_RB64(pkt->data + 21));
1920 }
1921
1922 if (!rt->is_input) {
1923 if ((ret = gen_publish(s, rt)) < 0)
1924 goto fail;
1925 } else {
1926 if ((ret = gen_play(s, rt)) < 0)
1927 goto fail;
1928 if ((ret = gen_buffer_time(s, rt)) < 0)
1929 goto fail;
1930 }
1931 }
1932
1933 fail:
1934 av_free(tracked_method);
1935 return ret;
1936 }
1937
1938 static int handle_invoke_status(URLContext *s, RTMPPacket *pkt)
1939 {
1940 RTMPContext *rt = s->priv_data;
1941 const uint8_t *data_end = pkt->data + pkt->data_size;
1942 const uint8_t *ptr = pkt->data + 11;
1943 uint8_t tmpstr[256];
1944 int i, t;
1945
1946 for (i = 0; i < 2; i++) {
1947 t = ff_amf_tag_size(ptr, data_end);
1948 if (t < 0)
1949 return 1;
1950 ptr += t;
1951 }
1952
1953 t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
1954 if (!t && !strcmp(tmpstr, "error")) {
1955 if (!ff_amf_get_field_value(ptr, data_end,
1956 "description", tmpstr, sizeof(tmpstr)))
1957 av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
1958 return -1;
1959 }
1960
1961 t = ff_amf_get_field_value(ptr, data_end, "code", tmpstr, sizeof(tmpstr));
1962 if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
1963 if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
1964 if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
1965 if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
1966
1967 return 0;
1968 }
1969
1970 static int handle_invoke(URLContext *s, RTMPPacket *pkt)
1971 {
1972 RTMPContext *rt = s->priv_data;
1973 int ret = 0;
1974
1975 //TODO: check for the messages sent for wrong state?
1976 if (!memcmp(pkt->data, "\002\000\006_error", 9)) {
1977 if ((ret = handle_invoke_error(s, pkt)) < 0)
1978 return ret;
1979 } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) {
1980 if ((ret = handle_invoke_result(s, pkt)) < 0)
1981 return ret;
1982 } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) {
1983 if ((ret = handle_invoke_status(s, pkt)) < 0)
1984 return ret;
1985 } else if (!memcmp(pkt->data, "\002\000\010onBWDone", 11)) {
1986 if ((ret = gen_check_bw(s, rt)) < 0)
1987 return ret;
1988 } else if (!memcmp(pkt->data, "\002\000\015releaseStream", 16) ||
1989 !memcmp(pkt->data, "\002\000\011FCPublish", 12) ||
1990 !memcmp(pkt->data, "\002\000\007publish", 10) ||
1991 !memcmp(pkt->data, "\002\000\010_checkbw", 11) ||
1992 !memcmp(pkt->data, "\002\000\014createStream", 15)) {
1993 if ((ret = send_invoke_response(s, pkt)) < 0)
1994 return ret;
1995 }
1996
1997 return ret;
1998 }
1999
2000 static int handle_notify(URLContext *s, RTMPPacket *pkt) {
2001 RTMPContext *rt = s->priv_data;
2002 const uint8_t *p = NULL;
2003 uint8_t *cp = NULL;
2004 uint8_t commandbuffer[64];
2005 char statusmsg[128];
2006 int stringlen;
2007 GetByteContext gbc;
2008 PutByteContext pbc;
2009 uint32_t ts;
2010 int old_flv_size;
2011 const uint8_t *datatowrite;
2012 unsigned datatowritelength;
2013
2014 p = pkt->data;
2015 bytestream2_init(&gbc, p, pkt->data_size);
2016 if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
2017 &stringlen))
2018 return AVERROR_INVALIDDATA;
2019 if (!strcmp(commandbuffer, "@setDataFrame")) {
2020 datatowrite = gbc.buffer;
2021 datatowritelength = bytestream2_get_bytes_left(&gbc);
2022 if (ff_amf_read_string(&gbc, statusmsg,
2023 sizeof(statusmsg), &stringlen))
2024 return AVERROR_INVALIDDATA;
2025 if (strcmp(statusmsg, "onMetaData")) {
2026 av_log(s, AV_LOG_INFO, "Expecting onMetadata but got %s\n",
2027 statusmsg);
2028 return 0;
2029 }
2030
2031 /* Provide ECMAArray to flv */
2032 ts = pkt->timestamp;
2033
2034 // generate packet header and put data into buffer for FLV demuxer
2035 if (rt->flv_off < rt->flv_size) {
2036 old_flv_size = rt->flv_size;
2037 rt->flv_size += datatowritelength + 15;
2038 } else {
2039 old_flv_size = 0;
2040 rt->flv_size = datatowritelength + 15;
2041 rt->flv_off = 0;
2042 }
2043
2044 cp = av_realloc(rt->flv_data, rt->flv_size);
2045 if (!cp)
2046 return AVERROR(ENOMEM);
2047 rt->flv_data = cp;
2048 bytestream2_init_writer(&pbc, cp, rt->flv_size);
2049 bytestream2_skip_p(&pbc, old_flv_size);
2050 bytestream2_put_byte(&pbc, pkt->type);
2051 bytestream2_put_be24(&pbc, datatowritelength);
2052 bytestream2_put_be24(&pbc, ts);
2053 bytestream2_put_byte(&pbc, ts >> 24);
2054 bytestream2_put_be24(&pbc, 0);
2055 bytestream2_put_buffer(&pbc, datatowrite, datatowritelength);
2056 bytestream2_put_be32(&pbc, 0);
2057 }
2058 return 0;
2059 }
2060
2061 /**
2062 * Parse received packet and possibly perform some action depending on
2063 * the packet contents.
2064 * @return 0 for no errors, negative values for serious errors which prevent
2065 * further communications, positive values for uncritical errors
2066 */
2067 static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt)
2068 {
2069 int ret;
2070
2071 #ifdef DEBUG
2072 ff_rtmp_packet_dump(s, pkt);
2073 #endif
2074
2075 switch (pkt->type) {
2076 case RTMP_PT_BYTES_READ:
2077 av_dlog(s, "received bytes read report\n");
2078 break;
2079 case RTMP_PT_CHUNK_SIZE:
2080 if ((ret = handle_chunk_size(s, pkt)) < 0)
2081 return ret;
2082 break;
2083 case RTMP_PT_PING:
2084 if ((ret = handle_ping(s, pkt)) < 0)
2085 return ret;
2086 break;
2087 case RTMP_PT_CLIENT_BW:
2088 if ((ret = handle_client_bw(s, pkt)) < 0)
2089 return ret;
2090 break;
2091 case RTMP_PT_SERVER_BW:
2092 if ((ret = handle_server_bw(s, pkt)) < 0)
2093 return ret;
2094 break;
2095 case RTMP_PT_INVOKE:
2096 if ((ret = handle_invoke(s, pkt)) < 0)
2097 return ret;
2098 break;
2099 case RTMP_PT_VIDEO:
2100 case RTMP_PT_AUDIO:
2101 case RTMP_PT_METADATA:
2102 case RTMP_PT_NOTIFY:
2103 /* Audio, Video and Metadata packets are parsed in get_packet() */
2104 break;
2105 default:
2106 av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
2107 break;
2108 }
2109 return 0;
2110 }
2111
2112 /**
2113 * Interact with the server by receiving and sending RTMP packets until
2114 * there is some significant data (media data or expected status notification).
2115 *
2116 * @param s reading context
2117 * @param for_header non-zero value tells function to work until it
2118 * gets notification from the server that playing has been started,
2119 * otherwise function will work until some media data is received (or
2120 * an error happens)
2121 * @return 0 for successful operation, negative value in case of error
2122 */
2123 static int get_packet(URLContext *s, int for_header)
2124 {
2125 RTMPContext *rt = s->priv_data;
2126 int ret;
2127 uint8_t *p;
2128 const uint8_t *next;
2129 uint32_t data_size;
2130 uint32_t ts, cts, pts=0;
2131
2132 if (rt->state == STATE_STOPPED)
2133 return AVERROR_EOF;
2134
2135 for (;;) {
2136 RTMPPacket rpkt = { 0 };
2137 if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
2138 rt->in_chunk_size, rt->prev_pkt[0])) <= 0) {
2139 if (ret == 0) {
2140 return AVERROR(EAGAIN);
2141 } else {
2142 return AVERROR(EIO);
2143 }
2144 }
2145 rt->bytes_read += ret;
2146 if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {
2147 av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
2148 if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
2149 return ret;
2150 rt->last_bytes_read = rt->bytes_read;
2151 }
2152
2153 ret = rtmp_parse_result(s, rt, &rpkt);
2154 if (ret < 0) {//serious error in current packet
2155 ff_rtmp_packet_destroy(&rpkt);
2156 return ret;
2157 }
2158 if (rt->do_reconnect && for_header) {
2159 ff_rtmp_packet_destroy(&rpkt);
2160 return 0;
2161 }
2162 if (rt->state == STATE_STOPPED) {
2163 ff_rtmp_packet_destroy(&rpkt);
2164 return AVERROR_EOF;
2165 }
2166 if (for_header && (rt->state == STATE_PLAYING ||
2167 rt->state == STATE_PUBLISHING ||
2168 rt->state == STATE_RECEIVING)) {
2169 ff_rtmp_packet_destroy(&rpkt);
2170 return 0;
2171 }
2172 if (!rpkt.data_size || !rt->is_input) {
2173 ff_rtmp_packet_destroy(&rpkt);
2174 continue;
2175 }
2176 if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||
2177 (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {
2178 ts = rpkt.timestamp;
2179
2180 // generate packet header and put data into buffer for FLV demuxer
2181 rt->flv_off = 0;
2182 rt->flv_size = rpkt.data_size + 15;
2183 rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);
2184 bytestream_put_byte(&p, rpkt.type);
2185 bytestream_put_be24(&p, rpkt.data_size);
2186 bytestream_put_be24(&p, ts);
2187 bytestream_put_byte(&p, ts >> 24);
2188 bytestream_put_be24(&p, 0);
2189 bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);
2190 bytestream_put_be32(&p, 0);
2191 ff_rtmp_packet_destroy(&rpkt);
2192 return 0;
2193 } else if (rpkt.type == RTMP_PT_NOTIFY) {
2194 ret = handle_notify(s, &rpkt);
2195 ff_rtmp_packet_destroy(&rpkt);
2196 if (ret) {
2197 av_log(s, AV_LOG_ERROR, "Handle notify error\n");
2198 return ret;
2199 }
2200 return 0;
2201 } else if (rpkt.type == RTMP_PT_METADATA) {
2202 // we got raw FLV data, make it available for FLV demuxer
2203 rt->flv_off = 0;
2204 rt->flv_size = rpkt.data_size;
2205 rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
2206 /* rewrite timestamps */
2207 next = rpkt.data;
2208 ts = rpkt.timestamp;
2209 while (next - rpkt.data < rpkt.data_size - 11) {
2210 next++;
2211 data_size = bytestream_get_be24(&next);
2212 p=next;
2213 cts = bytestream_get_be24(&next);
2214 cts |= bytestream_get_byte(&next) << 24;
2215 if (pts==0)
2216 pts=cts;
2217 ts += cts - pts;
2218 pts = cts;
2219 bytestream_put_be24(&p, ts);
2220 bytestream_put_byte(&p, ts >> 24);
2221 next += data_size + 3 + 4;
2222 }
2223 memcpy(rt->flv_data, rpkt.data, rpkt.data_size);
2224 ff_rtmp_packet_destroy(&rpkt);
2225 return 0;
2226 }
2227 ff_rtmp_packet_destroy(&rpkt);
2228 }
2229 }
2230
2231 static int rtmp_close(URLContext *h)
2232 {
2233 RTMPContext *rt = h->priv_data;
2234 int ret = 0;
2235
2236 if (!rt->is_input) {
2237 rt->flv_data = NULL;
2238 if (rt->out_pkt.data_size)
2239 ff_rtmp_packet_destroy(&rt->out_pkt);
2240 if (rt->state > STATE_FCPUBLISH)
2241 ret = gen_fcunpublish_stream(h, rt);
2242 }
2243 if (rt->state > STATE_HANDSHAKED)
2244 ret = gen_delete_stream(h, rt);
2245
2246 free_tracked_methods(rt);
2247 av_freep(&rt->flv_data);
2248 ffurl_close(rt->stream);
2249 return ret;
2250 }
2251
2252 /**
2253 * Open RTMP connection and verify that the stream can be played.
2254 *
2255 * URL syntax: rtmp://server[:port][/app][/playpath]
2256 * where 'app' is first one or two directories in the path
2257 * (e.g. /ondemand/, /flash/live/, etc.)
2258 * and 'playpath' is a file name (the rest of the path,
2259 * may be prefixed with "mp4:")
2260 */
2261 static int rtmp_open(URLContext *s, const char *uri, int flags)
2262 {
2263 RTMPContext *rt = s->priv_data;
2264 char proto[8], hostname[256], path[1024], auth[100], *fname;
2265 char *old_app;
2266 uint8_t buf[2048];
2267 int port;
2268 AVDictionary *opts = NULL;
2269 int ret;
2270
2271 if (rt->listen_timeout > 0)
2272 rt->listen = 1;
2273
2274 rt->is_input = !(flags & AVIO_FLAG_WRITE);
2275
2276 av_url_split(proto, sizeof(proto), auth, sizeof(auth),
2277 hostname, sizeof(hostname), &port,
2278 path, sizeof(path), s->filename);
2279
2280 if (auth[0]) {
2281 char *ptr = strchr(auth, ':');
2282 if (ptr) {
2283 *ptr = '\0';
2284 av_strlcpy(rt->username, auth, sizeof(rt->username));
2285 av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
2286 }
2287 }
2288
2289 if (rt->listen && strcmp(proto, "rtmp")) {
2290 av_log(s, AV_LOG_ERROR, "rtmp_listen not available for %s\n",
2291 proto);
2292 return AVERROR(EINVAL);
2293 }
2294 if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
2295 if (!strcmp(proto, "rtmpts"))
2296 av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
2297
2298 /* open the http tunneling connection */
2299 ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
2300 } else if (!strcmp(proto, "rtmps")) {
2301 /* open the tls connection */
2302 if (port < 0)
2303 port = RTMPS_DEFAULT_PORT;
2304 ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
2305 } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
2306 if (!strcmp(proto, "rtmpte"))
2307 av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
2308
2309 /* open the encrypted connection */
2310 ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
2311 rt->encrypted = 1;
2312 } else {
2313 /* open the tcp connection */
2314 if (port < 0)
2315 port = RTMP_DEFAULT_PORT;
2316 if (rt->listen)
2317 ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port,
2318 "?listen&listen_timeout=%d",
2319 rt->listen_timeout * 1000);
2320 else
2321 ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
2322 }
2323
2324 reconnect:
2325 if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
2326 &s->interrupt_callback, &opts)) < 0) {
2327 av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
2328 goto fail;
2329 }
2330
2331 if (rt->swfverify) {
2332 if ((ret = rtmp_calc_swfhash(s)) < 0)
2333 goto fail;
2334 }
2335
2336 rt->state = STATE_START;
2337 if (!rt->listen && (ret = rtmp_handshake(s, rt)) < 0)
2338 goto fail;
2339 if (rt->listen && (ret = rtmp_server_handshake(s, rt)) < 0)
2340 goto fail;
2341
2342 rt->out_chunk_size = 128;
2343 rt->in_chunk_size = 128; // Probably overwritten later
2344 rt->state = STATE_HANDSHAKED;
2345
2346 // Keep the application name when it has been defined by the user.
2347 old_app = rt->app;
2348
2349 rt->app = av_malloc(APP_MAX_LENGTH);
2350 if (!rt->app) {
2351 ret = AVERROR(ENOMEM);
2352 goto fail;
2353 }
2354
2355 //extract "app" part from path
2356 if (!strncmp(path, "/ondemand/", 10)) {
2357 fname = path + 10;
2358 memcpy(rt->app, "ondemand", 9);
2359 } else {
2360 char *next = *path ? path + 1 : path;
2361 char *p = strchr(next, '/');
2362 if (!p) {
2363 fname = next;
2364 rt->app[0] = '\0';
2365 } else {
2366 // make sure we do not mismatch a playpath for an application instance
2367 char *c = strchr(p + 1, ':');
2368 fname = strchr(p + 1, '/');
2369 if (!fname || (c && c < fname)) {
2370 fname = p + 1;
2371 av_strlcpy(rt->app, path + 1, p - path);
2372 } else {
2373 fname++;
2374 av_strlcpy(rt->app, path + 1, fname - path - 1);
2375 }
2376 }
2377 }
2378
2379 if (old_app) {
2380 // The name of application has been defined by the user, override it.
2381 av_free(rt->app);
2382 rt->app = old_app;
2383 }
2384
2385 if (!rt->playpath) {
2386 int len = strlen(fname);
2387
2388 rt->playpath = av_malloc(PLAYPATH_MAX_LENGTH);
2389 if (!rt->playpath) {
2390 ret = AVERROR(ENOMEM);
2391 goto fail;
2392 }
2393
2394 if (!strchr(fname, ':') && len >= 4 &&
2395 (!strcmp(fname + len - 4, ".f4v") ||
2396 !strcmp(fname + len - 4, ".mp4"))) {
2397 memcpy(rt->playpath, "mp4:", 5);
2398 } else if (len >= 4 && !strcmp(fname + len - 4, ".flv")) {
2399 fname[len - 4] = '\0';
2400 } else {
2401 rt->playpath[0] = 0;
2402 }
2403 av_strlcat(rt->playpath, fname, PLAYPATH_MAX_LENGTH);
2404 }
2405
2406 if (!rt->tcurl) {
2407 rt->tcurl = av_malloc(TCURL_MAX_LENGTH);
2408 if (!rt->tcurl) {
2409 ret = AVERROR(ENOMEM);
2410 goto fail;
2411 }
2412 ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
2413 port, "/%s", rt->app);
2414 }
2415
2416 if (!rt->flashver) {
2417 rt->flashver = av_malloc(FLASHVER_MAX_LENGTH);
2418 if (!rt->flashver) {
2419 ret = AVERROR(ENOMEM);
2420 goto fail;
2421 }
2422 if (rt->is_input) {
2423 snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
2424 RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1, RTMP_CLIENT_VER2,
2425 RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);
2426 } else {
2427 snprintf(rt->flashver, FLASHVER_MAX_LENGTH,
2428 "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
2429 }
2430 }
2431
2432 rt->client_report_size = 1048576;
2433 rt->bytes_read = 0;
2434 rt->last_bytes_read = 0;
2435 rt->server_bw = 2500000;
2436
2437 av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
2438 proto, path, rt->app, rt->playpath);
2439 if (!rt->listen) {
2440 if ((ret = gen_connect(s, rt)) < 0)
2441 goto fail;
2442 } else {
2443 if (read_connect(s, s->priv_data) < 0)
2444 goto fail;
2445 rt->is_input = 1;
2446 }
2447
2448 do {
2449 ret = get_packet(s, 1);
2450 } while (ret == EAGAIN);
2451 if (ret < 0)
2452 goto fail;
2453
2454 if (rt->do_reconnect) {
2455 ffurl_close(rt->stream);
2456 rt->stream = NULL;
2457 rt->do_reconnect = 0;
2458 rt->nb_invokes = 0;
2459 memset(rt->prev_pkt, 0, sizeof(rt->prev_pkt));
2460 free_tracked_methods(rt);
2461 goto reconnect;
2462 }
2463
2464 if (rt->is_input) {
2465 // generate FLV header for demuxer
2466 rt->flv_size = 13;
2467 rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);
2468 rt->flv_off = 0;
2469 memcpy(rt->flv_data, "FLV\1\5\0\0\0\011\0\0\0\0", rt->flv_size);
2470 } else {
2471 rt->flv_size = 0;
2472 rt->flv_data = NULL;
2473 rt->flv_off = 0;
2474 rt->skip_bytes = 13;
2475 }
2476
2477 s->max_packet_size = rt->stream->max_packet_size;
2478 s->is_streamed = 1;
2479 return 0;
2480
2481 fail:
2482 av_dict_free(&opts);
2483 rtmp_close(s);
2484 return ret;
2485 }
2486
2487 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
2488 {
2489 RTMPContext *rt = s->priv_data;
2490 int orig_size = size;
2491 int ret;
2492
2493 while (size > 0) {
2494 int data_left = rt->flv_size - rt->flv_off;
2495
2496 if (data_left >= size) {
2497 memcpy(buf, rt->flv_data + rt->flv_off, size);
2498 rt->flv_off += size;
2499 return orig_size;
2500 }
2501 if (data_left > 0) {
2502 memcpy(buf, rt->flv_data + rt->flv_off, data_left);
2503 buf += data_left;
2504 size -= data_left;
2505 rt->flv_off = rt->flv_size;
2506 return data_left;
2507 }
2508 if ((ret = get_packet(s, 0)) < 0)
2509 return ret;
2510 }
2511 return orig_size;
2512 }
2513
2514 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
2515 {
2516 RTMPContext *rt = s->priv_data;
2517 int size_temp = size;
2518 int pktsize, pkttype;
2519 uint32_t ts;
2520 const uint8_t *buf_temp = buf;
2521 uint8_t c;
2522 int ret;
2523
2524 do {
2525 if (rt->skip_bytes) {
2526 int skip = FFMIN(rt->skip_bytes, size_temp);
2527 buf_temp += skip;
2528 size_temp -= skip;
2529 rt->skip_bytes -= skip;
2530 continue;
2531 }
2532
2533 if (rt->flv_header_bytes < 11) {
2534 const uint8_t *header = rt->flv_header;
2535 int copy = FFMIN(11 - rt->flv_header_bytes, size_temp);
2536 bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
2537 rt->flv_header_bytes += copy;
2538 size_temp -= copy;
2539 if (rt->flv_header_bytes < 11)
2540 break;
2541
2542 pkttype = bytestream_get_byte(&header);
2543 pktsize = bytestream_get_be24(&header);
2544 ts = bytestream_get_be24(&header);
2545 ts |= bytestream_get_byte(&header) << 24;
2546 bytestream_get_be24(&header);
2547 rt->flv_size = pktsize;
2548
2549 //force 12bytes header
2550 if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
2551 pkttype == RTMP_PT_NOTIFY) {
2552 if (pkttype == RTMP_PT_NOTIFY)
2553 pktsize += 16;
2554 rt->prev_pkt[1][RTMP_SOURCE_CHANNEL].channel_id = 0;
2555 }
2556
2557 //this can be a big packet, it's better to send it right here
2558 if ((ret = ff_rtmp_packet_create(&rt->out_pkt, RTMP_SOURCE_CHANNEL,
2559 pkttype, ts, pktsize)) < 0)
2560 return ret;
2561
2562 rt->out_pkt.extra = rt->main_channel_id;
2563 rt->flv_data = rt->out_pkt.data;
2564
2565 if (pkttype == RTMP_PT_NOTIFY)
2566 ff_amf_write_string(&rt->flv_data, "@setDataFrame");
2567 }
2568
2569 if (rt->flv_size - rt->flv_off > size_temp) {
2570 bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
2571 rt->flv_off += size_temp;
2572 size_temp = 0;
2573 } else {
2574 bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
2575 size_temp -= rt->flv_size - rt->flv_off;
2576 rt->flv_off += rt->flv_size - rt->flv_off;
2577 }
2578
2579 if (rt->flv_off == rt->flv_size) {
2580 rt->skip_bytes = 4;
2581
2582 if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
2583 return ret;
2584 rt->flv_size = 0;
2585 rt->flv_off = 0;
2586 rt->flv_header_bytes = 0;
2587 rt->flv_nb_packets++;
2588 }
2589 } while (buf_temp - buf < size);
2590
2591 if (rt->flv_nb_packets < rt->flush_interval)
2592 return size;
2593 rt->flv_nb_packets = 0;
2594
2595 /* set stream into nonblocking mode */
2596 rt->stream->flags |= AVIO_FLAG_NONBLOCK;
2597
2598 /* try to read one byte from the stream */
2599 ret = ffurl_read(rt->stream, &c, 1);
2600
2601 /* switch the stream back into blocking mode */
2602 rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
2603
2604 if (ret == AVERROR(EAGAIN)) {
2605 /* no incoming data to handle */
2606 return size;
2607 } else if (ret < 0) {
2608 return ret;
2609 } else if (ret == 1) {
2610 RTMPPacket rpkt = { 0 };
2611
2612 if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
2613 rt->in_chunk_size,
2614 rt->prev_pkt[0], c)) <= 0)
2615 return ret;
2616
2617 if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
2618 return ret;
2619
2620 ff_rtmp_packet_destroy(&rpkt);
2621 }
2622
2623 return size;
2624 }
2625
2626 #define OFFSET(x) offsetof(RTMPContext, x)
2627 #define DEC AV_OPT_FLAG_DECODING_PARAM
2628 #define ENC AV_OPT_FLAG_ENCODING_PARAM
2629
2630 static const AVOption rtmp_options[] = {
2631 {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2632 {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {.i64 = 3000}, 0, INT_MAX, DEC|ENC},
2633 {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2634 {"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},
2635 {"rtmp_flush_interval", "Number of packets flushed in the same request (RTMPT only).", OFFSET(flush_interval), AV_OPT_TYPE_INT, {.i64 = 10}, 0, INT_MAX, ENC},
2636 {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {.i64 = -2}, INT_MIN, INT_MAX, DEC, "rtmp_live"},
2637 {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
2638 {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
2639 {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
2640 {"rtmp_pageurl", "URL of the web page in which the media was embedded. By default no value will be sent.", OFFSET(pageurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2641 {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2642 {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2643 {"rtmp_swfhash", "SHA256 hash of the decompressed SWF file (32 bytes).", OFFSET(swfhash), AV_OPT_TYPE_BINARY, .flags = DEC},
2644 {"rtmp_swfsize", "Size of the decompressed SWF file, required for SWFVerification.", OFFSET(swfsize), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC},
2645 {"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},
2646 {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically.", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
2647 {"rtmp_tcurl", "URL of the target stream. Defaults to proto://host[:port]/app.", OFFSET(tcurl), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
2648 {"rtmp_listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2649 {"timeout", "Maximum timeout (in seconds) to wait for incoming connections. -1 is infinite. Implies -rtmp_listen 1", OFFSET(listen_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
2650 { NULL },
2651 };
2652
2653 #define RTMP_PROTOCOL(flavor) \
2654 static const AVClass flavor##_class = { \
2655 .class_name = #flavor, \
2656 .item_name = av_default_item_name, \
2657 .option = rtmp_options, \
2658 .version = LIBAVUTIL_VERSION_INT, \
2659 }; \
2660 \
2661 URLProtocol ff_##flavor##_protocol = { \
2662 .name = #flavor, \
2663 .url_open = rtmp_open, \
2664 .url_read = rtmp_read, \
2665 .url_write = rtmp_write, \
2666 .url_close = rtmp_close, \
2667 .priv_data_size = sizeof(RTMPContext), \
2668 .flags = URL_PROTOCOL_FLAG_NETWORK, \
2669 .priv_data_class= &flavor##_class, \
2670 };
2671
2672
2673 RTMP_PROTOCOL(rtmp)
2674 RTMP_PROTOCOL(rtmpe)
2675 RTMP_PROTOCOL(rtmps)
2676 RTMP_PROTOCOL(rtmpt)
2677 RTMP_PROTOCOL(rtmpte)
2678 RTMP_PROTOCOL(rtmpts)