1 /* Copyright (C)2012 Xiph.Org Foundation
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
19 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "opus_header.h"
37 #include <vlc_common.h>
38 #include "../demux/xiph.h"
41 - "OpusHead" (64 bits)
42 - version number (8 bits)
45 - Sampling rate (32 bits)
46 - Gain in dB (16 bits, S7.8)
47 - Mapping (8 bits, 0=single stream (mono/stereo) 1=Vorbis mapping,
48 2..254: reserved, 255: multistream with no mapping)
51 - N = totel number of streams (8 bits)
52 - M = number of paired streams (8 bits)
53 - C times channel origin
71 const unsigned char *data;
76 static int write_uint32(Packet *p, uint32_t val)
78 if (p->pos>p->maxlen-4)
80 p->data[p->pos ] = (val ) & 0xFF;
81 p->data[p->pos+1] = (val>> 8) & 0xFF;
82 p->data[p->pos+2] = (val>>16) & 0xFF;
83 p->data[p->pos+3] = (val>>24) & 0xFF;
88 static int write_uint16(Packet *p, uint16_t val)
90 if (p->pos>p->maxlen-2)
92 p->data[p->pos ] = (val ) & 0xFF;
93 p->data[p->pos+1] = (val>> 8) & 0xFF;
98 static int write_chars(Packet *p, const unsigned char *str, int nb_chars)
100 if (p->pos>p->maxlen-nb_chars)
102 for (int i=0;i<nb_chars;i++)
103 p->data[p->pos++] = str[i];
107 static int read_uint32(ROPacket *p, uint32_t *val)
109 if (p->pos>p->maxlen-4)
111 *val = (uint32_t)p->data[p->pos ];
112 *val |= (uint32_t)p->data[p->pos+1]<< 8;
113 *val |= (uint32_t)p->data[p->pos+2]<<16;
114 *val |= (uint32_t)p->data[p->pos+3]<<24;
119 static int read_uint16(ROPacket *p, uint16_t *val)
121 if (p->pos>p->maxlen-2)
123 *val = (uint16_t)p->data[p->pos ];
124 *val |= (uint16_t)p->data[p->pos+1]<<8;
129 static int read_chars(ROPacket *p, unsigned char *str, int nb_chars)
131 if (p->pos>p->maxlen-nb_chars)
133 for (int i=0;i<nb_chars;i++)
134 str[i] = p->data[p->pos++];
138 int opus_header_parse(const unsigned char *packet, int len, OpusHeader *h)
150 read_chars(&p, (unsigned char*)str, 8);
151 if (memcmp(str, "OpusHead", 8)!=0)
154 if (!read_chars(&p, &ch, 1))
157 if((h->version&240) != 0) /* Only major version 0 supported. */
160 if (!read_chars(&p, &ch, 1))
163 if (h->channels == 0)
166 if (!read_uint16(&p, &shortval))
168 h->preskip = shortval;
170 if (!read_uint32(&p, &h->input_sample_rate))
173 if (!read_uint16(&p, &shortval))
175 h->gain = (short)shortval;
177 if (!read_chars(&p, &ch, 1))
179 h->channel_mapping = ch;
181 if (h->channel_mapping != 0)
183 if (!read_chars(&p, &ch, 1))
190 if (!read_chars(&p, &ch, 1))
193 if (ch>h->nb_streams || (ch+h->nb_streams)>255)
197 /* Multi-stream support */
198 for (int i=0;i<h->channels;i++)
200 if (!read_chars(&p, &h->stream_map[i], 1))
202 if (h->stream_map[i]>(h->nb_streams+h->nb_coupled) && h->stream_map[i]!=255)
209 h->nb_coupled = h->channels>1;
213 /*For version 0/1 we know there won't be any more data
214 so reject any that have data past the end.*/
215 if ((h->version==0 || h->version==1) && p.pos != len)
221 Comments will be stored in the Vorbis style.
222 It is described in the "Structure" section of
223 http://www.xiph.org/ogg/vorbis/doc/v-comment.html
225 However, Opus and other non-vorbis formats omit the "framing_bit".
227 The comment header is decoded as follows:
228 1) [vendor_length] = unsigned little endian 32 bits integer
229 2) [vendor_string] = UTF-8 vector as [vendor_length] octets
230 3) [user_comment_list_length] = unsigned little endian 32 bits integer
231 4) iterate [user_comment_list_length] times {
232 5) [length] = unsigned little endian 32 bits integer
233 6) this iteration's user comment = UTF-8 vector as [length] octets
238 static char *comment_init(size_t *length, const char *vendor)
240 /*The 'vendor' field should be the actual encoding library used.*/
243 int vendor_length = strlen(vendor);
245 int user_comment_list_length = 0;
246 int len = 8 + 4 + vendor_length + 4;
247 char *p = malloc(len);
251 memcpy(p, "OpusTags", 8);
252 SetDWLE(p + 8, vendor_length);
253 memcpy(p + 12, vendor, vendor_length);
254 SetDWLE(p + 12 + vendor_length, user_comment_list_length);
260 static int comment_add(char **comments, size_t *length, const char *tag,
264 int vendor_length = GetDWLE(p + 8);
265 size_t user_comment_list_length = GetDWLE(p + 8 + 4 + vendor_length);
266 size_t tag_len = (tag ? strlen(tag) : 0);
267 size_t val_len = strlen(val);
268 size_t len = (*length) + 4 + tag_len + val_len;
274 SetDWLE(p + *length, tag_len + val_len); /* length of comment */
275 if (tag) memcpy(p + *length + 4, tag, tag_len); /* comment */
276 memcpy(p + *length + 4 + tag_len, val, val_len); /* comment */
277 SetDWLE(p + 8 + 4 + vendor_length, user_comment_list_length + 1);
283 /* adds padding so that metadata can be updated without rewriting the whole file */
284 static int comment_pad(char **comments, size_t *length)
286 const unsigned padding = 512; /* default from opus-tools */
289 /* Make sure there is at least "padding" worth of padding free, and
290 round up to the maximum that fits in the current ogg segments. */
291 size_t newlen = ((*length + padding) / 255 + 1) * 255 - 1;
292 p = realloc(p, newlen);
296 memset(p + *length, 0, newlen - *length);
302 int opus_prepare_header(unsigned channels, unsigned rate, OpusHeader *header)
305 header->channels = channels;
306 header->nb_streams = header->channels;
307 header->nb_coupled = 0;
308 header->input_sample_rate = rate;
309 header->gain = 0; // 0dB
310 header->channel_mapping = header->channels > 8 ? 255 :
311 header->channels > 2;
316 static int opus_header_to_packet(const OpusHeader *h, unsigned char *packet, int len)
325 if (!write_chars(&p, (const unsigned char*)"OpusHead", 8))
329 if (!write_chars(&p, &ch, 1))
333 if (!write_chars(&p, &ch, 1))
336 if (!write_uint16(&p, h->preskip))
339 if (!write_uint32(&p, h->input_sample_rate))
342 if (!write_uint16(&p, h->gain))
345 ch = h->channel_mapping;
346 if (!write_chars(&p, &ch, 1))
349 if (h->channel_mapping != 0)
352 if (!write_chars(&p, &ch, 1))
356 if (!write_chars(&p, &ch, 1))
359 /* Multi-stream support */
360 for (int i=0;i<h->channels;i++)
362 if (!write_chars(&p, &h->stream_map[i], 1))
370 int opus_write_header(uint8_t **p_extra, int *i_extra, OpusHeader *header, const char *vendor)
372 unsigned char header_data[100];
373 const int packet_size = opus_header_to_packet(header, header_data,
374 sizeof(header_data));
376 unsigned char *data[2];
379 data[0] = header_data;
380 size[0] = packet_size;
382 size_t comments_length;
383 char *comments = comment_init(&comments_length, vendor);
386 if (comment_add(&comments, &comments_length, "ENCODER=",
393 if (comment_pad(&comments, &comments_length))
399 data[1] = (unsigned char *) comments;
400 size[1] = comments_length;
402 for (unsigned i = 0; i < ARRAY_SIZE(data); ++i)
403 if (xiph_AppendHeaders(i_extra, (void **) p_extra, size[i], data[i]))