3 * Copyright (c) 2009 Colin McQuillian
4 * Copyright (c) 2010 Josh Allmann
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 * @brief Xiph / RTP Code
26 * @author Colin McQuillan <m.niloc@gmail.com>
27 * @author Josh Allmann <joshua.allmann@gmail.com>
30 #include "libavutil/attributes.h"
31 #include "libavutil/avassert.h"
32 #include "libavutil/avstring.h"
33 #include "libavutil/base64.h"
34 #include "libavcodec/bytestream.h"
38 #include "rtpdec_formats.h"
41 * RTP/Xiph specific private data.
43 struct PayloadContext
{
44 unsigned ident
; ///< 24-bit stream configuration identifier
46 AVIOContext
* fragment
; ///< buffer for split payloads
48 int split_pos
, split_buf_len
, split_buf_size
;
52 static PayloadContext
*xiph_new_context(void)
54 return av_mallocz(sizeof(PayloadContext
));
57 static inline void free_fragment_if_needed(PayloadContext
* data
)
61 avio_close_dyn_buf(data
->fragment
, &p
);
63 data
->fragment
= NULL
;
67 static void xiph_free_context(PayloadContext
* data
)
69 free_fragment_if_needed(data
);
70 av_free(data
->split_buf
);
74 static av_cold
int xiph_vorbis_init(AVFormatContext
*ctx
, int st_index
,
79 ctx
->streams
[st_index
]->need_parsing
= AVSTREAM_PARSE_HEADERS
;
84 static int xiph_handle_packet(AVFormatContext
*ctx
, PayloadContext
*data
,
85 AVStream
*st
, AVPacket
*pkt
, uint32_t *timestamp
,
86 const uint8_t *buf
, int len
, uint16_t seq
,
90 int ident
, fragmented
, tdt
, num_pkts
, pkt_len
;
93 if (!data
->split_buf
|| data
->split_pos
+ 2 > data
->split_buf_len
||
94 data
->split_pkts
<= 0) {
95 av_log(ctx
, AV_LOG_ERROR
, "No more data to return\n");
96 return AVERROR_INVALIDDATA
;
98 pkt_len
= AV_RB16(data
->split_buf
+ data
->split_pos
);
100 if (data
->split_pos
+ pkt_len
> data
->split_buf_len
) {
101 av_log(ctx
, AV_LOG_ERROR
, "Not enough data to return\n");
102 return AVERROR_INVALIDDATA
;
104 if (av_new_packet(pkt
, pkt_len
)) {
105 av_log(ctx
, AV_LOG_ERROR
, "Out of memory.\n");
106 return AVERROR(ENOMEM
);
108 pkt
->stream_index
= st
->index
;
109 memcpy(pkt
->data
, data
->split_buf
+ data
->split_pos
, pkt_len
);
110 data
->split_pos
+= pkt_len
;
112 return data
->split_pkts
> 0;
116 av_log(ctx
, AV_LOG_ERROR
, "Invalid %d byte packet\n", len
);
117 return AVERROR_INVALIDDATA
;
120 // read xiph rtp headers
121 ident
= AV_RB24(buf
);
122 fragmented
= buf
[3] >> 6;
123 tdt
= (buf
[3] >> 4) & 3;
124 num_pkts
= buf
[3] & 0xf;
125 pkt_len
= AV_RB16(buf
+ 4);
127 if (pkt_len
> len
- 6) {
128 av_log(ctx
, AV_LOG_ERROR
,
129 "Invalid packet length %d in %d byte packet\n", pkt_len
,
131 return AVERROR_INVALIDDATA
;
134 if (ident
!= data
->ident
) {
135 av_log(ctx
, AV_LOG_ERROR
,
136 "Unimplemented Xiph SDP configuration change detected\n");
137 return AVERROR_PATCHWELCOME
;
141 av_log(ctx
, AV_LOG_ERROR
,
142 "Unimplemented RTP Xiph packet settings (%d,%d,%d)\n",
143 fragmented
, tdt
, num_pkts
);
144 return AVERROR_PATCHWELCOME
;
147 buf
+= 6; // move past header bits
150 if (fragmented
== 0) {
151 if (av_new_packet(pkt
, pkt_len
)) {
152 av_log(ctx
, AV_LOG_ERROR
, "Out of memory.\n");
153 return AVERROR(ENOMEM
);
155 pkt
->stream_index
= st
->index
;
156 memcpy(pkt
->data
, buf
, pkt_len
);
162 if (len
> data
->split_buf_size
|| !data
->split_buf
) {
163 av_freep(&data
->split_buf
);
164 data
->split_buf_size
= 2 * len
;
165 data
->split_buf
= av_malloc(data
->split_buf_size
);
166 if (!data
->split_buf
) {
167 av_log(ctx
, AV_LOG_ERROR
, "Out of memory.\n");
169 return AVERROR(ENOMEM
);
172 memcpy(data
->split_buf
, buf
, len
);
173 data
->split_buf_len
= len
;
175 data
->split_pkts
= num_pkts
;
181 } else if (fragmented
== 1) {
182 // start of xiph data fragment
185 // end packet has been lost somewhere, so drop buffered data
186 free_fragment_if_needed(data
);
188 if((res
= avio_open_dyn_buf(&data
->fragment
)) < 0)
191 avio_write(data
->fragment
, buf
, pkt_len
);
192 data
->timestamp
= *timestamp
;
195 av_assert1(fragmented
< 4);
196 if (data
->timestamp
!= *timestamp
) {
197 // skip if fragmented timestamp is incorrect;
198 // a start packet has been lost somewhere
199 free_fragment_if_needed(data
);
200 av_log(ctx
, AV_LOG_ERROR
, "RTP timestamps don't match!\n");
201 return AVERROR_INVALIDDATA
;
203 if (!data
->fragment
) {
204 av_log(ctx
, AV_LOG_WARNING
,
205 "Received packet without a start fragment; dropping.\n");
206 return AVERROR(EAGAIN
);
209 // copy data to fragment buffer
210 avio_write(data
->fragment
, buf
, pkt_len
);
212 if (fragmented
== 3) {
213 // end of xiph data packet
214 int ret
= ff_rtp_finalize_packet(pkt
, &data
->fragment
, st
->index
);
216 av_log(ctx
, AV_LOG_ERROR
,
217 "Error occurred when getting fragment buffer.");
225 return AVERROR(EAGAIN
);
229 * Length encoding described in RFC5215 section 3.1.1.
231 static int get_base128(const uint8_t ** buf
, const uint8_t * buf_end
)
234 for (; *buf
< buf_end
; ++*buf
) {
237 if (!(**buf
& 0x80)) {
246 * Based off parse_packed_headers in Vorbis RTP
249 parse_packed_headers(const uint8_t * packed_headers
,
250 const uint8_t * packed_headers_end
,
251 AVCodecContext
* codec
, PayloadContext
* xiph_data
)
254 unsigned num_packed
, num_headers
, length
, length1
, length2
, extradata_alloc
;
257 if (packed_headers_end
- packed_headers
< 9) {
258 av_log(codec
, AV_LOG_ERROR
,
259 "Invalid %"PTRDIFF_SPECIFIER
" byte packed header.",
260 packed_headers_end
- packed_headers
);
261 return AVERROR_INVALIDDATA
;
264 num_packed
= bytestream_get_be32(&packed_headers
);
265 xiph_data
->ident
= bytestream_get_be24(&packed_headers
);
266 length
= bytestream_get_be16(&packed_headers
);
267 num_headers
= get_base128(&packed_headers
, packed_headers_end
);
268 length1
= get_base128(&packed_headers
, packed_headers_end
);
269 length2
= get_base128(&packed_headers
, packed_headers_end
);
271 if (num_packed
!= 1 || num_headers
> 3) {
272 av_log(codec
, AV_LOG_ERROR
,
273 "Unimplemented number of headers: %d packed headers, %d headers\n",
274 num_packed
, num_headers
);
275 return AVERROR_PATCHWELCOME
;
278 if (packed_headers_end
- packed_headers
!= length
||
279 length1
> length
|| length2
> length
- length1
) {
280 av_log(codec
, AV_LOG_ERROR
,
281 "Bad packed header lengths (%d,%d,%"PTRDIFF_SPECIFIER
",%d)\n", length1
,
282 length2
, packed_headers_end
- packed_headers
, length
);
283 return AVERROR_INVALIDDATA
;
286 /* allocate extra space:
287 * -- length/255 +2 for xiphlacing
288 * -- one for the '2' marker
289 * -- FF_INPUT_BUFFER_PADDING_SIZE required */
290 extradata_alloc
= length
+ length
/255 + 3 + FF_INPUT_BUFFER_PADDING_SIZE
;
292 if (ff_alloc_extradata(codec
, extradata_alloc
)) {
293 av_log(codec
, AV_LOG_ERROR
, "Out of memory\n");
294 return AVERROR(ENOMEM
);
296 ptr
= codec
->extradata
;
298 ptr
+= av_xiphlacing(ptr
, length1
);
299 ptr
+= av_xiphlacing(ptr
, length2
);
300 memcpy(ptr
, packed_headers
, length
);
302 codec
->extradata_size
= ptr
- codec
->extradata
;
303 // clear out remaining parts of the buffer
304 memset(ptr
, 0, extradata_alloc
- codec
->extradata_size
);
309 static int xiph_parse_fmtp_pair(AVFormatContext
*s
,
311 PayloadContext
*xiph_data
,
312 char *attr
, char *value
)
314 AVCodecContext
*codec
= stream
->codec
;
317 if (!strcmp(attr
, "sampling")) {
318 if (!strcmp(value
, "YCbCr-4:2:0")) {
319 codec
->pix_fmt
= AV_PIX_FMT_YUV420P
;
320 } else if (!strcmp(value
, "YCbCr-4:4:2")) {
321 codec
->pix_fmt
= AV_PIX_FMT_YUV422P
;
322 } else if (!strcmp(value
, "YCbCr-4:4:4")) {
323 codec
->pix_fmt
= AV_PIX_FMT_YUV444P
;
325 av_log(s
, AV_LOG_ERROR
,
326 "Unsupported pixel format %s\n", attr
);
327 return AVERROR_INVALIDDATA
;
329 } else if (!strcmp(attr
, "width")) {
330 /* This is an integer between 1 and 1048561
331 * and MUST be in multiples of 16. */
332 codec
->width
= atoi(value
);
334 } else if (!strcmp(attr
, "height")) {
335 /* This is an integer between 1 and 1048561
336 * and MUST be in multiples of 16. */
337 codec
->height
= atoi(value
);
339 } else if (!strcmp(attr
, "delivery-method")) {
340 /* Possible values are: inline, in_band, out_band/specific_name. */
341 return AVERROR_PATCHWELCOME
;
342 } else if (!strcmp(attr
, "configuration-uri")) {
343 /* NOTE: configuration-uri is supported only under 2 conditions:
344 *--after the delivery-method tag
345 * --with a delivery-method value of out_band */
346 return AVERROR_PATCHWELCOME
;
347 } else if (!strcmp(attr
, "configuration")) {
348 /* NOTE: configuration is supported only AFTER the delivery-method tag
349 * The configuration value is a base64 encoded packed header */
350 uint8_t *decoded_packet
= NULL
;
352 size_t decoded_alloc
= strlen(value
) / 4 * 3 + 4;
354 if (decoded_alloc
<= INT_MAX
) {
355 decoded_packet
= av_malloc(decoded_alloc
);
356 if (decoded_packet
) {
358 av_base64_decode(decoded_packet
, value
, decoded_alloc
);
360 result
= parse_packed_headers
361 (decoded_packet
, decoded_packet
+ packet_size
, codec
,
364 av_log(s
, AV_LOG_ERROR
,
365 "Out of memory while decoding SDP configuration.\n");
366 result
= AVERROR(ENOMEM
);
369 av_log(s
, AV_LOG_ERROR
, "Packet too large\n");
370 result
= AVERROR_INVALIDDATA
;
372 av_free(decoded_packet
);
377 static int xiph_parse_sdp_line(AVFormatContext
*s
, int st_index
,
378 PayloadContext
*data
, const char *line
)
385 if (av_strstart(line
, "fmtp:", &p
)) {
386 return ff_parse_fmtp(s
, s
->streams
[st_index
], data
, p
,
387 xiph_parse_fmtp_pair
);
393 RTPDynamicProtocolHandler ff_theora_dynamic_handler
= {
394 .enc_name
= "theora",
395 .codec_type
= AVMEDIA_TYPE_VIDEO
,
396 .codec_id
= AV_CODEC_ID_THEORA
,
397 .parse_sdp_a_line
= xiph_parse_sdp_line
,
398 .alloc
= xiph_new_context
,
399 .free
= xiph_free_context
,
400 .parse_packet
= xiph_handle_packet
403 RTPDynamicProtocolHandler ff_vorbis_dynamic_handler
= {
404 .enc_name
= "vorbis",
405 .codec_type
= AVMEDIA_TYPE_AUDIO
,
406 .codec_id
= AV_CODEC_ID_VORBIS
,
407 .init
= xiph_vorbis_init
,
408 .parse_sdp_a_line
= xiph_parse_sdp_line
,
409 .alloc
= xiph_new_context
,
410 .free
= xiph_free_context
,
411 .parse_packet
= xiph_handle_packet