Mercurial > libavformat.hg
comparison oggparsevorbis.c @ 726:17178af951b4 libavformat
Ogg demuxer ported from tcvp by Luca Barbato <lu_zero at gentoo dot org>,
fixups by me.
author | mru |
---|---|
date | Sat, 09 Apr 2005 15:32:58 +0000 |
parents | |
children | 9372cd60d25d |
comparison
equal
deleted
inserted
replaced
725:dc20bf86353f | 726:17178af951b4 |
---|---|
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, char *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 static int | |
130 vorbis_header (AVFormatContext * s, int idx) | |
131 { | |
132 ogg_t *ogg = s->priv_data; | |
133 ogg_stream_t *os = ogg->streams + idx; | |
134 AVStream *st = s->streams[idx]; | |
135 int cds = st->codec.extradata_size + os->psize + 2; | |
136 u_char *cdp; | |
137 | |
138 if (os->seq > 2) | |
139 return 0; | |
140 | |
141 st->codec.extradata = av_realloc (st->codec.extradata, cds); | |
142 cdp = st->codec.extradata + st->codec.extradata_size; | |
143 *cdp++ = os->psize >> 8; | |
144 *cdp++ = os->psize & 0xff; | |
145 memcpy (cdp, os->buf + os->pstart, os->psize); | |
146 st->codec.extradata_size = cds; | |
147 | |
148 if (os->buf[os->pstart] == 1) { | |
149 u_char *p = os->buf + os->pstart + 11; //skip up to the audio channels | |
150 st->codec.channels = *p++; | |
151 st->codec.sample_rate = le2me_32 (unaligned32 (p)); | |
152 p += 8; //skip maximum and and nominal bitrate | |
153 st->codec.bit_rate = le2me_32 (unaligned32 (p)); //Minimum bitrate | |
154 | |
155 st->codec.codec_type = CODEC_TYPE_AUDIO; | |
156 st->codec.codec_id = CODEC_ID_VORBIS; | |
157 | |
158 } else if (os->buf[os->pstart] == 3) { | |
159 vorbis_comment (s, os->buf + os->pstart + 7, os->psize - 8); | |
160 } | |
161 | |
162 return os->seq < 3; | |
163 } | |
164 | |
165 ogg_codec_t vorbis_codec = { | |
166 .magic = "\001vorbis", | |
167 .magicsize = 7, | |
168 .header = vorbis_header | |
169 }; |