annotate rtp_vorbis.c @ 5453:39e5af193378 libavformat

Correct truncated ID3v1 genre name.
author astrange
date Sun, 13 Dec 2009 22:31:29 +0000
parents 75e51cba276e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4875
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
1 /*
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
2 * RTP Vorbis Protocol (RFC5215)
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
3 * Copyright (c) 2009 Colin McQuillan
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
4 *
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
5 * This file is part of FFmpeg.
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
6 *
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
11 *
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
15 * Lesser General Public License for more details.
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
16 *
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
20 */
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
21
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
22 /**
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
23 * @file libavformat/rtp_vorbis.c
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
24 * @brief Vorbis / RTP Code (RFC 5215)
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
25 * @author Colin McQuillan <m.niloc@gmail.com>
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
26 */
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
27
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
28 #include "libavutil/base64.h"
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
29 #include "libavutil/avstring.h"
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
30 #include "libavcodec/bytestream.h"
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
31
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
32 #include <assert.h>
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
33
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
34 #include "rtpdec.h"
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
35 #include "rtp_vorbis.h"
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
36
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
37 /**
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
38 * RTP/Vorbis specific private data.
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
39 */
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
40 struct PayloadContext {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
41 unsigned ident; ///< 24-bit stream configuration identifier
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
42 };
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
43
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
44 /**
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
45 * Length encoding described in RFC5215 section 3.1.1.
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
46 */
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
47 static int get_base128(const uint8_t ** buf, const uint8_t * buf_end)
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
48 {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
49 int n = 0;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
50 for (; *buf < buf_end; ++*buf) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
51 n <<= 7;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
52 n += **buf & 0x7f;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
53 if (!(**buf & 0x80)) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
54 ++*buf;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
55 return n;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
56 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
57 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
58 return 0;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
59 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
60
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
61 /**
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
62 * Out-of-band headers, described in RFC 5251 section 3.2.1
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
63 */
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
64 static unsigned int
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
65 parse_packed_headers(const uint8_t * packed_headers,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
66 const uint8_t * packed_headers_end,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
67 AVCodecContext * codec, PayloadContext * vorbis_data)
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
68 {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
69 unsigned num_packed, num_headers, length, length1, length2;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
70 uint8_t *ptr;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
71
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
72 num_packed = bytestream_get_be32(&packed_headers);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
73 vorbis_data->ident = bytestream_get_be24(&packed_headers);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
74 length = bytestream_get_be16(&packed_headers);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
75 num_headers = get_base128(&packed_headers, packed_headers_end);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
76 length1 = get_base128(&packed_headers, packed_headers_end);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
77 length2 = get_base128(&packed_headers, packed_headers_end);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
78
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
79 if (num_packed != 1 || num_headers > 3) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
80 av_log(codec, AV_LOG_ERROR,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
81 "Unimplemented number of headers: %d packed headers, %d headers\n",
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
82 num_packed, num_headers);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
83 return AVERROR_PATCHWELCOME;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
84 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
85
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
86 if (packed_headers_end - packed_headers != length ||
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
87 length1 > length || length2 > length - length1) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
88 av_log(codec, AV_LOG_ERROR,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
89 "Bad packed header lengths (%d,%d,%d,%d)\n", length1,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
90 length2, packed_headers_end - packed_headers, length);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
91 return AVERROR_INVALIDDATA;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
92 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
93
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
94 ptr = codec->extradata = av_mallocz(length + length / 255 + 64);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
95 if (!ptr) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
96 av_log(codec, AV_LOG_ERROR, "Out of memory");
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
97 return AVERROR_NOMEM;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
98 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
99 *ptr++ = 2;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
100 ptr += av_xiphlacing(ptr, length1);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
101 ptr += av_xiphlacing(ptr, length2);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
102 memcpy(ptr, packed_headers, length);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
103 ptr += length;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
104 codec->extradata_size = ptr - codec->extradata;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
105
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
106 return 0;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
107 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
108
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
109 int
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
110 ff_vorbis_parse_fmtp_config(AVCodecContext * codec,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
111 void *vorbis_data, char *attr, char *value)
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
112 {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
113 int result = 0;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
114 assert(codec->codec_id == CODEC_ID_VORBIS);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
115 assert(vorbis_data);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
116
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
117 // The configuration value is a base64 encoded packed header
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
118 if (!strcmp(attr, "configuration")) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
119 uint8_t *decoded_packet = NULL;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
120 int packet_size;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
121 size_t decoded_alloc = strlen(value) / 4 * 3 + 4;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
122
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
123 if (decoded_alloc <= INT_MAX) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
124 decoded_packet = av_malloc(decoded_alloc);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
125 if (decoded_packet) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
126 packet_size =
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
127 av_base64_decode(decoded_packet, value, decoded_alloc);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
128
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
129 result = parse_packed_headers
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
130 (decoded_packet, decoded_packet + packet_size, codec,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
131 vorbis_data);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
132 } else {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
133 av_log(codec, AV_LOG_ERROR,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
134 "Out of memory while decoding SDP configuration.\n");
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
135 result = AVERROR_NOMEM;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
136 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
137 } else {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
138 av_log(codec, AV_LOG_ERROR, "Packet too large\n");
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
139 result = AVERROR_INVALIDDATA;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
140 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
141 av_free(decoded_packet);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
142 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
143 return result;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
144 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
145
5113
75e51cba276e Use named initializers and use new/free_context() instead of extradata()
rbultje
parents: 4875
diff changeset
146 static PayloadContext *vorbis_new_context(void)
4875
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
147 {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
148 return av_mallocz(sizeof(PayloadContext));
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
149 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
150
5113
75e51cba276e Use named initializers and use new/free_context() instead of extradata()
rbultje
parents: 4875
diff changeset
151 static void vorbis_free_context(PayloadContext * data)
4875
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
152 {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
153 av_free(data);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
154 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
155
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
156 /**
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
157 * Handle payload as described in RFC 5215 section 2.2
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
158 */
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
159 static int
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
160 vorbis_handle_packet(AVFormatContext * ctx,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
161 PayloadContext * data,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
162 AVStream * st,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
163 AVPacket * pkt,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
164 uint32_t * timestamp,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
165 const uint8_t * buf, int len, int flags)
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
166 {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
167 int ident, fragmented, vdt, num_pkts, pkt_len;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
168
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
169 if (len < 6) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
170 av_log(ctx, AV_LOG_ERROR, "Invalid %d byte packet\n", len);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
171 return AVERROR_INVALIDDATA;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
172 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
173
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
174 ident = AV_RB24(buf);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
175 fragmented = buf[3] >> 6;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
176 vdt = (buf[3] >> 4) & 3;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
177 num_pkts = buf[3] & 7;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
178 pkt_len = AV_RB16(buf + 4);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
179
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
180 if (pkt_len > len - 6) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
181 av_log(ctx, AV_LOG_ERROR,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
182 "Invalid packet length %d in %d byte packet\n", pkt_len,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
183 len);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
184 return AVERROR_INVALIDDATA;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
185 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
186
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
187 if (ident != data->ident) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
188 av_log(ctx, AV_LOG_ERROR,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
189 "Unimplemented Vorbis SDP configuration change detected\n");
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
190 return AVERROR_PATCHWELCOME;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
191 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
192
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
193 if (fragmented != 0 || vdt != 0 || num_pkts != 1) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
194 av_log(ctx, AV_LOG_ERROR,
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
195 "Unimplemented RTP Vorbis packet settings (%d,%d,%d)\n",
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
196 fragmented, vdt, num_pkts);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
197 return AVERROR_PATCHWELCOME;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
198 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
199
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
200 if (av_new_packet(pkt, pkt_len)) {
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
201 av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
202 return AVERROR_NOMEM;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
203 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
204
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
205 memcpy(pkt->data, buf + 6, pkt_len);
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
206 pkt->stream_index = st->index;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
207 return 0;
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
208 }
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
209
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
210 RTPDynamicProtocolHandler ff_vorbis_dynamic_handler = {
5113
75e51cba276e Use named initializers and use new/free_context() instead of extradata()
rbultje
parents: 4875
diff changeset
211 .enc_name = "vorbis",
75e51cba276e Use named initializers and use new/free_context() instead of extradata()
rbultje
parents: 4875
diff changeset
212 .codec_type = CODEC_TYPE_AUDIO,
75e51cba276e Use named initializers and use new/free_context() instead of extradata()
rbultje
parents: 4875
diff changeset
213 .codec_id = CODEC_ID_VORBIS,
75e51cba276e Use named initializers and use new/free_context() instead of extradata()
rbultje
parents: 4875
diff changeset
214 .parse_sdp_a_line = NULL,
75e51cba276e Use named initializers and use new/free_context() instead of extradata()
rbultje
parents: 4875
diff changeset
215 .open = vorbis_new_context,
75e51cba276e Use named initializers and use new/free_context() instead of extradata()
rbultje
parents: 4875
diff changeset
216 .close = vorbis_free_context,
75e51cba276e Use named initializers and use new/free_context() instead of extradata()
rbultje
parents: 4875
diff changeset
217 .parse_packet = vorbis_handle_packet
4875
13a2a1a475d5 Add a Vorbis payload parser. Implemented by Colin McQuillan as a GSoC
rbultje
parents:
diff changeset
218 };