~ubuntu-branches/ubuntu/hoary/kdemultimedia/hoary

« back to all changes in this revision

Viewing changes to mpeglib/lib/decoder/vorbisPlugin.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin Schulze
  • Date: 2003-01-22 15:00:51 UTC
  • Revision ID: james.westby@ubuntu.com-20030122150051-uihwkdoxf15mi1tn
Tags: upstream-2.2.2
ImportĀ upstreamĀ versionĀ 2.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  vorbis player plugin
 
3
  Copyright (C) 2000  Martin Vogt
 
4
 
 
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.
 
8
 
 
9
  For more information look at the file COPYRIGHT in this package
 
10
 
 
11
 */
 
12
 
 
13
 
 
14
#include "vorbisPlugin.h"
 
15
 
 
16
#ifdef OGG_VORBIS
 
17
 
 
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);
 
21
}
 
22
 
 
23
 
 
24
int fseek_func(void *stream, ogg_int64_t offset, int whence) {
 
25
  int ret;
 
26
  InputStream* input=(InputStream*) stream;
 
27
 
 
28
  if (whence==SEEK_SET) {
 
29
    ret=input->seek(offset);
 
30
    return ret;
 
31
  }
 
32
  if (whence==SEEK_CUR) {
 
33
    ret=input->seek(input->getBytePosition()+offset);
 
34
    return ret;
 
35
  }  
 
36
  if (whence==SEEK_END) {
 
37
    ret=input->seek(input->getByteLength());
 
38
    return ret;
 
39
  }   
 
40
  cout << "hm, strange call"<<endl;
 
41
  return -1;
 
42
}
 
43
 
 
44
 
 
45
int fclose_func (void *) {
 
46
  //InputStream* input=(InputStream*) stream;
 
47
 
 
48
  // its handled different in kmpg
 
49
  // we close the stream if the decoder signals eof.
 
50
  return true;
 
51
 
 
52
}
 
53
 
 
54
 
 
55
long ftell_func  (void *stream) {
 
56
  InputStream* input=(InputStream*) stream;
 
57
  return input->getBytePosition();
 
58
}
 
59
 
 
60
 
 
61
VorbisPlugin::VorbisPlugin() {
 
62
  
 
63
 
 
64
  timeDummy=new TimeStamp();
 
65
  pcmout=new char[4096];
 
66
  lnoLength=false;
 
67
  lshutdown=true;
 
68
 
 
69
}
 
70
 
 
71
 
 
72
VorbisPlugin::~VorbisPlugin() {
 
73
  delete timeDummy;
 
74
  delete pcmout;
 
75
}
 
76
 
 
77
 
 
78
// here we can config our decoder with special flags
 
79
void VorbisPlugin::config(const char* key,const char* value,void* user_data) {
 
80
 
 
81
  if (strcmp(key,"-c")==0) {
 
82
    lnoLength=true;
 
83
  }
 
84
  DecoderPlugin::config(key,value,user_data);
 
85
}
 
86
 
 
87
 
 
88
int VorbisPlugin::init() {
 
89
  ov_callbacks callbacks;
 
90
 
 
91
  callbacks.read_func = fread_func;
 
92
  callbacks.seek_func = fseek_func;
 
93
  callbacks.close_func = fclose_func;
 
94
  callbacks.tell_func = ftell_func;
 
95
 
 
96
  // here is the hack to pass the pointer to
 
97
  // our streaming interface.
 
98
  
 
99
  if(ov_open_callbacks(input, &vf, NULL, 0, callbacks) < 0) {
 
100
    return false;
 
101
  }
 
102
 
 
103
  return true;
 
104
}
 
105
 
 
106
 
 
107
// called by decoder thread
 
