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