3
Copyright (C) 2000 Martin Vogt
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation.
9
For more information look at the file COPYRIGHT in this package
14
#include "vorbisPlugin.h"
18
size_t fread_func(void *ptr, size_t size, size_t nmemb, void *stream) {
19
InputStream* input=(InputStream*) stream;
20
return input->read((char*)ptr,size*nmemb);
24
int fseek_func(void *stream, ogg_int64_t offset, int whence) {
26
InputStream* input=(InputStream*) stream;
28
if (whence==SEEK_SET) {
29
ret=input->seek(offset);
32
if (whence==SEEK_CUR) {
33
ret=input->seek(input->getBytePosition()+offset);
36
if (whence==SEEK_END) {
37
ret=input->seek(input->getByteLength());
40
cout << "hm, strange call"<<endl;
45
int fclose_func (void *) {
46
//InputStream* input=(InputStream*) stream;
48
// its handled different in kmpg
49
// we close the stream if the decoder signals eof.
55
long ftell_func (void *stream) {
56
InputStream* input=(InputStream*) stream;
57
return input->getBytePosition();
61
VorbisPlugin::VorbisPlugin() {
64
timeDummy=new TimeStamp();
65
pcmout=new char[4096];
72
VorbisPlugin::~VorbisPlugin() {
78
// here we can config our decoder with special flags
79
void VorbisPlugin::config(const char* key,const char* value,void* user_data) {
81
if (strcmp(key,"-c")==0) {
84
DecoderPlugin::config(key,value,user_data);
88
int VorbisPlugin::init() {
89
ov_callbacks callbacks;
91
callbacks.read_func = fread_func;
92
callbacks.seek_func = fseek_func;
93
callbacks.close_func = fclose_func;
94
callbacks.tell_func = ftell_func;
96
// here is the hack to pass the pointer to
97
// our streaming interface.
99
if(ov_open_callbacks(input, &vf, NULL, 0, callbacks) < 0) {
107
// called by decoder thread
108
int VorbisPlugin::processVorbis(vorbis_info* vi,vorbis_comment* comment) {
112
int current_section=-1; /* A vorbis physical bitstream may
113
consist of many logical sections
114
(information for each of which may be
115
fetched from the vf structure). This
116
value is filled in by ov_read to alert
117
us what section we're currently
118
decoding in case we need to change
119
playback settings at a section
121
ret=ov_read(&vf,pcmout,4096,0,2,1,¤t_section);
128
/* error in the stream. Not a problem, just reporting it in
129
case we (the app) cares. In this case, we don't. */
132
if(current_section!=last_section){
133
vi=ov_info(&vf,-1); /* The info struct is different in each
134
section. vf holds them all for the
135
given bitstream. This requests the
138
double timeoffset=ov_time_tell(&vf);
140
comment = ov_comment(&vf, -1);
142
cout << "we have a comment:"<<timeoffset<<endl;
145
last_section=current_section;
146
output->audioPlay(timeDummy,timeDummy,pcmout,ret);
153
void VorbisPlugin::decoder_loop() {
154
vorbis_info *vi=NULL;
155
vorbis_comment *comment=NULL;
162
cout << "VorbisPlugin::decoder_loop input is NULL"<<endl;
165
if (output == NULL) {
166
cout << "VorbisPlugin::decoder_loop output is NULL"<<endl;
172
/********** Decode setup ************/
177
switch(streamState) {
178
case _STREAM_STATE_FIRST_INIT :
179
if (init()== false) {
180
// total failure. exit decoding
186
if (lnoLength==false) {
187
pluginInfo->setLength(getTotalLength());
188
output->writeInfo(pluginInfo);
191
output->audioSetup(vi->rate,vi->channels-1,1,0,16);
195
setStreamState(_STREAM_STATE_PLAY);
197
case _STREAM_STATE_INIT :
198
case _STREAM_STATE_PLAY :
199
processVorbis(vi,comment);
201
case _STREAM_STATE_WAIT_FOR_END:
206
cout << "unknown stream state vorbis decoder:"<<streamState<<endl;
210
ov_clear(&vf); /* ov_clear closes the stream if its open. Safe to
211
call on an uninitialized structure as long as
215
output->audioFlush();
218
// vorbis can seek in streams
219
int VorbisPlugin::seek_impl(int second) {
220
ov_time_seek(&vf,(double) second);
226
int VorbisPlugin::getTotalLength() {
228
int byteLen=input->getByteLength();
232
/* Retrieve the length in second*/
234
if (lshutdown==false) {
235
back = (int) ov_time_total(&vf, -1);