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, "connect")) {
1826  ret = handle_connect_error(s, tmpstr);
1827  if (!ret) {
1828  rt->do_reconnect = 1;
1829  level = AV_LOG_VERBOSE;
1830  }
1831  } else
1832  ret = AVERROR_UNKNOWN;
1833  av_log(s, level, "Server error: %s\n", tmpstr);
1834  }
1835 
1836  av_free(tracked_method);
1837  return ret;
1838 }
1839 
1841 {
1842  RTMPContext *rt = s->priv_data;
1843  PutByteContext pbc;
1844  RTMPPacket spkt = { 0 };
1845  int ret;
1846 
1847  // Send Stream Begin 1
1848  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_NETWORK_CHANNEL,
1849  RTMP_PT_PING, 0, 6)) < 0) {
1850  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1851  return ret;
1852  }
1853 
1854  bytestream2_init_writer(&pbc, spkt.data, spkt.size);
1855  bytestream2_put_be16(&pbc, 0); // 0 -> Stream Begin
1856  bytestream2_put_be32(&pbc, rt->nb_streamid);
1857 
1858  ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1859  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1860 
1861  ff_rtmp_packet_destroy(&spkt);
1862 
1863  return ret;
1864 }
1865 
1867  const char *status, const char *filename)
1868 {
1869  RTMPContext *rt = s->priv_data;
1870  RTMPPacket spkt = { 0 };
1871  char statusmsg[128];
1872  uint8_t *pp;
1873  int ret;
1874 
1875  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1876  RTMP_PT_INVOKE, 0,
1877  RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1878  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1879  return ret;
1880  }
1881 
1882  pp = spkt.data;
1883  spkt.extra = pkt->extra;
1884  ff_amf_write_string(&pp, "onStatus");
1885  ff_amf_write_number(&pp, 0);
1886  ff_amf_write_null(&pp);
1887 
1889  ff_amf_write_field_name(&pp, "level");
1890  ff_amf_write_string(&pp, "status");
1891  ff_amf_write_field_name(&pp, "code");
1892  ff_amf_write_string(&pp, status);
1893  ff_amf_write_field_name(&pp, "description");
1894  snprintf(statusmsg, sizeof(statusmsg),
1895  "%s is now published", filename);
1896  ff_amf_write_string(&pp, statusmsg);
1897  ff_amf_write_field_name(&pp, "details");
1898  ff_amf_write_string(&pp, filename);
1899  ff_amf_write_field_name(&pp, "clientid");
1900  snprintf(statusmsg, sizeof(statusmsg), "%s", LIBAVFORMAT_IDENT);
1901  ff_amf_write_string(&pp, statusmsg);
1903 
1904  spkt.size = pp - spkt.data;
1905  ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
1906  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
1907  ff_rtmp_packet_destroy(&spkt);
1908 
1909  return ret;
1910 }
1911 
1913 {
1914  RTMPContext *rt = s->priv_data;
1915  double seqnum;
1916  char filename[64];
1917  char command[64];
1918  int stringlen;
1919  char *pchar;
1920  const uint8_t *p = pkt->data;
1921  uint8_t *pp = NULL;
1922  RTMPPacket spkt = { 0 };
1923  GetByteContext gbc;
1924  int ret;
1925 
1926  bytestream2_init(&gbc, p, pkt->size);
1927  if (ff_amf_read_string(&gbc, command, sizeof(command),
1928  &stringlen)) {
1929  av_log(s, AV_LOG_ERROR, "Error in PT_INVOKE\n");
1930  return AVERROR_INVALIDDATA;
1931  }
1932 
1933  ret = ff_amf_read_number(&gbc, &seqnum);
1934  if (ret)
1935  return ret;
1936  ret = ff_amf_read_null(&gbc);
1937  if (ret)
1938  return ret;
1939  if (!strcmp(command, "FCPublish") ||
1940  !strcmp(command, "publish")) {
1941  ret = ff_amf_read_string(&gbc, filename,
1942  sizeof(filename), &stringlen);
1943  // check with url
1944  if (s->filename) {
1945  pchar = strrchr(s->filename, '/');
1946  if (!pchar) {
1948  "Unable to find / in url %s, bad format\n",
1949  s->filename);
1950  pchar = s->filename;
1951  }
1952  pchar++;
1953  if (strcmp(pchar, filename))
1954  av_log(s, AV_LOG_WARNING, "Unexpected stream %s, expecting"
1955  " %s\n", filename, pchar);
1956  }
1957  rt->state = STATE_RECEIVING;
1958  }
1959 
1960  if (!strcmp(command, "FCPublish")) {
1961  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1962  RTMP_PT_INVOKE, 0,
1963  RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1964  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1965  return ret;
1966  }
1967  pp = spkt.data;
1968  ff_amf_write_string(&pp, "onFCPublish");
1969  } else if (!strcmp(command, "publish")) {
1970  ret = write_begin(s);
1971  if (ret < 0)
1972  return ret;
1973 
1974  // Send onStatus(NetStream.Publish.Start)
1975  return write_status(s, pkt, "NetStream.Publish.Start",
1976  filename);
1977  } else if (!strcmp(command, "play")) {
1978  ret = write_begin(s);
1979  if (ret < 0)
1980  return ret;
1981  rt->state = STATE_SENDING;
1982  return write_status(s, pkt, "NetStream.Play.Start",
1983  filename);
1984  } else {
1985  if ((ret = ff_rtmp_packet_create(&spkt, RTMP_SYSTEM_CHANNEL,
1986  RTMP_PT_INVOKE, 0,
1987  RTMP_PKTDATA_DEFAULT_SIZE)) < 0) {
1988  av_log(s, AV_LOG_ERROR, "Unable to create response packet\n");
1989  return ret;
1990  }
1991  pp = spkt.data;
1992  ff_amf_write_string(&pp, "_result");
1993  ff_amf_write_number(&pp, seqnum);
1994  ff_amf_write_null(&pp);
1995  if (!strcmp(command, "createStream")) {
1996  rt->nb_streamid++;
1997  if (rt->nb_streamid == 0 || rt->nb_streamid == 2)
1998  rt->nb_streamid++; /* Values 0 and 2 are reserved */
1999  ff_amf_write_number(&pp, rt->nb_streamid);
2000  /* By now we don't control which streams are removed in
2001  * deleteStream. There is no stream creation control
2002  * if a client creates more than 2^32 - 2 streams. */
2003  }
2004  }
2005  spkt.size = pp - spkt.data;
2006  ret = ff_rtmp_packet_write(rt->stream, &spkt, rt->out_chunk_size,
2007  &rt->prev_pkt[1], &rt->nb_prev_pkt[1]);
2008  ff_rtmp_packet_destroy(&spkt);
2009  return ret;
2010 }
2011 
2012 /**
2013  * Read the AMF_NUMBER response ("_result") to a function call
2014  * (e.g. createStream()). This response should be made up of the AMF_STRING
2015  * "result", a NULL object and then the response encoded as AMF_NUMBER. On a
2016  * successful response, we will return set the value to number (otherwise number
2017  * will not be changed).
2018  *
2019  * @return 0 if reading the value succeeds, negative value otherwiss
2020  */
2021 static int read_number_result(RTMPPacket *pkt, double *number)
2022 {
2023  // We only need to fit "_result" in this.
2024  uint8_t strbuffer[8];
2025  int stringlen;
2026  double numbuffer;
2027  GetByteContext gbc;
2028 
2029  bytestream2_init(&gbc, pkt->data, pkt->size);
2030 
2031  // Value 1/4: "_result" as AMF_STRING
2032  if (ff_amf_read_string(&gbc, strbuffer, sizeof(strbuffer), &stringlen))
2033  return AVERROR_INVALIDDATA;
2034  if (strcmp(strbuffer, "_result"))
2035  return AVERROR_INVALIDDATA;
2036  // Value 2/4: The callee reference number
2037  if (ff_amf_read_number(&gbc, &numbuffer))
2038  return AVERROR_INVALIDDATA;
2039  // Value 3/4: Null
2040  if (ff_amf_read_null(&gbc))
2041  return AVERROR_INVALIDDATA;
2042  // Value 4/4: The resonse as AMF_NUMBER
2043  if (ff_amf_read_number(&gbc, &numbuffer))
2044  return AVERROR_INVALIDDATA;
2045  else
2046  *number = numbuffer;
2047 
2048  return 0;
2049 }
2050 
2052 {
2053  RTMPContext *rt = s->priv_data;
2054  char *tracked_method = NULL;
2055  int ret = 0;
2056 
2057  if ((ret = find_tracked_method(s, pkt, 10, &tracked_method)) < 0)
2058  return ret;
2059 
2060  if (!tracked_method) {
2061  /* Ignore this reply when the current method is not tracked. */
2062  return ret;
2063  }
2064 
2065  if (!strcmp(tracked_method, "connect")) {
2066  if (!rt->is_input) {
2067  if ((ret = gen_release_stream(s, rt)) < 0)
2068  goto fail;
2069 
2070  if ((ret = gen_fcpublish_stream(s, rt)) < 0)
2071  goto fail;
2072  } else {
2073  if ((ret = gen_server_bw(s, rt)) < 0)
2074  goto fail;
2075  }
2076 
2077  if ((ret = gen_create_stream(s, rt)) < 0)
2078  goto fail;
2079 
2080  if (rt->is_input) {
2081  /* Send the FCSubscribe command when the name of live
2082  * stream is defined by the user or if it's a live stream. */
2083  if (rt->subscribe) {
2084  if ((ret = gen_fcsubscribe_stream(s, rt, rt->subscribe)) < 0)
2085  goto fail;
2086  } else if (rt->live == -1) {
2087  if ((ret = gen_fcsubscribe_stream(s, rt, rt->playpath)) < 0)
2088  goto fail;
2089  }
2090  }
2091  } else if (!strcmp(tracked_method, "createStream")) {
2092  double stream_id;
2093  if (read_number_result(pkt, &stream_id)) {
2094  av_log(s, AV_LOG_WARNING, "Unexpected reply on connect()\n");
2095  } else {
2096  rt->stream_id = stream_id;
2097  }
2098 
2099  if (!rt->is_input) {
2100  if ((ret = gen_publish(s, rt)) < 0)
2101  goto fail;
2102  } else {
2103  if (rt->live != -1) {
2104  if ((ret = gen_get_stream_length(s, rt)) < 0)
2105  goto fail;
2106  }
2107  if ((ret = gen_play(s, rt)) < 0)
2108  goto fail;
2109  if ((ret = gen_buffer_time(s, rt)) < 0)
2110  goto fail;
2111  }
2112  } else if (!strcmp(tracked_method, "getStreamLength")) {
2113  if (read_number_result(pkt, &rt->duration)) {
2114  av_log(s, AV_LOG_WARNING, "Unexpected reply on getStreamLength()\n");
2115  }
2116  }
2117 
2118 fail:
2119  av_free(tracked_method);
2120  return ret;
2121 }
2122 
2124 {
2125  RTMPContext *rt = s->priv_data;
2126  const uint8_t *data_end = pkt->data + pkt->size;
2127  const uint8_t *ptr = pkt->data + RTMP_HEADER;
2128  uint8_t tmpstr[256];
2129  int i, t;
2130 
2131  for (i = 0; i < 2; i++) {
2132  t = ff_amf_tag_size(ptr, data_end);
2133  if (t < 0)
2134  return 1;
2135  ptr += t;
2136  }
2137 
2138  t = ff_amf_get_field_value(ptr, data_end, "level", tmpstr, sizeof(tmpstr));
2139  if (!t && !strcmp(tmpstr, "error")) {
2140  t = ff_amf_get_field_value(ptr, data_end,
2141  "description", tmpstr, sizeof(tmpstr));
2142  if (t || !tmpstr[0])
2143  t = ff_amf_get_field_value(ptr, data_end, "code",
2144  tmpstr, sizeof(tmpstr));
2145  if (!t)
2146  av_log(s, AV_LOG_ERROR, "Server error: %s\n", tmpstr);
2147  return -1;
2148  }
2149 
2150  t = ff_amf_get_field_value(ptr, data_end, "code", tmpstr, sizeof(tmpstr));
2151  if (!t && !strcmp(tmpstr, "NetStream.Play.Start")) rt->state = STATE_PLAYING;
2152  if (!t && !strcmp(tmpstr, "NetStream.Play.Stop")) rt->state = STATE_STOPPED;
2153  if (!t && !strcmp(tmpstr, "NetStream.Play.UnpublishNotify")) rt->state = STATE_STOPPED;
2154  if (!t && !strcmp(tmpstr, "NetStream.Publish.Start")) rt->state = STATE_PUBLISHING;
2155  if (!t && !strcmp(tmpstr, "NetStream.Seek.Notify")) rt->state = STATE_PLAYING;
2156 
2157  return 0;
2158 }
2159 
2161 {
2162  RTMPContext *rt = s->priv_data;
2163  int ret = 0;
2164 
2165  //TODO: check for the messages sent for wrong state?
2166  if (ff_amf_match_string(pkt->data, pkt->size, "_error")) {
2167  if ((ret = handle_invoke_error(s, pkt)) < 0)
2168  return ret;
2169  } else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) {
2170  if ((ret = handle_invoke_result(s, pkt)) < 0)
2171  return ret;
2172  } else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) {
2173  if ((ret = handle_invoke_status(s, pkt)) < 0)
2174  return ret;
2175  } else if (ff_amf_match_string(pkt->data, pkt->size, "onBWDone")) {
2176  if ((ret = gen_check_bw(s, rt)) < 0)
2177  return ret;
2178  } else if (ff_amf_match_string(pkt->data, pkt->size, "releaseStream") ||
2179  ff_amf_match_string(pkt->data, pkt->size, "FCPublish") ||
2180  ff_amf_match_string(pkt->data, pkt->size, "publish") ||
2181  ff_amf_match_string(pkt->data, pkt->size, "play") ||
2182  ff_amf_match_string(pkt->data, pkt->size, "_checkbw") ||
2183  ff_amf_match_string(pkt->data, pkt->size, "createStream")) {
2184  if ((ret = send_invoke_response(s, pkt)) < 0)
2185  return ret;
2186  }
2187 
2188  return ret;
2189 }
2190 
2191 static int update_offset(RTMPContext *rt, int size)
2192 {
2193  int old_flv_size;
2194 
2195  // generate packet header and put data into buffer for FLV demuxer
2196  if (rt->flv_off < rt->flv_size) {
2197  // There is old unread data in the buffer, thus append at the end
2198  old_flv_size = rt->flv_size;
2199  rt->flv_size += size;
2200  } else {
2201  // All data has been read, write the new data at the start of the buffer
2202  old_flv_size = 0;
2203  rt->flv_size = size;
2204  rt->flv_off = 0;
2205  }
2206 
2207  return old_flv_size;
2208 }
2209 
2210 static int append_flv_data(RTMPContext *rt, RTMPPacket *pkt, int skip)
2211 {
2212  int old_flv_size, ret;
2213  PutByteContext pbc;
2214  const uint8_t *data = pkt->data + skip;
2215  const int size = pkt->size - skip;
2216  uint32_t ts = pkt->timestamp;
2217 
2218  if (pkt->type == RTMP_PT_AUDIO) {
2219  rt->has_audio = 1;
2220  } else if (pkt->type == RTMP_PT_VIDEO) {
2221  rt->has_video = 1;
2222  }
2223 
2224  old_flv_size = update_offset(rt, size + 15);
2225 
2226  if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2227  rt->flv_size = rt->flv_off = 0;
2228  return ret;
2229  }
2230  bytestream2_init_writer(&pbc, rt->flv_data, rt->flv_size);
2231  bytestream2_skip_p(&pbc, old_flv_size);
2232  bytestream2_put_byte(&pbc, pkt->type);
2233  bytestream2_put_be24(&pbc, size);
2234  bytestream2_put_be24(&pbc, ts);
2235  bytestream2_put_byte(&pbc, ts >> 24);
2236  bytestream2_put_be24(&pbc, 0);
2237  bytestream2_put_buffer(&pbc, data, size);
2238  bytestream2_put_be32(&pbc, 0);
2239 
2240  return 0;
2241 }
2242 
2244 {
2245  RTMPContext *rt = s->priv_data;
2246  uint8_t commandbuffer[64];
2247  char statusmsg[128];
2248  int stringlen, ret, skip = 0;
2249  GetByteContext gbc;
2250 
2251  bytestream2_init(&gbc, pkt->data, pkt->size);
2252  if (ff_amf_read_string(&gbc, commandbuffer, sizeof(commandbuffer),
2253  &stringlen))
2254  return AVERROR_INVALIDDATA;
2255 
2256  if (!strcmp(commandbuffer, "onMetaData")) {
2257  // metadata properties should be stored in a mixed array
2258  if (bytestream2_get_byte(&gbc) == AMF_DATA_TYPE_MIXEDARRAY) {
2259  // We have found a metaData Array so flv can determine the streams
2260  // from this.
2261  rt->received_metadata = 1;
2262  // skip 32-bit max array index
2263  bytestream2_skip(&gbc, 4);
2264  while (bytestream2_get_bytes_left(&gbc) > 3) {
2265  if (ff_amf_get_string(&gbc, statusmsg, sizeof(statusmsg),
2266  &stringlen))
2267  return AVERROR_INVALIDDATA;
2268  // We do not care about the content of the property (yet).
2269  stringlen = ff_amf_tag_size(gbc.buffer, gbc.buffer_end);
2270  if (stringlen < 0)
2271  return AVERROR_INVALIDDATA;
2272  bytestream2_skip(&gbc, stringlen);
2273 
2274  // The presence of the following properties indicates that the
2275  // respective streams are present.
2276  if (!strcmp(statusmsg, "videocodecid")) {
2277  rt->has_video = 1;
2278  }
2279  if (!strcmp(statusmsg, "audiocodecid")) {
2280  rt->has_audio = 1;
2281  }
2282  }
2283  if (bytestream2_get_be24(&gbc) != AMF_END_OF_OBJECT)
2284  return AVERROR_INVALIDDATA;
2285  }
2286  }
2287 
2288  // Skip the @setDataFrame string and validate it is a notification
2289  if (!strcmp(commandbuffer, "@setDataFrame")) {
2290  skip = gbc.buffer - pkt->data;
2291  ret = ff_amf_read_string(&gbc, statusmsg,
2292  sizeof(statusmsg), &stringlen);
2293  if (ret < 0)
2294  return AVERROR_INVALIDDATA;
2295  }
2296 
2297  return append_flv_data(rt, pkt, skip);
2298 }
2299 
2300 /**
2301  * Parse received packet and possibly perform some action depending on
2302  * the packet contents.
2303  * @return 0 for no errors, negative values for serious errors which prevent
2304  * further communications, positive values for uncritical errors
2305  */
2307 {
2308  int ret;
2309 
2310 #ifdef DEBUG
2311  ff_rtmp_packet_dump(s, pkt);
2312 #endif
2313 
2314  switch (pkt->type) {
2315  case RTMP_PT_BYTES_READ:
2316  av_dlog(s, "received bytes read report\n");
2317  break;
2318  case RTMP_PT_CHUNK_SIZE:
2319  if ((ret = handle_chunk_size(s, pkt)) < 0)
2320  return ret;
2321  break;
2322  case RTMP_PT_PING:
2323  if ((ret = handle_ping(s, pkt)) < 0)
2324  return ret;
2325  break;
2326  case RTMP_PT_CLIENT_BW:
2327  if ((ret = handle_client_bw(s, pkt)) < 0)
2328  return ret;
2329  break;
2330  case RTMP_PT_SERVER_BW:
2331  if ((ret = handle_server_bw(s, pkt)) < 0)
2332  return ret;
2333  break;
2334  case RTMP_PT_INVOKE:
2335  if ((ret = handle_invoke(s, pkt)) < 0)
2336  return ret;
2337  break;
2338  case RTMP_PT_VIDEO:
2339  case RTMP_PT_AUDIO:
2340  case RTMP_PT_METADATA:
2341  case RTMP_PT_NOTIFY:
2342  /* Audio, Video and Metadata packets are parsed in get_packet() */
2343  break;
2344  default:
2345  av_log(s, AV_LOG_VERBOSE, "Unknown packet type received 0x%02X\n", pkt->type);
2346  break;
2347  }
2348  return 0;
2349 }
2350 
2352 {
2353  int ret, old_flv_size, type;
2354  const uint8_t *next;
2355  uint8_t *p;
2356  uint32_t size;
2357  uint32_t ts, cts, pts = 0;
2358 
2359  old_flv_size = update_offset(rt, pkt->size);
2360 
2361  if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0) {
2362  rt->flv_size = rt->flv_off = 0;
2363  return ret;
2364  }
2365 
2366  next = pkt->data;
2367  p = rt->flv_data + old_flv_size;
2368 
2369  /* copy data while rewriting timestamps */
2370  ts = pkt->timestamp;
2371 
2372  while (next - pkt->data < pkt->size - RTMP_HEADER) {
2373  type = bytestream_get_byte(&next);
2374  size = bytestream_get_be24(&next);
2375  cts = bytestream_get_be24(&next);
2376  cts |= bytestream_get_byte(&next) << 24;
2377  if (!pts)
2378  pts = cts;
2379  ts += cts - pts;
2380  pts = cts;
2381  if (size + 3 + 4 > pkt->data + pkt->size - next)
2382  break;
2383  bytestream_put_byte(&p, type);
2384  bytestream_put_be24(&p, size);
2385  bytestream_put_be24(&p, ts);
2386  bytestream_put_byte(&p, ts >> 24);
2387  memcpy(p, next, size + 3 + 4);
2388  next += size + 3 + 4;
2389  p += size + 3 + 4;
2390  }
2391  if (p != rt->flv_data + rt->flv_size) {
2392  av_log(NULL, AV_LOG_WARNING, "Incomplete flv packets in "
2393  "RTMP_PT_METADATA packet\n");
2394  rt->flv_size = p - rt->flv_data;
2395  }
2396 
2397  return 0;
2398 }
2399 
2400 /**
2401  * Interact with the server by receiving and sending RTMP packets until
2402  * there is some significant data (media data or expected status notification).
2403  *
2404  * @param s reading context
2405  * @param for_header non-zero value tells function to work until it
2406  * gets notification from the server that playing has been started,
2407  * otherwise function will work until some media data is received (or
2408  * an error happens)
2409  * @return 0 for successful operation, negative value in case of error
2410  */
2411 static int get_packet(URLContext *s, int for_header)
2412 {
2413  RTMPContext *rt = s->priv_data;
2414  int ret;
2415 
2416  if (rt->state == STATE_STOPPED)
2417  return AVERROR_EOF;
2418 
2419  for (;;) {
2420  RTMPPacket rpkt = { 0 };
2421  if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,
2422  rt->in_chunk_size, &rt->prev_pkt[0],
2423  &rt->nb_prev_pkt[0])) <= 0) {
2424  if (ret == 0) {
2425  return AVERROR(EAGAIN);
2426  } else {
2427  return AVERROR(EIO);
2428  }
2429  }
2430 
2431  // Track timestamp for later use
2432  rt->last_timestamp = rpkt.timestamp;
2433 
2434  rt->bytes_read += ret;
2435  if (rt->bytes_read - rt->last_bytes_read > rt->client_report_size) {
2436  av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");
2437  if ((ret = gen_bytes_read(s, rt, rpkt.timestamp + 1)) < 0)
2438  return ret;
2439  rt->last_bytes_read = rt->bytes_read;
2440  }
2441 
2442  ret = rtmp_parse_result(s, rt, &rpkt);
2443 
2444  // At this point we must check if we are in the seek state and continue
2445  // with the next packet. handle_invoke will get us out of this state
2446  // when the right message is encountered
2447  if (rt->state == STATE_SEEKING) {
2448  ff_rtmp_packet_destroy(&rpkt);
2449  // We continue, let the natural flow of things happen:
2450  // AVERROR(EAGAIN) or handle_invoke gets us out of here
2451  continue;
2452  }
2453 
2454  if (ret < 0) {//serious error in current packet
2455  ff_rtmp_packet_destroy(&rpkt);
2456  return ret;
2457  }
2458  if (rt->do_reconnect && for_header) {
2459  ff_rtmp_packet_destroy(&rpkt);
2460  return 0;
2461  }
2462  if (rt->state == STATE_STOPPED) {
2463  ff_rtmp_packet_destroy(&rpkt);
2464  return AVERROR_EOF;
2465  }
2466  if (for_header && (rt->state == STATE_PLAYING ||
2467  rt->state == STATE_PUBLISHING ||
2468  rt->state == STATE_SENDING ||
2469  rt->state == STATE_RECEIVING)) {
2470  ff_rtmp_packet_destroy(&rpkt);
2471  return 0;
2472  }
2473  if (!rpkt.size || !rt->is_input) {
2474  ff_rtmp_packet_destroy(&rpkt);
2475  continue;
2476  }
2477  if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO) {
2478  ret = append_flv_data(rt, &rpkt, 0);
2479  ff_rtmp_packet_destroy(&rpkt);
2480  return ret;
2481  } else if (rpkt.type == RTMP_PT_NOTIFY) {
2482  ret = handle_notify(s, &rpkt);
2483  ff_rtmp_packet_destroy(&rpkt);
2484  return ret;
2485  } else if (rpkt.type == RTMP_PT_METADATA) {
2486  ret = handle_metadata(rt, &rpkt);
2487  ff_rtmp_packet_destroy(&rpkt);
2488  return 0;
2489  }
2490  ff_rtmp_packet_destroy(&rpkt);
2491  }
2492 }
2493 
2494 static int rtmp_close(URLContext *h)
2495 {
2496  RTMPContext *rt = h->priv_data;
2497  int ret = 0, i, j;
2498 
2499  if (!rt->is_input) {
2500  rt->flv_data = NULL;
2501  if (rt->out_pkt.size)
2503  if (rt->state > STATE_FCPUBLISH)
2504  ret = gen_fcunpublish_stream(h, rt);
2505  }
2506  if (rt->state > STATE_HANDSHAKED)
2507  ret = gen_delete_stream(h, rt);
2508  for (i = 0; i < 2; i++) {
2509  for (j = 0; j < rt->nb_prev_pkt[i]; j++)
2510  ff_rtmp_packet_destroy(&rt->prev_pkt[i][j]);
2511  av_freep(&rt->prev_pkt[i]);
2512  }
2513 
2515  av_freep(&rt->flv_data);
2516  ffurl_close(rt->stream);
2517  return ret;
2518 }
2519 
2520 /**
2521  * Insert a fake onMetadata packet into the FLV stream to notify the FLV
2522  * demuxer about the duration of the stream.
2523  *
2524  * This should only be done if there was no real onMetadata packet sent by the
2525  * server at the start of the stream and if we were able to retrieve a valid
2526  * duration via a getStreamLength call.
2527  *
2528  * @return 0 for successful operation, negative value in case of error
2529  */
2531 {
2532  // We need to insert the metdata packet directly after the FLV
2533  // header, i.e. we need to move all other already read data by the
2534  // size of our fake metadata packet.
2535 
2536  uint8_t* p;
2537  // Keep old flv_data pointer
2538  uint8_t* old_flv_data = rt->flv_data;
2539  // Allocate a new flv_data pointer with enough space for the additional package
2540  if (!(rt->flv_data = av_malloc(rt->flv_size + 55))) {
2541  rt->flv_data = old_flv_data;
2542  return AVERROR(ENOMEM);
2543  }
2544 
2545  // Copy FLV header
2546  memcpy(rt->flv_data, old_flv_data, 13);
2547  // Copy remaining packets
2548  memcpy(rt->flv_data + 13 + 55, old_flv_data + 13, rt->flv_size - 13);
2549  // Increase the size by the injected packet
2550  rt->flv_size += 55;
2551  // Delete the old FLV data
2552  av_free(old_flv_data);
2553 
2554  p = rt->flv_data + 13;
2555  bytestream_put_byte(&p, FLV_TAG_TYPE_META);
2556  bytestream_put_be24(&p, 40); // size of data part (sum of all parts below)
2557  bytestream_put_be24(&p, 0); // timestamp
2558  bytestream_put_be32(&p, 0); // reserved
2559 
2560  // first event name as a string
2561  bytestream_put_byte(&p, AMF_DATA_TYPE_STRING);
2562  // "onMetaData" as AMF string
2563  bytestream_put_be16(&p, 10);
2564  bytestream_put_buffer(&p, "onMetaData", 10);
2565 
2566  // mixed array (hash) with size and string/type/data tuples
2567  bytestream_put_byte(&p, AMF_DATA_TYPE_MIXEDARRAY);
2568  bytestream_put_be32(&p, 1); // metadata_count
2569 
2570  // "duration" as AMF string
2571  bytestream_put_be16(&p, 8);
2572  bytestream_put_buffer(&p, "duration", 8);
2573  bytestream_put_byte(&p, AMF_DATA_TYPE_NUMBER);
2574  bytestream_put_be64(&p, av_double2int(rt->duration));
2575 
2576  // Finalise object
2577  bytestream_put_be16(&p, 0); // Empty string
2578  bytestream_put_byte(&p, AMF_END_OF_OBJECT);
2579  bytestream_put_be32(&p, 40); // size of data part (sum of all parts below)
2580 
2581  return 0;
2582 }
2583 
2584 /**
2585  * Open RTMP connection and verify that the stream can be played.
2586  *
2587  * URL syntax: rtmp://server[:port][/app][/playpath]
2588  * where 'app' is first one or two directories in the path
2589  * (e.g. /ondemand/, /flash/live/, etc.)
2590  * and 'playpath' is a file name (the rest of the path,
2591  * may be prefixed with "mp4:")
2592  */
2593 static int rtmp_open(URLContext *s, const char *uri, int flags)
2594 {
2595  RTMPContext *rt = s->priv_data;
2596  char proto[8], hostname[256], path[1024], auth[100], *fname;
2597  char *old_app, *qmark, *n, fname_buffer[1024];
2598  uint8_t buf[2048];
2599  int port;
2600  AVDictionary *opts = NULL;
2601  int ret;
2602 
2603  if (rt->listen_timeout > 0)
2604  rt->listen = 1;
2605 
2606  rt->is_input = !(flags & AVIO_FLAG_WRITE);
2607 
2608  av_url_split(proto, sizeof(proto), auth, sizeof(auth),
2609  hostname, sizeof(hostname), &port,
2610  path, sizeof(path), s->filename);
2611 
2612  n = strchr(path, ' ');
2613  if (n) {
2615  "Detected librtmp style URL parameters, these aren't supported "
2616  "by the libavformat internal RTMP handler currently enabled. "
2617  "See the documentation for the correct way to pass parameters.\n");
2618  *n = '\0'; // Trim not supported part
2619  }
2620 
2621  if (auth[0]) {
2622  char *ptr = strchr(auth, ':');
2623  if (ptr) {
2624  *ptr = '\0';
2625  av_strlcpy(rt->username, auth, sizeof(rt->username));
2626  av_strlcpy(rt->password, ptr + 1, sizeof(rt->password));
2627  }
2628  }
2629 
2630  if (rt->listen && strcmp(proto, "rtmp")) {
2631  av_log(s, AV_LOG_ERROR, "rtmp_listen not available for %s\n",
2632  proto);
2633  return AVERROR(EINVAL);
2634  }
2635  if (!strcmp(proto, "rtmpt") || !strcmp(proto, "rtmpts")) {
2636  if (!strcmp(proto, "rtmpts"))
2637  av_dict_set(&opts, "ffrtmphttp_tls", "1", 1);
2638 
2639  /* open the http tunneling connection */
2640  ff_url_join(buf, sizeof(buf), "ffrtmphttp", NULL, hostname, port, NULL);
2641  } else if (!strcmp(proto, "rtmps")) {
2642  /* open the tls connection */
2643  if (port < 0)
2644  port = RTMPS_DEFAULT_PORT;
2645  ff_url_join(buf, sizeof(buf), "tls", NULL, hostname, port, NULL);
2646  } else if (!strcmp(proto, "rtmpe") || (!strcmp(proto, "rtmpte"))) {
2647  if (!strcmp(proto, "rtmpte"))
2648  av_dict_set(&opts, "ffrtmpcrypt_tunneling", "1", 1);
2649 
2650  /* open the encrypted connection */
2651  ff_url_join(buf, sizeof(buf), "ffrtmpcrypt", NULL, hostname, port, NULL);
2652  rt->encrypted = 1;
2653  } else {
2654  /* open the tcp connection */
2655  if (port < 0)
2656  port = RTMP_DEFAULT_PORT;
2657  if (rt->listen)
2658  ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port,
2659  "?listen&listen_timeout=%d",
2660  rt->listen_timeout * 1000);
2661  else
2662  ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);
2663  }
2664 
2665 reconnect:
2666  if ((ret = ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE,
2667  &s->interrupt_callback, &opts)) < 0) {
2668  av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf);
2669  goto fail;
2670  }
2671 
2672  if (rt->swfverify) {
2673  if ((ret = rtmp_calc_swfhash(s)) < 0)
2674  goto fail;
2675  }
2676 
2677  rt->state = STATE_START;
2678  if (!rt->listen && (ret = rtmp_handshake(s, rt)) < 0)
2679  goto fail;
2680  if (rt->listen && (ret = rtmp_server_handshake(s, rt)) < 0)
2681  goto fail;
2682 
2683  rt->out_chunk_size = 128;
2684  rt->in_chunk_size = 128; // Probably overwritten later
2685  rt->state = STATE_HANDSHAKED;
2686 
2687  // Keep the application name when it has been defined by the user.
2688  old_app = rt->app;
2689 
2690  rt->app = av_malloc(APP_MAX_LENGTH);
2691  if (!rt->app) {
2692  ret = AVERROR(ENOMEM);
2693  goto fail;
2694  }
2695 
2696  //extract "app" part from path
2697  qmark = strchr(path, '?');
2698  if (qmark && strstr(qmark, "slist=")) {
2699  char* amp;
2700  // After slist we have the playpath, before the params, the app
2701  av_strlcpy(rt->app, path + 1, FFMIN(qmark - path, APP_MAX_LENGTH));
2702  fname = strstr(path, "slist=") + 6;
2703  // Strip any further query parameters from fname
2704  amp = strchr(fname, '&');
2705  if (amp) {
2706  av_strlcpy(fname_buffer, fname, FFMIN(amp - fname + 1,
2707  sizeof(fname_buffer)));
2708  fname = fname_buffer;
2709  }
2710  } else if (!strncmp(path, "/ondemand/", 10)) {
2711  fname = path + 10;
2712  memcpy(rt->app, "ondemand", 9);
2713  } else {
2714  char *next = *path ? path + 1 : path;
2715  char *p = strchr(next, '/');
2716  if (!p) {
2717  if (old_app) {
2718  // If name of application has been defined by the user, assume that
2719  // playpath is provided in the URL
2720  fname = next;
2721  } else {
2722  fname = NULL;
2723  av_strlcpy(rt->app, next, APP_MAX_LENGTH);
2724  }
2725  } else {
2726  // make sure we do not mismatch a playpath for an application instance
2727  char *c = strchr(p + 1, ':');
2728  fname = strchr(p + 1, '/');
2729  if (!fname || (c && c < fname)) {
2730  fname = p + 1;
2731  av_strlcpy(rt->app, path + 1, FFMIN(p - path, APP_MAX_LENGTH));
2732  } else {
2733  fname++;
2734  av_strlcpy(rt->app, path + 1, FFMIN(fname - path - 1, APP_MAX_LENGTH));
2735  }
2736  }
2737  }
2738 
2739  if (old_app) {
2740  // The name of application has been defined by the user, override it.
2741  if (strlen(old_app) >= APP_MAX_LENGTH) {
2742  ret = AVERROR(EINVAL);
2743  goto fail;
2744  }
2745  av_free(rt->app);
2746  rt->app = old_app;
2747  }
2748 
2749  if (!rt->playpath) {
2751  if (!rt->playpath) {
2752  ret = AVERROR(ENOMEM);
2753  goto fail;
2754  }
2755 
2756  if (fname) {
2757  int len = strlen(fname);
2758  if (!strchr(fname, ':') && len >= 4 &&
2759  (!strcmp(fname + len - 4, ".f4v") ||
2760  !strcmp(fname + len - 4, ".mp4"))) {
2761  memcpy(rt->playpath, "mp4:", 5);
2762  } else {
2763  if (len >= 4 && !strcmp(fname + len - 4, ".flv"))
2764  fname[len - 4] = '\0';
2765  rt->playpath[0] = 0;
2766  }
2768  } else {
2769  rt->playpath[0] = '\0';
2770  }
2771  }
2772 
2773  if (!rt->tcurl) {
2775  if (!rt->tcurl) {
2776  ret = AVERROR(ENOMEM);
2777  goto fail;
2778  }
2779  ff_url_join(rt->tcurl, TCURL_MAX_LENGTH, proto, NULL, hostname,
2780  port, "/%s", rt->app);
2781  }
2782 
2783  if (!rt->flashver) {
2785  if (!rt->flashver) {
2786  ret = AVERROR(ENOMEM);
2787  goto fail;
2788  }
2789  if (rt->is_input) {
2790  snprintf(rt->flashver, FLASHVER_MAX_LENGTH, "%s %d,%d,%d,%d",
2793  } else {
2795  "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);
2796  }
2797  }
2798 
2799  rt->client_report_size = 1048576;
2800  rt->bytes_read = 0;
2801  rt->has_audio = 0;
2802  rt->has_video = 0;
2803  rt->received_metadata = 0;
2804  rt->last_bytes_read = 0;
2805  rt->server_bw = 2500000;
2806  rt->duration = 0;
2807 
2808  av_log(s, AV_LOG_DEBUG, "Proto = %s, path = %s, app = %s, fname = %s\n",
2809  proto, path, rt->app, rt->playpath);
2810  if (!rt->listen) {
2811  if ((ret = gen_connect(s, rt)) < 0)
2812  goto fail;
2813  } else {
2814  if ((ret = read_connect(s, s->priv_data)) < 0)
2815  goto fail;
2816  }
2817 
2818  do {
2819  ret = get_packet(s, 1);
2820  } while (ret == AVERROR(EAGAIN));
2821  if (ret < 0)
2822  goto fail;
2823 
2824  if (rt->do_reconnect) {
2825  int i;
2826  ffurl_close(rt->stream);
2827  rt->stream = NULL;
2828  rt->do_reconnect = 0;
2829  rt->nb_invokes = 0;
2830  for (i = 0; i < 2; i++)
2831  memset(rt->prev_pkt[i], 0,
2832  sizeof(**rt->prev_pkt) * rt->nb_prev_pkt[i]);
2834  goto reconnect;
2835  }
2836 
2837  if (rt->is_input) {
2838  // generate FLV header for demuxer
2839  rt->flv_size = 13;
2840  if ((ret = av_reallocp(&rt->flv_data, rt->flv_size)) < 0)
2841  goto fail;
2842  rt->flv_off = 0;
2843  memcpy(rt->flv_data, "FLV\1\0\0\0\0\011\0\0\0\0", rt->flv_size);
2844 
2845  // Read packets until we reach the first A/V packet or read metadata.
2846  // If there was a metadata package in front of the A/V packets, we can
2847  // build the FLV header from this. If we do not receive any metadata,
2848  // the FLV decoder will allocate the needed streams when their first
2849  // audio or video packet arrives.
2850  while (!rt->has_audio && !rt->has_video && !rt->received_metadata) {
2851  if ((ret = get_packet(s, 0)) < 0)
2852  goto fail;
2853  }
2854 
2855  // Either after we have read the metadata or (if there is none) the
2856  // first packet of an A/V stream, we have a better knowledge about the
2857  // streams, so set the FLV header accordingly.
2858  if (rt->has_audio) {
2860  }
2861  if (rt->has_video) {
2863  }
2864 
2865  // If we received the first packet of an A/V stream and no metadata but
2866  // the server returned a valid duration, create a fake metadata packet
2867  // to inform the FLV decoder about the duration.
2868  if (!rt->received_metadata && rt->duration > 0) {
2869  if ((ret = inject_fake_duration_metadata(rt)) < 0)
2870  goto fail;
2871  }
2872  } else {
2873  rt->flv_size = 0;
2874  rt->flv_data = NULL;
2875  rt->flv_off = 0;
2876  rt->skip_bytes = 13;
2877  }
2878 
2880  s->is_streamed = 1;
2881  return 0;
2882 
2883 fail:
2884  av_dict_free(&opts);
2885  rtmp_close(s);
2886  return ret;
2887 }
2888 
2889 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
2890 {
2891  RTMPContext *rt = s->priv_data;
2892  int orig_size = size;
2893  int ret;
2894 
2895  while (size > 0) {
2896  int data_left = rt->flv_size - rt->flv_off;
2897 
2898  if (data_left >= size) {
2899  memcpy(buf, rt->flv_data + rt->flv_off, size);
2900  rt->flv_off += size;
2901  return orig_size;
2902  }
2903  if (data_left > 0) {
2904  memcpy(buf, rt->flv_data + rt->flv_off, data_left);
2905  buf += data_left;
2906  size -= data_left;
2907  rt->flv_off = rt->flv_size;
2908  return data_left;
2909  }
2910  if ((ret = get_packet(s, 0)) < 0)
2911  return ret;
2912  }
2913  return orig_size;
2914 }
2915 
2916 static int64_t rtmp_seek(URLContext *s, int stream_index, int64_t timestamp,
2917  int flags)
2918 {
2919  RTMPContext *rt = s->priv_data;
2920  int ret;
2921  av_log(s, AV_LOG_DEBUG,
2922  "Seek on stream index %d at timestamp %"PRId64" with flags %08x\n",
2923  stream_index, timestamp, flags);
2924  if ((ret = gen_seek(s, rt, timestamp)) < 0) {
2925  av_log(s, AV_LOG_ERROR,
2926  "Unable to send seek command on stream index %d at timestamp "
2927  "%"PRId64" with flags %08x\n",
2928  stream_index, timestamp, flags);
2929  return ret;
2930  }
2931  rt->flv_off = rt->flv_size;
2932  rt->state = STATE_SEEKING;
2933  return timestamp;
2934 }
2935 
2936 static int rtmp_pause(URLContext *s, int pause)
2937 {
2938  RTMPContext *rt = s->priv_data;
2939  int ret;
2940  av_log(s, AV_LOG_DEBUG, "Pause at timestamp %d\n",
2941  rt->last_timestamp);
2942  if ((ret = gen_pause(s, rt, pause, rt->last_timestamp)) < 0) {
2943  av_log(s, AV_LOG_ERROR, "Unable to send pause command at timestamp %d\n",
2944  rt->last_timestamp);
2945  return ret;
2946  }
2947  return 0;
2948 }
2949 
2950 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
2951 {
2952  RTMPContext *rt = s->priv_data;
2953  int size_temp = size;
2954  int pktsize, pkttype;
2955  uint32_t ts;
2956  const uint8_t *buf_temp = buf;
2957  uint8_t c;
2958  int ret;
2959 
2960  do {
2961  if (rt->skip_bytes) {
2962  int skip = FFMIN(rt->skip_bytes, size_temp);
2963  buf_temp += skip;
2964  size_temp -= skip;
2965  rt->skip_bytes -= skip;
2966  continue;
2967  }
2968 
2969  if (rt->flv_header_bytes < RTMP_HEADER) {
2970  const uint8_t *header = rt->flv_header;
2971  int copy = FFMIN(RTMP_HEADER - rt->flv_header_bytes, size_temp);
2972  int channel = RTMP_AUDIO_CHANNEL;
2973  bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy);
2974  rt->flv_header_bytes += copy;
2975  size_temp -= copy;
2976  if (rt->flv_header_bytes < RTMP_HEADER)
2977  break;
2978 
2979  pkttype = bytestream_get_byte(&header);
2980  pktsize = bytestream_get_be24(&header);
2981  ts = bytestream_get_be24(&header);
2982  ts |= bytestream_get_byte(&header) << 24;
2983  bytestream_get_be24(&header);
2984  rt->flv_size = pktsize;
2985 
2986  if (pkttype == RTMP_PT_VIDEO)
2987  channel = RTMP_VIDEO_CHANNEL;
2988 
2989  //force 12bytes header
2990  if (((pkttype == RTMP_PT_VIDEO || pkttype == RTMP_PT_AUDIO) && ts == 0) ||
2991  pkttype == RTMP_PT_NOTIFY) {
2992  if (pkttype == RTMP_PT_NOTIFY)
2993  pktsize += 16;
2994  if ((ret = ff_rtmp_check_alloc_array(&rt->prev_pkt[1],
2995  &rt->nb_prev_pkt[1],
2996  channel)) < 0)
2997  return ret;
2998  rt->prev_pkt[1][channel].channel_id = 0;
2999  }
3000 
3001  //this can be a big packet, it's better to send it right here
3002  if ((ret = ff_rtmp_packet_create(&rt->out_pkt, channel,
3003  pkttype, ts, pktsize)) < 0)
3004  return ret;
3005 
3006  rt->out_pkt.extra = rt->stream_id;
3007  rt->flv_data = rt->out_pkt.data;
3008 
3009  if (pkttype == RTMP_PT_NOTIFY)
3010  ff_amf_write_string(&rt->flv_data, "@setDataFrame");
3011  }
3012 
3013  if (rt->flv_size - rt->flv_off > size_temp) {
3014  bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, size_temp);
3015  rt->flv_off += size_temp;
3016  size_temp = 0;
3017  } else {
3018  bytestream_get_buffer(&buf_temp, rt->flv_data + rt->flv_off, rt->flv_size - rt->flv_off);
3019  size_temp -= rt->flv_size - rt->flv_off;
3020  rt->flv_off += rt->flv_size - rt->flv_off;
3021  }
3022 
3023  if (rt->flv_off == rt->flv_size) {
3024  rt->skip_bytes = 4;
3025 
3026  if ((ret = rtmp_send_packet(rt, &rt->out_pkt, 0)) < 0)
3027  return ret;
3028  rt->flv_size = 0;
3029  rt->flv_off = 0;
3030  rt->flv_header_bytes = 0;
3031  rt->flv_nb_packets++;
3032  }
3033  } while (buf_temp - buf < size);
3034 
3035  if (rt->flv_nb_packets < rt->flush_interval)
3036  return size;
3037  rt->flv_nb_packets = 0;
3038 
3039  /* set stream into nonblocking mode */
3041 
3042  /* try to read one byte from the stream */
3043  ret = ffurl_read(rt->stream, &c, 1);
3044 
3045  /* switch the stream back into blocking mode */
3046  rt->stream->flags &= ~AVIO_FLAG_NONBLOCK;
3047 
3048  if (ret == AVERROR(EAGAIN)) {
3049  /* no incoming data to handle */
3050  return size;
3051  } else if (ret < 0) {
3052  return ret;
3053  } else if (ret == 1) {
3054  RTMPPacket rpkt = { 0 };
3055 
3056  if ((ret = ff_rtmp_packet_read_internal(rt->stream, &rpkt,
3057  rt->in_chunk_size,
3058  &rt->prev_pkt[0],
3059  &rt->nb_prev_pkt[0], c)) <= 0)
3060  return ret;
3061 
3062  if ((ret = rtmp_parse_result(s, rt, &rpkt)) < 0)
3063  return ret;
3064 
3065  ff_rtmp_packet_destroy(&rpkt);
3066  }
3067 
3068  return size;
3069 }
3070 
3071 #define OFFSET(x) offsetof(RTMPContext, x)
3072 #define DEC AV_OPT_FLAG_DECODING_PARAM
3073 #define ENC AV_OPT_FLAG_ENCODING_PARAM
3074 
3075 static const AVOption rtmp_options[] = {
3076  {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3077  {"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},
3078  {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3079  {"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},
3080  {"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},
3081  {"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"},
3082  {"any", "both", 0, AV_OPT_TYPE_CONST, {.i64 = -2}, 0, 0, DEC, "rtmp_live"},
3083  {"live", "live stream", 0, AV_OPT_TYPE_CONST, {.i64 = -1}, 0, 0, DEC, "rtmp_live"},
3084  {"recorded", "recorded stream", 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 0, DEC, "rtmp_live"},
3085  {"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},
3086  {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
3087  {"rtmp_subscribe", "Name of live stream to subscribe to. Defaults to rtmp_playpath.", OFFSET(subscribe), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
3088  {"rtmp_swfhash", "SHA256 hash of the decompressed SWF file (32 bytes).", OFFSET(swfhash), AV_OPT_TYPE_BINARY, .flags = DEC},
3089  {"rtmp_swfsize", "Size of the decompressed SWF file, required for SWFVerification.", OFFSET(swfsize), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, DEC},
3090  {"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},
3091  {"rtmp_swfverify", "URL to player swf file, compute hash/size automatically.", OFFSET(swfverify), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC},
3092  {"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},
3093  {"rtmp_listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
3094  {"listen", "Listen for incoming rtmp connections", OFFSET(listen), AV_OPT_TYPE_INT, {.i64 = 0}, INT_MIN, INT_MAX, DEC, "rtmp_listen" },
3095  {"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" },
3096  { NULL },
3097 };
3098 
3099 #define RTMP_PROTOCOL(flavor) \
3100 static const AVClass flavor##_class = { \
3101  .class_name = #flavor, \
3102  .item_name = av_default_item_name, \
3103  .option = rtmp_options, \
3104  .version = LIBAVUTIL_VERSION_INT, \
3105 }; \
3106  \
3107 URLProtocol ff_##flavor##_protocol = { \
3108  .name = #flavor, \
3109  .url_open = rtmp_open, \
3110  .url_read = rtmp_read, \
3111  .url_read_seek = rtmp_seek, \
3112  .url_read_pause = rtmp_pause, \
3113  .url_write = rtmp_write, \
3114  .url_close = rtmp_close, \
3115  .priv_data_size = sizeof(RTMPContext), \
3116  .flags = URL_PROTOCOL_FLAG_NETWORK, \
3117  .priv_data_class= &flavor##_class, \
3118 };
3119 
3120 
3121 RTMP_PROTOCOL(rtmp)
3122 RTMP_PROTOCOL(rtmpe)
3123 RTMP_PROTOCOL(rtmps)
3124 RTMP_PROTOCOL(rtmpt)
3125 RTMP_PROTOCOL(rtmpte)
3126 RTMP_PROTOCOL(rtmpts)