ffmpeg / libavformat / librtmp.c @ 6cc7f139
History | View | Annotate | Download (5.29 KB)
1 | 0f943ce6 | Howard Chu | /*
|
---|---|---|---|
2 | * RTMP network protocol
|
||
3 | * Copyright (c) 2010 Howard Chu
|
||
4 | *
|
||
5 | 2912e87a | Mans Rullgard | * This file is part of Libav.
|
6 | 0f943ce6 | Howard Chu | *
|
7 | 2912e87a | Mans Rullgard | * Libav is free software; you can redistribute it and/or
|
8 | 0f943ce6 | Howard Chu | * 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 | 2912e87a | Mans Rullgard | * Libav is distributed in the hope that it will be useful,
|
13 | 0f943ce6 | Howard Chu | * 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 | 2912e87a | Mans Rullgard | * License along with Libav; if not, write to the Free Software
|
19 | 0f943ce6 | Howard Chu | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 | */
|
||
21 | |||
22 | /**
|
||
23 | ba87f080 | Diego Biurrun | * @file
|
24 | fc122efd | Diego Biurrun | * RTMP protocol based on http://rtmpdump.mplayerhq.hu/ librtmp
|
25 | 0f943ce6 | Howard Chu | */
|
26 | |||
27 | #include "avformat.h" |
||
28 | |||
29 | #include <librtmp/rtmp.h> |
||
30 | #include <librtmp/log.h> |
||
31 | |||
32 | 19c9eedc | Howard Chu | static void rtmp_log(int level, const char *fmt, va_list args) |
33 | { |
||
34 | switch (level) {
|
||
35 | default:
|
||
36 | case RTMP_LOGCRIT: level = AV_LOG_FATAL; break; |
||
37 | case RTMP_LOGERROR: level = AV_LOG_ERROR; break; |
||
38 | case RTMP_LOGWARNING: level = AV_LOG_WARNING; break; |
||
39 | case RTMP_LOGINFO: level = AV_LOG_INFO; break; |
||
40 | case RTMP_LOGDEBUG: level = AV_LOG_VERBOSE; break; |
||
41 | case RTMP_LOGDEBUG2: level = AV_LOG_DEBUG; break; |
||
42 | } |
||
43 | |||
44 | av_vlog(NULL, level, fmt, args);
|
||
45 | av_log(NULL, level, "\n"); |
||
46 | } |
||
47 | |||
48 | 0f943ce6 | Howard Chu | static int rtmp_close(URLContext *s) |
49 | { |
||
50 | RTMP *r = s->priv_data; |
||
51 | |||
52 | RTMP_Close(r); |
||
53 | av_free(r); |
||
54 | return 0; |
||
55 | } |
||
56 | |||
57 | /**
|
||
58 | 49bd8e4b | Måns Rullgård | * Open RTMP connection and verify that the stream can be played.
|
59 | 0f943ce6 | Howard Chu | *
|
60 | * URL syntax: rtmp://server[:port][/app][/playpath][ keyword=value]...
|
||
61 | * where 'app' is first one or two directories in the path
|
||
62 | * (e.g. /ondemand/, /flash/live/, etc.)
|
||
63 | * and 'playpath' is a file name (the rest of the path,
|
||
64 | * may be prefixed with "mp4:")
|
||
65 | *
|
||
66 | * Additional RTMP library options may be appended as
|
||
67 | * space-separated key-value pairs.
|
||
68 | */
|
||
69 | static int rtmp_open(URLContext *s, const char *uri, int flags) |
||
70 | { |
||
71 | RTMP *r; |
||
72 | int rc;
|
||
73 | |||
74 | r = av_mallocz(sizeof(RTMP));
|
||
75 | if (!r)
|
||
76 | return AVERROR(ENOMEM);
|
||
77 | |||
78 | fc122efd | Diego Biurrun | switch (av_log_get_level()) {
|
79 | 0f943ce6 | Howard Chu | default:
|
80 | case AV_LOG_FATAL: rc = RTMP_LOGCRIT; break; |
||
81 | case AV_LOG_ERROR: rc = RTMP_LOGERROR; break; |
||
82 | case AV_LOG_WARNING: rc = RTMP_LOGWARNING; break; |
||
83 | case AV_LOG_INFO: rc = RTMP_LOGINFO; break; |
||
84 | case AV_LOG_VERBOSE: rc = RTMP_LOGDEBUG; break; |
||
85 | case AV_LOG_DEBUG: rc = RTMP_LOGDEBUG2; break; |
||
86 | } |
||
87 | RTMP_LogSetLevel(rc); |
||
88 | 19c9eedc | Howard Chu | RTMP_LogSetCallback(rtmp_log); |
89 | 0f943ce6 | Howard Chu | |
90 | RTMP_Init(r); |
||
91 | if (!RTMP_SetupURL(r, s->filename)) {
|
||
92 | rc = -1;
|
||
93 | goto fail;
|
||
94 | } |
||
95 | |||
96 | if (flags & URL_WRONLY)
|
||
97 | 4bbb3e3a | Howard Chu | RTMP_EnableWrite(r); |
98 | 0f943ce6 | Howard Chu | |
99 | if (!RTMP_Connect(r, NULL) || !RTMP_ConnectStream(r, 0)) { |
||
100 | rc = -1;
|
||
101 | goto fail;
|
||
102 | } |
||
103 | |||
104 | fc122efd | Diego Biurrun | s->priv_data = r; |
105 | 0f943ce6 | Howard Chu | s->is_streamed = 1;
|
106 | return 0; |
||
107 | fail:
|
||
108 | av_free(r); |
||
109 | return rc;
|
||
110 | } |
||
111 | |||
112 | 27241cbf | Martin Storsjö | static int rtmp_write(URLContext *s, const uint8_t *buf, int size) |
113 | 0f943ce6 | Howard Chu | { |
114 | RTMP *r = s->priv_data; |
||
115 | |||
116 | return RTMP_Write(r, buf, size);
|
||
117 | } |
||
118 | |||
119 | static int rtmp_read(URLContext *s, uint8_t *buf, int size) |
||
120 | { |
||
121 | RTMP *r = s->priv_data; |
||
122 | |||
123 | return RTMP_Read(r, buf, size);
|
||
124 | } |
||
125 | |||
126 | static int rtmp_read_pause(URLContext *s, int pause) |
||
127 | { |
||
128 | RTMP *r = s->priv_data; |
||
129 | |||
130 | 4bbb3e3a | Howard Chu | if (!RTMP_Pause(r, pause))
|
131 | 0f943ce6 | Howard Chu | return -1; |
132 | return 0; |
||
133 | } |
||
134 | |||
135 | static int64_t rtmp_read_seek(URLContext *s, int stream_index, |
||
136 | int64_t timestamp, int flags)
|
||
137 | { |
||
138 | RTMP *r = s->priv_data; |
||
139 | |||
140 | if (flags & AVSEEK_FLAG_BYTE)
|
||
141 | d79fc840 | Stefano Sabatini | return AVERROR(ENOSYS);
|
142 | 0f943ce6 | Howard Chu | |
143 | /* seeks are in milliseconds */
|
||
144 | fc8fa007 | Howard Chu | if (stream_index < 0) |
145 | timestamp = av_rescale_rnd(timestamp, 1000, AV_TIME_BASE,
|
||
146 | flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); |
||
147 | |||
148 | 0f943ce6 | Howard Chu | if (!RTMP_SendSeek(r, timestamp))
|
149 | return -1; |
||
150 | return timestamp;
|
||
151 | } |
||
152 | |||
153 | static int rtmp_get_file_handle(URLContext *s) |
||
154 | { |
||
155 | RTMP *r = s->priv_data; |
||
156 | |||
157 | 4bbb3e3a | Howard Chu | return RTMP_Socket(r);
|
158 | 0f943ce6 | Howard Chu | } |
159 | |||
160 | c6610a21 | Diego Elio Pettenò | URLProtocol ff_rtmp_protocol = { |
161 | 0f943ce6 | Howard Chu | "rtmp",
|
162 | rtmp_open, |
||
163 | rtmp_read, |
||
164 | rtmp_write, |
||
165 | NULL, /* seek */ |
||
166 | rtmp_close, |
||
167 | NULL, /* next */ |
||
168 | rtmp_read_pause, |
||
169 | rtmp_read_seek, |
||
170 | rtmp_get_file_handle |
||
171 | }; |
||
172 | |||
173 | c6610a21 | Diego Elio Pettenò | URLProtocol ff_rtmpt_protocol = { |
174 | 0f943ce6 | Howard Chu | "rtmpt",
|
175 | rtmp_open, |
||
176 | rtmp_read, |
||
177 | rtmp_write, |
||
178 | NULL, /* seek */ |
||
179 | rtmp_close, |
||
180 | NULL, /* next */ |
||
181 | rtmp_read_pause, |
||
182 | rtmp_read_seek, |
||
183 | rtmp_get_file_handle |
||
184 | }; |
||
185 | |||
186 | c6610a21 | Diego Elio Pettenò | URLProtocol ff_rtmpe_protocol = { |
187 | 0f943ce6 | Howard Chu | "rtmpe",
|
188 | rtmp_open, |
||
189 | rtmp_read, |
||
190 | rtmp_write, |
||
191 | NULL, /* seek */ |
||
192 | rtmp_close, |
||
193 | NULL, /* next */ |
||
194 | rtmp_read_pause, |
||
195 | rtmp_read_seek, |
||
196 | rtmp_get_file_handle |
||
197 | }; |
||
198 | |||
199 | c6610a21 | Diego Elio Pettenò | URLProtocol ff_rtmpte_protocol = { |
200 | 0f943ce6 | Howard Chu | "rtmpte",
|
201 | rtmp_open, |
||
202 | rtmp_read, |
||
203 | rtmp_write, |
||
204 | NULL, /* seek */ |
||
205 | rtmp_close, |
||
206 | NULL, /* next */ |
||
207 | rtmp_read_pause, |
||
208 | rtmp_read_seek, |
||
209 | rtmp_get_file_handle |
||
210 | }; |
||
211 | |||
212 | c6610a21 | Diego Elio Pettenò | URLProtocol ff_rtmps_protocol = { |
213 | 0f943ce6 | Howard Chu | "rtmps",
|
214 | rtmp_open, |
||
215 | rtmp_read, |
||
216 | rtmp_write, |
||
217 | NULL, /* seek */ |
||
218 | rtmp_close, |
||
219 | NULL, /* next */ |
||
220 | rtmp_read_pause, |
||
221 | rtmp_read_seek, |
||
222 | rtmp_get_file_handle |
||
223 | }; |