108
int VorbisPlugin::processVorbis(vorbis_info* vi,vorbis_comment* comment) {
 
109
 
 
110
  // decode
 
111
  int ret;
 
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
 
120
                             boundary */
 
121
  ret=ov_read(&vf,pcmout,4096,0,2,1,&current_section);
 
122
  switch(ret){
 
123
  case 0:
 
124
    /* EOF */
 
125
    lDecoderLoop=false;
 
126
    break;
 
127
  case -1:
 
128
    /* error in the stream.  Not a problem, just reporting it in
 
129
       case we (the app) cares.  In this case, we don't. */
 
130
    break;  
 
131
  default:
 
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
 
136
                             current one */
 
137
      
 
138
      double timeoffset=ov_time_tell(&vf);
 
139
      
 
140
      comment = ov_comment(&vf, -1);
 
141
      if(comment) {
 
142
        cout << "we have a comment:"<<timeoffset<<endl;
 
143
      }
 
144
    }  
 
145
      last_section=current_section;
 
146
      output->audioPlay(timeDummy,timeDummy,pcmout,ret);
 
147
      break;
 
148
    }
 
149
  return true;
 
150
}
 
151
 
 
152
 
 
153
void VorbisPlugin::decoder_loop() {
 
154
  vorbis_info *vi=NULL;
 
155
  vorbis_comment *comment=NULL;
 
156
  last_section=0;
 
157
  current_section=0;
 
158
       
 
159
 
 
160
 
 
161
  if (input == NULL) {
 
162
    cout << "VorbisPlugin::decoder_loop input is NULL"<<endl;
 
163
    exit(0);
 
164
  }
 
165
  if (output == NULL) {
 
166
    cout << "VorbisPlugin::decoder_loop output is NULL"<<endl;
 
167
    exit(0);
 
168
  }
 
169
  // init audio stream
 
170
  output->audioInit();
 
171
 
 
172
  /********** Decode setup ************/
 
173
  // start decoding
 
174
  lshutdown=false;
 
175
  while(runCheck()) {
 
176
 
 
177
    switch(streamState) {
 
178
    case _STREAM_STATE_FIRST_INIT :
 
179
      if (init()== false) {
 
180
        // total failure. exit decoding
 
181
        lDecoderLoop=false;
 
182
        break;
 
183
      } 
 
184
      // now init stream
 
185
      vi=ov_info(&vf,-1);
 
186
      if (lnoLength==false) {
 
187
        pluginInfo->setLength(getTotalLength());
 
188
        output->writeInfo(pluginInfo);
 
189
      }
 
190
      output->audioOpen();
 
191
      output->audioSetup(vi->rate,vi->channels-1,1,0,16);
 
192
  
 
193
 
 
194
      lhasLength=true;
 
195
      setStreamState(_STREAM_STATE_PLAY);
 
196
      break;
 
197
    case _STREAM_STATE_INIT :
 
198
    case _STREAM_STATE_PLAY :
 
199
      processVorbis(vi,comment);
 
200
      break;
 
201
    case _STREAM_STATE_WAIT_FOR_END:
 
202
      // exit while loop
 
203
      lDecoderLoop=false;
 
204
      break;
 
205
    default:
 
206
      cout << "unknown stream state vorbis decoder:"<<streamState<<endl;
 
207
    }
 
208
  }
 
209
  lshutdown=true;
 
210
  ov_clear(&vf); /* ov_clear closes the stream if its open.  Safe to
 
211
                    call on an uninitialized structure as long as
 
212
                    we've zeroed it */
 
213
  
 
214
 
 
215
  output->audioFlush();
 
216
}
 
217
 
 
218
// vorbis can seek in streams
 
219
int VorbisPlugin::seek_impl(int second) {
 
220
  ov_time_seek(&vf,(double) second);
 
221
  return true;
 
222
}
 
223
 
 
224
 
 
225
 
 
226
int VorbisPlugin::getTotalLength() {
 
227
  int back=0;
 
228
  int byteLen=input->getByteLength();
 
229
  if (byteLen == 0) {
 
230
    return 0;
 
231
  }
 
232
  /* Retrieve the length in second*/
 
233
  shutdownLock();
 
234
  if (lshutdown==false) {
 
235
      back = (int) ov_time_total(&vf, -1);
 
236
  }
 
237
  shutdownUnlock();
 
238
  
 
239
  return back;
 
240
}
 
241
 
 
242
 
 
243
 
 
244
 
 
245
#endif
 
246
//OGG_VORBIS
 
247
 
 
248