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 size_t vendor_length
= strlen(vendor
);
245 size_t user_comment_list_length
= 0;
246 size_t 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 uint32_t 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
;
270 char *reaced
= realloc(p
, len
);
275 SetDWLE(p
+ *length
, tag_len
+ val_len
); /* length of comment */
276 if (tag
) memcpy(p
+ *length
+ 4, tag
, tag_len
); /* comment */
277 memcpy(p
+ *length
+ 4 + tag_len
, val
, val_len
); /* comment */
278 SetDWLE(p
+ 8 + 4 + vendor_length
, user_comment_list_length
+ 1);
284 /* adds padding so that metadata can be updated without rewriting the whole file */
285 static int comment_pad(char **comments
, size_t *length
)
287 const unsigned padding
= 512; /* default from opus-tools */
289 if(SIZE_MAX
- *length
< padding
+ 255)
293 /* Make sure there is at least "padding" worth of padding free, and
294 round up to the maximum that fits in the current ogg segments. */
295 size_t newlen
= ((*length
+ padding
) / 255 + 1) * 255 - 1;
296 char *reaced
= realloc(p
, newlen
);
301 memset(p
+ *length
, 0, newlen
- *length
);
307 void opus_prepare_header(unsigned channels
, unsigned rate
, OpusHeader
*header
)
310 header
->channels
= channels
;
311 header
->nb_streams
= header
->channels
;
312 header
->nb_coupled
= 0;
313 header
->input_sample_rate
= rate
;
314 header
->gain
= 0; // 0dB
315 header
->channel_mapping
= header
->channels
> 8 ? 255 :
316 header
->channels
> 2;
319 static int opus_header_to_packet(const OpusHeader
*h
, unsigned char *packet
, int len
)
328 if (!write_chars(&p
, (const unsigned char*)"OpusHead", 8))
332 if (!write_chars(&p
, &ch
, 1))
336 if (!write_chars(&p
, &ch
, 1))
339 if (!write_uint16(&p
, h
->preskip
))
342 if (!write_uint32(&p
, h
->input_sample_rate
))
345 if (!write_uint16(&p
, h
->gain
))
348 ch
= h
->channel_mapping
;
349 if (!write_chars(&p
, &ch
, 1))
352 if (h
->channel_mapping
!= 0)
355 if (!write_chars(&p
, &ch
, 1))
359 if (!write_chars(&p
, &ch
, 1))
362 /* Multi-stream support */
363 for (int i
=0;i
<h
->channels
;i
++)
365 if (!write_chars(&p
, &h
->stream_map
[i
], 1))
373 int opus_write_header(uint8_t **p_extra
, int *i_extra
, OpusHeader
*header
, const char *vendor
)
375 unsigned char header_data
[100];
376 const int packet_size
= opus_header_to_packet(header
, header_data
,
377 sizeof(header_data
));
379 const unsigned char *data
[2];
382 data
[0] = header_data
;
383 size
[0] = packet_size
;
385 size_t comments_length
;
386 char *comments
= comment_init(&comments_length
, vendor
);
389 if (comment_add(&comments
, &comments_length
, "ENCODER=",
396 if (comment_pad(&comments
, &comments_length
))
402 data
[1] = (unsigned char *) comments
;
403 size
[1] = comments_length
;
408 for (unsigned i
= 0; i
< ARRAY_SIZE(data
); ++i
)
410 if (xiph_AppendHeaders(i_extra
, (void **) p_extra
, size
[i
], data
[i
]))