Mercurial > audlegacy-plugins
comparison src/ffmpeg/libavformat/oggparsevorbis.c @ 808:e8776388b02a trunk
[svn] - add ffmpeg
author | nenolod |
---|---|
date | Mon, 12 Mar 2007 11:18:54 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
807:0f9c8d4d3ac4 | 808:e8776388b02a |
---|---|
1 /** | |
2 Copyright (C) 2005 Michael Ahlberg, Måns Rullgård | |
3 | |
4 Permission is hereby granted, free of charge, to any person | |
5 obtaining a copy of this software and associated documentation | |
6 files (the "Software"), to deal in the Software without | |
7 restriction, including without limitation the rights to use, copy, | |
8 modify, merge, publish, distribute, sublicense, and/or sell copies | |
9 of the Software, and to permit persons to whom the Software is | |
10 furnished to do so, subject to the following conditions: | |
11 | |
12 The above copyright notice and this permission notice shall be | |
13 included in all copies or substantial portions of the Software. | |
14 | |
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
16 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
17 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
18 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |
19 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |
20 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
22 DEALINGS IN THE SOFTWARE. | |
23 **/ | |
24 | |
25 #include <stdlib.h> | |
26 #include "avformat.h" | |
27 #include "bitstream.h" | |
28 #include "bswap.h" | |
29 #include "ogg2.h" | |
30 | |
31 extern int | |
32 vorbis_comment (AVFormatContext * as, uint8_t *buf, int size) | |
33 { | |
34 char *p = buf; | |
35 int s, n, j; | |
36 | |
37 if (size < 4) | |
38 return -1; | |
39 | |
40 s = le2me_32 (unaligned32 (p)); | |
41 p += 4; | |
42 size -= 4; | |
43 | |
44 if (size < s + 4) | |
45 return -1; | |
46 | |
47 p += s; | |
48 size -= s; | |
49 | |
50 n = le2me_32 (unaligned32 (p)); | |
51 p += 4; | |
52 size -= 4; | |
53 | |
54 while (size >= 4){ | |
55 char *t, *v; | |
56 int tl, vl; | |
57 | |
58 s = le2me_32 (unaligned32 (p)); | |
59 p += 4; | |
60 size -= 4; | |
61 | |
62 if (size < s) | |
63 break; | |
64 | |
65 t = p; | |
66 p += s; | |
67 size -= s; | |
68 n--; | |
69 | |
70 v = memchr (t, '=', s); | |
71 if (!v) | |
72 continue; | |
73 | |
74 tl = v - t; | |
75 vl = s - tl - 1; | |
76 v++; | |
77 | |
78 if (tl && vl){ | |
79 char tt[tl + 1]; | |
80 char ct[vl + 1]; | |
81 | |
82 for (j = 0; j < tl; j++) | |
83 tt[j] = toupper (t[j]); | |
84 tt[tl] = 0; | |
85 | |
86 memcpy (ct, v, vl); | |
87 ct[vl] = 0; | |
88 | |
89 // took from Vorbis_I_spec | |
90 if (!strcmp (tt, "AUTHOR")) | |
91 strncpy (as->author, ct, FFMIN(sizeof (as->author), vl)); | |
92 else if (!strcmp (tt, "TITLE")) | |
93 strncpy (as->title, ct, FFMIN(sizeof (as->title), vl)); | |
94 else if (!strcmp (tt, "COPYRIGHT")) | |
95 strncpy (as->copyright, ct, FFMIN(sizeof (as->copyright), vl)); | |
96 else if (!strcmp (tt, "DESCRIPTION")) | |
97 strncpy (as->comment, ct, FFMIN(sizeof (as->comment), vl)); | |
98 else if (!strcmp (tt, "GENRE")) | |
99 strncpy (as->genre, ct, FFMIN(sizeof (as->genre), vl)); | |
100 else if (!strcmp (tt, "TRACKNUMBER")) | |
101 as->track = atoi (ct); | |
102 //Too bored to add others for today | |
103 } | |
104 } | |
105 | |
106 if (size > 0) | |
107 av_log (as, AV_LOG_INFO, "%i bytes of comment header remain\n", size); | |
108 if (n > 0) | |
109 av_log (as, AV_LOG_INFO, | |
110 "truncated comment header, %i comments not found\n", n); | |
111 | |
112 return 0; | |
113 } | |
114 | |
115 | |
116 /** Parse the vorbis header | |
117 * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec | |
118 * [vorbis_version] = read 32 bits as unsigned integer | Not used | |
119 * [audio_channels] = read 8 bit integer as unsigned | Used | |
120 * [audio_sample_rate] = read 32 bits as unsigned integer | Used | |
121 * [bitrate_maximum] = read 32 bits as signed integer | Not used yet | |
122 * [bitrate_nominal] = read 32 bits as signed integer | Not used yet | |
123 * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate | |
124 * [blocksize_0] = read 4 bits as unsigned integer | Not Used | |
125 * [blocksize_1] = read 4 bits as unsigned integer | Not Used | |
126 * [framing_flag] = read one bit | Not Used | |
127 * */ | |
128 | |
129 typedef struct { | |
130 unsigned int len[3]; | |
131 unsigned char *packet[3]; | |
132 } oggvorbis_private_t; | |
133 | |
134 | |
135 static unsigned int | |
136 fixup_vorbis_headers(AVFormatContext * as, oggvorbis_private_t *priv, | |
137 void **buf) | |
138 { | |
139 int i,offset, len; | |
140 unsigned char *ptr; | |
141 | |
142 len = priv->len[0] + priv->len[1] + priv->len[2]; | |
143 ptr = *buf = av_mallocz(len + len/255 + 64); | |
144 | |
145 ptr[0] = 2; | |
146 offset = 1; | |
147 offset += av_xiphlacing(&ptr[offset], priv->len[0]); | |
148 offset += av_xiphlacing(&ptr[offset], priv->len[1]); | |
149 for(i = 0; i < 3; i++) { | |
150 memcpy(&ptr[offset], priv->packet[i], priv->len[i]); | |
151 offset += priv->len[i]; | |
152 } | |
153 *buf = av_realloc(*buf, offset); | |
154 return offset; | |
155 } | |
156 | |
157 | |
158 static int | |
159 vorbis_header (AVFormatContext * s, int idx) | |
160 { | |
161 ogg_t *ogg = s->priv_data; | |
162 ogg_stream_t *os = ogg->streams + idx; | |
163 AVStream *st = s->streams[idx]; | |
164 oggvorbis_private_t *priv; | |
165 | |
166 if (os->seq > 2) | |
167 return 0; | |
168 | |
169 if(os->seq == 0) { | |
170 os->private = av_mallocz(sizeof(oggvorbis_private_t)); | |
171 if(!os->private) | |
172 return 0; | |
173 } | |
174 | |
175 priv = os->private; | |
176 priv->len[os->seq] = os->psize; | |
177 priv->packet[os->seq] = av_mallocz(os->psize); | |
178 memcpy(priv->packet[os->seq], os->buf + os->pstart, os->psize); | |
179 if (os->buf[os->pstart] == 1) { | |
180 uint8_t *p = os->buf + os->pstart + 11; //skip up to the audio channels | |
181 st->codec->channels = *p++; | |
182 st->codec->sample_rate = le2me_32 (unaligned32 (p)); | |
183 p += 8; //skip maximum and and nominal bitrate | |
184 st->codec->bit_rate = le2me_32 (unaligned32 (p)); //Minimum bitrate | |
185 | |
186 st->codec->codec_type = CODEC_TYPE_AUDIO; | |
187 st->codec->codec_id = CODEC_ID_VORBIS; | |
188 | |
189 st->time_base.num = 1; | |
190 st->time_base.den = st->codec->sample_rate; | |
191 } else if (os->buf[os->pstart] == 3) { | |
192 vorbis_comment (s, os->buf + os->pstart + 7, os->psize - 8); | |
193 } else { | |
194 st->codec->extradata_size = | |
195 fixup_vorbis_headers(s, priv, &st->codec->extradata); | |
196 } | |
197 | |
198 return os->seq < 3; | |
199 } | |
200 | |
201 ogg_codec_t vorbis_codec = { | |
202 .magic = "\001vorbis", | |
203 .magicsize = 7, | |
204 .header = vorbis_header | |
205 }; |