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
31
34
42
44 {
45 int i, cnum,
h, m,
s, ms, keylen = strlen(
key);
47
49 return 0;
50
51 if (keylen <= 10) {
52 if (sscanf(
val,
"%02d:%02d:%02d.%03d", &
h, &m, &
s, &ms) < 4)
53 return 0;
54
56 ms + 1000 * (
s + 60 * (m + 60 *
h)),
62 break;
63 }
64 if (!chapter)
65 return 0;
66
68 } else
69 return 0;
70
71 return 1;
72 }
73
75 const uint8_t *buf,
int size)
76 {
78
79 if (updates > 0) {
81 }
82
83 return updates;
84 }
85
86 /**
87 * This function temporarily modifies the (const qualified) input buffer
88 * and reverts its changes before return. The input buffer needs to have
89 * at least one byte of padding.
90 */
92 const uint8_t *buf, uint32_t
size,
93 int *updates, int parse_picture)
94 {
95 char *t = (
char*)buf, *v = memchr(t,
'=',
size);
96 int tl, vl;
97 char backup;
98
99 if (!v)
100 return 0;
101
102 tl = v - t;
104 v++;
105
106 if (!tl || !vl)
107 return 0;
108
109 t[tl] = 0;
110
111 backup = v[vl];
112 v[vl] = 0;
113
114 /* The format in which the pictures are stored is the FLAC format.
115 * Xiph says: "The binary FLAC picture structure is base64 encoded
116 * and placed within a VorbisComment with the tag name
117 * 'METADATA_BLOCK_PICTURE'. This is the preferred and
118 * recommended way of embedding cover art within VorbisComments."
119 */
120 if (!
av_strcasecmp(t,
"METADATA_BLOCK_PICTURE") && parse_picture) {
123
124 if (!pict) {
126 goto end;
127 }
134 goto end;
135 }
137 (*updates)++;
141 }
142 end:
143 t[tl] = '=';
144 v[vl] = backup;
145
146 return 0;
147 }
148
150 const uint8_t *buf,
int size,
151 int parse_picture)
152 {
153 const uint8_t *p = buf;
154 const uint8_t *end = buf +
size;
155 int updates = 0;
156 unsigned n;
158
159 /* must have vendor_length and user_comment_list_length */
162
163 s = bytestream_get_le32(&p);
164
165 if (end - p - 4 <
s ||
s < 0)
167
169
170 n = bytestream_get_le32(&p);
171
172 while (end - p >= 4 && n > 0) {
173 s = bytestream_get_le32(&p);
174
175 if (end - p <
s ||
s < 0)
176 break;
177
182 n--;
183 }
184
185 if (p != end)
188 if (n > 0)
190 "truncated comment header, %i comments not found\n", n);
191
193
194 return updates;
195 }
196
197 /*
198 * Parse the vorbis header
199 *
200 * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
201 * [vorbis_version] = read 32 bits as unsigned integer | Not used
202 * [audio_channels] = read 8 bit integer as unsigned | Used
203 * [audio_sample_rate] = read 32 bits as unsigned integer | Used
204 * [bitrate_maximum] = read 32 bits as signed integer | Not used yet
205 * [bitrate_nominal] = read 32 bits as signed integer | Not used yet
206 * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate
207 * [blocksize_0] = read 4 bits as unsigned integer | Not Used
208 * [blocksize_1] = read 4 bits as unsigned integer | Not Used
209 * [framing_flag] = read one bit | Not Used
210 */
211
218 };
219
222 uint8_t **buf)
223 {
225 int buf_len;
226 unsigned char *ptr;
227
229 buf_len =
len +
len / 255 + 64;
230
231 if (*buf)
233
235 if (!ptr)
237 memset(*buf, '0円', buf_len);
238
239 ptr[0] = 2;
243 for (
i = 0;
i < 3;
i++) {
247 }
249 return err;
251 }
252
254 {
255 struct ogg *
ogg =
s->priv_data;
261 for (
i = 0;
i < 3;
i++)
263 }
264 }
265
267 {
268 struct ogg *
ogg =
s->priv_data;
272
274 return 0;
275
276 /* New metadata packet; release old data. */
282
283 /* Update the metadata if possible. */
287 /* Send an empty dictionary to indicate that metadata has been cleared. */
288 } else {
291 }
292
294 }
295
297 {
298 struct ogg *
ogg =
s->priv_data;
303
308 }
309
311
312 if (!(pkt_type & 1))
314
315 if (pkt_type > 5) {
317 return 1;
318 }
319
322
323 if (priv->
packet[pkt_type >> 1])
325 if (pkt_type > 1 && !priv->
packet[0] || pkt_type > 3 && !priv->
packet[1])
327
328 priv->
len[pkt_type >> 1] = os->
psize;
330 if (!priv->
packet[pkt_type >> 1])
333 const uint8_t *p = os->
buf + os->
pstart + 7;
/* skip "001円vorbis" tag */
334 unsigned blocksize, bs0, bs1;
335 int srate;
337
340
341 if (bytestream_get_le32(&p) != 0) /* vorbis_version */
343
349 }
351 srate = bytestream_get_le32(&p);
352 p += 4; // skip maximum bitrate
354 p += 4; // skip minimum bitrate
355
356 blocksize = bytestream_get_byte(&p);
357 bs0 = blocksize & 15;
358 bs1 = blocksize >> 4;
359
360 if (bs0 > bs1)
362 if (bs0 < 6 || bs1 > 13)
364
365 if (bytestream_get_byte(&p) != 1) /* framing_flag */
367
370
371 if (srate > 0) {
374 }
377 unsigned new_len;
378
382
383 // drop all metadata we parsed and which is not required by libvorbis
385 if (new_len >= 16 && new_len < os->psize) {
387 priv->
packet[1][new_len - 1] = 1;
388 priv->
len[1] = new_len;
389 }
390 }
391 } else {
393
396
401 }
403
409 }
410 }
411
412 return 1;
413 }
414
416 {
417 struct ogg *
ogg =
s->priv_data;
421
424
425 /* first packet handling
426 * here we parse the duration of each packet in the first page and compare
427 * the total duration to the page granule to find the encoder delay and
428 * set the first timestamp */
430 int seg, d;
431 uint8_t *last_pkt = os->
buf + os->
pstart;
432 uint8_t *next_pkt = last_pkt;
433
438 if (d < 0) {
440 return 0;
444 }
446 last_pkt = next_pkt = next_pkt + os->
psize;
447 for (; seg < os->
nsegs; seg++) {
450 if (d < 0) {
452 break;
456 }
458 last_pkt = next_pkt + os->
segments[seg];
459 }
461 }
464
465 if (!os->
granule &&
duration)
//hack to deal with broken files (Ticket3710)
467
471 s->streams[idx]->duration -=
s->streams[idx]->start_time;
472 }
475 }
476
477 /* parse packet duration */
482 return 0;
486 }
488 }
489
490 /* final packet handling
491 * here we save the pts of the first packet in the final page, sum up all
492 * packet durations in the final page except for the last one, and compare
493 * to the page granule to find the duration of the final packet */
498 }
504 }
506 }
507
508 return 0;
509 }
510
512 .
magic =
"001円vorbis",
513 .magicsize = 7,
517 .nb_header = 3,
518 };