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