FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rtmpproto.c
Go to the documentation of this file.
1 /*
2  * RTMP network protocol
3  * Copyright (c) 2009 Konstantin Shishkov
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * RTMP protocol
25  */
26 
27 #include "libavcodec/bytestream.h"
28 #include "libavutil/avstring.h"
29 #include "libavutil/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 1024
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 #define RTMP_HEADER 11
57 
58 /** RTMP protocol handler state */
59 typedef enum {
60  STATE_START, ///< client has not done anything yet
61  STATE_HANDSHAKED, ///< client has performed handshake
62  STATE_FCPUBLISH, ///< client FCPublishing stream (for output)
63  STATE_PLAYING, ///< client has started receiving multimedia data from server
64  STATE_SEEKING, ///< client has started the seek operation. Back on STATE_PLAYING when the time comes
65  STATE_PUBLISHING, ///< client has started sending multimedia data to server (for output)
66  STATE_RECEIVING, ///< received a publish command (for input)
67  STATE_SENDING, ///< received a play command (for output)
68  STATE_STOPPED, ///< the broadcast has been stopped
69 } ClientState;
70 
71 typedef struct TrackedMethod {
72  char *name;
73  int id;
75 
76 /** protocol handler context */
77 typedef struct RTMPContext {
78  const AVClass *class;
79  URLContext* stream; ///< TCP stream used in interactions with RTMP server
80  RTMPPacket *prev_pkt[2]; ///< packet history used when reading and sending packets ([0] for reading, [1] for writing)
81  int nb_prev_pkt[2]; ///< number of elements in prev_pkt
82  int in_chunk_size; ///< size of the chunks incoming RTMP packets are divided into
83  int out_chunk_size; ///< size of the chunks outgoing RTMP packets are divided into
84  int is_input; ///< input/output flag
85  char *playpath; ///< stream identifier to play (with possible "mp4:" prefix)
86  int live; ///< 0: recorded, -1: live, -2: both
87  char *app; ///< name of application
88  char *conn; ///< append arbitrary AMF data to the Connect message
89  ClientState state; ///< current state
90  int stream_id; ///< ID assigned by the server for the stream
91  uint8_t* flv_data; ///< buffer with data for demuxer
92  int flv_size; ///< current buffer size
93  int flv_off; ///< number of bytes read from current buffer
94  int flv_nb_packets; ///< number of flv packets published
95  RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output)
96  uint32_t client_report_size; ///< number of bytes after which client should report to server
97  uint32_t bytes_read; ///< number of bytes read from server
98  uint32_t last_bytes_read; ///< number of bytes read last reported to server
99  uint32_t last_timestamp; ///< last timestamp received in a packet
100  int skip_bytes; ///< number of bytes to skip from the input FLV stream in the next write call
101  int has_audio; ///< presence of audio data
102  int has_video; ///< presence of video data
103  int received_metadata; ///< Indicates if we have received metadata about the streams
104  uint8_t flv_header[RTMP_HEADER]; ///< partial incoming flv packet header
105  int flv_header_bytes; ///< number of initialized bytes in flv_header
106  int nb_invokes; ///< keeps track of invoke messages
107  char* tcurl; ///< url of the target stream
108  char* flashver; ///< version of the flash plugin
109  char* swfhash; ///< SHA256 hash of the decompressed SWF file (32 bytes)
110  int swfhash_len; ///< length of the SHA256 hash
111  int swfsize; ///< size of the decompressed SWF file
112  char* swfurl; ///< url of the swf player
113  char* swfverify; ///< URL to player swf file, compute hash/size automatically
114  char swfverification[42]; ///< hash of the SWF verification
115  char* pageurl; ///< url of the web page
116  char* subscribe; ///< name of live stream to subscribe
117  int server_bw; ///< server bandwidth
118  int client_buffer_time; ///< client buffer time in ms
119  int flush_interval; ///< number of packets flushed in the same request (RTMPT only)
120  int encrypted; ///< use an encrypted connection (RTMPE only)
121  TrackedMethod*tracked_methods; ///< tracked methods buffer
122  int nb_tracked_methods; ///< number of tracked methods
123  int tracked_methods_size; ///< size of the tracked methods buffer
124  int listen; ///< listen mode flag
125  int listen_timeout; ///< listen timeout to wait for new connections
126  int nb_streamid; ///< The next stream id to return on createStream calls
127  double duration; ///< Duration of the stream in seconds as returned by the server (only valid if non-zero)
128  char username[50];
129  char password[50];
130  char auth_params[500];
133 } RTMPContext;
134 
135 #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing
136 /** Client key used for digest signing */
137 static const uint8_t rtmp_player_key[] = {
138  'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
139  'F', 'l', 'a', 's', 'h', ' ', 'P', 'l', 'a', 'y', 'e', 'r', ' ', '0', '0', '1',
140 
141  0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
142  0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
143  0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
144 };
145 
146 #define SERVER_KEY_OPEN_PART_LEN 36 ///< length of partial key used for first server digest signing
147 /** Key used for RTMP server digest signing */
148 static const uint8_t rtmp_server_key[] = {
149  'G', 'e', 'n', 'u', 'i', 'n', 'e', ' ', 'A', 'd', 'o', 'b', 'e', ' ',
150  'F', 'l', 'a', 's', 'h', ' ', 'M', 'e', 'd', 'i', 'a', ' ',
151  'S', 'e', 'r', 'v', 'e', 'r', ' ', '0', '0', '1',
152 
153  0xF0, 0xEE, 0xC2, 0x4A, 0x80, 0x68, 0xBE, 0xE8, 0x2E, 0x00, 0xD0, 0xD1, 0x02,
154  0x9E, 0x7E, 0x57, 0x6E, 0xEC, 0x5D, 0x2D, 0x29, 0x80, 0x6F, 0xAB, 0x93, 0xB8,
155  0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE
156 };
157 
159 
160 static int add_tracked_method(RTMPContext *rt, const char *name, int id)
161 {
162  int err;
163 
164  if (rt->nb_tracked_methods + 1 > rt->tracked_methods_size) {
165  rt->tracked_methods_size = (rt->nb_tracked_methods + 1) * 2;
166  if ((err = av_reallocp(&rt->tracked_methods, rt->tracked_methods_size *
167  sizeof(*rt->tracked_methods))) < 0) {
168  rt->nb_tracked_methods = 0;
169  rt->tracked_methods_size = 0;
170  return err;
171  }
172  }
173 
176  return AVERROR(ENOMEM);
178  rt->nb_tracked_methods++;
179 
180  return 0;
181 }
182 
183 static void del_tracked_method(RTMPContext *rt, int index)
184 {
185  memmove(&rt->tracked_methods[index], &rt->tracked_methods[index + 1],
186  sizeof(*rt->tracked_methods) * (rt->nb_tracked_methods - index - 1));
187  rt->nb_tracked_methods--;
188 }
189 
191  char **tracked_method)
192 {
193  RTMPContext *rt = s->priv_data;
194  GetByteContext gbc;
195  double pkt_id;
196  int ret;
197  int i;
198 
199  bytestream2_init(&gbc, pkt->data + offset, pkt->size - offset);
200  if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
201  return ret;
202 
203  for (i = 0; i < rt->nb_tracked_methods; i++) {
204  if (rt->tracked_methods[i].id != pkt_id)
205  continue;
206 
207  *tracked_method = rt->tracked_methods[i].name;
208  del_tracked_method(rt, i);
209  break;
210  }
211 
212  return 0;
213 }
214 
216 {
217  int i;
218 
219  for (i = 0; i < rt->nb_tracked_methods; i ++)
220  av_free(rt->tracked_methods[i].name);
222  rt->tracked_methods = NULL;
223  rt->tracked_methods_size = 0;
224  rt->nb_tracked_methods = 0;
225 }
226 
227 static int rtmp_send_packet(RTMPContext *rt, RTMPPacket *pkt, int track)
228 {
229  int ret;
230 
231  if (pkt->type == RTMP_PT_INVOKE && track) {
232  GetByteContext gbc;
233  char name[128];
234  double pkt_id;
235  int len;
236 
237  bytestream2_init(&gbc, pkt->data, pkt->size);
238  if ((ret = ff_amf_read_string(&gbc, name, sizeof(name), &len)) < 0)
239  goto fail;
240 
241  if ((ret = ff_amf_read_number(&gbc, &pkt_id)) < 0)
242  goto fail;
243 
244  if ((ret = add_tracked_method(rt, name, pkt_id)) < 0)
245  goto fail;
246  }
247 
248  ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
249  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
250 fail:
252  return ret;
253 }
254 
255 static int rtmp_write_amf_data(URLContext *s, char *param, uint8_t **p)
256 {
257  char *field, *value;
258  char type;
259 
260  /* The type must be B for Boolean, N for number, S for string, O for
261  * object, or Z for null. For Booleans the data must be either 0 or 1 for
262  * FALSE or TRUE, respectively. Likewise for Objects the data must be
263  * 0 or 1 to end or begin an object, respectively. Data items in subobjects
264  * may be named, by prefixing the type with 'N' and specifying the name
265  * before the value (ie. NB:myFlag:1). This option may be used multiple times
266  * to construct arbitrary AMF sequences. */
267  if (param[0] && param[1] == ':') {
268  type = param[0];
269  value = param + 2;
270  } else if (param[0] == 'N' && param[1] && param[2] == ':') {
271  type = param[1];
272  field = param + 3;
273  value = strchr(field, ':');
274  if (!value)
275  goto fail;
276  *value = '\0';
277  value++;
278 
279  ff_amf_write_field_name(p, field);
280  } else {
281  goto fail;
282  }
283 
284  switch (type) {
285  case 'B':
286  ff_amf_write_bool(p, value[0] != '0');
287  break;
288  case 'S':
289  ff_amf_write_string(p, value);
290  break;
291  case 'N':
292  ff_amf_write_number(p, strtod(value, NULL));
293  break;
294  case 'Z':
296  break;
297  case 'O':
298  if (value[0] != '0')
300  else
302  break;
303  default:
304  goto fail;
305  break;
306  }
307 
308  return 0;
309 
310 fail:
311  av_log(s, AV_LOG_ERROR, "Invalid AMF parameter: %s\n", param);
312  return AVERROR(EINVAL);
313 }
314 
315 /**
316  * Generate 'connect' call and send it to the server.
317  */
319 {
320  RTMPPacket pkt;
321  uint8_t *p;
322  int ret;
323 
325  0, 4096 + APP_MAX_LENGTH)) < 0)
326  return ret;
327 
328  p = pkt.data;
329 
330  ff_amf_write_string(&p, "connect");
331  ff_amf_write_number(&p, ++rt->nb_invokes);
333  ff_amf_write_field_name(&p, "app");
334  ff_amf_write_string2(&p, rt->app, rt->auth_params);
335 
336  if (!rt->is_input) {
337  ff_amf_write_field_name(&p, "type");
338  ff_amf_write_string(&p, "nonprivate");
339  }
340  ff_amf_write_field_name(&p, "flashVer");
341  ff_amf_write_string(&p, rt->flashver);
342 
343  if (rt->swfurl) {
344  ff_amf_write_field_name(&p, "swfUrl");
345  ff_amf_write_string(&p, rt->swfurl);
346  }
347 
348  ff_amf_write_field_name(&p, "tcUrl");
349  ff_amf_write_string2(&p, rt->tcurl, rt->auth_params);
350  if (rt->is_input) {
351  ff_amf_write_field_name(&p, "fpad");
352  ff_amf_write_bool(&p, 0);
353  ff_amf_write_field_name(&p, "capabilities");
354  ff_amf_write_number(&p, 15.0);
355 
356  /* Tell the server we support all the audio codecs except
357  * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)
358  * which are unused in the RTMP protocol implementation. */
359  ff_amf_write_field_name(&p, "audioCodecs");
360  ff_amf_write_number(&p, 4071.0);
361  ff_amf_write_field_name(&p, "videoCodecs");
362  ff_amf_write_number(&p, 252.0);
363  ff_amf_write_field_name(&p, "videoFunction");
364  ff_amf_write_number(&p, 1.0);
365 
366  if (rt->pageurl) {
367  ff_amf_write_field_name(&p, "pageUrl");
368  ff_amf_write_string(&p, rt->pageurl);
369  }
370  }
372 
373  if (rt->conn) {
374  char *param = rt->conn;
375 
376  // Write arbitrary AMF data to the Connect message.
377  while (param) {
378  char *sep;
379  param += strspn(param, " ");
380  if (!*param)
381  break;
382  sep = strchr(param, ' ');
383  if (sep)
384  *sep = '\0';
385  if ((ret = rtmp_write_amf_data(s, param, &p)) < 0) {
386  // Invalid AMF parameter.
388  return ret;
389  }
390 
391  if (sep)
392  param = sep + 1;
393  else
394  break;
395  }
396  }
397 
398  pkt.size = p - pkt.data;
399 
400  return rtmp_send_packet(rt, &pkt, 1);
401 }
402 
404 {
405  RTMPPacket pkt = { 0 };
406  uint8_t *p;
407  const uint8_t *cp;
408  int ret;
409  char command[64];
410  int stringlen;
411  double seqnum;
412  uint8_t tmpstr[256];
413  GetByteContext gbc;
414 
415  if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
416  &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
417  return ret;
418 
419  if (pkt.type == RTMP_PT_CHUNK_SIZE) {
420  if ((ret = handle_chunk_size(s, &pkt)) < 0)
421  return ret;
422 
424  if ((ret = ff_rtmp_packet_read(rt->stream, &pkt, rt->in_chunk_size,
425  &rt->prev_pkt[0], &rt->nb_prev_pkt[0])) < 0)
426  return ret;
427  }
428 
429  cp = pkt.data;
430  bytestream2_init(&gbc, cp, pkt.size);
431  if (ff_amf_read_string(&gbc, command, sizeof(command), &stringlen)) {
432  av_log(s, AV_LOG_ERROR, "Unable to read command string\n");
434  return AVERROR_INVALIDDATA;
435  }
436  if (strcmp(command, "connect")) {
437  av_log(s, AV_LOG_ERROR, "Expecting connect, got %s\n", command);
439  return AVERROR_INVALIDDATA;
440  }
441  ret = ff_amf_read_number(&gbc, &seqnum);
442  if (ret)
443  av_log(s, AV_LOG_WARNING, "SeqNum not found\n");
444  /* Here one could parse an AMF Object with data as flashVers and others. */
445  ret = ff_amf_get_field_value(gbc.buffer,
447  "app", tmpstr, sizeof(tmpstr));
448  if (ret)
449  av_log(s, AV_LOG_WARNING, "App field not found in connect\n");
450  if (!ret && strcmp(tmpstr, rt->app))
451  av_log(s, AV_LOG_WARNING, "App field don't match up: %s <-> %s\n",
452  tmpstr, rt->app);
454 
455  // Send Window Acknowledgement Size (as defined in speficication)
457  RTMP_PT_SERVER_BW, 0, 4)) < 0)
458  return ret;
459  p = pkt.data;
460  bytestream_put_be32(&p, rt->server_bw);
461  pkt.size = p - pkt.data;
462  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
463  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
465  if (ret < 0)
466  return ret;
467  // Send Peer Bandwidth
469  RTMP_PT_CLIENT_BW, 0, 5)) < 0)
470  return ret;
471  p = pkt.data;
472  bytestream_put_be32(&p, rt->server_bw);
473  bytestream_put_byte(&p, 2); // dynamic
474  pkt.size = p - pkt.data;
475  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
476  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
478  if (ret < 0)
479  return ret;
480 
481  // Ping request
483  RTMP_PT_PING, 0, 6)) < 0)
484  return ret;
485 
486  p = pkt.data;
487  bytestream_put_be16(&p, 0); // 0 -> Stream Begin
488  bytestream_put_be32(&p, 0);
489  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
490  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
492  if (ret < 0)
493  return ret;
494 
495  // Chunk size
497  RTMP_PT_CHUNK_SIZE, 0, 4)) < 0)
498  return ret;
499 
500  p = pkt.data;
501  bytestream_put_be32(&p, rt->out_chunk_size);
502  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
503  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
505  if (ret < 0)
506  return ret;
507 
508  // Send _result NetConnection.Connect.Success to connect
510  RTMP_PT_INVOKE, 0,
512  return ret;
513 
514  p = pkt.data;
515  ff_amf_write_string(&p, "_result");
516  ff_amf_write_number(&p, seqnum);
517 
519  ff_amf_write_field_name(&p, "fmsVer");
520  ff_amf_write_string(&p, "FMS/3,0,1,123");
521  ff_amf_write_field_name(&p, "capabilities");
522  ff_amf_write_number(&p, 31);
524 
526  ff_amf_write_field_name(&p, "level");
527  ff_amf_write_string(&p, "status");
528  ff_amf_write_field_name(&p, "code");
529  ff_amf_write_string(&p, "NetConnection.Connect.Success");
530  ff_amf_write_field_name(&p, "description");
531  ff_amf_write_string(&p, "Connection succeeded.");
532  ff_amf_write_field_name(&p, "objectEncoding");
533  ff_amf_write_number(&p, 0);
535 
536  pkt.size = p - pkt.data;
537  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
538  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
540  if (ret < 0)
541  return ret;
542 
544  RTMP_PT_INVOKE, 0, 30)) < 0)
545  return ret;
546  p = pkt.data;
547  ff_amf_write_string(&p, "onBWDone");
548  ff_amf_write_number(&p, 0);
549  ff_amf_write_null(&p);
550  ff_amf_write_number(&p, 8192);
551  pkt.size = p - pkt.data;
552  ret = ff_rtmp_packet_write(rt->stream, &pkt, rt->out_chunk_size,
553  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
555 
556  return ret;
557 }
558 
559 /**
560  * Generate 'releaseStream' call and send it to the server. It should make
561  * the server release some channel for media streams.
562  */
564 {
565  RTMPPacket pkt;
566  uint8_t *p;
567  int ret;
568 
570  0, 29 + strlen(rt->playpath))) < 0)
571  return ret;
572 
573  av_log(s, AV_LOG_DEBUG, "Releasing stream...\n");
574  p = pkt.data;
575  ff_amf_write_string(&p, "releaseStream");
576  ff_amf_write_number(&p, ++rt->nb_invokes);
577  ff_amf_write_null(&p);
578  ff_amf_write_string(&p, rt->playpath);
579 
580  return rtmp_send_packet(rt, &pkt, 1);
581 }
582 
583 /**
584  * Generate 'FCPublish' call and send it to the server. It should make
585  * the server preapare for receiving media streams.
586  */
588 {
589  RTMPPacket pkt;
590  uint8_t *p;
591  int ret;
592 
594  0, 25 + strlen(rt->playpath))) < 0)
595  return ret;
596 
597  av_log(s, AV_LOG_DEBUG, "FCPublish stream...\n");
598  p = pkt.data;
599  ff_amf_write_string(&p, "FCPublish");
600  ff_amf_write_number(&p, ++rt->nb_invokes);
601  ff_amf_write_null(&p);
602  ff_amf_write_string(&p, rt->playpath);
603 
604  return rtmp_send_packet(rt, &pkt, 1);
605 }
606 
607 /**
608  * Generate 'FCUnpublish' call and send it to the server. It should make
609  * the server destroy stream.
610  */
612 {
613  RTMPPacket pkt;
614  uint8_t *p;
615  int ret;
616 
618  0, 27 + strlen(rt->playpath))) < 0)
619  return ret;
620 
621  av_log(s, AV_LOG_DEBUG, "UnPublishing stream...\n");
622  p = pkt.data;
623  ff_amf_write_string(&p, "FCUnpublish");
624  ff_amf_write_number(&p, ++rt->nb_invokes);
625  ff_amf_write_null(&p);
626  ff_amf_write_string(&p, rt->playpath);
627 
628  return rtmp_send_packet(rt, &pkt, 0);
629 }
630 
631 /**
632  * Generate 'createStream' call and send it to the server. It should make
633  * the server allocate some channel for media streams.
634  */
636 {
637  RTMPPacket pkt;
638  uint8_t *p;
639  int ret;
640 
641  av_log(s, AV_LOG_DEBUG, "Creating stream...\n");
642 
644  0, 25)) < 0)
645  return ret;
646 
647  p = pkt.data;
648  ff_amf_write_string(&p, "createStream");
649  ff_amf_write_number(&p, ++rt->nb_invokes);
650  ff_amf_write_null(&p);
651 
652  return rtmp_send_packet(rt, &pkt, 1);
653 }
654 
655 
656 /**
657  * Generate 'deleteStream' call and send it to the server. It should make
658  * the server remove some channel for media streams.
659  */
661 {
662  RTMPPacket pkt;
663  uint8_t *p;
664  int ret;
665 
666  av_log(s, AV_LOG_DEBUG, "Deleting stream...\n");
667 
669  0, 34)) < 0)
670  return ret;
671 
672  p = pkt.data;
673  ff_amf_write_string(&p, "deleteStream");
674  ff_amf_write_number(&p, ++rt->nb_invokes);
675  ff_amf_write_null(&p);
677 
678  return rtmp_send_packet(rt, &pkt, 0);
679 }
680 
681 /**
682  * Generate 'getStreamLength' call and send it to the server. If the server
683  * knows the duration of the selected stream, it will reply with the duration
684  * in seconds.
685  */
687 {
688  RTMPPacket pkt;
689  uint8_t *p;
690  int ret;
691 
693  0, 31 + strlen(rt->playpath))) < 0)
694  return ret;
695 
696  p = pkt.data;
697  ff_amf_write_string(&p, "getStreamLength");
698  ff_amf_write_number(&p, ++rt->nb_invokes);
699  ff_amf_write_null(&p);
700  ff_amf_write_string(&p, rt->playpath);
701 
702  return rtmp_send_packet(rt, &pkt, 1);
703 }
704 
705 /**
706  * Generate client buffer time and send it to the server.
707  */
709 {
710  RTMPPacket pkt;
711  uint8_t *p;
712  int ret;
713 
715  1, 10)) < 0)
716  return ret;
717 
718  p = pkt.data;
719  bytestream_put_be16(&p, 3);
720  bytestream_put_be32(&p, rt->stream_id);
721  bytestream_put_be32(&p, rt->client_buffer_time);
722 
723  return rtmp_send_packet(rt, &pkt, 0);
724 }
725 
726 /**
727  * Generate 'play' call and send it to the server, then ping the server
728  * to start actual playing.
729  */
730 static int gen_play(URLContext *s, RTMPContext *rt)
731 {
732  RTMPPacket pkt;
733  uint8_t *p;
734  int ret;
735 
736  av_log(s, AV_LOG_DEBUG, "Sending play command for '%s'\n", rt->playpath);
737 
739  0, 29 + strlen(rt->playpath))) < 0)
740  return ret;
741 
742  pkt.extra = rt->stream_id;
743 
744  p = pkt.data;
745  ff_amf_write_string(&p, "play");
746  ff_amf_write_number(&p, ++rt->nb_invokes);
747  ff_amf_write_null(&p);
748  ff_amf_write_string(&p, rt->playpath);
749  ff_amf_write_number(&p, rt->live * 1000);
750 
751  return rtmp_send_packet(rt, &pkt, 1);
752 }
753 
754 static int gen_seek(URLContext *s, RTMPContext *rt, int64_t timestamp)
755 {
756  RTMPPacket pkt;
757  uint8_t *p;
758  int ret;
759 
760  av_log(s, AV_LOG_DEBUG, "Sending seek command for timestamp %"PRId64"\n",
761  timestamp);
762 
763  if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 26)) < 0)
764  return ret;
765 
766  pkt.extra = rt->stream_id;
767 
768  p = pkt.data;
769  ff_amf_write_string(&p, "seek");
770  ff_amf_write_number(&p, 0); //no tracking back responses
771  ff_amf_write_null(&p); //as usual, the first null param
772  ff_amf_write_number(&p, timestamp); //where we want to jump
773 
774  return rtmp_send_packet(rt, &pkt, 1);
775 }
776 
777 /**
778  * Generate a pause packet that either pauses or unpauses the current stream.
779  */
780 static int gen_pause(URLContext *s, RTMPContext *rt, int pause, uint32_t timestamp)
781 {
782  RTMPPacket pkt;
783  uint8_t *p;
784  int ret;
785 
786  av_log(s, AV_LOG_DEBUG, "Sending pause command for timestamp %d\n",
787  timestamp);
788 
789  if ((ret = ff_rtmp_packet_create(&pkt, 3, RTMP_PT_INVOKE, 0, 29)) < 0)
790  return ret;
791 
792  pkt.extra = rt->stream_id;
793 
794  p = pkt.data;
795  ff_amf_write_string(&p, "pause");
796  ff_amf_write_number(&p, 0); //no tracking back responses
797  ff_amf_write_null(&p); //as usual, the first null param
798  ff_amf_write_bool(&p, pause); // pause or unpause
799  ff_amf_write_number(&p, timestamp); //where we pause the stream
800 
801  return rtmp_send_packet(rt, &pkt, 1);
802 }
803 
804 /**
805  * Generate 'publish' call and send it to the server.
806  */
808 {
809  RTMPPacket pkt;
810  uint8_t *p;
811  int ret;
812 
813  av_log(s, AV_LOG_DEBUG, "Sending publish command for '%s'\n", rt->playpath);
814 
816  0, 30 + strlen(rt->playpath))) < 0)
817  return ret;
818 
819  pkt.extra = rt->stream_id;
820 
821  p = pkt.data;
822  ff_amf_write_string(&p, "publish");
823  ff_amf_write_number(&p, ++rt->nb_invokes);
824  ff_amf_write_null(&p);
825  ff_amf_write_string(&p, rt->playpath);
826  ff_amf_write_string(&p, "live");
827 
828  return rtmp_send_packet(rt, &pkt, 1);
829 }
830 
831 /**
832  * Generate ping reply and send it to the server.
833  */
834 static int gen_pong(URLContext *s, RTMPContext *rt, RTMPPacket *ppkt)
835 {
836  RTMPPacket pkt;
837  uint8_t *p;
838  int ret;
839 
840  if (ppkt->size < 6) {
841  av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
842  ppkt->size);
843  return AVERROR_INVALIDDATA;
844  }
845 
847  ppkt->timestamp + 1, 6)) < 0)
848  return ret;
849 
850  p = pkt.data;
851  bytestream_put_be16(&p, 7);
852  bytestream_put_be32(&p, AV_RB32(ppkt->data+2));
853 
854  return rtmp_send_packet(rt, &pkt, 0);
855 }
856 
857 /**
858  * Generate SWF verification message and send it to the server.
859  */
861 {
862  RTMPPacket pkt;
863  uint8_t *p;
864  int ret;
865 
866  av_log(s, AV_LOG_DEBUG, "Sending SWF verification...\n");
868  0, 44)) < 0)
869  return ret;
870 
871  p = pkt.data;
872  bytestream_put_be16(&p, 27);
873  memcpy(p, rt->swfverification, 42);
874 
875  return rtmp_send_packet(rt, &pkt, 0);
876 }
877 
878 /**
879  * Generate server bandwidth message and send it to the server.
880  */
882 {
883  RTMPPacket pkt;
884  uint8_t *p;
885  int ret;
886 
888  0, 4)) < 0)
889  return ret;
890 
891  p = pkt.data;
892  bytestream_put_be32(&p, rt->server_bw);
893 
894  return rtmp_send_packet(rt, &pkt, 0);
895 }
896 
897 /**
898  * Generate check bandwidth message and send it to the server.
899  */
901 {
902  RTMPPacket pkt;
903  uint8_t *p;
904  int ret;
905 
907  0, 21)) < 0)
908  return ret;
909 
910  p = pkt.data;
911  ff_amf_write_string(&p, "_checkbw");
912  ff_amf_write_number(&p, ++rt->nb_invokes);
913  ff_amf_write_null(&p);
914 
915  return rtmp_send_packet(rt, &pkt, 1);
916 }
917 
918 /**
919  * Generate report on bytes read so far and send it to the server.
920  */
921 static int gen_bytes_read(URLContext *s, RTMPContext *rt, uint32_t ts)
922 {
923  RTMPPacket pkt;
924  uint8_t *p;
925  int ret;
926 
928  ts, 4)) < 0)
929  return ret;
930 
931  p = pkt.data;
932  bytestream_put_be32(&p, rt->bytes_read);
933 
934  return rtmp_send_packet(rt, &pkt, 0);
935 }
936 
938  const char *subscribe)
939 {
940  RTMPPacket pkt;
941  uint8_t *p;
942  int ret;
943 
945  0, 27 + strlen(subscribe))) < 0)
946  return ret;
947 
948  p = pkt.data;
949  ff_amf_write_string(&p, "FCSubscribe");
950  ff_amf_write_number(&p, ++rt->nb_invokes);
951  ff_amf_write_null(&p);
952  ff_amf_write_string(&p, subscribe);
953 
954  return rtmp_send_packet(rt, &pkt, 1);
955 }
956 
957 int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap,
958  const uint8_t *key, int keylen, uint8_t *dst)
959 {
960  struct AVSHA *sha;
961  uint8_t hmac_buf[64+32] = {0};
962  int i;
963 
964  sha = av_sha_alloc();
965  if (!sha)
966  return AVERROR(ENOMEM);
967 
968  if (keylen < 64) {
969  memcpy(hmac_buf, key, keylen);
970  } else {
971  av_sha_init(sha, 256);
972  av_sha_update(sha,key, keylen);
973  av_sha_final(sha, hmac_buf);
974  }
975  for (i = 0; i < 64; i++)
976  hmac_buf[i] ^= HMAC_IPAD_VAL;
977 
978  av_sha_init(sha, 256);
979  av_sha_update(sha, hmac_buf, 64);
980  if (gap <= 0) {
981  av_sha_update(sha, src, len);
982  } else { //skip 32 bytes used for storing digest
983  av_sha_update(sha, src, gap);
984  av_sha_update(sha, src + gap + 32, len - gap - 32);
985  }
986  av_sha_final(sha, hmac_buf + 64);
987 
988  for (i = 0; i < 64; i++)
989  hmac_buf[i] ^= HMAC_IPAD_VAL ^ HMAC_OPAD_VAL; //reuse XORed key for opad
990  av_sha_init(sha, 256);
991  av_sha_update(sha, hmac_buf, 64+32);
992  av_sha_final(sha, dst);
993 
994  av_free(sha);
995 
996  return 0;
997 }
998 
999 int ff_rtmp_calc_digest_pos(const uint8_t *buf, int off, int mod_val,
1000  int add_val)
1001 {
1002  int i, digest_pos = 0;
1003 
1004  for (i = 0; i < 4; i++)
1005  digest_pos += buf[i + off];
1006  digest_pos = digest_pos % mod_val + add_val;
1007 
1008  return digest_pos;
1009 }
1010 
1011 /**
1012  * Put HMAC-SHA2 digest of packet data (except for the bytes where this digest
1013  * will be stored) into that packet.
1014  *
1015  * @param buf handshake data (1536 bytes)
1016  * @param encrypted use an encrypted connection (RTMPE)
1017  * @return offset to the digest inside input data
1018  */
1020 {
1021  int ret, digest_pos;
1022 
1023  if (encrypted)
1024  digest_pos = ff_rtmp_calc_digest_pos(buf, 772, 728, 776);
1025  else
1026  digest_pos = ff_rtmp_calc_digest_pos(buf, 8, 728, 12);
1027 
1028  ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
1030  buf + digest_pos);
1031  if (ret < 0)
1032  return ret;
1033 
1034  return digest_pos;
1035 }
1036 
1037 /**
1038  * Verify that the received server response has the expected digest value.
1039  *
1040  * @param buf handshake data received from the server (1536 bytes)
1041  * @param off position to search digest offset from
1042  * @return 0 if digest is valid, digest position otherwise
1043  */
1044 static int rtmp_validate_digest(uint8_t *buf, int off)
1045 {
1046  uint8_t digest[32];
1047  int ret, digest_pos;
1048 
1049  digest_pos = ff_rtmp_calc_digest_pos(buf, off, 728, off + 4);
1050 
1051  ret = ff_rtmp_calc_digest(buf, RTMP_HANDSHAKE_PACKET_SIZE, digest_pos,
1053  digest);
1054  if (ret < 0)
1055  return ret;
1056 
1057  if (!memcmp(digest, buf + digest_pos, 32))
1058  return digest_pos;
1059  return 0;
1060 }
1061 
1063  uint8_t *buf)
1064 {
1065  uint8_t *p;
1066  int ret;
1067 
1068  if (rt->swfhash_len != 32) {
1069  av_log(s, AV_LOG_ERROR,
1070  "Hash of the decompressed SWF file is not 32 bytes long.\n");
1071  return AVERROR(EINVAL);
1072  }
1073 
1074  p = &rt->swfverification[0];
1075  bytestream_put_byte(&p, 1);
1076  bytestream_put_byte(&p, 1);
1077  bytestream_put_be32(&p, rt->swfsize);
1078  bytestream_put_be32(&p, rt->swfsize);
1079 
1080  if ((ret = ff_rtmp_calc_digest(rt->swfhash, 32, 0, buf, 32, p)) < 0)
1081  return ret;
1082 
1083  return 0;
1084 }
1085 
1086 #if CONFIG_ZLIB
1087 static int rtmp_uncompress_swfplayer(uint8_t *in_data, int64_t in_size,
1088  uint8_t **out_data, int64_t *out_size)
1089 {
1090  z_stream zs = { 0 };
1091  void *ptr;
1092  int size;
1093  int ret = 0;
1094 
1095  zs.avail_in = in_size;
1096  zs.next_in = in_data;
1097  ret = inflateInit(&zs);
1098  if (ret != Z_OK)
1099  return AVERROR_UNKNOWN;
1100 
1101  do {
1102  uint8_t tmp_buf[16384];
1103 
1104  zs.avail_out = sizeof(tmp_buf);
1105  zs.next_out = tmp_buf;
1106 
1107  ret = inflate(&zs, Z_NO_FLUSH);
1108  if (ret != Z_OK && ret != Z_STREAM_END) {
1109  ret = AVERROR_UNKNOWN;
1110  goto fail;
1111  }
1112 
1113  size = sizeof(tmp_buf) - zs.avail_out;
1114  if (!(ptr = av_realloc(*out_data, *out_size + size))) {
1115  ret = AVERROR(ENOMEM);
1116  goto fail;
1117  }
1118  *out_data = ptr;
1119 
1120  memcpy(*out_data + *out_size, tmp_buf, size);
1121  *out_size += size;
1122  } while (zs.avail_out == 0);
1123 
1124 fail:
1125  inflateEnd(&zs);
1126  return ret;
1127 }
1128 #endif
1129 
1131 {
1132  RTMPContext *rt = s->priv_data;
1133  uint8_t *in_data = NULL, *out_data = NULL, *swfdata;
1134  int64_t in_size, out_size;
1135  URLContext *stream;
1136  char swfhash[32];
1137  int swfsize;
1138  int ret = 0;
1139 
1140  /* Get the SWF player file. */
1141  if ((ret = ffurl_open(&stream, rt->swfverify, AVIO_FLAG_READ,
1142  &s->interrupt_callback, NULL)) < 0) {
1143  av_log(s, AV_LOG_ERROR, "Cannot open connection %s.\n", rt->swfverify);
1144  goto fail;
1145  }
1146 
1147  if ((in_size = ffurl_seek(stream, 0, AVSEEK_SIZE)) < 0) {
1148  ret = AVERROR(EIO);
1149  goto fail;
1150  }
1151 
1152  if (!(in_data = av_malloc(in_size))) {
1153  ret = AVERROR(ENOMEM);
1154  goto fail;
1155  }
1156 
1157  if ((ret = ffurl_read_complete(stream, in_data, in_size)) < 0)
1158  goto fail;
1159 
1160  if (in_size < 3) {
1161  ret = AVERROR_INVALIDDATA;
1162  goto fail;
1163  }
1164 
1165  if (!memcmp(in_data, "CWS", 3)) {
1166  /* Decompress the SWF player file using Zlib. */
1167  if (!(out_data = av_malloc(8))) {
1168  ret = AVERROR(ENOMEM);
1169  goto fail;
1170  }
1171  *in_data = 'F'; // magic stuff
1172  memcpy(out_data, in_data, 8);
1173  out_size = 8;
1174 
1175 #if CONFIG_ZLIB
1176  if ((ret = rtmp_uncompress_swfplayer(in_data + 8, in_size - 8,
1177  &out_data, &out_size)) < 0)
1178  goto fail;
1179 #else
1180  av_log(s, AV_LOG_ERROR,
1181  "Zlib is required for decompressing the SWF player file.\n");
1182  ret = AVERROR(EINVAL);
1183  goto fail;
1184 #endif
1185  swfsize = out_size;
1186  swfdata = out_data;
1187  } else {
1188  swfsize = in_size;
1189  swfdata = in_data;
1190  }
1191 
1192  /* Compute the SHA256 hash of the SWF player file. */
1193  if ((ret = ff_rtmp_calc_digest(swfdata, swfsize, 0,
1194  "Genuine Adobe Flash Player 001", 30,
1195  swfhash)) < 0)
1196  goto fail;
1197 
1198  /* Set SWFVerification parameters. */
1199  av_opt_set_bin(rt, "rtmp_swfhash", swfhash, 32, 0);
1200  rt->swfsize = swfsize;
1201 
1202 fail:
1203  av_freep(&in_data);
1204  av_freep(&out_data);
1205  ffurl_close(stream);
1206  return ret;
1207 }
1208 
1209 /**
1210  * Perform handshake with the server by means of exchanging pseudorandom data
1211  * signed with HMAC-SHA2 digest.
1212  *
1213  * @return 0 if handshake succeeds, negative value otherwise
1214  */
1216 {
1217  AVLFG rnd;
1218  uint8_t tosend [RTMP_HANDSHAKE_PACKET_SIZE+1] = {
1219  3, // unencrypted data
1220  0, 0, 0, 0, // client uptime
1225  };
1226  uint8_t clientdata[RTMP_HANDSHAKE_PACKET_SIZE];
1227  uint8_t serverdata[RTMP_HANDSHAKE_PACKET_SIZE+1];
1228  int i;
1229  int server_pos, client_pos;
1230  uint8_t digest[32], signature[32];
1231  int ret, type = 0;
1232 
1233  av_log(s, AV_LOG_DEBUG, "Handshaking...\n");
1234 
1235  av_lfg_init(&rnd, 0xDEADC0DE);
1236  // generate handshake packet - 1536 bytes of pseudorandom data
1237  for (i = 9; i <= RTMP_HANDSHAKE_PACKET_SIZE; i++)
1238  tosend[i] = av_lfg_get(&rnd) >> 24;
1239 
1240  if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1241  /* When the client wants to use RTMPE, we have to change the command
1242  * byte to 0x06 which means to use encrypted data and we have to set
1243  * the flash version to at least 9.0.115.0. */
1244  tosend[0] = 6;
1245  tosend[5] = 128;
1246  tosend[6] = 0;
1247  tosend[7] = 3;
1248  tosend[8] = 2;
1249 
1250  /* Initialize the Diffie-Hellmann context and generate the public key
1251  * to send to the server. */
1252  if ((ret = ff_rtmpe_gen_pub_key(rt->stream, tosend + 1)) < 0)
1253  return ret;
1254  }
1255 
1256  client_pos = rtmp_handshake_imprint_with_digest(tosend + 1, rt->encrypted);
1257  if (client_pos < 0)
1258  return client_pos;
1259 
1260  if ((ret = ffurl_write(rt->stream, tosend,
1261  RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1262  av_log(s, AV_LOG_ERROR, "Cannot write RTMP handshake request\n");
1263  return ret;
1264  }
1265 
1266  if ((ret = ffurl_read_complete(rt->stream, serverdata,
1267  RTMP_HANDSHAKE_PACKET_SIZE + 1)) < 0) {
1268  av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1269  return ret;
1270  }
1271 
1272  if ((ret = ffurl_read_complete(rt->stream, clientdata,
1274  av_log(s, AV_LOG_ERROR, "Cannot read RTMP handshake response\n");
1275  return ret;
1276  }
1277 
1278  av_log(s, AV_LOG_DEBUG, "Type answer %d\n", serverdata[0]);
1279  av_log(s, AV_LOG_DEBUG, "Server version %d.%d.%d.%d\n",
1280  serverdata[5], serverdata[6], serverdata[7], serverdata[8]);
1281 
1282  if (rt->is_input && serverdata[5] >= 3) {
1283  server_pos = rtmp_validate_digest(serverdata + 1, 772);
1284  if (server_pos < 0)
1285  return server_pos;
1286 
1287  if (!server_pos) {
1288  type = 1;
1289  server_pos = rtmp_validate_digest(serverdata + 1, 8);
1290  if (server_pos < 0)
1291  return server_pos;
1292 
1293  if (!server_pos) {
1294  av_log(s, AV_LOG_ERROR, "Server response validating failed\n");
1295  return AVERROR(EIO);
1296  }
1297  }
1298 
1299  /* Generate SWFVerification token (SHA256 HMAC hash of decompressed SWF,
1300  * key are the last 32 bytes of the server handshake. */
1301  if (rt->swfsize) {
1302  if ((ret = rtmp_calc_swf_verification(s, rt, serverdata + 1 +
1303  RTMP_HANDSHAKE_PACKET_SIZE - 32)) < 0)
1304  return ret;
1305  }
1306 
1307  ret = ff_rtmp_calc_digest(tosend + 1 + client_pos, 32, 0,
1309  digest);
1310  if (ret < 0)
1311  return ret;
1312 
1313  ret = ff_rtmp_calc_digest(clientdata, RTMP_HANDSHAKE_PACKET_SIZE - 32,
1314  0, digest, 32, signature);
1315  if (ret < 0)
1316  return ret;
1317 
1318  if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1319  /* Compute the shared secret key sent by the server and initialize
1320  * the RC4 encryption. */
1321  if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1322  tosend + 1, type)) < 0)
1323  return ret;
1324 
1325  /* Encrypt the signature received by the server. */
1326  ff_rtmpe_encrypt_sig(rt->stream, signature, digest, serverdata[0]);
1327  }
1328 
1329  if (memcmp(signature, clientdata + RTMP_HANDSHAKE_PACKET_SIZE - 32, 32)) {
1330  av_log(s, AV_LOG_ERROR, "Signature mismatch\n");
1331  return AVERROR(EIO);
1332  }
1333 
1334  for (i = 0; i < RTMP_HANDSHAKE_PACKET_SIZE; i++)
1335  tosend[i] = av_lfg_get(&rnd) >> 24;
1336  ret = ff_rtmp_calc_digest(serverdata + 1 + server_pos, 32, 0,
1338  digest);
1339  if (ret < 0)
1340  return ret;
1341 
1342  ret = ff_rtmp_calc_digest(tosend, RTMP_HANDSHAKE_PACKET_SIZE - 32, 0,
1343  digest, 32,
1344  tosend + RTMP_HANDSHAKE_PACKET_SIZE - 32);
1345  if (ret < 0)
1346  return ret;
1347 
1348  if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1349  /* Encrypt the signature to be send to the server. */
1350  ff_rtmpe_encrypt_sig(rt->stream, tosend +
1351  RTMP_HANDSHAKE_PACKET_SIZE - 32, digest,
1352  serverdata[0]);
1353  }
1354 
1355  // write reply back to the server
1356  if ((ret = ffurl_write(rt->stream, tosend,
1357  RTMP_HANDSHAKE_PACKET_SIZE)) < 0)
1358  return ret;
1359 
1360  if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1361  /* Set RC4 keys for encryption and update the keystreams. */
1362  if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1363  return ret;
1364  }
1365  } else {
1366  if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1367  /* Compute the shared secret key sent by the server and initialize
1368  * the RC4 encryption. */
1369  if ((ret = ff_rtmpe_compute_secret_key(rt->stream, serverdata + 1,
1370  tosend + 1, 1)) < 0)
1371  return ret;
1372 
1373  if (serverdata[0] == 9) {
1374  /* Encrypt the signature received by the server. */
1375  ff_rtmpe_encrypt_sig(rt->stream, signature, digest,
1376  serverdata[0]);
1377  }
1378  }
1379 
1380  if ((ret = ffurl_write(rt->stream, serverdata + 1,
1382  return ret;
1383 
1384  if (CONFIG_FFRTMPCRYPT_PROTOCOL && rt->encrypted) {
1385  /* Set RC4 keys for encryption and update the keystreams. */
1386  if ((ret = ff_rtmpe_update_keystream(rt->stream)) < 0)
1387  return ret;
1388  }
1389  }
1390 
1391  return 0;
1392 }
1393 
1394 static int rtmp_receive_hs_packet(RTMPContext* rt, uint32_t *first_int,
1395  uint32_t *second_int, char *arraydata,
1396  int size)
1397 {
1398  int inoutsize;
1399 
1400  inoutsize = ffurl_read_complete(rt->stream, arraydata,
1402  if (inoutsize <= 0)
1403  return AVERROR(EIO);
1404  if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1405  av_log(rt, AV_LOG_ERROR, "Erroneous Message size %d"
1406  " not following standard\n", (int)inoutsize);
1407  return AVERROR(EINVAL);
1408  }
1409 
1410  *first_int = AV_RB32(arraydata);
1411  *second_int = AV_RB32(arraydata + 4);
1412  return 0;
1413 }
1414 
1415 static int rtmp_send_hs_packet(RTMPContext* rt, uint32_t first_int,
1416  uint32_t second_int, char *arraydata, int size)
1417 {
1418  int inoutsize;
1419 
1420  AV_WB32(arraydata, first_int);
1421  AV_WB32(arraydata + 4, second_int);
1422  inoutsize = ffurl_write(rt->stream, arraydata,
1424  if (inoutsize != RTMP_HANDSHAKE_PACKET_SIZE) {
1425  av_log(rt, AV_LOG_ERROR, "Unable to write answer\n");
1426  return AVERROR(EIO);
1427  }
1428 
1429  return 0;
1430 }
1431 
1432 /**
1433  * rtmp handshake server side
1434  */
1436 {
1438  uint32_t hs_epoch;
1439  uint32_t hs_my_epoch;
1442  uint32_t zeroes;
1443  uint32_t temp = 0;
1444  int randomidx = 0;
1445  int inoutsize = 0;
1446  int ret;
1447 
1448  inoutsize = ffurl_read_complete(rt->stream, buffer, 1); // Receive C0
1449  if (inoutsize <= 0) {
1450  av_log(s, AV_LOG_ERROR, "Unable to read handshake\n");
1451  return AVERROR(EIO);
1452  }
1453  // Check Version
1454  if (buffer[0] != 3) {
1455  av_log(s, AV_LOG_ERROR, "RTMP protocol version mismatch\n");
1456  return AVERROR(EIO);
1457  }
1458  if (ffurl_write(rt->stream, buffer, 1) <= 0) { // Send S0
1459  av_log(s, AV_LOG_ERROR,
1460  "Unable to write answer - RTMP S0\n");
1461  return AVERROR(EIO);
1462  }
1463  /* Receive C1 */
1464  ret = rtmp_receive_hs_packet(rt, &hs_epoch, &zeroes, hs_c1,
1466  if (ret) {
1467  av_log(s, AV_LOG_ERROR, "RTMP Handshake C1 Error\n");
1468  return ret;
1469  }
1470  /* Send S1 */
1471  /* By now same epoch will be sent */
1472  hs_my_epoch = hs_epoch;
1473  /* Generate random */
1474  for (randomidx = 8; randomidx < (RTMP_HANDSHAKE_PACKET_SIZE);
1475  randomidx += 4)
1476  AV_WB32(hs_s1 + randomidx, av_get_random_seed());
1477 
1478  ret = rtmp_send_hs_packet(rt, hs_my_epoch, 0, hs_s1,
1480  if (ret) {
1481  av_log(s, AV_LOG_ERROR, "RTMP Handshake S1 Error\n");
1482  return ret;
1483  }
1484  /* Send S2 */
1485  ret = rtmp_send_hs_packet(rt, hs_epoch, 0, hs_c1,
1487  if (ret) {
1488  av_log(s, AV_LOG_ERROR, "RTMP Handshake S2 Error\n");
1489  return ret;
1490  }
1491  /* Receive C2 */
1492  ret = rtmp_receive_hs_packet(rt, &temp, &zeroes, buffer,
1494  if (ret) {
1495  av_log(s, AV_LOG_ERROR, "RTMP Handshake C2 Error\n");
1496  return ret;
1497  }
1498  if (temp != hs_my_epoch)
1500  "Erroneous C2 Message epoch does not match up with C1 epoch\n");
1501  if (memcmp(buffer + 8, hs_s1 + 8,
1504  "Erroneous C2 Message random does not match up\n");
1505 
1506  return 0;
1507 }
1508 
1510 {
1511  RTMPContext *rt = s->priv_data;
1512  int ret;
1513 
1514  if (pkt->size < 4) {
1515  av_log(s, AV_LOG_ERROR,
1516  "Too short chunk size change packet (%d)\n",
1517  pkt->size);
1518  return AVERROR_INVALIDDATA;
1519  }
1520 
1521  if (!rt->is_input) {
1522  /* Send the same chunk size change packet back to the server,
1523  * setting the outgoing chunk size to the same as the incoming one. */
1524  if ((ret = ff_rtmp_packet_write(rt->stream, pkt, rt->out_chunk_size,
1525  &rt->prev_pkt[1], &rt->nb_prev_pkt[1])) < 0)
1526  return ret;
1527  rt->out_chunk_size = AV_RB32(pkt->data);
1528  }
1529 
1530  rt->in_chunk_size = AV_RB32(pkt->data);
1531  if (rt->in_chunk_size <= 0) {
1532  av_log(s, AV_LOG_ERROR, "Incorrect chunk size %d\n",
1533  rt->in_chunk_size);
1534  return AVERROR_INVALIDDATA;
1535  }
1536  av_log(s, AV_LOG_DEBUG, "New incoming chunk size = %d\n",
1537  rt->in_chunk_size);
1538 
1539  return 0;
1540 }
1541 
1543 {
1544  RTMPContext *rt = s->priv_data;
1545  int t, ret;
1546 
1547  if (pkt->size < 2) {
1548  av_log(s, AV_LOG_ERROR, "Too short ping packet (%d)\n",
1549  pkt->size);
1550  return AVERROR_INVALIDDATA;
1551  }
1552 
1553  t = AV_RB16(pkt->data);
1554  if (t == 6) {
1555  if ((ret = gen_pong(s, rt, pkt)) < 0)
1556  return ret;
1557  } else if (t == 26) {
1558  if (rt->swfsize) {
1559  if ((ret = gen_swf_verification(s, rt)) < 0)
1560  return ret;
1561  } else {
1562  av_log(s, AV_LOG_WARNING, "Ignoring SWFVerification request.\n");
1563  }
1564  }
1565 
1566  return 0;
1567 }
1568 
1570 {
1571  RTMPContext *rt = s->priv_data;
1572 
1573  if (pkt->size < 4) {
1574  av_log(s, AV_LOG_ERROR,
1575  "Client bandwidth report packet is less than 4 bytes long (%d)\n",
1576  pkt->size);
1577  return AVERROR_INVALIDDATA;
1578  }
1579 
1580  rt->client_report_size = AV_RB32(pkt->data);
1581  if (rt->client_report_size <= 0) {
1582  av_log(s, AV_LOG_ERROR, "Incorrect client bandwidth %d\n",
1583  rt->client_report_size);
1584  return AVERROR_INVALIDDATA;
1585 
1586  }
1587  av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", rt->client_report_size);
1588  rt->client_report_size >>= 1;
1589 
1590  return 0;
1591 }
1592 
1594 {
1595  RTMPContext *rt = s->priv_data;
1596 
1597  if (pkt->size < 4) {
1598  av_log(s, AV_LOG_ERROR,
1599  "Too short server bandwidth report packet (%d)\n",
1600  pkt->size);
1601  return AVERROR_INVALIDDATA;
1602  }
1603 
1604  rt->server_bw = AV_RB32(pkt->data);
1605  if (rt->server_bw <= 0) {
1606  av_log(s, AV_LOG_ERROR, "Incorrect server bandwidth %d\n",
1607  rt->server_bw);
1608  return AVERROR_INVALIDDATA;
1609  }
1610  av_log(s, AV_LOG_DEBUG, "Server bandwidth = %d\n", rt->server_bw);
1611 
1612  return 0;
1613 }
1614 
1615 static int do_adobe_auth(RTMPContext *rt, const char *user, const char *salt,
1616  const char *opaque, const char *challenge)
1617 {
1618  uint8_t hash[16];
1619  char hashstr[AV_BASE64_SIZE(sizeof(hash))], challenge2[10];
1620  struct AVMD5 *md5 = av_md5_alloc();
1621  if (!md5)
1622  return AVERROR(ENOMEM);
1623 
1624  snprintf(challenge2, sizeof(challenge2), "%08x", av_get_random_seed());
1625 
1626  av_md5_init(md5);
1627  av_md5_update(md5, user, strlen(user));
1628  av_md5_update(md5, salt, strlen(salt));
1629  av_md5_update(md5, rt->password, strlen(rt->password));
1630  av_md5_final(md5, hash);
1631  av_base64_encode(hashstr, sizeof(hashstr), hash,
1632  sizeof(hash));
1633  av_md5_init(md5);
1634  av_md5_update(md5, hashstr, strlen(hashstr));
1635  if (opaque)
1636  av_md5_update(md5, opaque, strlen(opaque));
1637  else if (challenge)
1638  av_md5_update(md5, challenge, strlen(challenge));
1639  av_md5_update(md5, challenge2, strlen(challenge2));
1640  av_md5_final(md5, hash);
1641  av_base64_encode(hashstr, sizeof(hashstr), hash,
1642  sizeof(hash));
1643  snprintf(rt->auth_params, sizeof(rt->auth_params),
1644  "?authmod=%s&user=%s&challenge=%s&response=%s",
1645  "adobe", user, challenge2, hashstr);
1646  if (opaque)
1647  av_strlcatf(rt->auth_params, sizeof(rt->auth_params),
1648  "&opaque=%s", opaque);
1649 
1650  av_free(md5);
1651  return 0;
1652 }
1653 
1654 static int do_llnw_auth(RTMPContext *rt, const char *user, const char *nonce)
1655 {
1656  uint8_t hash[16];
1657  char hashstr1[33], hashstr2[33];
1658  const char *realm = "live";
1659  const char *method = "publish";
1660  const char *qop = "auth";
1661  const char *nc = "00000001";
1662  char cnonce[10];
1663  struct AVMD5 *md5 = av_md5_alloc();
1664  if (!md5)
1665  return AVERROR(ENOMEM);
1666 
1667  snprintf(cnonce, sizeof(cnonce), "%08x", av_get_random_seed());
1668 
1669  av_md5_init(md5);
1670  av_md5_update(md5, user, strlen(user));
1671  av_md5_update(md5, ":", 1);
1672  av_md5_update(md5, realm, strlen(realm));
1673  av_md5_update(md5, ":", 1);
1674  av_md5_update(md5, rt->password, strlen(rt->password));
1675  av_md5_final(md5, hash);
1676  ff_data_to_hex(hashstr1, hash, 16, 1);
1677  hashstr1[32] = '\0';
1678 
1679  av_md5_init(md5);
1680  av_md5_update(md5, method, strlen(method));
1681  av_md5_update(md5, ":/", 2);
1682  av_md5_update(md5, rt->app, strlen(rt->app));
1683  if (!strchr(rt->app, '/'))
1684  av_md5_update(md5, "/_definst_", strlen("/_definst_"));
1685  av_md5_final(md5, hash);
1686  ff_data_to_hex(hashstr2, hash, 16, 1);
1687  hashstr2[32] = '\0';
1688 
1689  av_md5_init(md5);
1690  av_md5_update(md5, hashstr1, strlen(hashstr1));
1691  av_md5_update(md5, ":", 1);
1692  if (nonce)
1693  av_md5_update(md5, nonce, strlen(nonce));
1694  av_md5_update(md5, ":", 1);
1695  av_md5_update(md5, nc, strlen(nc));
1696  av_md5_update(md5, ":", 1);
1697  av_md5_update(md5, cnonce, strlen(cnonce));
1698  av_md5_update(md5, ":", 1);
1699  av_md5_update(md5, qop, strlen(qop));
1700  av_md5_update(md5, ":", 1);
1701  av_md5_update(md5, hashstr2, strlen(hashstr2));
1702  av_md5_final(md5, hash);
1703  ff_data_to_hex(hashstr1, hash, 16, 1);
1704 
1705  snprintf(rt->auth_params, sizeof(rt->auth_params),
1706  "?authmod=%s&user=%s&nonce=%s&cnonce=%s&nc=%s&response=%s",
1707  "llnw", user, nonce, cnonce, nc, hashstr1);
1708 
1709  av_free(md5);
1710  return 0;
1711 }
1712 
1713 static int handle_connect_error(URLContext *s, const char *desc)
1714 {
1715  RTMPContext *rt = s->priv_data;
1716  char buf[300], *ptr, authmod[15];
1717  int i = 0, ret = 0;
1718  const char *user = "", *salt = "", *opaque = NULL,
1719  *challenge = NULL, *cptr = NULL, *nonce = NULL;
1720 
1721  if (!(cptr = strstr(desc, "authmod=adobe")) &&
1722  !(cptr = strstr(desc, "authmod=llnw"))) {
1723  av_log(s, AV_LOG_ERROR,
1724  "Unknown connect error (unsupported authentication method?)\n");
1725  return AVERROR_UNKNOWN;
1726  }
1727  cptr += strlen("authmod=");
1728  while (*cptr && *cptr != ' ' && i < sizeof(authmod) - 1)
1729  authmod[i++] = *cptr++;
1730  authmod[i] = '\0';
1731 
1732  if (!rt->username[0] || !rt->password[0]) {
1733  av_log(s, AV_LOG_ERROR, "No credentials set\n");
1734  return AVERROR_UNKNOWN;
1735  }
1736 
1737  if (strstr(desc, "?reason=authfailed")) {
1738  av_log(s, AV_LOG_ERROR, "Incorrect username/password\n");
1739  return AVERROR_UNKNOWN;
1740  } else if (strstr(desc, "?reason=nosuchuser")) {
1741  av_log(s, AV_LOG_ERROR, "Incorrect username\n");
1742  return AVERROR_UNKNOWN;
1743  }
1744 
1745  if (rt->auth_tried) {
1746  av_log(s, AV_LOG_ERROR, "Authentication failed\n");
1747  return AVERROR_UNKNOWN;
1748  }
1749 
1750  rt->auth_params[0] = '\0';
1751 
1752  if (strstr(desc, "code=403 need auth")) {
1753  snprintf(rt->auth_params, sizeof(rt->auth_params),
1754  "?authmod=%s&user=%s", authmod, rt->username);
1755  return 0;
1756  }
1757 
1758  if (!(cptr = strstr(desc, "?reason=needauth"))) {
1759  av_log(s, AV_LOG_ERROR, "No auth parameters found\n");
1760  return AVERROR_UNKNOWN;
1761  }
1762 
1763  av_strlcpy(buf, cptr + 1, sizeof(buf));
1764  ptr = buf;
1765 
1766  while (ptr) {
1767  char *next = strchr(ptr, '&');
1768  char *value = strchr(ptr, '=');
1769  if (next)
1770  *next++ = '\0';
1771  if (value) {
1772  *value++ = '\0';
1773  if (!strcmp(ptr, "user")) {
1774  user = value;
1775  } else if (!strcmp(ptr, "salt")) {
1776  salt = value;
1777  } else if (!strcmp(ptr, "opaque")) {
1778  opaque = value;
1779  } else if (!strcmp(ptr, "challenge")) {
1780  challenge = value;
1781  } else if (!strcmp(ptr, "nonce")) {
1782  nonce = value;
1783  } else {
1784  av_log(s, AV_LOG_INFO, "Ignoring unsupported var %s\n", ptr);
1785  }
1786  } else {
1787  av_log(s, AV_LOG_WARNING, "Variable %s has NULL value\n", ptr);
1788  }
1789  ptr = next;
1790  }
1791 
1792  if (!strcmp(authmod, "adobe")) {
1793  if ((ret = do_adobe_auth(rt, user, salt, opaque, challenge)) < 0)
1794  return ret;
1795  } else {
1796  if ((ret = do_llnw_auth(rt, user, nonce)) < 0)
1797  return ret;
1798  }
1799 
1800  rt->auth_tried = 1;
1801  return 0;
1802 }
1803 
1805 {
1806  RTMPContext *rt = s->priv_data;
1807  const uint8_t *data_end = pkt->data + pkt->size;
1808  char *tracked_method = NULL;
1809  int level = AV_LOG_ERROR;
1810  uint8_t tmpstr[256];
1811  int ret;
1812 
1813  if ((ret = find_tracked_method(s, pkt, 9, &tracked_method)) < 0)
1814  return ret;
1815 
1816  if (!ff_amf_get_field_value(pkt->data + 9, data_end,
1817  "description", tmpstr, sizeof(tmpstr))) {
1818  if (tracked_method && (!strcmp(tracked_method, "_checkbw") ||
1819  !strcmp(tracked_method, "releaseStream") ||
1820  !strcmp(tracked_method, "FCSubscribe") ||
1821  !strcmp(tracked_method, "FCPublish"))) {
1822  /* Gracefully ignore Adobe-specific historical artifact errors. */
1823  level = AV_LOG_WARNING;
1824  ret = 0;
1825  } else if (tracked_method && !strcmp(tracked_method, "getStreamLength")) {
1826  level = rt->live ? AV_LOG_DEBUG : AV_LOG_WARNING;
1827  ret = 0;
1828  } else if (tracked_method && !strcmp(tracked_method, "connect")) {
1829  ret = handle_connect_error(s, tmpstr);
1830  if (!ret) {
1831  rt->do_reconnect = 1;
1832  level = AV_LOG_VERBOSE;
1833  }
1834  } else
1835  ret = AVERROR_UNKNOWN;
1836  av_log(s, level, "Server error: %s\n", tmpstr);
1837  }
1838 
1839  av_free(tracked_method);
1840  return ret;
1841 }
1842 
1844 {
1845  RTMPContext *rt = s->priv_data;
1846  PutByteContext pbc;
1847  RTMPPacket spkt = { 0 };
1848  int ret;
1849 
1850  // Send Stream Begin 1
1851  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
1852  RTMP_PT_PING, 0, 6)) < 0) {
1853  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1854  return ret;
1855  }
1856 
1857  bytestream2_init_writer(&pbc, spkt.data, spkt.size);
1858  bytestream2_put_be16(&pbc, 0); // 0 -> Stream Begin
1859  bytestream2_put_be32(&pbc, rt->nb_streamid);
1860 
1861  ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1862  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1863 
1864  ff_rtmp_packet_destroy(&spkt);
1865 
1866  return ret;
1867 }
1868 
1870  const char *status, const char *filename)
1871 {
1872  RTMPContext *rt = s->priv_data;
1873  RTMPPacket spkt = { 0 };
1874  char statusmsg[128];
1875  uint8_t *pp;
1876  int ret;
1877 
1878  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1879  RTMP_PT_INVOKE, 0,
1880  RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1881  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1882  return ret;
1883  }
1884 
1885  pp = spkt.data;
1886  spkt.extra = pkt->extra;
1887  ff_amf_write_string(&pp, "onStatus");
1888  ff_amf_write_number(&pp, 0);
1889  ff_amf_write_null(&pp);
1890 
1892  ff_amf_write_field_name(&pp, "level");
1893  ff_amf_write_string(&pp, "status");
1894  ff_amf_write_field_name(&pp, "code");
1895  ff_amf_write_string(&pp, status);
1896  ff_amf_write_field_name(&pp, "description");
1897  snprintf(statusmsg, sizeof(statusmsg),
1898  "%s is now published", filename);
1899  ff_amf_write_string(&pp, statusmsg);
1900  ff_amf_write_field_name(&pp, "details");
1901  ff_amf_write_string(&pp, filename);
1902  ff_amf_write_field_name(&pp, "clientid");
1903  snprintf(statusmsg, sizeof(statusmsg), "%s", LIBAVFORMAT_IDENT);
1904  ff_amf_write_string(&pp, statusmsg);
1906 
1907  spkt.size = pp - spkt.data;
1908  ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1909  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1910  ff_rtmp_packet_destroy(&spkt);
1911 
1912  return ret;
1913 }
1914 
1916 {
1917  RTMPContext *rt = s->priv_data;
1918  double seqnum;
1919  char filename[64];
1920  char command[64];
1921  int stringlen;
1922  char *pchar;
1923  const uint8_t *p = pkt->data;
1924  uint8_t *pp = NULL;
1925  RTMPPacket spkt = { 0 };
1926  GetByteContext gbc;
1927  int ret;
1928 
1929  bytestream2_init(&gbc, p, pkt->size);
1930  if (ff_amf_read_string(&gbc, command, sizeof(command),
1931  &stringlen)) {
1932  av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n");
1933  return AVERROR_INVALIDDATA;
1934  }
1935 
1936  ret = ff_amf_read_number(&gbc, &seqnum);
1937  if (ret)
1938  return ret;
1939  ret = ff_amf_read_null(&gbc);
1940  if (ret)
1941  return ret;
1942  if (!strcmp(command, "FCPublish") ||
1943  !strcmp(command, "publish")) {
1944  ret = ff_amf_read_string(&gbc, filename,
1945  sizeof(filename), &stringlen);
1946  // check with url
1947  if (s->filename) {
1948  pchar = strrchr(s->filename, '/');
1949  if (!pchar) {
1951  "Unable to find / in url %s, bad format\n",
1952  s->filename);
1953  pchar = s->filename;
1954  }
1955  pchar++;
1956  if (strcmp(pchar, filename))
1957  av_log(s, AV_LOG_WARNING, "Unexpected stream %s, expecting"
1958  " %s\n", filename, pchar);
1959  }
1960  rt->state = STATE_RECEIVING;
1961  }
1962 
1963  if (!strcmp(command, "FCPublish")) {
1964  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1965  RTMP_PT_INVOKE, 0,
1966  RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1967  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1968  return ret;
1969  }
1970  pp = spkt.data;
1971  ff_amf_write_string(&pp, "onFCPublish");
1972  } else if (!strcmp(command, "publish")) {
1973  ret = write_begin(s);
1974  if (ret < 0)
1975  return ret;
1976 
1977  // Send onStatus(NetStream.Publish.Start)
1978  return write_status(s, pkt, "NetStream.Publish.Start",
1979  filename);
1980  } else if (!strcmp(command, "play")) {
1981  ret = write_begin(s);
1982  if (ret < 0)
1983  return ret;
1984  rt->state = STATE_SENDING;
1985  return write_status(s, pkt, "NetStream.Play.Start",
1986  filename);
1987  } else {
1988  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1989  RTMP_PT_INVOKE, 0,
1990  RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1991  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1992  return ret;
1993  }
1994  pp = spkt.data;
1995  ff_amf_write_string(&pp, "_result");
1996  ff_amf_write_number(&pp, seqnum);
1997  ff_amf_write_null(&pp);
1998  if (!strcmp(command, "createStream")) {
1999  rt->nb_streamid++;
2000  if (rt->nb_streamid == 0 || rt->nb_streamid == 2)
2001  rt->nb_streamid++; /* Values 0 and 2 are reserved */
2002  ff_amf_write_number(&pp, rt->nb_streamid);
2003  /* By now we don't control which streams are removed in
2004  * deleteStream. There is no stream creation control
2005  * if a client creates more than 2^32 - 2 streams. */
2006  }
2007  }
2008  spkt.size = pp - spkt.data;
2009  ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
2010  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
2011  ff_rtmp_packet_destroy(&spkt);
2012  return ret;
2013 }
2014 
2015 /**
2016  * Read the AMF_NUMBER response ("_result") to a function call
2017  * (e.g. createStream()). This response should be made up of the AMF_STRING
2018  * "result", a NULL object and then the response encoded as AMF_NUMBER. On a
2019  * successful response, we will return set the value to number (otherwise number
2020  * will not be changed).
2021  *
2022  * @return 0 if reading the value succeeds, negative value otherwiss
2023  */
2024 static int read_number_result(RTMPPacket *pkt, double *number)
2025 {
2026  // We only need to fit "_result" in this.
2027  uint8_t strbuffer[8];
2028  int stringlen;
2029  double numbuffer;
2030  GetByteContext gbc;
2031 
2032  bytestream2_init(&gbc, pkt->data, pkt->size);
2033 
2034  // Value 1/4: "_result" as AMF_STRING
2035  if (ff_amf_read_string(&gbc, strbuffer, sizeof(strbuffer), &stringlen))
2036  return AVERROR_INVALIDDATA;
2037  if (strcmp(strbuffer, "_result"))
2038  return AVERROR_INVALIDDATA;
2039  // Value 2/4: The callee reference number
2040  if (ff_amf_read_number(&gbc, &numbuffer))
2041  return AVERROR_INVALIDDATA;
2042  // Value 3/4: Null
2043  if (ff_amf_read_null(&gbc))
2044  return AVERROR_INVALIDDATA;
2045  // Value 4/4: The resonse as AMF_NUMBER
2046  if (ff_amf_read_number(&gbc, &numbuffer))
2047  return AVERROR_INVALIDDATA;
2048  else
2049  *number = numbuffer;
2050 
2051  return 0;
2052 }
2053 
2055 {
2056  RTMPContext *rt = s->priv_data;
2057  char *tracked_method = NULL;
2058  int ret = 0;
2059 
2060  if ((ret = find_tracked_method(s, pkt, 10, &tracked_method)) < 0)
2061  return ret;
2062 
2063  if (!tracked_method) {
2064  /* Ignore this reply when the current method is not tracked. */
2065  return ret;
2066  }
2067 
2068  if (!strcmp(tracked_method, "connect")) {
2069  if (!rt->is_input) {
2070  if ((ret = gen_release_stream(s, rt)) < 0)
2071  goto fail;
2072 
2073  if ((ret = gen_fcpublish_stream(s, rt)) < 0)
2074  goto fail;
2075  } else {
2076  if ((ret = gen_server_bw(s, rt)) < 0)
2077  goto fail;
2078  }
2079 
2080  if ((ret = gen_create_stream(s, rt)) < 0)
2081  goto fail;
2082 
2083  if (rt->is_input) {
2084  /* Send the FCSubscribe command when the name of live
2085  * stream is defined by the user or if it's a live stream. */
2086  if (rt->subscribe) {
2087  if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
2088  goto fail;
2089  } else if (rt->live == -1) {
2090  if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
2091  goto fail;
2092  }
2093  }
2094  } else if (!strcmp(tracked_method, "createStream")) {
2095  double stream_id;
2096  if (read_number_result(pkt, &stream_id)) {
2097  av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
2098  } else {
2099  rt->stream_id = stream_id;
2100  }
2101 
2102  if (!rt->is_input) {
2103  if ((ret = gen_publish(s, rt)) < 0)
2104  goto fail;
2105  } else {
2106  if (rt->live != -1) {
2107  if ((ret = gen_get_stream_length(s, rt)) < 0)
2108  goto fail;
2109  }
2110  if ((ret = gen_play(s, rt)) < 0)
2111  goto fail;
2112  if ((ret = gen_buffer_time(s, rt)) < 0)
2113  goto fail;
2114  }
2115  } else if (!strcmp(tracked_method, "getStreamLength")) {
2116  if (read_number_result(pkt, &rt->duration)) {
2117  av_log(s, AV_LOG_WARNING, "Unexpected reply on getStreamLength()\n");
2118  }
2119  }
2120 
2121 fail:
2122  av_free(tracked_method);
2123  return ret;
2124 }
2125 
2127 {
2128  RTMPContext *rt = s->priv_data;
2129  const uint8_t *data_end = pkt->data + pkt->size;
2130  const uint8_t *ptr = pkt->data + RTMP_HEADER;
2131  uint8_t tmpstr[256];
2132  int i, t;
2133 
2134  for (i = 0; i < 2; i++) {
2135  t = ff_amf_tag_size(ptr, data_end);
2136  if (t < 0)
2137  return 1;
2138  ptr += t;
2139  }
2140 
2141  t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
2142  if (!t && !strcmp(tmpstr, "error")) {
2143  t = ff_amf_get_field_value(ptr, data_end,
2144  "description", tmpstr, sizeof(tmpstr));
2145  if (t || !tmpstr[0])
2146  t = ff_amf_get_field_value(ptr, data_end, "code",
2147  tmpstr, sizeof(tmpstr));
2148  if (!t)
2149  av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
2150  return -1;
2151  }
2152 
2153  t = ff_amf_get_field_value(ptr, data_end, "code", tmpstr, sizeof(tmpstr));
2154  if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
2155  if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
2156  if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
2157  if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
2158  if (!t && !strcmp(tmpstr, "NetStream.Seek.Notify")) rt->state = STATE_PLAYING;
2159 
2160  return 0;
2161 }
2162 
2164 {
2165  RTMPContext *rt = s->priv_data;
2166  int ret = 0;
2167 
2168  //TODO: check for the messages sent for wrong state?
2169  if (ff_amf_match_string(pkt->data, pkt->size, "_error")) {
2170  if ((ret = handle_invoke_error(s, pkt)) < 0)
2171  return ret;
2172  } else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) {
2173  if ((ret = handle_invoke_result(s, pkt)) < 0)
2174  return ret;
2175  } else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) {
2176  if ((ret = handle_invoke_status(s, pkt)) < 0)
2177  return ret;
2178  } else if (ff_amf_match_string(pkt->data, pkt->size, "onBWDone")) {
2179  if ((ret = gen_check_bw(s, rt)) < 0)
2180  return ret;
2181  } else if (ff_amf_match_string(pkt->data, pkt->size, "releaseStream") ||
2182  ff_amf_match_string(pkt->data, pkt->size, "FCPublish") ||
2183  ff_amf_match_string(pkt->data, pkt->size, "publish") ||
2184  ff_amf_match_string(pkt->data, pkt->size, "play") ||
2185  ff_amf_match_string(pkt->data, pkt->size, "_checkbw") ||
2186  ff_amf_match_string(pkt->data, pkt->size, "createStream")) {
2187  if ((ret = send_invoke_response(s, pkt)) < 0)
2188  return ret;
2189  }
2190 
2191  return ret;
2192 }
2193 
2194 static int update_offset(RTMPContext *rt, int size)
2195 {
2196  int old_flv_size;
2197 
2198  // generate packet header and put data into buffer for FLV demuxer
2199  if (rt->flv_off < rt->flv_size) {
2200  // There is old unread data in the buffer, thus append at the end
2201  old_flv_size = rt->flv_size;
2202  rt->flv_size += size;
2203  } else {
2204  // All data has been read, write the new data at the start of the buffer
2205  old_flv_size = 0;
2206  rt->flv_size = size;
2207  rt->flv_off = 0;
2208  }
2209 
2210  return old_flv_size;
2211 }
2212 
2213 static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)
2214 {
2215  int old_flv_size, ret;
2216  PutByteContext pbc;
2217  const uint8_t *data = pkt->data + skip;
2218  const int size = pkt->size - skip;
2219  uint32_t ts = pkt->timestamp;
2220 
2221  if (pkt->type == RTMP_PT_AUDIO) {
2222  rt->has_audio = 1;
2223  } else if (pkt->type == RTMP_PT_VIDEO) {
2224  rt->has_video = 1;
2225  }
2226 
2227  old_flv_size = update_offset(rt, size + 15);
2228 
2229  if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2230  rt->flv_size = rt->flv_off = 0;
2231  return ret;
2232  }
2233  bytestream2_init_writer(&pbc, rt->flv_data, rt->flv_size);
2234  bytestream2_skip_p(&pbc, old_flv_size);
2235  bytestream2_put_byte(&pbc, pkt->type);
2236  bytestream2_put_be24(&pbc, size);
2237  bytestream2_put_be24(&pbc, ts);
2238  bytestream2_put_byte(&pbc, ts >> 24);
2239  bytestream2_put_be24(&pbc, 0);
2240  bytestream2_put_buffer(&pbc, data, size);
2241  bytestream2_put_be32(&pbc, 0);
2242 
2243  return 0;
2244 }
2245 
2247 {
2248  RTMPContext *rt = s->priv_data;
2249  uint8_t commandbuffer[64];
2250  char statusmsg[128];
2251  int stringlen, ret, skip = 0;
2252  GetByteContext gbc;
2253 
2254  bytestream2_init(&gbc, pkt->data, pkt->size);
2255  if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
2256  &stringlen))
2257  return AVERROR_INVALIDDATA;
2258 
2259  if (!strcmp(commandbuffer, "onMetaData")) {
2260  // metadata properties should be stored in a mixed array
2261  if (bytestream2_get_byte(&gbc) == AMF_DATA_TYPE_MIXEDARRAY) {
2262  // We have found a metaData Array so flv can determine the streams
2263  // from this.
2264  rt->received_metadata = 1;
2265  // skip 32-bit max array index
2266  bytestream2_skip(&gbc, 4);
2267  while (bytestream2_get_bytes_left(&gbc) > 3) {
2268  if (ff_amf_get_string(&gbc, statusmsg, sizeof(statusmsg),
2269  &stringlen))
2270  return AVERROR_INVALIDDATA;
2271  // We do not care about the content of the property (yet).
2272  stringlen = ff_amf_tag_size(gbc.buffer, gbc.buffer_end);
2273  if (stringlen < 0)
2274  return AVERROR_INVALIDDATA;
2275  bytestream2_skip(&gbc, stringlen);
2276 
2277  // The presence of the following properties indicates that the
2278  // respective streams are present.
2279  if (!strcmp(statusmsg, "videocodecid")) {
2280  rt->has_video = 1;
2281  }
2282  if (!strcmp(statusmsg, "audiocodecid")) {
2283  rt->has_audio = 1;
2284  }
2285  }
2286  if (bytestream2_get_be24(&gbc) != AMF_END_OF_OBJECT)
2287  return AVERROR_INVALIDDATA;
2288  }
2289  }
2290 
2291  // Skip the @setDataFrame string and validate it is a notification
2292  if (!strcmp(commandbuffer, "@setDataFrame")) {
2293  skip = gbc.buffer - pkt->data;
2294  ret = ff_amf_read_string(&gbc, statusmsg,
2295  sizeof(statusmsg), &stringlen);
2296  if (ret < 0)
2297  return AVERROR_INVALIDDATA;
2298  }
2299 
2300  return append_flv_data(rt, pkt, skip);
2301 }
2302 
2303 /**
2304  * Parse received packet and possibly perform some action depending on
2305  * the packet contents.
2306  * @return 0 for no errors, negative values for serious errors which prevent
2307  * further communications, positive values for uncritical errors
2308  */
2310 {
2311  int ret;
2312 
2313 #ifdef DEBUG
2314  ff_rtmp_packet_dump(s, pkt);
2315 #endif
2316 
2317  switch (pkt->type) {
2318  case RTMP_PT_BYTES_READ:
2319  av_dlog(s, "received bytes read report\n");
2320  break;
2321  case RTMP_PT_CHUNK_SIZE:
2322  if ((ret = handle_chunk_size(s, pkt)) < 0)
2323  return ret;
2324  break;
2325  case RTMP_PT_PING:
2326  if ((ret = handle_ping(s, pkt)) < 0)
2327  return ret;
2328  break;
2329  case RTMP_PT_CLIENT_BW:
2330  if ((ret = handle_client_bw(s, pkt)) < 0)
2331  return ret;
2332  break;
2333  case RTMP_PT_SERVER_BW:
2334  if ((ret = handle_server_bw(s, pkt)) < 0)
2335  return ret;
2336  break;
2337  case RTMP_PT_INVOKE:
2338  if ((ret = handle_invoke(s, pkt)) < 0)
2339  return ret;
2340  break;
2341  case RTMP_PT_VIDEO:
2342  case RTMP_PT_AUDIO:
2343  case RTMP_PT_METADATA:
2344  case RTMP_PT_NOTIFY:
2345  /* Audio, Video and Metadata packets are parsed in get_packet() */
2346  break;
2347  default:
2348  av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
2349  break;
2350  }
2351  return 0;
2352 }
2353 
2355 {
2356  int ret, old_flv_size, type;
2357  const uint8_t *next;
2358  uint8_t *p;
2359  uint32_t size;
2360  uint32_t ts, cts, pts = 0;
2361 
2362  old_flv_size = update_offset(rt, pkt->size);
2363 
2364  if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2365  rt->flv_size = rt->flv_off = 0;
2366  return ret;
2367  }
2368 
2369  next = pkt->data;
2370  p = rt->flv_data + old_flv_size;
2371 
2372  /* copy data while rewriting timestamps */
2373  ts = pkt->timestamp;
2374 
2375  while (next - pkt->data < pkt->size - RTMP_HEADER) {
2376  type = bytestream_get_byte(&next);
2377  size = bytestream_get_be24(&next);
2378  cts = bytestream_get_be24(&next);
2379  cts |= bytestream_get_byte(&next) << 24;
2380  if (!pts)
2381  pts = cts;
2382  ts += cts - pts;
2383  pts = cts;
2384  if (size + 3 + 4 > pkt->data + pkt->size - next)
2385  break;
2386  bytestream_put_byte(&p, type);
2387  bytestream_put_be24(&p, size);
2388  bytestream_put_be24(&p, ts);
2389  bytestream_put_byte(&p, ts >> 24);
2390  memcpy(p, next, size + 3 + 4);
2391  next += size + 3 + 4;
2392  p += size + 3 + 4;
2393  }
2394  if (p != rt->flv_data + rt->flv_size) {
2395  av_log(NULL, AV_LOG_WARNING, "Incomplete flv packets in "
2396  "RTMP_PT_METADATA packet\n");
2397  rt->flv_size = p - rt->flv_data;
2398  }
2399 
2400  return 0;
2401 }
2402 
2403 /**
2404  * Interact with the server by receiving and sending RTMP packets until
2405  * there is some significant data (media data or expected status notification).
2406  *
2407  * @param s reading context
2408  * @param for_header non-zero value tells function to work until it
2409  * gets notification from the server that playing has been started,
2410  * otherwise function will work until some media data is received (or
2411  * an error happens)
2412  * @return 0 for successful operation, negative value in case of error
2413  */
2414 static int get_packet(URLContext *s, int for_header)
2415 {
2416  RTMPContext *rt = s->priv_data;
2417  int ret;
2418 
2419  if (rt->state == STATE_STOPPED)
2420  return AVERROR_EOF;
2421 
2422  for (;;) {
2423  RTMPPacket rpkt = { 0 };
2424  if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
2425  rt->in_chunk_size, &rt->prev_pkt[0],
2426  &rt->nb_prev_pkt[0])) <= 0) {
2427  if (ret == 0) {
2428  return AVERROR(EAGAIN);
2429  } else {
2430  return AVERROR(EIO);
2431  }
2432  }
2433 
2434  // Track timestamp for later use
2435  rt->last_timestamp = rpkt.timestamp;
2436 
2437  rt->bytes_read += ret;
2438  if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) {
2439  av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
2440  if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
2441  return ret;
2442  rt->last_bytes_read = rt->bytes_read;
2443  }
2444 
2445  ret = rtmp_parse_result(s, rt, &rpkt);
2446 
2447  // At this point we must check if we are in the seek state and continue
2448  // with the next packet. handle_invoke will get us out of this state
2449  // when the right message is encountered
2450  if (rt->state == STATE_SEEKING) {
2451  ff_rtmp_packet_destroy(&rpkt);
2452  // We continue, let the natural flow of things happen:
2453  // AVERROR(EAGAIN) or handle_invoke gets us out of here
2454  continue;
2455  }
2456 
2457  if (ret < 0) {//serious error in current packet
2458  ff_rtmp_packet_destroy(&rpkt);
2459  return ret;
2460  }
2461  if (rt->do_reconnect && for_header) {
2462  ff_rtmp_packet_destroy(&rpkt);
2463  return 0;
2464  }
2465  if (rt->state == STATE_STOPPED) {
2466  ff_rtmp_packet_destroy(&rpkt);
2467  return AVERROR_EOF;
2468  }
2469  if (for_header && (rt->state == STATE_PLAYING ||
2470  rt->state == STATE_PUBLISHING ||
2471  rt->state == STATE_SENDING ||
2472  rt->state == STATE_RECEIVING)) {
2473  ff_rtmp_packet_destroy(&rpkt);
2474  return 0;
2475  }
2476  if (!rpkt.size || !rt->is_input) {
2477  ff_rtmp_packet_destroy(&rpkt);
2478  continue;
2479  }
2480  if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO) {
2481  ret = append_flv_data(rt, &rpkt, 0);
2482  ff_rtmp_packet_destroy(&rpkt);
2483  return ret;
2484  } else if (rpkt.type == RTMP_PT_NOTIFY) {
2485  ret = handle_notify(s, &rpkt);
2486  ff_rtmp_packet_destroy(&rpkt);
2487  return ret;
2488  } else if (rpkt.type == RTMP_PT_METADATA) {
2489  ret = handle_metadata(rt, &rpkt);
2490  ff_rtmp_packet_destroy(&rpkt);
2491  return 0;
2492  }
2493  ff_rtmp_packet_destroy(&rpkt);
2494  }
2495 }
2496 
2497 static int rtmp_close(URLContext *h)
2498 {
2499  RTMPContext *rt = h->priv_data;
2500  int ret = 0, i, j;
2501 
2502  if (!rt->is_input) {
2503  rt->flv_data = NULL;
2504  if (rt->out_pkt.size)
2506  if (rt->state > STATE_FCPUBLISH)
2507  ret = gen_fcunpublish_stream(h, rt);
2508  }
2509  if (rt->state > STATE_HANDSHAKED)
2510  ret = gen_delete_stream(h, rt);
2511  for (i = 0; i < 2; i++) {
2512  for (j = 0; j < rt->nb_prev_pkt[i]; j++)
2513  ff_rtmp_packet_destroy(&rt->prev_pkt[i][j]);
2514  av_freep(&rt->prev_pkt[i]);
2515  }
2516 
2518  av_freep(&rt->flv_data);
2519  ffurl_close(rt->stream);
2520  return ret;
2521 }
2522 
2523 /**
2524  * Insert a fake onMetadata packet into the FLV stream to notify the FLV
2525  * demuxer about the duration of the stream.
2526  *
2527  * This should only be done if there was no real onMetadata packet sent by the
2528  * server at the start of the stream and if we were able to retrieve a valid
2529  * duration via a getStreamLength call.
2530  *
2531  * @return 0 for successful operation, negative value in case of error
2532  */
2534 {
2535  // We need to insert the metdata packet directly after the FLV
2536  // header, i.e. we need to move all other already read data by the
2537  // size of our fake metadata packet.
2538 
2539  uint8_t* p;
2540  // Keep old flv_data pointer
2541  uint8_t* old_flv_data = rt->flv_data;
2542  // Allocate a new flv_data pointer with enough space for the additional package
2543  if (!(rt->flv_data = av_malloc(rt->flv_size + 55))) {
2544  rt->flv_data = old_flv_data;
2545  return AVERROR(ENOMEM);
2546  }
2547 
2548  // Copy FLV header
2549  memcpy(rt->flv_data, old_flv_data, 13);
2550  // Copy remaining packets
2551  memcpy(rt->flv_data + 13 + 55, old_flv_data + 13, rt->flv_size - 13);
2552  // Increase the size by the injected packet
2553  rt->flv_size += 55;
2554  // Delete the old FLV data
2555  av_free(old_flv_data);
2556 
2557  p = rt->flv_data + 13;
2558  bytestream_put_byte(&p, FLV_TAG_TYPE_META);
2559  bytestream_put_be24(&p, 40); // size of data part (sum of all parts below)
2560  bytestream_put_be24(&p, 0); // timestamp
2561  bytestream_put_be32(&p, 0); // reserved
2562 
2563  // first event name as a string
2564  bytestream_put_byte(&p, AMF_DATA_TYPE_STRING);
2565  // "onMetaData" as AMF string
2566  bytestream_put_be16(&p, 10);
2567  bytestream_put_buffer(&p, "onMetaData", 10);
2568 
2569  // mixed array (hash) with size and string/type/data tuples
2570  bytestream_put_byte(&p, AMF_DATA_TYPE_MIXEDARRAY);
2571  bytestream_put_be32(&p, 1); // metadata_count
2572 
2573  // "duration" as AMF string
2574  bytestream_put_be16(&p, 8);
2575  bytestream_put_buffer(&p, "duration", 8);
2576  bytestream_put_byte(&p, AMF_DATA_TYPE_NUMBER);
2577  bytestream_put_be64(&p, av_double2int(rt->duration));
2578 
2579  // Finalise object
2580  bytestream_put_be16(&p, 0); // Empty string
2581  bytestream_put_byte(&p, AMF_END_OF_OBJECT);
2582  bytestream_put_be32(&p, 40); // size of data part (sum of all parts below)
2583 
2584  return 0;
2585 }
2586 
2587 /**
2588  * Open RTMP connection and verify that the stream can be played.
2589  *
2590  * URL syntax: rtmp://server[:port][/app][/playpath]
2591  * where 'app' is first one or two directories in the path
2592  * (e.g. /ondemand/, /flash/live/, etc.)
2593  * and 'playpath' is a file name (the rest of the path,
2594  * may be prefixed with "mp4:")
2595  */
2596 static int rtmp_open(URLContext *s, const char *uri, int flags)
2597 {
2598  RTMPContext *rt = s->priv_data;
2599  char proto[8], hostname[256], path[1024], auth[100], *fname;
2600  char *old_app, *qmark, *n, fname_buffer[1024];
2601  uint8_t buf[2048];
2602  int port;
2603  AVDictionary *opts = NULL;
2604  int ret;
2605 
2606  if (rt->listen_timeout > 0)
2607  rt->listen = 1;
2608 
2609  rt->is_input = !(flags & AVIO_FLAG_WRITE);
2610 
2611  av_url_split(proto, sizeof(proto), auth, sizeof(auth),
2612  hostname, sizeof(hostname), &port,
2613  path, sizeof(path), s->filename);
2614 
2615  n = strchr(path, ' ');
2616  if (n) {
2618  "Detected librtmp style URL parameters, these aren't supported "
2619  "by the libavformat internal RTMP handler currently enabled. "
2620  "See the documentation for the correct way to pass parameters.\n");
2621  *n = '\0'; // Trim not supported part
2622  }
2623 
2624  if (auth[0]) {
2625  char *ptr = strchr(auth, ':');
2626  if (ptr) {
2627  *ptr = '\0';
2628  av_strlcpy(rt->username, auth, sizeof(rt->username));
2629  av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
2630  }
2631  }
2632 
2633  if (rt->listen && strcmp(proto, "rtmp")) {
2634  av_log(s, AV_LOG_ERROR, "rtmp_listen not available for %s\n",
2635  proto);
2636  return AVERROR(EINVAL);
2637  }
2638  if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
2639  if (!strcmp(proto, "rtmpts"))
2640  av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
2641 
2642  /* open the http tunneling connection */
2643  ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
2644  } else if (!strcmp(proto, "rtmps")) {
2645  /* open the tls connection */
2646  if (port < 0)
2647  port = RTMPS_DEFAULT_PORT;
2648  ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
2649  } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
2650  if (!strcmp(proto, "rtmpte"))
2651  av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
2652 
2653  /* open the encrypted connection */
2654  ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
2655  rt->encrypted = 1;
2656  } else {
2657  /* open the tcp connection */
2658  if (port < 0)
2659  port = RTMP_DEFAULT_PORT;
2660  if (rt->listen)
2661  ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port,
2662  "?listen&listen_timeout=%d",
2663  rt->listen_timeout * 1000);
2664  else
2665  ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
2666  }
2667 
2668 reconnect:
2669  if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
2670  &s->interrupt_callback, &opts)) < 0) {
2671  av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
2672  goto fail;
2673  }
2674 
2675  if (rt->swfverify) {
2676  if ((ret = rtmp_calc_swfhash(s)) < 0)
2677  goto fail;
2678  }
2679 
2680  rt->state = STATE_START;
2681  if (!rt->listen && (ret = rtmp_handshake(s, rt)) < 0)
2682  goto fail;
2683  if (rt->listen && (ret = rtmp_server_handshake(s, rt)) < 0)
2684  goto fail;
2685 
2686  rt->out_chunk_size = 128;
2687  rt->in_chunk_size = 128; // Probably overwritten later
2688  rt->state = STATE_HANDSHAKED;
2689 
2690  // Keep the application name when it has been defined by the user.
2691  old_app = rt->app;
2692 
2693  rt->app = av_malloc(APP_MAX_LENGTH);
2694  if (!rt->app) {
2695  ret = AVERROR(ENOMEM);
2696  goto fail;
2697  }
2698 
2699  //extract "app" part from path
2700  qmark = strchr(path, '?');
2701  if (qmark && strstr(qmark, "slist=")) {
2702  char* amp;
2703  // After slist we have the playpath, before the params, the app
2704  av_strlcpy(rt->app, path + 1, FFMIN(qmark - path, APP_MAX_LENGTH));
2705  fname = strstr(path, "slist=") + 6;
2706  // Strip any further query parameters from fname
2707  amp = strchr(fname, '&');
2708  if (amp) {
2709  av_strlcpy(fname_buffer, fname, FFMIN(amp - fname + 1,
2710  sizeof(fname_buffer)));
2711  fname = fname_buffer;
2712  }
2713  } else if (!strncmp(path, "/ondemand/", 10)) {
2714  fname = path + 10;
2715  memcpy(rt->app, "ondemand", 9);
2716  } else {
2717  char *next = *path ? path + 1 : path;
2718  char *p = strchr(next, '/');
2719  if (!p) {
2720  if (old_app) {
2721  // If name of application has been defined by the user, assume that
2722  // playpath is provided in the URL
2723  fname = next;
2724  } else {
2725  fname = NULL;
2726  av_strlcpy(rt->app, next, APP_MAX_LENGTH);
2727  }
2728  } else {
2729  // make sure we do not mismatch a playpath for an application instance
2730  char *c = strchr(p + 1, ':');
2731  fname = strchr(p + 1, '/');
2732  if (!fname || (c && c < fname)) {
2733  fname = p + 1;
2734  av_strlcpy(rt->app, path + 1, FFMIN(p - path, APP_MAX_LENGTH));
2735  } else {
2736  fname++;
2737  av_strlcpy(rt->app, path + 1, FFMIN(fname - path - 1, APP_MAX_LENGTH));
2738  }
2739  }
2740  }
2741 
2742  if (old_app) {
2743  // The name of application has been defined by the user, override it.
2744  if (strlen(old_app) >= APP_MAX_LENGTH) {
2745  ret = AVERROR(EINVAL);
2746  goto fail;
2747  }
2748  av_free(rt->app);
2749  rt->app = old_app;
2750  }
2751 
2752  if (!rt->playpath) {
2754  if (!rt->playpath) {
2755  ret = AVERROR(ENOMEM);
2756  goto fail;
2757  }
2758 
2759  if (fname) {
2760  int len = strlen(fname);
2761  if (!strchr(fname, ':') && len >= 4 &&
2762  (!strcmp(fname + len - 4, ".f4v") ||
2763  !strcmp(fname + len - 4, ".mp4"))) {
2764  memcpy(rt->playpath, "mp4:", 5);
2765  } else {
2766  if (len >= 4 && !strcmp(fname + len - 4, ".flv"))
2767  fname[len - 4] = '\0';
2768  rt->playpath[0] = 0;
2769  }
2771  } else {
2772  rt->playpath[0] = '\0';
2773  }
2774  }
2775 
2776  if (!rt->tcurl) {
2778  if (!rt->tcurl) {
2779  ret = AVERROR(ENOMEM);
2780  goto fail;
2781  }
2782  ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
2783  port, "/%s", rt->app);
2784  }
2785 
2786  if (!rt->flashver) {
2788  if (!rt->flashver) {
2789  ret = AVERROR(ENOMEM);
2790  goto fail;
2791  }
2792  if (rt->is_input) {
2793  snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
2796  } else {
2798  "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
2799  }
2800  }
2801 
2802  rt->client_report_size = 1048576;
2803  rt->bytes_read = 0;
2804  rt->has_audio = 0;
2805  rt->has_video = 0;
2806  rt->received_metadata = 0;
2807  rt->last_bytes_read = 0;
2808  rt->server_bw = 2500000;
2809  rt->duration = 0;
2810 
2811  av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
2812  proto, path, rt->app, rt->playpath);
2813  if (!rt->listen) {
2814  if ((ret = gen_connect(s, rt)) < 0)
2815  goto fail;
2816  } else {
2817  if ((ret = read_connect(s, s->priv_data)) < 0)
2818  goto fail;
2819  }
2820 
2821  do {
2822  ret = get_packet(s, 1);
2823  } while (ret == AVERROR(EAGAIN));
2824  if (ret < 0)
2825  goto fail;
2826 
2827  if (rt->do_reconnect) {
2828  int i;
2829  ffurl_close(rt->stream);
2830  rt->stream = NULL;
2831  rt->do_reconnect = 0;
2832  rt->nb_invokes = 0;
2833  for (i = 0; i < 2; i++)
2834  memset(rt->prev_pkt[i], 0,
2835  sizeof(**rt->prev_pkt) * rt->nb_prev_pkt[i]);
2837  goto reconnect;
2838  }
2839 
2840  if (rt->is_input) {
2841  // generate FLV header for demuxer
2842  rt->flv_size = 13;
2843  if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
2844  goto fail;
2845  rt->flv_off = 0;
2846  memcpy(rt->flv_data, "FLV\1\0\0\0\0\011\0\0\0\0", rt->flv_size);
2847 
2848  // Read packets until we reach the first A/V packet or read metadata.
2849  // If there was a metadata package in front of the A/V packets, we can
2850  // build the FLV header from this. If we do not receive any metadata,
2851  // the FLV decoder will allocate the needed streams when their first
2852  // audio or video packet arrives.
2853  while (!rt->has_audio && !rt->has_video && !rt->received_metadata) {
2854  if ((ret = get_packet(s, 0)) < 0)
2855  goto fail;
2856  }
2857 
2858  // Either after we have read the metadata or (if there is none) the
2859  // first packet of an A/V stream, we have a better knowledge about the
2860  // streams, so set the FLV header accordingly.
2861  if (rt->has_audio) {
2863  }
2864  if (rt->has_video) {
2866  }
2867 
2868  // If we received the first packet of an A/V stream and no metadata but
2869  // the server returned a valid duration, create a fake metadata packet
2870  // to inform the FLV decoder about the duration.
2871  if (!rt->received_metadata && rt->duration > 0) {
2872  if ((ret = inject_fake_duration_metadata(rt)) < 0)
2873  goto fail;
2874  }
2875  } else {
2876  rt->flv_size = 0;
2877  rt->flv_data = NULL;
2878  rt->flv_off = 0;
2879  rt->skip_bytes = 13;
2880  }
2881 
2883  s->is_streamed = 1;
2884  return 0;
2885 
2886 fail:
2887  av_dict_free(&opts);
2888  rtmp_close(s);
2889  return ret;
2890 }
2891 
2892 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
2893 {
2894  RTMPContext *rt = s->priv_data;
2895  int orig_size = size;
2896  int ret;
2897 
2898  while (size > 0) {
2899  int data_left = rt->flv_size - rt->flv_off;
2900 
2901  if (data_left >= size) {
2902  memcpy(buf, rt->flv_data + rt->flv_off, size);
2903  rt->flv_off += size;
2904  return orig_size;
2905  }
2906  if (data_left > 0) {
2907  memcpy(buf, rt->flv_data + rt->flv_off, data_left);
2908  buf += data_left;
2909  size -= data_left;
2910  rt->flv_off = rt->flv_size;
2911  return data_left;
2912  }
2913  if ((ret = get_packet(s, 0)) < 0)
2914  return ret;
2915  }
2916  return orig_size;
2917 }
2918 
2919 static int64_t rtmp_seek(URLContext *s, int stream_index, int64_t timestamp,
2920  int flags)
2921 {
2922  RTMPContext *rt = s->priv_data;
2923  int ret;
2924  av_log(s, AV_LOG_DEBUG,
2925  "Seek on stream index %d at timestamp %"PRId64" with flags %08x\n",
2926  stream_index, timestamp, flags);
2927  if ((ret = gen_seek(s, rt, timestamp)) < 0) {
2928  av_log(s, AV_LOG_ERROR,
2929  "Unable to send seek command on stream index %d at timestamp "
2930  "%"PRId64" with flags %08x\n",
2931  stream_index, timestamp, flags);
2932  return ret;
2933  }
2934  rt->flv_off = rt->flv_size;
2935  rt->state = STATE_SEEKING;
2936  return timestamp;
2937 }
2938 
2939 static int rtmp_pause(URLContext *s, int pause)
2940 {
2941  RTMPContext *rt = s->priv_data;
2942  int ret;
2943  av_log(s, AV_LOG_DEBUG, "Pause at timestamp %d\n",
2944  rt->last_timestamp);
2945  if ((ret = gen_pause(s, rt, pause, rt->last_timestamp)) < 0) {
2946  av_log(s, AV_LOG_ERROR, "Unable to send pause command at timestamp %d\n",
2947  rt->last_timestamp);
2948  return ret;
2949  }
2950  return 0;
2951 }
2952 
2953 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
2954 {
2955  RTMPContext *rt = s->priv_data;
2956  int size_temp = size;
2957  int pktsize, pkttype;
2958  uint32_t ts;
2959  const uint8_t *buf_temp = buf;
2960  uint8_t c;
2961  int ret;
2962 
2963  do {
2964  if (rt->skip_bytes) {
2965  int skip = FFMIN(rt->skip_bytes, size_temp);
2966  buf_temp += skip;
2967  size_temp -= skip;
2968  rt->skip_bytes -= skip;
2969  continue;
2970  }
2971 
2972  if (rt->flv_header_bytes < RTMP_HEADER) {
2973  int set_data_frame = 0;
2974  const uint8_t *header = rt->flv_header;
2975  int copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp);
2976  int channel = RTMP_AUDIO_CHANNEL;
2977 
2978  bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
2979  rt->flv_header_bytes += copy;
2980  size_temp -= copy;
2981  if (rt->flv_header_bytes < RTMP_HEADER)
2982  break;
2983 
2984  pkttype = bytestream_get_byte(&header);
2985  pktsize = bytestream_get_be24(&header);
2986  ts = bytestream_get_be24(&header);
2987  ts |= bytestream_get_byte(&header) << 24;
2988  bytestream_get_be24(&header);
2989  rt->flv_size = pktsize;
2990 
2991  if (pkttype == RTMP_PT_VIDEO)
2992  channel = RTMP_VIDEO_CHANNEL;
2993 
2994  if (pkttype == RTMP_PT_NOTIFY) {
2995  // For onMetaData and |RtmpSampleAccess packets, we want
2996  // @setDataFrame prepended to the packet before it gets sent.
2997  // However, definitely not *all* RTMP_PT_NOTIFY packets (e.g.,
2998  // onTextData and onCuePoint).
2999  uint8_t commandbuffer[64];
3000  int stringlen = 0, commandsize = size - rt->flv_header_bytes;
3001  GetByteContext gbc;
3002 
3003  // buf_temp at this point should be pointing to the RTMP command
3004  bytestream2_init(&gbc, buf_temp, commandsize);
3005  if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
3006  &stringlen))
3007  return AVERROR_INVALIDDATA;
3008 
3009  if (!strcmp(commandbuffer, "onMetaData") ||
3010  !strcmp(commandbuffer, "|RtmpSampleAccess")) {
3011  set_data_frame = 1;
3012  }
3013  }
3014 
3015  if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
3016  pkttype == RTMP_PT_NOTIFY) {
3017  // add 12 bytes header if passing @setDataFrame
3018  if (set_data_frame)
3019  pktsize += 16;
3020  if ((ret = ff_rtmp_check_alloc_array(&rt->prev_pkt[1],
3021  &rt->nb_prev_pkt[1],
3022  channel)) < 0)
3023  return ret;
3024  rt->prev_pkt[1][channel].channel_id = 0;
3025  }
3026 
3027  //this can be a big packet, it's better to send it right here
3028  if ((ret = ff_rtmp_packet_create(&rt->out_pkt, channel,
3029  pkttype, ts, pktsize)) < 0)
3030  return ret;
3031 
3032  rt->out_pkt.extra = rt->stream_id;
3033  rt->flv_data = rt->out_pkt.data;
3034 
3035  if (set_data_frame) {
3036  ff_amf_write_string(&rt->flv_data, "@setDataFrame");
3037  }
3038  }
3039 
3040  if (rt->flv_size - rt->flv_off > size_temp) {
3041  bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
3042  rt->flv_off += size_temp;
3043  size_temp = 0;
3044  } else {
3045  bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
3046  size_temp -= rt->flv_size - rt->flv_off;
3047  rt->flv_off += rt->flv_size - rt->flv_off;
3048  }
3049 
3050  if (rt->flv_off == rt->flv_size) {
3051  rt->skip_bytes = 4;
3052 
3053  if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
3054  return ret;
3055  rt->flv_size = 0;
3056  rt->flv_off = 0;
3057  rt->flv_header_bytes = 0;
3058  rt->flv_nb_packets++;
3059  }
3060  } while (buf_temp - buf < size);
3061 
3062  if (rt->flv_nb_packets < rt->flush_interval)
3063  return size;
3064  rt->flv_nb_packets = 0;
3065 
3066  /* set stream into nonblocking mode */
3068 
3069  /* try to read one byte from the stream */
3070  ret = ffurl_read(rt->stream, &c, 1);
3071 
3072  /* switch the stream back into blocking mode */
3073  rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
3074 
3075  if (ret == AVERROR(EAGAIN)) {
3076  /* no incoming data to handle */
3077  return size;
3078  } else if (ret < 0) {
3079  return ret;
3080  } else if (ret == 1) {
3081  RTMPPacket rpkt = { 0 };
3082 
3083  if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
3084  rt->in_chunk_size,
3085  &rt->prev_pkt[0],
3086  &rt->nb_prev_pkt[0], c)) <= 0)
3087  return ret;
3088 
3089  if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
3090  return ret;
3091 
3092  ff_rtmp_packet_destroy(&rpkt);
3093  }
3094 
3095  return size;
3096 }
3097 
3098 #define OFFSET(x) offsetof(RTMPContext, x)
3099 #define DEC AV_OPT_FLAG_DECODING_PARAM
3100 #define ENC AV_OPT_FLAG_ENCODING_PARAM
3101 
3102 static const AVOption rtmp_options[] = {
3103  {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3104  {"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},
3105  {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3106  {"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},
3107  {"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},
3108  {"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"},
3109  {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
3110  {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
3111  {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
3112  {"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},
3113  {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3114  {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
3115  {"rtmp_swfhash", "SHA256 hash of the decompressed SWF file (32 bytes).", OFFSET(swfhash), AV_OPT_TYPE_BINARY, .flags = DEC},
3116  {"rtmp_swfsize", "Size of the decompressed SWF file, required for SWFVerification.", OFFSET(swfsize), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC},
3117  {"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},
3118  {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically.", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
3119  {"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},
3120  {"rtmp_listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
3121  {"listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
3122  {"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" },
3123  { NULL },
3124 };
3125 
3126 #define RTMP_PROTOCOL(flavor) \
3127 static const AVClass flavor##_class = { \
3128  .class_name = #flavor, \
3129  .item_name = av_default_item_name, \
3130  .option = rtmp_options, \
3131  .version = LIBAVUTIL_VERSION_INT, \
3132 }; \
3133  \
3134 URLProtocol ff_##flavor##_protocol = { \
3135  .name = #flavor, \
3136  .url_open = rtmp_open, \
3137  .url_read = rtmp_read, \
3138  .url_read_seek = rtmp_seek, \
3139  .url_read_pause = rtmp_pause, \
3140  .url_write = rtmp_write, \
3141  .url_close = rtmp_close, \
3142  .priv_data_size = sizeof(RTMPContext), \
3143  .flags = URL_PROTOCOL_FLAG_NETWORK, \
3144  .priv_data_class= &flavor##_class, \
3145 };
3146 
3147 
3148 RTMP_PROTOCOL(rtmp)
3149 RTMP_PROTOCOL(rtmpe)
3150 RTMP_PROTOCOL(rtmps)
3151 RTMP_PROTOCOL(rtmpt)
3152 RTMP_PROTOCOL(rtmpte)
3153 RTMP_PROTOCOL(rtmpts)