yading@11
|
1 /*
|
yading@11
|
2 * copyright (c) 2007 Luca Abeni
|
yading@11
|
3 *
|
yading@11
|
4 * This file is part of FFmpeg.
|
yading@11
|
5 *
|
yading@11
|
6 * FFmpeg is free software; you can redistribute it and/or
|
yading@11
|
7 * modify it under the terms of the GNU Lesser General Public
|
yading@11
|
8 * License as published by the Free Software Foundation; either
|
yading@11
|
9 * version 2.1 of the License, or (at your option) any later version.
|
yading@11
|
10 *
|
yading@11
|
11 * FFmpeg is distributed in the hope that it will be useful,
|
yading@11
|
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@11
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@11
|
14 * Lesser General Public License for more details.
|
yading@11
|
15 *
|
yading@11
|
16 * You should have received a copy of the GNU Lesser General Public
|
yading@11
|
17 * License along with FFmpeg; if not, write to the Free Software
|
yading@11
|
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@11
|
19 */
|
yading@11
|
20
|
yading@11
|
21 #include <string.h>
|
yading@11
|
22 #include "libavutil/avstring.h"
|
yading@11
|
23 #include "libavutil/base64.h"
|
yading@11
|
24 #include "libavutil/dict.h"
|
yading@11
|
25 #include "libavutil/parseutils.h"
|
yading@11
|
26 #include "libavutil/opt.h"
|
yading@11
|
27 #include "libavcodec/xiph.h"
|
yading@11
|
28 #include "libavcodec/mpeg4audio.h"
|
yading@11
|
29 #include "avformat.h"
|
yading@11
|
30 #include "internal.h"
|
yading@11
|
31 #include "avc.h"
|
yading@11
|
32 #include "rtp.h"
|
yading@11
|
33 #if CONFIG_NETWORK
|
yading@11
|
34 #include "network.h"
|
yading@11
|
35 #endif
|
yading@11
|
36
|
yading@11
|
37 #if CONFIG_RTP_MUXER
|
yading@11
|
38 #define MAX_EXTRADATA_SIZE ((INT_MAX - 10) / 2)
|
yading@11
|
39
|
yading@11
|
40 struct sdp_session_level {
|
yading@11
|
41 int sdp_version; /**< protocol version (currently 0) */
|
yading@11
|
42 int id; /**< session ID */
|
yading@11
|
43 int version; /**< session version */
|
yading@11
|
44 int start_time; /**< session start time (NTP time, in seconds),
|
yading@11
|
45 or 0 in case of permanent session */
|
yading@11
|
46 int end_time; /**< session end time (NTP time, in seconds),
|
yading@11
|
47 or 0 if the session is not bounded */
|
yading@11
|
48 int ttl; /**< TTL, in case of multicast stream */
|
yading@11
|
49 const char *user; /**< username of the session's creator */
|
yading@11
|
50 const char *src_addr; /**< IP address of the machine from which the session was created */
|
yading@11
|
51 const char *src_type; /**< address type of src_addr */
|
yading@11
|
52 const char *dst_addr; /**< destination IP address (can be multicast) */
|
yading@11
|
53 const char *dst_type; /**< destination IP address type */
|
yading@11
|
54 const char *name; /**< session name (can be an empty string) */
|
yading@11
|
55 };
|
yading@11
|
56
|
yading@11
|
57 static void sdp_write_address(char *buff, int size, const char *dest_addr,
|
yading@11
|
58 const char *dest_type, int ttl)
|
yading@11
|
59 {
|
yading@11
|
60 if (dest_addr) {
|
yading@11
|
61 if (!dest_type)
|
yading@11
|
62 dest_type = "IP4";
|
yading@11
|
63 if (ttl > 0 && !strcmp(dest_type, "IP4")) {
|
yading@11
|
64 /* The TTL should only be specified for IPv4 multicast addresses,
|
yading@11
|
65 * not for IPv6. */
|
yading@11
|
66 av_strlcatf(buff, size, "c=IN %s %s/%d\r\n", dest_type, dest_addr, ttl);
|
yading@11
|
67 } else {
|
yading@11
|
68 av_strlcatf(buff, size, "c=IN %s %s\r\n", dest_type, dest_addr);
|
yading@11
|
69 }
|
yading@11
|
70 }
|
yading@11
|
71 }
|
yading@11
|
72
|
yading@11
|
73 static void sdp_write_header(char *buff, int size, struct sdp_session_level *s)
|
yading@11
|
74 {
|
yading@11
|
75 av_strlcatf(buff, size, "v=%d\r\n"
|
yading@11
|
76 "o=- %d %d IN %s %s\r\n"
|
yading@11
|
77 "s=%s\r\n",
|
yading@11
|
78 s->sdp_version,
|
yading@11
|
79 s->id, s->version, s->src_type, s->src_addr,
|
yading@11
|
80 s->name);
|
yading@11
|
81 sdp_write_address(buff, size, s->dst_addr, s->dst_type, s->ttl);
|
yading@11
|
82 av_strlcatf(buff, size, "t=%d %d\r\n"
|
yading@11
|
83 "a=tool:libavformat " AV_STRINGIFY(LIBAVFORMAT_VERSION) "\r\n",
|
yading@11
|
84 s->start_time, s->end_time);
|
yading@11
|
85 }
|
yading@11
|
86
|
yading@11
|
87 #if CONFIG_NETWORK
|
yading@11
|
88 static int resolve_destination(char *dest_addr, int size, char *type,
|
yading@11
|
89 int type_size)
|
yading@11
|
90 {
|
yading@11
|
91 struct addrinfo hints = { 0 }, *ai;
|
yading@11
|
92 int is_multicast;
|
yading@11
|
93
|
yading@11
|
94 av_strlcpy(type, "IP4", type_size);
|
yading@11
|
95 if (!dest_addr[0])
|
yading@11
|
96 return 0;
|
yading@11
|
97
|
yading@11
|
98 /* Resolve the destination, since it must be written
|
yading@11
|
99 * as a numeric IP address in the SDP. */
|
yading@11
|
100
|
yading@11
|
101 if (getaddrinfo(dest_addr, NULL, &hints, &ai))
|
yading@11
|
102 return 0;
|
yading@11
|
103 getnameinfo(ai->ai_addr, ai->ai_addrlen, dest_addr, size,
|
yading@11
|
104 NULL, 0, NI_NUMERICHOST);
|
yading@11
|
105 #ifdef AF_INET6
|
yading@11
|
106 if (ai->ai_family == AF_INET6)
|
yading@11
|
107 av_strlcpy(type, "IP6", type_size);
|
yading@11
|
108 #endif
|
yading@11
|
109 is_multicast = ff_is_multicast_address(ai->ai_addr);
|
yading@11
|
110 freeaddrinfo(ai);
|
yading@11
|
111 return is_multicast;
|
yading@11
|
112 }
|
yading@11
|
113 #else
|
yading@11
|
114 static int resolve_destination(char *dest_addr, int size, char *type,
|
yading@11
|
115 int type_size)
|
yading@11
|
116 {
|
yading@11
|
117 return 0;
|
yading@11
|
118 }
|
yading@11
|
119 #endif
|
yading@11
|
120
|
yading@11
|
121 static int sdp_get_address(char *dest_addr, int size, int *ttl, const char *url)
|
yading@11
|
122 {
|
yading@11
|
123 int port;
|
yading@11
|
124 const char *p;
|
yading@11
|
125 char proto[32];
|
yading@11
|
126
|
yading@11
|
127 av_url_split(proto, sizeof(proto), NULL, 0, dest_addr, size, &port, NULL, 0, url);
|
yading@11
|
128
|
yading@11
|
129 *ttl = 0;
|
yading@11
|
130
|
yading@11
|
131 if (strcmp(proto, "rtp") && strcmp(proto, "srtp")) {
|
yading@11
|
132 /* The url isn't for the actual rtp sessions,
|
yading@11
|
133 * don't parse out anything else than the destination.
|
yading@11
|
134 */
|
yading@11
|
135 return 0;
|
yading@11
|
136 }
|
yading@11
|
137
|
yading@11
|
138 p = strchr(url, '?');
|
yading@11
|
139 if (p) {
|
yading@11
|
140 char buff[64];
|
yading@11
|
141
|
yading@11
|
142 if (av_find_info_tag(buff, sizeof(buff), "ttl", p)) {
|
yading@11
|
143 *ttl = strtol(buff, NULL, 10);
|
yading@11
|
144 } else {
|
yading@11
|
145 *ttl = 5;
|
yading@11
|
146 }
|
yading@11
|
147 }
|
yading@11
|
148
|
yading@11
|
149 return port;
|
yading@11
|
150 }
|
yading@11
|
151
|
yading@11
|
152 #define MAX_PSET_SIZE 1024
|
yading@11
|
153 static char *extradata2psets(AVCodecContext *c)
|
yading@11
|
154 {
|
yading@11
|
155 char *psets, *p;
|
yading@11
|
156 const uint8_t *r;
|
yading@11
|
157 static const char pset_string[] = "; sprop-parameter-sets=";
|
yading@11
|
158 static const char profile_string[] = "; profile-level-id=";
|
yading@11
|
159 uint8_t *orig_extradata = NULL;
|
yading@11
|
160 int orig_extradata_size = 0;
|
yading@11
|
161 const uint8_t *sps = NULL, *sps_end;
|
yading@11
|
162
|
yading@11
|
163 if (c->extradata_size > MAX_EXTRADATA_SIZE) {
|
yading@11
|
164 av_log(c, AV_LOG_ERROR, "Too much extradata!\n");
|
yading@11
|
165
|
yading@11
|
166 return NULL;
|
yading@11
|
167 }
|
yading@11
|
168 if (c->extradata[0] == 1) {
|
yading@11
|
169 uint8_t *dummy_p;
|
yading@11
|
170 int dummy_int;
|
yading@11
|
171 AVBitStreamFilterContext *bsfc= av_bitstream_filter_init("h264_mp4toannexb");
|
yading@11
|
172
|
yading@11
|
173 if (!bsfc) {
|
yading@11
|
174 av_log(c, AV_LOG_ERROR, "Cannot open the h264_mp4toannexb BSF!\n");
|
yading@11
|
175
|
yading@11
|
176 return NULL;
|
yading@11
|
177 }
|
yading@11
|
178
|
yading@11
|
179 orig_extradata_size = c->extradata_size;
|
yading@11
|
180 orig_extradata = av_mallocz(orig_extradata_size +
|
yading@11
|
181 FF_INPUT_BUFFER_PADDING_SIZE);
|
yading@11
|
182 if (!orig_extradata) {
|
yading@11
|
183 av_bitstream_filter_close(bsfc);
|
yading@11
|
184 return NULL;
|
yading@11
|
185 }
|
yading@11
|
186 memcpy(orig_extradata, c->extradata, orig_extradata_size);
|
yading@11
|
187 av_bitstream_filter_filter(bsfc, c, NULL, &dummy_p, &dummy_int, NULL, 0, 0);
|
yading@11
|
188 av_bitstream_filter_close(bsfc);
|
yading@11
|
189 }
|
yading@11
|
190
|
yading@11
|
191 psets = av_mallocz(MAX_PSET_SIZE);
|
yading@11
|
192 if (psets == NULL) {
|
yading@11
|
193 av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the parameter sets.\n");
|
yading@11
|
194 av_free(orig_extradata);
|
yading@11
|
195 return NULL;
|
yading@11
|
196 }
|
yading@11
|
197 memcpy(psets, pset_string, strlen(pset_string));
|
yading@11
|
198 p = psets + strlen(pset_string);
|
yading@11
|
199 r = ff_avc_find_startcode(c->extradata, c->extradata + c->extradata_size);
|
yading@11
|
200 while (r < c->extradata + c->extradata_size) {
|
yading@11
|
201 const uint8_t *r1;
|
yading@11
|
202 uint8_t nal_type;
|
yading@11
|
203
|
yading@11
|
204 while (!*(r++));
|
yading@11
|
205 nal_type = *r & 0x1f;
|
yading@11
|
206 r1 = ff_avc_find_startcode(r, c->extradata + c->extradata_size);
|
yading@11
|
207 if (nal_type != 7 && nal_type != 8) { /* Only output SPS and PPS */
|
yading@11
|
208 r = r1;
|
yading@11
|
209 continue;
|
yading@11
|
210 }
|
yading@11
|
211 if (p != (psets + strlen(pset_string))) {
|
yading@11
|
212 *p = ',';
|
yading@11
|
213 p++;
|
yading@11
|
214 }
|
yading@11
|
215 if (!sps) {
|
yading@11
|
216 sps = r;
|
yading@11
|
217 sps_end = r1;
|
yading@11
|
218 }
|
yading@11
|
219 if (av_base64_encode(p, MAX_PSET_SIZE - (p - psets), r, r1 - r) == NULL) {
|
yading@11
|
220 av_log(c, AV_LOG_ERROR, "Cannot Base64-encode %td %td!\n", MAX_PSET_SIZE - (p - psets), r1 - r);
|
yading@11
|
221 av_free(psets);
|
yading@11
|
222
|
yading@11
|
223 return NULL;
|
yading@11
|
224 }
|
yading@11
|
225 p += strlen(p);
|
yading@11
|
226 r = r1;
|
yading@11
|
227 }
|
yading@11
|
228 if (sps && sps_end - sps >= 4) {
|
yading@11
|
229 memcpy(p, profile_string, strlen(profile_string));
|
yading@11
|
230 p += strlen(p);
|
yading@11
|
231 ff_data_to_hex(p, sps + 1, 3, 0);
|
yading@11
|
232 p[6] = '\0';
|
yading@11
|
233 }
|
yading@11
|
234 if (orig_extradata) {
|
yading@11
|
235 av_free(c->extradata);
|
yading@11
|
236 c->extradata = orig_extradata;
|
yading@11
|
237 c->extradata_size = orig_extradata_size;
|
yading@11
|
238 }
|
yading@11
|
239
|
yading@11
|
240 return psets;
|
yading@11
|
241 }
|
yading@11
|
242
|
yading@11
|
243 static char *extradata2config(AVCodecContext *c)
|
yading@11
|
244 {
|
yading@11
|
245 char *config;
|
yading@11
|
246
|
yading@11
|
247 if (c->extradata_size > MAX_EXTRADATA_SIZE) {
|
yading@11
|
248 av_log(c, AV_LOG_ERROR, "Too much extradata!\n");
|
yading@11
|
249
|
yading@11
|
250 return NULL;
|
yading@11
|
251 }
|
yading@11
|
252 config = av_malloc(10 + c->extradata_size * 2);
|
yading@11
|
253 if (config == NULL) {
|
yading@11
|
254 av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n");
|
yading@11
|
255 return NULL;
|
yading@11
|
256 }
|
yading@11
|
257 memcpy(config, "; config=", 9);
|
yading@11
|
258 ff_data_to_hex(config + 9, c->extradata, c->extradata_size, 0);
|
yading@11
|
259 config[9 + c->extradata_size * 2] = 0;
|
yading@11
|
260
|
yading@11
|
261 return config;
|
yading@11
|
262 }
|
yading@11
|
263
|
yading@11
|
264 static char *xiph_extradata2config(AVCodecContext *c)
|
yading@11
|
265 {
|
yading@11
|
266 char *config, *encoded_config;
|
yading@11
|
267 uint8_t *header_start[3];
|
yading@11
|
268 int headers_len, header_len[3], config_len;
|
yading@11
|
269 int first_header_size;
|
yading@11
|
270
|
yading@11
|
271 switch (c->codec_id) {
|
yading@11
|
272 case AV_CODEC_ID_THEORA:
|
yading@11
|
273 first_header_size = 42;
|
yading@11
|
274 break;
|
yading@11
|
275 case AV_CODEC_ID_VORBIS:
|
yading@11
|
276 first_header_size = 30;
|
yading@11
|
277 break;
|
yading@11
|
278 default:
|
yading@11
|
279 av_log(c, AV_LOG_ERROR, "Unsupported Xiph codec ID\n");
|
yading@11
|
280 return NULL;
|
yading@11
|
281 }
|
yading@11
|
282
|
yading@11
|
283 if (avpriv_split_xiph_headers(c->extradata, c->extradata_size,
|
yading@11
|
284 first_header_size, header_start,
|
yading@11
|
285 header_len) < 0) {
|
yading@11
|
286 av_log(c, AV_LOG_ERROR, "Extradata corrupt.\n");
|
yading@11
|
287 return NULL;
|
yading@11
|
288 }
|
yading@11
|
289
|
yading@11
|
290 headers_len = header_len[0] + header_len[2];
|
yading@11
|
291 config_len = 4 + // count
|
yading@11
|
292 3 + // ident
|
yading@11
|
293 2 + // packet size
|
yading@11
|
294 1 + // header count
|
yading@11
|
295 2 + // header size
|
yading@11
|
296 headers_len; // and the rest
|
yading@11
|
297
|
yading@11
|
298 config = av_malloc(config_len);
|
yading@11
|
299 if (!config)
|
yading@11
|
300 goto xiph_fail;
|
yading@11
|
301
|
yading@11
|
302 encoded_config = av_malloc(AV_BASE64_SIZE(config_len));
|
yading@11
|
303 if (!encoded_config) {
|
yading@11
|
304 av_free(config);
|
yading@11
|
305 goto xiph_fail;
|
yading@11
|
306 }
|
yading@11
|
307
|
yading@11
|
308 config[0] = config[1] = config[2] = 0;
|
yading@11
|
309 config[3] = 1;
|
yading@11
|
310 config[4] = (RTP_XIPH_IDENT >> 16) & 0xff;
|
yading@11
|
311 config[5] = (RTP_XIPH_IDENT >> 8) & 0xff;
|
yading@11
|
312 config[6] = (RTP_XIPH_IDENT ) & 0xff;
|
yading@11
|
313 config[7] = (headers_len >> 8) & 0xff;
|
yading@11
|
314 config[8] = headers_len & 0xff;
|
yading@11
|
315 config[9] = 2;
|
yading@11
|
316 config[10] = header_len[0];
|
yading@11
|
317 config[11] = 0; // size of comment header; nonexistent
|
yading@11
|
318 memcpy(config + 12, header_start[0], header_len[0]);
|
yading@11
|
319 memcpy(config + 12 + header_len[0], header_start[2], header_len[2]);
|
yading@11
|
320
|
yading@11
|
321 av_base64_encode(encoded_config, AV_BASE64_SIZE(config_len),
|
yading@11
|
322 config, config_len);
|
yading@11
|
323 av_free(config);
|
yading@11
|
324
|
yading@11
|
325 return encoded_config;
|
yading@11
|
326
|
yading@11
|
327 xiph_fail:
|
yading@11
|
328 av_log(c, AV_LOG_ERROR,
|
yading@11
|
329 "Not enough memory for configuration string\n");
|
yading@11
|
330 return NULL;
|
yading@11
|
331 }
|
yading@11
|
332
|
yading@11
|
333 static int latm_context2profilelevel(AVCodecContext *c)
|
yading@11
|
334 {
|
yading@11
|
335 /* MP4A-LATM
|
yading@11
|
336 * The RTP payload format specification is described in RFC 3016
|
yading@11
|
337 * The encoding specifications are provided in ISO/IEC 14496-3 */
|
yading@11
|
338
|
yading@11
|
339 int profile_level = 0x2B;
|
yading@11
|
340
|
yading@11
|
341 /* TODO: AAC Profile only supports AAC LC Object Type.
|
yading@11
|
342 * Different Object Types should implement different Profile Levels */
|
yading@11
|
343
|
yading@11
|
344 if (c->sample_rate <= 24000) {
|
yading@11
|
345 if (c->channels <= 2)
|
yading@11
|
346 profile_level = 0x28; // AAC Profile, Level 1
|
yading@11
|
347 } else if (c->sample_rate <= 48000) {
|
yading@11
|
348 if (c->channels <= 2) {
|
yading@11
|
349 profile_level = 0x29; // AAC Profile, Level 2
|
yading@11
|
350 } else if (c->channels <= 5) {
|
yading@11
|
351 profile_level = 0x2A; // AAC Profile, Level 4
|
yading@11
|
352 }
|
yading@11
|
353 } else if (c->sample_rate <= 96000) {
|
yading@11
|
354 if (c->channels <= 5) {
|
yading@11
|
355 profile_level = 0x2B; // AAC Profile, Level 5
|
yading@11
|
356 }
|
yading@11
|
357 }
|
yading@11
|
358
|
yading@11
|
359 return profile_level;
|
yading@11
|
360 }
|
yading@11
|
361
|
yading@11
|
362 static char *latm_context2config(AVCodecContext *c)
|
yading@11
|
363 {
|
yading@11
|
364 /* MP4A-LATM
|
yading@11
|
365 * The RTP payload format specification is described in RFC 3016
|
yading@11
|
366 * The encoding specifications are provided in ISO/IEC 14496-3 */
|
yading@11
|
367
|
yading@11
|
368 uint8_t config_byte[6];
|
yading@11
|
369 int rate_index;
|
yading@11
|
370 char *config;
|
yading@11
|
371
|
yading@11
|
372 for (rate_index = 0; rate_index < 16; rate_index++)
|
yading@11
|
373 if (avpriv_mpeg4audio_sample_rates[rate_index] == c->sample_rate)
|
yading@11
|
374 break;
|
yading@11
|
375 if (rate_index == 16) {
|
yading@11
|
376 av_log(c, AV_LOG_ERROR, "Unsupported sample rate\n");
|
yading@11
|
377 return NULL;
|
yading@11
|
378 }
|
yading@11
|
379
|
yading@11
|
380 config_byte[0] = 0x40;
|
yading@11
|
381 config_byte[1] = 0;
|
yading@11
|
382 config_byte[2] = 0x20 | rate_index;
|
yading@11
|
383 config_byte[3] = c->channels << 4;
|
yading@11
|
384 config_byte[4] = 0x3f;
|
yading@11
|
385 config_byte[5] = 0xc0;
|
yading@11
|
386
|
yading@11
|
387 config = av_malloc(6*2+1);
|
yading@11
|
388 if (!config) {
|
yading@11
|
389 av_log(c, AV_LOG_ERROR, "Cannot allocate memory for the config info.\n");
|
yading@11
|
390 return NULL;
|
yading@11
|
391 }
|
yading@11
|
392 ff_data_to_hex(config, config_byte, 6, 1);
|
yading@11
|
393 config[12] = 0;
|
yading@11
|
394
|
yading@11
|
395 return config;
|
yading@11
|
396 }
|
yading@11
|
397
|
yading@11
|
398 static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, int payload_type, AVFormatContext *fmt)
|
yading@11
|
399 {
|
yading@11
|
400 char *config = NULL;
|
yading@11
|
401
|
yading@11
|
402 switch (c->codec_id) {
|
yading@11
|
403 case AV_CODEC_ID_H264: {
|
yading@11
|
404 int mode = 1;
|
yading@11
|
405 if (fmt && fmt->oformat->priv_class &&
|
yading@11
|
406 av_opt_flag_is_set(fmt->priv_data, "rtpflags", "h264_mode0"))
|
yading@11
|
407 mode = 0;
|
yading@11
|
408 if (c->extradata_size) {
|
yading@11
|
409 config = extradata2psets(c);
|
yading@11
|
410 }
|
yading@11
|
411 av_strlcatf(buff, size, "a=rtpmap:%d H264/90000\r\n"
|
yading@11
|
412 "a=fmtp:%d packetization-mode=%d%s\r\n",
|
yading@11
|
413 payload_type,
|
yading@11
|
414 payload_type, mode, config ? config : "");
|
yading@11
|
415 break;
|
yading@11
|
416 }
|
yading@11
|
417 case AV_CODEC_ID_H263:
|
yading@11
|
418 case AV_CODEC_ID_H263P:
|
yading@11
|
419 /* a=framesize is required by 3GPP TS 26.234 (PSS). It
|
yading@11
|
420 * actually specifies the maximum video size, but we only know
|
yading@11
|
421 * the current size. This is required for playback on Android
|
yading@11
|
422 * stagefright and on Samsung bada. */
|
yading@11
|
423 if (!fmt || !fmt->oformat->priv_class ||
|
yading@11
|
424 !av_opt_flag_is_set(fmt->priv_data, "rtpflags", "rfc2190") ||
|
yading@11
|
425 c->codec_id == AV_CODEC_ID_H263P)
|
yading@11
|
426 av_strlcatf(buff, size, "a=rtpmap:%d H263-2000/90000\r\n"
|
yading@11
|
427 "a=framesize:%d %d-%d\r\n",
|
yading@11
|
428 payload_type,
|
yading@11
|
429 payload_type, c->width, c->height);
|
yading@11
|
430 break;
|
yading@11
|
431 case AV_CODEC_ID_MPEG4:
|
yading@11
|
432 if (c->extradata_size) {
|
yading@11
|
433 config = extradata2config(c);
|
yading@11
|
434 }
|
yading@11
|
435 av_strlcatf(buff, size, "a=rtpmap:%d MP4V-ES/90000\r\n"
|
yading@11
|
436 "a=fmtp:%d profile-level-id=1%s\r\n",
|
yading@11
|
437 payload_type,
|
yading@11
|
438 payload_type, config ? config : "");
|
yading@11
|
439 break;
|
yading@11
|
440 case AV_CODEC_ID_AAC:
|
yading@11
|
441 if (fmt && fmt->oformat && fmt->oformat->priv_class &&
|
yading@11
|
442 av_opt_flag_is_set(fmt->priv_data, "rtpflags", "latm")) {
|
yading@11
|
443 config = latm_context2config(c);
|
yading@11
|
444 if (!config)
|
yading@11
|
445 return NULL;
|
yading@11
|
446 av_strlcatf(buff, size, "a=rtpmap:%d MP4A-LATM/%d/%d\r\n"
|
yading@11
|
447 "a=fmtp:%d profile-level-id=%d;cpresent=0;config=%s\r\n",
|
yading@11
|
448 payload_type, c->sample_rate, c->channels,
|
yading@11
|
449 payload_type, latm_context2profilelevel(c), config);
|
yading@11
|
450 } else {
|
yading@11
|
451 if (c->extradata_size) {
|
yading@11
|
452 config = extradata2config(c);
|
yading@11
|
453 } else {
|
yading@11
|
454 /* FIXME: maybe we can forge config information based on the
|
yading@11
|
455 * codec parameters...
|
yading@11
|
456 */
|
yading@11
|
457 av_log(c, AV_LOG_ERROR, "AAC with no global headers is currently not supported.\n");
|
yading@11
|
458 return NULL;
|
yading@11
|
459 }
|
yading@11
|
460 if (config == NULL) {
|
yading@11
|
461 return NULL;
|
yading@11
|
462 }
|
yading@11
|
463 av_strlcatf(buff, size, "a=rtpmap:%d MPEG4-GENERIC/%d/%d\r\n"
|
yading@11
|
464 "a=fmtp:%d profile-level-id=1;"
|
yading@11
|
465 "mode=AAC-hbr;sizelength=13;indexlength=3;"
|
yading@11
|
466 "indexdeltalength=3%s\r\n",
|
yading@11
|
467 payload_type, c->sample_rate, c->channels,
|
yading@11
|
468 payload_type, config);
|
yading@11
|
469 }
|
yading@11
|
470 break;
|
yading@11
|
471 case AV_CODEC_ID_PCM_S16BE:
|
yading@11
|
472 if (payload_type >= RTP_PT_PRIVATE)
|
yading@11
|
473 av_strlcatf(buff, size, "a=rtpmap:%d L16/%d/%d\r\n",
|
yading@11
|
474 payload_type,
|
yading@11
|
475 c->sample_rate, c->channels);
|
yading@11
|
476 break;
|
yading@11
|
477 case AV_CODEC_ID_PCM_MULAW:
|
yading@11
|
478 if (payload_type >= RTP_PT_PRIVATE)
|
yading@11
|
479 av_strlcatf(buff, size, "a=rtpmap:%d PCMU/%d/%d\r\n",
|
yading@11
|
480 payload_type,
|
yading@11
|
481 c->sample_rate, c->channels);
|
yading@11
|
482 break;
|
yading@11
|
483 case AV_CODEC_ID_PCM_ALAW:
|
yading@11
|
484 if (payload_type >= RTP_PT_PRIVATE)
|
yading@11
|
485 av_strlcatf(buff, size, "a=rtpmap:%d PCMA/%d/%d\r\n",
|
yading@11
|
486 payload_type,
|
yading@11
|
487 c->sample_rate, c->channels);
|
yading@11
|
488 break;
|
yading@11
|
489 case AV_CODEC_ID_AMR_NB:
|
yading@11
|
490 av_strlcatf(buff, size, "a=rtpmap:%d AMR/%d/%d\r\n"
|
yading@11
|
491 "a=fmtp:%d octet-align=1\r\n",
|
yading@11
|
492 payload_type, c->sample_rate, c->channels,
|
yading@11
|
493 payload_type);
|
yading@11
|
494 break;
|
yading@11
|
495 case AV_CODEC_ID_AMR_WB:
|
yading@11
|
496 av_strlcatf(buff, size, "a=rtpmap:%d AMR-WB/%d/%d\r\n"
|
yading@11
|
497 "a=fmtp:%d octet-align=1\r\n",
|
yading@11
|
498 payload_type, c->sample_rate, c->channels,
|
yading@11
|
499 payload_type);
|
yading@11
|
500 break;
|
yading@11
|
501 case AV_CODEC_ID_VORBIS:
|
yading@11
|
502 if (c->extradata_size)
|
yading@11
|
503 config = xiph_extradata2config(c);
|
yading@11
|
504 else
|
yading@11
|
505 av_log(c, AV_LOG_ERROR, "Vorbis configuration info missing\n");
|
yading@11
|
506 if (!config)
|
yading@11
|
507 return NULL;
|
yading@11
|
508
|
yading@11
|
509 av_strlcatf(buff, size, "a=rtpmap:%d vorbis/%d/%d\r\n"
|
yading@11
|
510 "a=fmtp:%d configuration=%s\r\n",
|
yading@11
|
511 payload_type, c->sample_rate, c->channels,
|
yading@11
|
512 payload_type, config);
|
yading@11
|
513 break;
|
yading@11
|
514 case AV_CODEC_ID_THEORA: {
|
yading@11
|
515 const char *pix_fmt;
|
yading@11
|
516 if (c->extradata_size)
|
yading@11
|
517 config = xiph_extradata2config(c);
|
yading@11
|
518 else
|
yading@11
|
519 av_log(c, AV_LOG_ERROR, "Theora configuation info missing\n");
|
yading@11
|
520 if (!config)
|
yading@11
|
521 return NULL;
|
yading@11
|
522
|
yading@11
|
523 switch (c->pix_fmt) {
|
yading@11
|
524 case AV_PIX_FMT_YUV420P:
|
yading@11
|
525 pix_fmt = "YCbCr-4:2:0";
|
yading@11
|
526 break;
|
yading@11
|
527 case AV_PIX_FMT_YUV422P:
|
yading@11
|
528 pix_fmt = "YCbCr-4:2:2";
|
yading@11
|
529 break;
|
yading@11
|
530 case AV_PIX_FMT_YUV444P:
|
yading@11
|
531 pix_fmt = "YCbCr-4:4:4";
|
yading@11
|
532 break;
|
yading@11
|
533 default:
|
yading@11
|
534 av_log(c, AV_LOG_ERROR, "Unsupported pixel format.\n");
|
yading@11
|
535 return NULL;
|
yading@11
|
536 }
|
yading@11
|
537
|
yading@11
|
538 av_strlcatf(buff, size, "a=rtpmap:%d theora/90000\r\n"
|
yading@11
|
539 "a=fmtp:%d delivery-method=inline; "
|
yading@11
|
540 "width=%d; height=%d; sampling=%s; "
|
yading@11
|
541 "configuration=%s\r\n",
|
yading@11
|
542 payload_type, payload_type,
|
yading@11
|
543 c->width, c->height, pix_fmt, config);
|
yading@11
|
544 break;
|
yading@11
|
545 }
|
yading@11
|
546 case AV_CODEC_ID_VP8:
|
yading@11
|
547 av_strlcatf(buff, size, "a=rtpmap:%d VP8/90000\r\n",
|
yading@11
|
548 payload_type);
|
yading@11
|
549 break;
|
yading@11
|
550 case AV_CODEC_ID_MJPEG:
|
yading@11
|
551 if (payload_type >= RTP_PT_PRIVATE)
|
yading@11
|
552 av_strlcatf(buff, size, "a=rtpmap:%d JPEG/90000\r\n",
|
yading@11
|
553 payload_type);
|
yading@11
|
554 break;
|
yading@11
|
555 case AV_CODEC_ID_ADPCM_G722:
|
yading@11
|
556 if (payload_type >= RTP_PT_PRIVATE)
|
yading@11
|
557 av_strlcatf(buff, size, "a=rtpmap:%d G722/%d/%d\r\n",
|
yading@11
|
558 payload_type,
|
yading@11
|
559 8000, c->channels);
|
yading@11
|
560 break;
|
yading@11
|
561 case AV_CODEC_ID_ADPCM_G726: {
|
yading@11
|
562 if (payload_type >= RTP_PT_PRIVATE)
|
yading@11
|
563 av_strlcatf(buff, size, "a=rtpmap:%d G726-%d/%d\r\n",
|
yading@11
|
564 payload_type,
|
yading@11
|
565 c->bits_per_coded_sample*8,
|
yading@11
|
566 c->sample_rate);
|
yading@11
|
567 break;
|
yading@11
|
568 }
|
yading@11
|
569 case AV_CODEC_ID_ILBC:
|
yading@11
|
570 av_strlcatf(buff, size, "a=rtpmap:%d iLBC/%d\r\n"
|
yading@11
|
571 "a=fmtp:%d mode=%d\r\n",
|
yading@11
|
572 payload_type, c->sample_rate,
|
yading@11
|
573 payload_type, c->block_align == 38 ? 20 : 30);
|
yading@11
|
574 break;
|
yading@11
|
575 case AV_CODEC_ID_SPEEX:
|
yading@11
|
576 av_strlcatf(buff, size, "a=rtpmap:%d speex/%d\r\n",
|
yading@11
|
577 payload_type, c->sample_rate);
|
yading@11
|
578 if (c->codec) {
|
yading@11
|
579 const char *mode;
|
yading@11
|
580 uint64_t vad_option;
|
yading@11
|
581
|
yading@11
|
582 if (c->flags & CODEC_FLAG_QSCALE)
|
yading@11
|
583 mode = "on";
|
yading@11
|
584 else if (!av_opt_get_int(c, "vad", AV_OPT_FLAG_ENCODING_PARAM, &vad_option) && vad_option)
|
yading@11
|
585 mode = "vad";
|
yading@11
|
586 else
|
yading@11
|
587 mode = "off";
|
yading@11
|
588
|
yading@11
|
589 av_strlcatf(buff, size, "a=fmtp:%d vbr=%s\r\n",
|
yading@11
|
590 payload_type, mode);
|
yading@11
|
591 }
|
yading@11
|
592 break;
|
yading@11
|
593 case AV_CODEC_ID_OPUS:
|
yading@11
|
594 av_strlcatf(buff, size, "a=rtpmap:%d opus/48000\r\n",
|
yading@11
|
595 payload_type);
|
yading@11
|
596 break;
|
yading@11
|
597 default:
|
yading@11
|
598 /* Nothing special to do here... */
|
yading@11
|
599 break;
|
yading@11
|
600 }
|
yading@11
|
601
|
yading@11
|
602 av_free(config);
|
yading@11
|
603
|
yading@11
|
604 return buff;
|
yading@11
|
605 }
|
yading@11
|
606
|
yading@11
|
607 void ff_sdp_write_media(char *buff, int size, AVStream *st, int idx,
|
yading@11
|
608 const char *dest_addr, const char *dest_type,
|
yading@11
|
609 int port, int ttl, AVFormatContext *fmt)
|
yading@11
|
610 {
|
yading@11
|
611 AVCodecContext *c = st->codec;
|
yading@11
|
612 const char *type;
|
yading@11
|
613 int payload_type;
|
yading@11
|
614
|
yading@11
|
615 payload_type = ff_rtp_get_payload_type(fmt, c, idx);
|
yading@11
|
616
|
yading@11
|
617 switch (c->codec_type) {
|
yading@11
|
618 case AVMEDIA_TYPE_VIDEO : type = "video" ; break;
|
yading@11
|
619 case AVMEDIA_TYPE_AUDIO : type = "audio" ; break;
|
yading@11
|
620 case AVMEDIA_TYPE_SUBTITLE: type = "text" ; break;
|
yading@11
|
621 default : type = "application"; break;
|
yading@11
|
622 }
|
yading@11
|
623
|
yading@11
|
624 av_strlcatf(buff, size, "m=%s %d RTP/AVP %d\r\n", type, port, payload_type);
|
yading@11
|
625 sdp_write_address(buff, size, dest_addr, dest_type, ttl);
|
yading@11
|
626 if (c->bit_rate) {
|
yading@11
|
627 av_strlcatf(buff, size, "b=AS:%d\r\n", c->bit_rate / 1000);
|
yading@11
|
628 }
|
yading@11
|
629
|
yading@11
|
630 sdp_write_media_attributes(buff, size, c, payload_type, fmt);
|
yading@11
|
631 }
|
yading@11
|
632
|
yading@11
|
633 int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
|
yading@11
|
634 {
|
yading@11
|
635 AVDictionaryEntry *title = av_dict_get(ac[0]->metadata, "title", NULL, 0);
|
yading@11
|
636 struct sdp_session_level s = { 0 };
|
yading@11
|
637 int i, j, port, ttl, is_multicast, index = 0;
|
yading@11
|
638 char dst[32], dst_type[5];
|
yading@11
|
639
|
yading@11
|
640 memset(buf, 0, size);
|
yading@11
|
641 s.user = "-";
|
yading@11
|
642 s.src_addr = "127.0.0.1"; /* FIXME: Properly set this */
|
yading@11
|
643 s.src_type = "IP4";
|
yading@11
|
644 s.name = title ? title->value : "No Name";
|
yading@11
|
645
|
yading@11
|
646 port = 0;
|
yading@11
|
647 ttl = 0;
|
yading@11
|
648 if (n_files == 1) {
|
yading@11
|
649 port = sdp_get_address(dst, sizeof(dst), &ttl, ac[0]->filename);
|
yading@11
|
650 is_multicast = resolve_destination(dst, sizeof(dst), dst_type,
|
yading@11
|
651 sizeof(dst_type));
|
yading@11
|
652 if (!is_multicast)
|
yading@11
|
653 ttl = 0;
|
yading@11
|
654 if (dst[0]) {
|
yading@11
|
655 s.dst_addr = dst;
|
yading@11
|
656 s.dst_type = dst_type;
|
yading@11
|
657 s.ttl = ttl;
|
yading@11
|
658 if (!strcmp(dst_type, "IP6")) {
|
yading@11
|
659 s.src_addr = "::1";
|
yading@11
|
660 s.src_type = "IP6";
|
yading@11
|
661 }
|
yading@11
|
662 }
|
yading@11
|
663 }
|
yading@11
|
664 sdp_write_header(buf, size, &s);
|
yading@11
|
665
|
yading@11
|
666 dst[0] = 0;
|
yading@11
|
667 for (i = 0; i < n_files; i++) {
|
yading@11
|
668 if (n_files != 1) {
|
yading@11
|
669 port = sdp_get_address(dst, sizeof(dst), &ttl, ac[i]->filename);
|
yading@11
|
670 is_multicast = resolve_destination(dst, sizeof(dst), dst_type,
|
yading@11
|
671 sizeof(dst_type));
|
yading@11
|
672 if (!is_multicast)
|
yading@11
|
673 ttl = 0;
|
yading@11
|
674 }
|
yading@11
|
675 for (j = 0; j < ac[i]->nb_streams; j++) {
|
yading@11
|
676 ff_sdp_write_media(buf, size, ac[i]->streams[j], index++,
|
yading@11
|
677 dst[0] ? dst : NULL, dst_type,
|
yading@11
|
678 (port > 0) ? port + j * 2 : 0,
|
yading@11
|
679 ttl, ac[i]);
|
yading@11
|
680 if (port <= 0) {
|
yading@11
|
681 av_strlcatf(buf, size,
|
yading@11
|
682 "a=control:streamid=%d\r\n", i + j);
|
yading@11
|
683 }
|
yading@11
|
684 if (ac[i]->pb && ac[i]->pb->av_class) {
|
yading@11
|
685 uint8_t *crypto_suite = NULL, *crypto_params = NULL;
|
yading@11
|
686 av_opt_get(ac[i]->pb, "srtp_out_suite", AV_OPT_SEARCH_CHILDREN,
|
yading@11
|
687 &crypto_suite);
|
yading@11
|
688 av_opt_get(ac[i]->pb, "srtp_out_params", AV_OPT_SEARCH_CHILDREN,
|
yading@11
|
689 &crypto_params);
|
yading@11
|
690 if (crypto_suite && crypto_suite[0])
|
yading@11
|
691 av_strlcatf(buf, size,
|
yading@11
|
692 "a=crypto:1 %s inline:%s\r\n",
|
yading@11
|
693 crypto_suite, crypto_params);
|
yading@11
|
694 av_free(crypto_suite);
|
yading@11
|
695 av_free(crypto_params);
|
yading@11
|
696 }
|
yading@11
|
697 }
|
yading@11
|
698 }
|
yading@11
|
699
|
yading@11
|
700 return 0;
|
yading@11
|
701 }
|
yading@11
|
702 #else
|
yading@11
|
703 int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size)
|
yading@11
|
704 {
|
yading@11
|
705 return AVERROR(ENOSYS);
|
yading@11
|
706 }
|
yading@11
|
707
|
yading@11
|
708 void ff_sdp_write_media(char *buff, int size, AVStream *st, int idx,
|
yading@11
|
709 const char *dest_addr, const char *dest_type,
|
yading@11
|
710 int port, int ttl, AVFormatContext *fmt)
|
yading@11
|
711 {
|
yading@11
|
712 }
|
yading@11
|
713 #endif
|