1 /********************************************************************
2  *                                                                  *
3  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
4  * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5  * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE.    *
6  * PLEASE READ THESE TERMS BEFORE DISTRIBUTING.                     *
7  *                                                                  *
8  * THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2003                *
9  * by Stan Seibert <volsung@xiph.org> AND OTHER CONTRIBUTORS        *
10  * http://www.xiph.org/                                             *
11  *                                                                  *
12  ********************************************************************
13 
14  last mod: $Id$
15 
16  ********************************************************************/
17 
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <ogg/ogg.h>
27 #include <vorbis/codec.h>
28 #include <vorbis/vorbisfile.h>
29 #include "transport.h"
30 #include "format.h"
31 #include "vorbis_comments.h"
32 #include "utf8.h"
33 #include "i18n.h"
34 
35 #ifdef HAVE_OV_READ_FILTER
36 #include "vgfilter.h"
37 #endif
38 
39 typedef struct ovf_private_t {
40   OggVorbis_File vf;
41   vorbis_comment *vc;
42   vorbis_info *vi;
43   int current_section;
44 
45   int bos; /* At beginning of logical bitstream */
46 
47   decoder_stats_t stats;
48 #ifdef HAVE_OV_READ_FILTER
49   vgain_state vg;
50 #endif
51 } ovf_private_t;
52 
53 /* Forward declarations */
54 format_t oggvorbis_format;
55 ov_callbacks vorbisfile_callbacks;
56 
57 
58 void print_vorbis_stream_info (decoder_t *decoder);
59 void print_vorbis_comments (vorbis_comment *vc, decoder_callbacks_t *cb,
60 			    void *callback_arg);
61 
62 
63 /* ----------------------------------------------------------- */
64 
65 
ovf_can_decode(data_source_t * source)66 int ovf_can_decode (data_source_t *source)
67 {
68   return 1;  /* The file transport is tested last, so always try it */
69 }
70 
71 
ovf_init(data_source_t * source,ogg123_options_t * ogg123_opts,audio_format_t * audio_fmt,decoder_callbacks_t * callbacks,void * callback_arg)72 decoder_t* ovf_init (data_source_t *source, ogg123_options_t *ogg123_opts,
73 		     audio_format_t *audio_fmt,
74 		     decoder_callbacks_t *callbacks, void *callback_arg)
75 {
76   decoder_t *decoder;
77   ovf_private_t *private;
78   int ret;
79 
80 
81   /* Allocate data source structures */
82   decoder = malloc(sizeof(decoder_t));
83   private = malloc(sizeof(ovf_private_t));
84 
85   if (decoder != NULL && private != NULL) {
86     decoder->source = source;
87     decoder->actual_fmt = decoder->request_fmt = *audio_fmt;
88     decoder->format = &oggvorbis_format;
89     decoder->callbacks = callbacks;
90     decoder->callback_arg = callback_arg;
91     decoder->private = private;
92 
93     private->bos = 1;
94     private->current_section = -1;
95 
96     private->stats.total_time = 0.0;
97     private->stats.current_time = 0.0;
98     private->stats.instant_bitrate = 0;
99     private->stats.avg_bitrate = 0;
100 
101 #ifdef HAVE_OV_READ_FILTER
102     private->vg.scale_factor = 1.0;
103     private->vg.max_scale = 1.0;
104 #endif
105   } else {
106     fprintf(stderr, _("ERROR: Out of memory.\n"));
107     exit(1);
108   }
109 
110   /* Initialize vorbisfile decoder */
111 
112   ret = ov_open_callbacks (decoder, &private->vf, NULL, 0,
113 			   vorbisfile_callbacks);
114 
115   if (ret < 0) {
116     free(private);
117 /*    free(source);     nope.  caller frees. */
118     return NULL;
119   }
120 
121   return decoder;
122 }
123 
124 
ovf_read(decoder_t * decoder,void * ptr,int nbytes,int * eos,audio_format_t * audio_fmt)125 int ovf_read (decoder_t *decoder, void *ptr, int nbytes, int *eos,
126 	      audio_format_t *audio_fmt)
127 {
128   ovf_private_t *priv = decoder->private;
129   decoder_callbacks_t *cb = decoder->callbacks;
130   int bytes_read = 0;
131   int ret;
132   int old_section;
133 
134   /* Read comments and audio info at the start of a logical bitstream */
135   if (priv->bos) {
136     priv->vc = ov_comment(&priv->vf, -1);
137     priv->vi = ov_info(&priv->vf, -1);
138 
139     decoder->actual_fmt.rate = priv->vi->rate;
140     decoder->actual_fmt.channels = priv->vi->channels;
141 
142     switch(decoder->actual_fmt.channels){
143     case 1:
144       decoder->actual_fmt.matrix="M";
145       break;
146     case 2:
147       decoder->actual_fmt.matrix="L,R";
148       break;
149     case 3:
150       decoder->actual_fmt.matrix="L,C,R";
151       break;
152     case 4:
153       decoder->actual_fmt.matrix="L,R,BL,BR";
154       break;
155     case 5:
156       decoder->actual_fmt.matrix="L,C,R,BL,BR";
157       break;
158     case 6:
159       decoder->actual_fmt.matrix="L,C,R,BL,BR,LFE";
160       break;
161     case 7:
162       decoder->actual_fmt.matrix="L,C,R,SL,SR,BC,LFE";
163       break;
164     case 8:
165       decoder->actual_fmt.matrix="L,C,R,SL,SR,BL,BR,LFE";
166       break;
167     default:
168       decoder->actual_fmt.matrix=NULL;
169       break;
170     }
171 
172 #ifdef HAVE_OV_READ_FILTER
173     vg_init(&priv->vg, priv->vc);
174 #endif
175 
176     print_vorbis_stream_info(decoder);
177     print_vorbis_comments(priv->vc, cb, decoder->callback_arg);
178     priv->bos = 0;
179   }
180 
181   *audio_fmt = decoder->actual_fmt;
182 
183   /* Attempt to read as much audio as is requested */
184   while (nbytes >= audio_fmt->word_size * audio_fmt->channels) {
185 
186     old_section = priv->current_section;
187 #ifdef HAVE_OV_READ_FILTER
188     ret = ov_read_filter(&priv->vf, ptr, nbytes, audio_fmt->big_endian,
189 			 audio_fmt->word_size, audio_fmt->signed_sample,
190 			 &priv->current_section,
191 			 vg_filter, &priv->vg);
192 #else
193     ret = ov_read(&priv->vf, ptr, nbytes, audio_fmt->big_endian,
194 		  audio_fmt->word_size, audio_fmt->signed_sample,
195 		  &priv->current_section);
196 #endif
197 
198     if (ret == 0) {
199 
200       /* EOF */
201       *eos = 1;
202       break;
203 
204     } else if (ret == OV_HOLE) {
205 
206       if (cb->printf_error != NULL)
207 	cb->printf_error(decoder->callback_arg, INFO,
208 			   _("--- Hole in the stream; probably harmless\n"));
209 
210     } else if (ret < 0) {
211 
212       if (cb->printf_error != NULL)
213 	cb->printf_error(decoder->callback_arg, ERROR,
214 			 _("=== Vorbis library reported a stream error.\n"));
215 
216       /* EOF */
217       *eos = 1;
218       break;
219     } else {
220 
221       bytes_read += ret;
222       ptr = (void *)((unsigned char *)ptr + ret);
223       nbytes -= ret;
224 
225       /* did we enter a new logical bitstream? */
226       if (old_section != priv->current_section && old_section != -1) {
227 
228 	*eos = 1;
229 	priv->bos = 1; /* Read new headers next time through */
230 	break;
231       }
232     }
233 
234   }
235 
236   return bytes_read;
237 }
238 
239 
ovf_seek(decoder_t * decoder,double offset,int whence)240 int ovf_seek (decoder_t *decoder, double offset, int whence)
241 {
242   ovf_private_t *priv = decoder->private;
243   int ret;
244   double cur;
245 
246   if (whence == DECODER_SEEK_CUR) {
247     cur = ov_time_tell(&priv->vf);
248     if (cur >= 0.0)
249       offset += cur;
250     else
251       return 0;
252   }
253 
254   ret = ov_time_seek(&priv->vf, offset);
255   if (ret == 0)
256     return 1;
257   else
258     return 0;
259 }
260 
261 
ovf_statistics(decoder_t * decoder)262 decoder_stats_t *ovf_statistics (decoder_t *decoder)
263 {
264   ovf_private_t *priv = decoder->private;
265   long instant_bitrate;
266   long avg_bitrate;
267 
268   /* ov_time_tell() doesn't work on non-seekable streams, so we use
269      ov_pcm_tell()  */
270   priv->stats.total_time = (double) ov_pcm_total(&priv->vf, -1) /
271     (double) decoder->actual_fmt.rate;
272   priv->stats.current_time = (double) ov_pcm_tell(&priv->vf) /
273     (double) decoder->actual_fmt.rate;
274 
275   /* vorbisfile returns 0 when no bitrate change has occurred */
276   instant_bitrate = ov_bitrate_instant(&priv->vf);
277   if (instant_bitrate > 0)
278     priv->stats.instant_bitrate = instant_bitrate;
279 
280   avg_bitrate = ov_bitrate(&priv->vf, priv->current_section);
281   /* Catch error case caused by non-seekable stream */
282   priv->stats.avg_bitrate = avg_bitrate > 0 ? avg_bitrate : 0;
283 
284 
285   return malloc_decoder_stats(&priv->stats);
286 }
287 
288 
ovf_cleanup(decoder_t * decoder)289 void ovf_cleanup (decoder_t *decoder)
290 {
291   ovf_private_t *priv = decoder->private;
292 
293   ov_clear(&priv->vf);
294 
295   free(decoder->private);
296   free(decoder);
297 }
298 
299 
300 format_t oggvorbis_format = {
301   "oggvorbis",
302   &ovf_can_decode,
303   &ovf_init,
304   &ovf_read,
305   &ovf_seek,
306   &ovf_statistics,
307   &ovf_cleanup,
308 };
309 
310 
311 /* ------------------- Vorbisfile Callbacks ----------------- */
312 
vorbisfile_cb_read(void * ptr,size_t size,size_t nmemb,void * arg)313 size_t vorbisfile_cb_read (void *ptr, size_t size, size_t nmemb, void *arg)
314 {
315   decoder_t *decoder = arg;
316 
317   return decoder->source->transport->read(decoder->source, ptr, size, nmemb);
318 }
319 
vorbisfile_cb_seek(void * arg,ogg_int64_t offset,int whence)320 int vorbisfile_cb_seek (void *arg, ogg_int64_t offset, int whence)
321 {
322   decoder_t *decoder = arg;
323 
324   return decoder->source->transport->seek(decoder->source, offset, whence);
325 }
326 
vorbisfile_cb_close(void * arg)327 int vorbisfile_cb_close (void *arg)
328 {
329   return 1; /* Ignore close request so transport can be closed later */
330 }
331 
vorbisfile_cb_tell(void * arg)332 long vorbisfile_cb_tell (void *arg)
333 {
334   decoder_t *decoder = arg;
335 
336   return decoder->source->transport->tell(decoder->source);
337 }
338 
339 
340 ov_callbacks vorbisfile_callbacks = {
341   &vorbisfile_cb_read,
342   &vorbisfile_cb_seek,
343   &vorbisfile_cb_close,
344   &vorbisfile_cb_tell
345 };
346 
347 
348 /* ------------------- Private functions -------------------- */
349 
350 
print_vorbis_stream_info(decoder_t * decoder)351 void print_vorbis_stream_info (decoder_t *decoder)
352 {
353   ovf_private_t *priv = decoder->private;
354   decoder_callbacks_t *cb = decoder->callbacks;
355 
356 
357   if (cb == NULL || cb->printf_metadata == NULL)
358     return;
359 
360   cb->printf_metadata(decoder->callback_arg, 2,
361 		      _("Ogg Vorbis stream: %d channel, %ld Hz"),
362 		      priv->vi->channels,
363 		      priv->vi->rate);
364 
365   cb->printf_metadata(decoder->callback_arg, 3,
366 		      _("Vorbis format: Version %d"),
367 		      priv->vi->version);
368 
369   cb->printf_metadata(decoder->callback_arg, 3,
370 		      _("Bitrate hints: upper=%ld nominal=%ld lower=%ld "
371 		      "window=%ld"),
372 		      priv->vi->bitrate_upper,
373 		      priv->vi->bitrate_nominal,
374 		      priv->vi->bitrate_lower,
375 		      priv->vi->bitrate_window);
376 
377   cb->printf_metadata(decoder->callback_arg, 3,
378 		      _("Encoded by: %s"), priv->vc->vendor);
379 }
380 
print_vorbis_comments(vorbis_comment * vc,decoder_callbacks_t * cb,void * callback_arg)381 void print_vorbis_comments (vorbis_comment *vc, decoder_callbacks_t *cb,
382 			    void *callback_arg)
383 {
384   int i;
385   char *temp = NULL;
386   int temp_len = 0;
387 
388   for (i = 0; i < vc->comments; i++) {
389 
390     /* Gotta null terminate these things */
391     if (temp_len < vc->comment_lengths[i] + 1) {
392       temp_len = vc->comment_lengths[i] + 1;
393       temp = realloc(temp, sizeof(char) * temp_len);
394     }
395 
396     strncpy(temp, vc->user_comments[i], vc->comment_lengths[i]);
397     temp[vc->comment_lengths[i]] = '\0';
398 
399     print_vorbis_comment(temp, cb, callback_arg);
400   }
401 
402   free(temp);
403 }
404