librtmp.c
Go to the documentation of this file.
1 /*
2  * RTMP network protocol
3  * Copyright (c) 2010 Howard Chu
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 based on http://rtmpdump.mplayerhq.hu/ librtmp
25  */
26 
27 #include "libavutil/avstring.h"
28 #include "libavutil/mathematics.h"
29 #include "libavutil/opt.h"
30 #include "avformat.h"
31 #include "url.h"
32 
33 #include <librtmp/rtmp.h>
34 #include <librtmp/log.h>
35 
36 typedef struct LibRTMPContext {
37  const AVClass *class;
38  RTMP rtmp;
39  char *app;
40  char *playpath;
42 
43 static void rtmp_log(int level, const char *fmt, va_list args)
44 {
45  switch (level) {
46  default:
47  case RTMP_LOGCRIT: level = AV_LOG_FATAL; break;
48  case RTMP_LOGERROR: level = AV_LOG_ERROR; break;
49  case RTMP_LOGWARNING: level = AV_LOG_WARNING; break;
50  case RTMP_LOGINFO: level = AV_LOG_INFO; break;
51  case RTMP_LOGDEBUG: level = AV_LOG_VERBOSE; break;
52  case RTMP_LOGDEBUG2: level = AV_LOG_DEBUG; break;
53  }
54 
55  av_vlog(NULL, level, fmt, args);
56  av_log(NULL, level, "\n");
57 }
58 
59 static int rtmp_close(URLContext *s)
60 {
61  LibRTMPContext *ctx = s->priv_data;
62  RTMP *r = &ctx->rtmp;
63 
64  RTMP_Close(r);
65  return 0;
66 }
67 
68 /**
69  * Open RTMP connection and verify that the stream can be played.
70  *
71  * URL syntax: rtmp://server[:port][/app][/playpath][ keyword=value]...
72  * where 'app' is first one or two directories in the path
73  * (e.g. /ondemand/, /flash/live/, etc.)
74  * and 'playpath' is a file name (the rest of the path,
75  * may be prefixed with "mp4:")
76  *
77  * Additional RTMP library options may be appended as
78  * space-separated key-value pairs.
79  */
80 static int rtmp_open(URLContext *s, const char *uri, int flags)
81 {
82  LibRTMPContext *ctx = s->priv_data;
83  RTMP *r = &ctx->rtmp;
84  int rc = 0, level;
85  char *filename = s->filename;
86 
87  switch (av_log_get_level()) {
88  default:
89  case AV_LOG_FATAL: level = RTMP_LOGCRIT; break;
90  case AV_LOG_ERROR: level = RTMP_LOGERROR; break;
91  case AV_LOG_WARNING: level = RTMP_LOGWARNING; break;
92  case AV_LOG_INFO: level = RTMP_LOGINFO; break;
93  case AV_LOG_VERBOSE: level = RTMP_LOGDEBUG; break;
94  case AV_LOG_DEBUG: level = RTMP_LOGDEBUG2; break;
95  }
96  RTMP_LogSetLevel(level);
97  RTMP_LogSetCallback(rtmp_log);
98 
99  if (ctx->app || ctx->playpath) {
100  int len = strlen(s->filename) + 1;
101  if (ctx->app) len += strlen(ctx->app) + sizeof(" app=");
102  if (ctx->playpath) len += strlen(ctx->playpath) + sizeof(" playpath=");
103 
104  if (!(filename = av_malloc(len)))
105  return AVERROR(ENOMEM);
106 
107  av_strlcpy(filename, s->filename, len);
108  if (ctx->app) {
109  av_strlcat(filename, " app=", len);
110  av_strlcat(filename, ctx->app, len);
111  }
112  if (ctx->playpath) {
113  av_strlcat(filename, " playpath=", len);
114  av_strlcat(filename, ctx->playpath, len);
115  }
116  }
117 
118  RTMP_Init(r);
119  if (!RTMP_SetupURL(r, filename)) {
120  rc = AVERROR_UNKNOWN;
121  goto fail;
122  }
123 
124  if (flags & AVIO_FLAG_WRITE)
125  RTMP_EnableWrite(r);
126 
127  if (!RTMP_Connect(r, NULL) || !RTMP_ConnectStream(r, 0)) {
128  rc = AVERROR_UNKNOWN;
129  goto fail;
130  }
131 
132  s->is_streamed = 1;
133  rc = 0;
134 fail:
135  if (filename != s->filename)
136  av_freep(&filename);
137  return rc;
138 }
139 
140 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
141 {
142  LibRTMPContext *ctx = s->priv_data;
143  RTMP *r = &ctx->rtmp;
144 
145  return RTMP_Write(r, buf, size);
146 }
147 
148 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
149 {
150  LibRTMPContext *ctx = s->priv_data;
151  RTMP *r = &ctx->rtmp;
152 
153  return RTMP_Read(r, buf, size);
154 }
155 
157 {
158  LibRTMPContext *ctx = s->priv_data;
159  RTMP *r = &ctx->rtmp;
160 
161  if (!RTMP_Pause(r, pause))
162  return AVERROR_UNKNOWN;
163  return 0;
164 }
165 
166 static int64_t rtmp_read_seek(URLContext *s, int stream_index,
167  int64_t timestamp, int flags)
168 {
169  LibRTMPContext *ctx = s->priv_data;
170  RTMP *r = &ctx->rtmp;
171 
172  if (flags & AVSEEK_FLAG_BYTE)
173  return AVERROR(ENOSYS);
174 
175  /* seeks are in milliseconds */
176  if (stream_index < 0)
177  timestamp = av_rescale_rnd(timestamp, 1000, AV_TIME_BASE,
179 
180  if (!RTMP_SendSeek(r, timestamp))
181  return AVERROR_UNKNOWN;
182  return timestamp;
183 }
184 
186 {
187  LibRTMPContext *ctx = s->priv_data;
188  RTMP *r = &ctx->rtmp;
189 
190  return RTMP_Socket(r);
191 }
192 
193 #define OFFSET(x) offsetof(LibRTMPContext, x)
194 #define DEC AV_OPT_FLAG_DECODING_PARAM
195 #define ENC AV_OPT_FLAG_ENCODING_PARAM
196 static const AVOption options[] = {
197  {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
198  {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC},
199  { NULL },
200 };
201 
202 #define RTMP_CLASS(flavor)\
203 static const AVClass lib ## flavor ## _class = {\
204  .class_name = "lib" #flavor " protocol",\
205  .item_name = av_default_item_name,\
206  .option = options,\
207  .version = LIBAVUTIL_VERSION_INT,\
208 };
209 
212  .name = "rtmp",
213  .url_open = rtmp_open,
214  .url_read = rtmp_read,
215  .url_write = rtmp_write,
216  .url_close = rtmp_close,
217  .url_read_pause = rtmp_read_pause,
218  .url_read_seek = rtmp_read_seek,
219  .url_get_file_handle = rtmp_get_file_handle,
220  .priv_data_size = sizeof(LibRTMPContext),
221  .priv_data_class = &librtmp_class,
223 };
224 
225 RTMP_CLASS(rtmpt)
227  .name = "rtmpt",
228  .url_open = rtmp_open,
229  .url_read = rtmp_read,
230  .url_write = rtmp_write,
231  .url_close = rtmp_close,
232  .url_read_pause = rtmp_read_pause,
233  .url_read_seek = rtmp_read_seek,
234  .url_get_file_handle = rtmp_get_file_handle,
235  .priv_data_size = sizeof(LibRTMPContext),
236  .priv_data_class = &librtmpt_class,
238 };
239 
240 RTMP_CLASS(rtmpe)
242  .name = "rtmpe",
243  .url_open = rtmp_open,
244  .url_read = rtmp_read,
245  .url_write = rtmp_write,
246  .url_close = rtmp_close,
247  .url_read_pause = rtmp_read_pause,
248  .url_read_seek = rtmp_read_seek,
249  .url_get_file_handle = rtmp_get_file_handle,
250  .priv_data_size = sizeof(LibRTMPContext),
251  .priv_data_class = &librtmpe_class,
253 };
254 
255 RTMP_CLASS(rtmpte)
257  .name = "rtmpte",
258  .url_open = rtmp_open,
259  .url_read = rtmp_read,
260  .url_write = rtmp_write,
261  .url_close = rtmp_close,
262  .url_read_pause = rtmp_read_pause,
263  .url_read_seek = rtmp_read_seek,
264  .url_get_file_handle = rtmp_get_file_handle,
265  .priv_data_size = sizeof(LibRTMPContext),
266  .priv_data_class = &librtmpte_class,
268 };
269 
270 RTMP_CLASS(rtmps)
272  .name = "rtmps",
273  .url_open = rtmp_open,
274  .url_read = rtmp_read,
275  .url_write = rtmp_write,
276  .url_close = rtmp_close,
277  .url_read_pause = rtmp_read_pause,
278  .url_read_seek = rtmp_read_seek,
279  .url_get_file_handle = rtmp_get_file_handle,
280  .priv_data_size = sizeof(LibRTMPContext),
281  .priv_data_class = &librtmps_class,
283 };
#define AVSEEK_FLAG_BACKWARD
Definition: avformat.h:1743
char * app
Definition: librtmp.c:39
const char * s
Definition: avisynth_c.h:668
#define ENC
Definition: librtmp.c:195
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:35
static int64_t rtmp_read_seek(URLContext *s, int stream_index, int64_t timestamp, int flags)
Definition: librtmp.c:166
AVOption.
Definition: opt.h:251
const char * fmt
Definition: avisynth_c.h:669
int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd)
Rescale a 64-bit integer with specified rounding.
Definition: mathematics.c:60
int is_streamed
true if streamed (no seek possible), default = false
Definition: url.h:48
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:333
static int rtmp_read_pause(URLContext *s, int pause)
Definition: librtmp.c:156
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
uint8_t
int av_log_get_level(void)
Definition: log.c:264
Round toward +infinity.
Definition: mathematics.h:71
AVOptions.
static int rtmp_close(URLContext *s)
Definition: librtmp.c:59
static int rtmp_open(URLContext *s, const char *uri, int flags)
Open RTMP connection and verify that the stream can be played.
Definition: librtmp.c:80
#define DEC
Definition: librtmp.c:194
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
Definition: log.h:142
URLProtocol ff_librtmpt_protocol
Definition: librtmp.c:226
void av_vlog(void *avcl, int level, const char *fmt, va_list vl)
Definition: log.c:258
static void rtmp_log(int level, const char *fmt, va_list args)
Definition: librtmp.c:43
const char * r
Definition: vf_curves.c:94
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
Definition: avstring.c:82
int size
#define AV_LOG_VERBOSE
Definition: log.h:157
URLProtocol ff_librtmpte_protocol
Definition: librtmp.c:256
#define AV_TIME_BASE
Internal time base represented as integer.
Definition: avutil.h:196
URLProtocol ff_librtmpe_protocol
Definition: librtmp.c:241
URLProtocol ff_librtmp_protocol
Definition: librtmp.c:211
FIXME Range Coding of cr are level
Definition: snow.txt:367
NULL
Definition: eval.c:55
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
static const AVOption options[]
Definition: librtmp.c:196
void * buf
Definition: avisynth_c.h:594
Definition: url.h:41
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
Describe the class of an AVClass context structure.
Definition: log.h:50
void * priv_data
Definition: url.h:44
#define OFFSET(x)
Definition: librtmp.c:193
#define AVSEEK_FLAG_BYTE
seeking based on position in bytes
Definition: avformat.h:1744
pause
Definition: plot_peaks.m:14
char * playpath
Definition: librtmp.c:40
static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
Definition: librtmp.c:140
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
size_t av_strlcat(char *dst, const char *src, size_t size)
Append the string src to the string dst, but to a total length of no more than size - 1 bytes...
Definition: avstring.c:92
const char * name
Definition: url.h:55
Round toward -infinity.
Definition: mathematics.h:70
static int flags
Definition: cpu.c:23
Main libavformat public API header.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
char * filename
specified URL
Definition: url.h:45
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
struct LibRTMPContext LibRTMPContext
static int rtmp_get_file_handle(URLContext *s)
Definition: librtmp.c:185
URLProtocol ff_librtmps_protocol
Definition: librtmp.c:271
int len
static int rtmp_read(URLContext *s, uint8_t *buf, int size)
Definition: librtmp.c:148
#define AV_LOG_INFO
Definition: log.h:156
unbuffered private I/O API
#define RTMP_CLASS(flavor)
Definition: librtmp.c:202