FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
rtpdec_xiph.c
Go to the documentation of this file.
1 /*
2  * Xiph RTP Protocols
3  * Copyright (c) 2009 Colin McQuillian
4  * Copyright (c) 2010 Josh Allmann
5  *
6  * This file is part of FFmpeg.
7  *
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.
12  *
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.
17  *
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
21  */
22 
23 /**
24  * @file
25  * @brief Xiph / RTP Code
26  * @author Colin McQuillan <m.niloc@gmail.com>
27  * @author Josh Allmann <joshua.allmann@gmail.com>
28  */
29 
30 #include "libavutil/avassert.h"
31 #include "libavutil/avstring.h"
32 #include "libavutil/base64.h"
33 #include "libavcodec/bytestream.h"
34 
35 #include "rtpdec.h"
36 #include "rtpdec_formats.h"
37 
38 /**
39  * RTP/Xiph specific private data.
40  */
41 struct PayloadContext {
42  unsigned ident; ///< 24-bit stream configuration identifier
43  uint32_t timestamp;
44  AVIOContext* fragment; ///< buffer for split payloads
48 };
49 
51 {
52  return av_mallocz(sizeof(PayloadContext));
53 }
54 
56 {
57  if (data->fragment) {
58  uint8_t* p;
59  avio_close_dyn_buf(data->fragment, &p);
60  av_free(p);
61  data->fragment = NULL;
62  }
63 }
64 
66 {
68  av_free(data->split_buf);
69  av_free(data);
70 }
71 
73  AVStream *st, AVPacket *pkt, uint32_t *timestamp,
74  const uint8_t *buf, int len, uint16_t seq,
75  int flags)
76 {
77 
78  int ident, fragmented, tdt, num_pkts, pkt_len;
79 
80  if (!buf) {
81  if (!data->split_buf || data->split_pos + 2 > data->split_buf_len ||
82  data->split_pkts <= 0) {
83  av_log(ctx, AV_LOG_ERROR, "No more data to return\n");
84  return AVERROR_INVALIDDATA;
85  }
86  pkt_len = AV_RB16(data->split_buf + data->split_pos);
87  data->split_pos += 2;
88  if (data->split_pos + pkt_len > data->split_buf_len) {
89  av_log(ctx, AV_LOG_ERROR, "Not enough data to return\n");
90  return AVERROR_INVALIDDATA;
91  }
92  if (av_new_packet(pkt, pkt_len)) {
93  av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
94  return AVERROR(ENOMEM);
95  }
96  pkt->stream_index = st->index;
97  memcpy(pkt->data, data->split_buf + data->split_pos, pkt_len);
98  data->split_pos += pkt_len;
99  data->split_pkts--;
100  return data->split_pkts > 0;
101  }
102 
103  if (len < 6) {
104  av_log(ctx, AV_LOG_ERROR, "Invalid %d byte packet\n", len);
105  return AVERROR_INVALIDDATA;
106  }
107 
108  // read xiph rtp headers
109  ident = AV_RB24(buf);
110  fragmented = buf[3] >> 6;
111  tdt = (buf[3] >> 4) & 3;
112  num_pkts = buf[3] & 0xf;
113  pkt_len = AV_RB16(buf + 4);
114 
115  if (pkt_len > len - 6) {
116  av_log(ctx, AV_LOG_ERROR,
117  "Invalid packet length %d in %d byte packet\n", pkt_len,
118  len);
119  return AVERROR_INVALIDDATA;
120  }
121 
122  if (ident != data->ident) {
123  av_log(ctx, AV_LOG_ERROR,
124  "Unimplemented Xiph SDP configuration change detected\n");
125  return AVERROR_PATCHWELCOME;
126  }
127 
128  if (tdt) {
129  av_log(ctx, AV_LOG_ERROR,
130  "Unimplemented RTP Xiph packet settings (%d,%d,%d)\n",
131  fragmented, tdt, num_pkts);
132  return AVERROR_PATCHWELCOME;
133  }
134 
135  buf += 6; // move past header bits
136  len -= 6;
137 
138  if (fragmented == 0) {
139  if (av_new_packet(pkt, pkt_len)) {
140  av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
141  return AVERROR(ENOMEM);
142  }
143  pkt->stream_index = st->index;
144  memcpy(pkt->data, buf, pkt_len);
145  buf += pkt_len;
146  len -= pkt_len;
147  num_pkts--;
148 
149  if (num_pkts > 0) {
150  if (len > data->split_buf_size || !data->split_buf) {
151  av_freep(&data->split_buf);
152  data->split_buf_size = 2 * len;
153  data->split_buf = av_malloc(data->split_buf_size);
154  if (!data->split_buf) {
155  av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
156  av_free_packet(pkt);
157  return AVERROR(ENOMEM);
158  }
159  }
160  memcpy(data->split_buf, buf, len);
161  data->split_buf_len = len;
162  data->split_pos = 0;
163  data->split_pkts = num_pkts;
164  return 1;
165  }
166 
167  return 0;
168 
169  } else if (fragmented == 1) {
170  // start of xiph data fragment
171  int res;
172 
173  // end packet has been lost somewhere, so drop buffered data
175 
176  if((res = avio_open_dyn_buf(&data->fragment)) < 0)
177  return res;
178 
179  avio_write(data->fragment, buf, pkt_len);
180  data->timestamp = *timestamp;
181 
182  } else {
183  av_assert1(fragmented < 4);
184  if (data->timestamp != *timestamp) {
185  // skip if fragmented timestamp is incorrect;
186  // a start packet has been lost somewhere
188  av_log(ctx, AV_LOG_ERROR, "RTP timestamps don't match!\n");
189  return AVERROR_INVALIDDATA;
190  }
191  if (!data->fragment) {
192  av_log(ctx, AV_LOG_WARNING,
193  "Received packet without a start fragment; dropping.\n");
194  return AVERROR(EAGAIN);
195  }
196 
197  // copy data to fragment buffer
198  avio_write(data->fragment, buf, pkt_len);
199 
200  if (fragmented == 3) {
201  // end of xiph data packet
202  int ret = ff_rtp_finalize_packet(pkt, &data->fragment, st->index);
203  if (ret < 0) {
204  av_log(ctx, AV_LOG_ERROR,
205  "Error occurred when getting fragment buffer.");
206  return ret;
207  }
208 
209  return 0;
210  }
211  }
212 
213  return AVERROR(EAGAIN);
214 }
215 
216 /**
217  * Length encoding described in RFC5215 section 3.1.1.
218  */
219 static int get_base128(const uint8_t ** buf, const uint8_t * buf_end)
220 {
221  int n = 0;
222  for (; *buf < buf_end; ++*buf) {
223  n <<= 7;
224  n += **buf & 0x7f;
225  if (!(**buf & 0x80)) {
226  ++*buf;
227  return n;
228  }
229  }
230  return 0;
231 }
232 
233 /**
234  * Based off parse_packed_headers in Vorbis RTP
235  */
236 static int
237 parse_packed_headers(const uint8_t * packed_headers,
238  const uint8_t * packed_headers_end,
239  AVCodecContext * codec, PayloadContext * xiph_data)
240 {
241 
242  unsigned num_packed, num_headers, length, length1, length2, extradata_alloc;
243  uint8_t *ptr;
244 
245  if (packed_headers_end - packed_headers < 9) {
246  av_log(codec, AV_LOG_ERROR,
247  "Invalid %td byte packed header.",
248  packed_headers_end - packed_headers);
249  return AVERROR_INVALIDDATA;
250  }
251 
252  num_packed = bytestream_get_be32(&packed_headers);
253  xiph_data->ident = bytestream_get_be24(&packed_headers);
254  length = bytestream_get_be16(&packed_headers);
255  num_headers = get_base128(&packed_headers, packed_headers_end);
256  length1 = get_base128(&packed_headers, packed_headers_end);
257  length2 = get_base128(&packed_headers, packed_headers_end);
258 
259  if (num_packed != 1 || num_headers > 3) {
260  av_log(codec, AV_LOG_ERROR,
261  "Unimplemented number of headers: %d packed headers, %d headers\n",
262  num_packed, num_headers);
263  return AVERROR_PATCHWELCOME;
264  }
265 
266  if (packed_headers_end - packed_headers != length ||
267  length1 > length || length2 > length - length1) {
268  av_log(codec, AV_LOG_ERROR,
269  "Bad packed header lengths (%d,%d,%td,%d)\n", length1,
270  length2, packed_headers_end - packed_headers, length);
271  return AVERROR_INVALIDDATA;
272  }
273 
274  /* allocate extra space:
275  * -- length/255 +2 for xiphlacing
276  * -- one for the '2' marker
277  * -- FF_INPUT_BUFFER_PADDING_SIZE required */
278  extradata_alloc = length + length/255 + 3 + FF_INPUT_BUFFER_PADDING_SIZE;
279 
280  ptr = codec->extradata = av_malloc(extradata_alloc);
281  if (!ptr) {
282  av_log(codec, AV_LOG_ERROR, "Out of memory\n");
283  return AVERROR(ENOMEM);
284  }
285  *ptr++ = 2;
286  ptr += av_xiphlacing(ptr, length1);
287  ptr += av_xiphlacing(ptr, length2);
288  memcpy(ptr, packed_headers, length);
289  ptr += length;
290  codec->extradata_size = ptr - codec->extradata;
291  // clear out remaining parts of the buffer
292  memset(ptr, 0, extradata_alloc - codec->extradata_size);
293 
294  return 0;
295 }
296 
297 static int xiph_parse_fmtp_pair(AVStream* stream,
298  PayloadContext *xiph_data,
299  char *attr, char *value)
300 {
301  AVCodecContext *codec = stream->codec;
302  int result = 0;
303 
304  if (!strcmp(attr, "sampling")) {
305  if (!strcmp(value, "YCbCr-4:2:0")) {
306  codec->pix_fmt = AV_PIX_FMT_YUV420P;
307  } else if (!strcmp(value, "YCbCr-4:4:2")) {
308  codec->pix_fmt = AV_PIX_FMT_YUV422P;
309  } else if (!strcmp(value, "YCbCr-4:4:4")) {
310  codec->pix_fmt = AV_PIX_FMT_YUV444P;
311  } else {
312  av_log(codec, AV_LOG_ERROR,
313  "Unsupported pixel format %s\n", attr);
314  return AVERROR_INVALIDDATA;
315  }
316  } else if (!strcmp(attr, "width")) {
317  /* This is an integer between 1 and 1048561
318  * and MUST be in multiples of 16. */
319  codec->width = atoi(value);
320  return 0;
321  } else if (!strcmp(attr, "height")) {
322  /* This is an integer between 1 and 1048561
323  * and MUST be in multiples of 16. */
324  codec->height = atoi(value);
325  return 0;
326  } else if (!strcmp(attr, "delivery-method")) {
327  /* Possible values are: inline, in_band, out_band/specific_name. */
328  return AVERROR_PATCHWELCOME;
329  } else if (!strcmp(attr, "configuration-uri")) {
330  /* NOTE: configuration-uri is supported only under 2 conditions:
331  *--after the delivery-method tag
332  * --with a delivery-method value of out_band */
333  return AVERROR_PATCHWELCOME;
334  } else if (!strcmp(attr, "configuration")) {
335  /* NOTE: configuration is supported only AFTER the delivery-method tag
336  * The configuration value is a base64 encoded packed header */
337  uint8_t *decoded_packet = NULL;
338  int packet_size;
339  size_t decoded_alloc = strlen(value) / 4 * 3 + 4;
340 
341  if (decoded_alloc <= INT_MAX) {
342  decoded_packet = av_malloc(decoded_alloc);
343  if (decoded_packet) {
344  packet_size =
345  av_base64_decode(decoded_packet, value, decoded_alloc);
346 
347  result = parse_packed_headers
348  (decoded_packet, decoded_packet + packet_size, codec,
349  xiph_data);
350  } else {
351  av_log(codec, AV_LOG_ERROR,
352  "Out of memory while decoding SDP configuration.\n");
353  result = AVERROR(ENOMEM);
354  }
355  } else {
356  av_log(codec, AV_LOG_ERROR, "Packet too large\n");
357  result = AVERROR_INVALIDDATA;
358  }
359  av_free(decoded_packet);
360  }
361  return result;
362 }
363 
364 static int xiph_parse_sdp_line(AVFormatContext *s, int st_index,
365  PayloadContext *data, const char *line)
366 {
367  const char *p;
368 
369  if (st_index < 0)
370  return 0;
371 
372  if (av_strstart(line, "fmtp:", &p)) {
373  return ff_parse_fmtp(s->streams[st_index], data, p,
375  }
376 
377  return 0;
378 }
379 
381  .enc_name = "theora",
382  .codec_type = AVMEDIA_TYPE_VIDEO,
383  .codec_id = AV_CODEC_ID_THEORA,
384  .parse_sdp_a_line = xiph_parse_sdp_line,
385  .alloc = xiph_new_context,
386  .free = xiph_free_context,
387  .parse_packet = xiph_handle_packet
388 };
389 
391  .enc_name = "vorbis",
392  .codec_type = AVMEDIA_TYPE_AUDIO,
393  .codec_id = AV_CODEC_ID_VORBIS,
394  .parse_sdp_a_line = xiph_parse_sdp_line,
395  .alloc = xiph_new_context,
396  .free = xiph_free_context,
397  .parse_packet = xiph_handle_packet
398 };