comparison liboggplayer-src/src/play.cpp @ 60:9c63b355c82b

Remove the audio code completely.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 06 Aug 2013 23:45:05 +0300
parents 3eacedd172ab
children
comparison
equal deleted inserted replaced
59:3eacedd172ab 60:9c63b355c82b
1 #include "imp.hpp" 1 #include "imp.hpp"
2 2
3 bool OggPlayer::Imp::ready() { 3 bool OggPlayer::Imp::ready() {
4 #ifdef VORBIS_SUPPORT
5 return audio_cache_ready;
6 #else
7 return true;
8 #endif
9 }
10
11
12 #ifdef VORBIS_SUPPORT
13 // return true if need more data
14 // the return value is strange but the function is
15 // for internal use only and should only be called
16 // in play()
17 bool OggPlayer::Imp::decode_audio() {
18 int ret;
19 float **pcm;
20 // if there's pending, decoded audio, grab it
21 while ((ret = vorbis_synthesis_pcmout(&v_state, &pcm)) > 0) {
22 boost::unique_lock<boost::mutex> lock(audio_mut);
23 // first we need to convert from float to signed short
24 // then we will use SDL_ConvertAudio
25 // is our temp buffer big enough?
26 if (cirbuf.capacity() < ret * v_info.channels * cvt.len_mult
27 * sizeof(short)) {
28 cirbuf.set_capacity(ret * v_info.channels * cvt.len_mult * 16
29 * sizeof(short));
30 }
31 if (cirbuf.capacity() - cirbuf.size() < ret * v_info.channels
32 * cvt.len_mult * sizeof(short)) {
33 audio_cache_ready = true;
34 return false;
35 }
36 if ((audio_buffer_size) < ret * v_info.channels * cvt.len_mult
37 * sizeof(short)) {
38 if (audio_buffer)
39 delete[] audio_buffer;
40 audio_buffer_size = ret * v_info.channels * cvt.len_mult
41 * sizeof(short);
42 audio_buffer = new char[audio_buffer_size];
43 }
44 // convert from float to short
45 int k = 0;
46 char* char_ab = (char*) audio_buffer;
47 short* short_ab = (short*) audio_buffer;
48 for (int i = 0; i < ret; i++) {
49 for (int j = 0; j < v_info.channels; j++) {
50 int val = (int)(pcm[j][i] * 32767.f);
51 if (val > 32767)
52 val = 32767;
53 if (val < -32768)
54 val = -32768;
55 short_ab[k++] = val;
56
57 }
58 }
59 vorbis_synthesis_read(&v_state, ret);
60 // now we can use SDL_ConvertAudio
61 cvt.len = k * sizeof(short);
62 cvt.buf = (Uint8*) char_ab;
63 SDL_ConvertAudio(&cvt);
64
65 for (int i = 0; i < cvt.len_cvt; i++) {
66 cirbuf.push_back(char_ab[i]);
67 }
68
69
70 if(v_state.granulepos!=0){
71 AudioGranulePos agp;
72 agp.pos = audio_bytes_played+cvt.len_cvt;
73 agp.set_time = (double)v_state.granulepos/(double)v_info.rate;
74 audio_granule_poses.push_back(agp);
75 }
76
77 lock.unlock();
78 audio_ready_cond.notify_one();
79 return false;
80
81 }
82 // no pending audio; is there a pending packet to decode?
83 if (ogg_stream_packetout(&o_vsstate, &o_packet) > 0) {
84 if (vorbis_synthesis(&v_block, &o_packet) == 0) {
85 vorbis_synthesis_blockin(&v_state, &v_block);
86 return false;
87 }
88 } else { return true; }
89 return true; 4 return true;
90 } 5 }
91 #endif
92
93 // similar to decode_audio 6 // similar to decode_audio
94 bool OggPlayer::Imp::decode_video() { 7 bool OggPlayer::Imp::decode_video() {
95 bool was_ready=videobuf_ready; 8 bool was_ready=videobuf_ready;
96 boost::unique_lock<boost::mutex> lock(video_mut, boost::defer_lock); 9 boost::unique_lock<boost::mutex> lock(video_mut, boost::defer_lock);
97 ogg_int64_t videobuf_granulepos = -1; 10 ogg_int64_t videobuf_granulepos = -1;
136 return !videobuf_ready; 49 return !videobuf_ready;
137 } 50 }
138 51
139 void OggPlayer::Imp::play_loop() { 52 void OggPlayer::Imp::play_loop() {
140 if(!file_in.is_open()) return; 53 if(!file_in.is_open()) return;
141 #ifdef VORBIS_SUPPORT
142 audio_cache_ready = false;
143 audio_bytes_played = 0;
144 bool audio_need_data = vorbis_p;
145 #else
146 bool audio_need_data = false;
147 #endif
148 bool video_need_data = theora_p; 54 bool video_need_data = theora_p;
149 timer.restart(); 55 timer.restart();
150 // buffer_data() will close the file on eof 56 // buffer_data() will close the file on eof
151 while ((file_in.is_open() || !audio_need_data || !video_need_data) && playing) { 57 while ((file_in.is_open() || !video_need_data) && playing) {
152
153 // sync audio video timer
154 while(!audio_granule_poses.empty() &&
155 audio_granule_poses.front().pos <= audio_bytes_played){
156 time_factor= audio_granule_poses.front().set_time/timer.elapsed();
157 audio_granule_poses.pop_front();
158 }
159
160 if (theora_p && !videobuf_ready) { 58 if (theora_p && !videobuf_ready) {
161 video_need_data = decode_video(); 59 video_need_data = decode_video();
162 } 60 }
163
164 #ifdef VORBIS_SUPPORT
165 if (vorbis_p) {
166 audio_need_data = decode_audio();
167 }
168 #endif
169 61
170 // are we at or past time for this video frame? 62 // are we at or past time for this video frame?
171 if (videobuf_ready && videobuf_time <= get_time()) { 63 if (videobuf_ready && videobuf_time <= get_time()) {
172 videobuf_ready = false; 64 videobuf_ready = false;
173 } 65 }
174 // if no data yet for somebody, grab another page 66 // if no data yet for somebody, grab another page
175 if (file_in.is_open() && (audio_need_data || video_need_data)) { 67 if (file_in.is_open() && (video_need_data)) {
176 // buffer_data() can handle eof itself 68 // buffer_data() can handle eof itself
177 buffer_data(); 69 buffer_data();
178 while (ogg_sync_pageout(&o_sync, &o_page) > 0) { 70 while (ogg_sync_pageout(&o_sync, &o_page) > 0) {
179 queue_page(&o_page); 71 queue_page(&o_page);
180 } 72 }
181 audio_need_data = false;
182 video_need_data = false; 73 video_need_data = false;
183 } 74 }
184 } 75 }
185 playing = false; 76 playing = false;
186 77
187 // do not risk a lock 78 // do not risk a lock
188 #ifdef VORBIS_SUPPORT
189 audio_ready_cond.notify_one();
190 #endif
191 video_ready_cond.notify_one(); 79 video_ready_cond.notify_one();
192 80
193 // cleanup 81 // cleanup
194 close(); 82 close();
195 } 83 }