1 /* -*- c-basic-offset: 8; -*- */
2 /* opus.c: Ogg Opus data handlers for libshout
3 *
4 * Copyright (C) 2005 the Icecast team <team@icecast.org>
5 * Copyright (C) 2011,2012 Xiph.Org Foundation
6 * Copyright (C) 2015-2019 Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #ifdef HAVE_INTTYPES_H
28 #include <inttypes.h>
29 #endif
30 #include <string.h>
31
32 #include <ogg/ogg.h>
33
34 #include "shout_private.h"
35 #include "format_ogg.h"
36
37 /* -- local data structures -- */
38 typedef struct {
39 int version;
40 int channels; /* Number of channels: 1..255 */
41 int preskip;
42 uint32_t input_sample_rate;
43 int gain; /* in dB S7.8 should be zero whenever possible */
44 int channel_mapping;
45
46 /* The rest is only used if channel_mapping != 0 */
47 int nb_streams;
48 int nb_coupled;
49 unsigned char stream_map[255];
50 } OpusHeader;
51
52 typedef struct {
53 OpusHeader oh;
54 int skipped;
55 } opus_data_t;
56
57 typedef struct {
58 const unsigned char *data;
59 int maxlen;
60 int pos;
61 } ROPacket;
62
63 /* -- local prototypes -- */
64 static int read_opus_page(ogg_codec_t *codec, ogg_page *page);
65 static void free_opus_data(void *codec_data);
66 static int opus_header_parse(const unsigned char *header, int len, OpusHeader *h);
67
68 /* -- header functions -- */
69
read_uint32(ROPacket * p,uint32_t * val)70 static int read_uint32(ROPacket *p, uint32_t *val)
71 {
72 if (p->pos>p->maxlen-4)
73 return 0;
74 *val = (uint32_t)p->data[p->pos ];
75 *val |= (uint32_t)p->data[p->pos + 1] << 8;
76 *val |= (uint32_t)p->data[p->pos + 2] << 16;
77 *val |= (uint32_t)p->data[p->pos + 3] << 24;
78 p->pos += 4;
79 return 1;
80 }
81
read_uint16(ROPacket * p,uint16_t * val)82 static int read_uint16(ROPacket *p, uint16_t *val)
83 {
84 if (p->pos>p->maxlen-2)
85 return 0;
86 *val = (uint16_t)p->data[p->pos ];
87 *val |= (uint16_t)p->data[p->pos + 1] << 8;
88 p->pos += 2;
89 return 1;
90 }
91
read_chars(ROPacket * p,unsigned char * str,int nb_chars)92 static int read_chars(ROPacket *p, unsigned char *str, int nb_chars)
93 {
94 int i;
95 if (p->pos>p->maxlen-nb_chars)
96 return 0;
97 for (i = 0; i < nb_chars; i++)
98 str[i] = p->data[p->pos++];
99 return 1;
100 }
101
opus_header_parse(const unsigned char * packet,int len,OpusHeader * h)102 static int opus_header_parse(const unsigned char *packet, int len, OpusHeader *h)
103 {
104 int i;
105 char str[9];
106 ROPacket p;
107 unsigned char ch;
108 uint16_t shortval;
109
110 p.data = packet;
111 p.maxlen = len;
112 p.pos = 0;
113
114 str[8] = 0;
115
116 if (len<19)
117 return 0;
118
119 read_chars(&p, (unsigned char*)str, 8);
120 if (strcmp(str, "OpusHead")!=0)
121 return 0;
122
123 if (!read_chars(&p, &ch, 1))
124 return 0;
125
126 h->version = ch;
127 if ((h->version&240) != 0) /* Only major version 0 supported. */
128 return 0;
129
130 if (!read_chars(&p, &ch, 1))
131 return 0;
132
133 h->channels = ch;
134 if (h->channels == 0)
135 return 0;
136
137 if (!read_uint16(&p, &shortval))
138 return 0;
139
140 h->preskip = shortval;
141 if (!read_uint32(&p, &h->input_sample_rate))
142 return 0;
143
144 if (!read_uint16(&p, &shortval))
145 return 0;
146
147 h->gain = (short)shortval;
148 if (!read_chars(&p, &ch, 1))
149 return 0;
150
151 h->channel_mapping = ch;
152 if (h->channel_mapping != 0) {
153 if (!read_chars(&p, &ch, 1))
154 return 0;
155
156 h->nb_streams = ch;
157 if (!read_chars(&p, &ch, 1))
158 return 0;
159
160 h->nb_coupled = ch;
161 /* Multi-stream support */
162 for (i=0; i < h->channels; i++) {
163 if (!read_chars(&p, &h->stream_map[i], 1))
164 return 0;
165 }
166 } else {
167 h->nb_streams = 1;
168 h->nb_coupled = h->channels > 1;
169 h->stream_map[0] = 0;
170 h->stream_map[1] = 1;
171 }
172
173 /* For version 0/1 we know there won't be any more data
174 * so reject any that have data past the end.
175 */
176 if ((h->version==0 || h->version==1) && p.pos != len)
177 return 0;
178 return 1;
179 }
180
181 /* From libopus, src/opus_decode.c */
packet_get_samples_per_frame(const unsigned char * data,int32_t Fs)182 static int packet_get_samples_per_frame(const unsigned char *data, int32_t Fs)
183 {
184 int audiosize;
185
186 if (data[0] & 0x80) {
187 audiosize = ((data[0] >> 3) & 0x3);
188 audiosize = (Fs << audiosize) / 400;
189 } else if ((data[0]&0x60) == 0x60) {
190 audiosize = (data[0] & 0x08) ? Fs / 50 : Fs / 100;
191 } else {
192 audiosize = ((data[0] >> 3) & 0x3);
193 if (audiosize == 3) {
194 audiosize = Fs * 60 / 1000;
195 } else {
196 audiosize = (Fs << audiosize) / 100;
197 }
198 }
199 return audiosize;
200 }
201
202 /* From libopus, src/opus_decode.c */
packet_get_nb_frames(const unsigned char packet[],int32_t len)203 static int packet_get_nb_frames(const unsigned char packet[], int32_t len)
204 {
205 int count;
206
207 if (len < 1)
208 return -1;
209
210 count = packet[0] & 0x3;
211 if (count==0) {
212 return 1;
213 } else if (count!=3) {
214 return 2;
215 } else if (len<2) {
216 return -4;
217 } else {
218 return packet[1] & 0x3F;
219 }
220 }
221
222 /* -- opus functions -- */
_shout_open_opus(ogg_codec_t * codec,ogg_page * page)223 int _shout_open_opus(ogg_codec_t *codec, ogg_page *page)
224 {
225 opus_data_t *opus_data = calloc(1, sizeof(opus_data_t));
226 ogg_packet packet;
227
228 (void) page;
229
230 if (!opus_data)
231 return SHOUTERR_MALLOC;
232
233 ogg_stream_packetout(&codec->os, &packet);
234
235 if (!opus_header_parse(packet.packet, packet.bytes, &opus_data->oh)) {
236 free_opus_data(opus_data);
237 return SHOUTERR_UNSUPPORTED;
238 }
239 opus_data->skipped = 0;
240
241 codec->codec_data = opus_data;
242 codec->read_page = read_opus_page;
243 codec->free_data = free_opus_data;
244
245 return SHOUTERR_SUCCESS;
246 }
247
read_opus_page(ogg_codec_t * codec,ogg_page * page)248 static int read_opus_page(ogg_codec_t *codec, ogg_page *page)
249 {
250 ogg_packet packet;
251 opus_data_t *opus_data = codec->codec_data;
252
253 (void) page;
254
255 /* We use the strategy of counting the packet times and ignoring
256 * the granpos. This has the advantage of needing less code to
257 * sanely handle non-zero starttimes and slightly saner behavior
258 * on files with holes.
259 */
260 while (ogg_stream_packetout(&codec->os, &packet) > 0) {
261 if (packet.bytes > 0 && (packet.bytes < 2 || memcmp(packet.packet, "Op", 2) != 0)) {
262 int32_t spf;
263 spf = packet_get_samples_per_frame(packet.packet, 48000);
264 if (spf > 0) {
265 int32_t spp;
266 spp = packet_get_nb_frames(packet.packet, packet.bytes);
267 if (spp > 0) {
268 int needskip;
269 needskip = opus_data->oh.preskip - opus_data->skipped;
270 spp *= spf;
271 /* Opus files can begin with some frames which are
272 * just there to prime the decoder and are not played
273 * these should just be sent as fast as we get them.
274 */
275 if (needskip > 0) {
276 int skip;
277 skip = spp < needskip ? spp : needskip;
278 spp -= skip;
279 opus_data->skipped += skip;
280 }
281 codec->senttime += ((spp * 1000000ULL) / 48000ULL);
282 }
283 } else if (packet.bytes >= 19 && memcmp(packet.packet, "OpusHead", 8) == 0) {
284 /* We appear to be chaining, reset skip to burst the pregap. */
285 if (opus_header_parse(packet.packet,packet.bytes,&opus_data->oh))
286 opus_data->skipped = 0;
287 }
288 }
289 }
290 return SHOUTERR_SUCCESS;
291 }
292
free_opus_data(void * codec_data)293 static void free_opus_data(void *codec_data)
294 {
295 free(codec_data);
296 }
297