Mercurial > hg > forks > bilotrip-mj12
annotate liboggplayer-src/src/play.cpp @ 59:3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 06 Aug 2013 23:27:37 +0300 |
parents | 083c73ceb716 |
children | 9c63b355c82b |
rev | line source |
---|---|
2 | 1 #include "imp.hpp" |
2 | |
3 bool OggPlayer::Imp::ready() { | |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
4 #ifdef VORBIS_SUPPORT |
2 | 5 return audio_cache_ready; |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
6 #else |
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
7 return true; |
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
8 #endif |
2 | 9 } |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
10 |
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
11 |
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
12 #ifdef VORBIS_SUPPORT |
2 | 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; } | |
14
083c73ceb716
Get rid of the vorbis related code.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
89 return true; |
2 | 90 } |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
91 #endif |
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
92 |
2 | 93 // similar to decode_audio |
94 bool OggPlayer::Imp::decode_video() { | |
95 bool was_ready=videobuf_ready; | |
96 boost::unique_lock<boost::mutex> lock(video_mut, boost::defer_lock); | |
97 ogg_int64_t videobuf_granulepos = -1; | |
98 if (!videobuf_ready){ | |
99 if(!lock.try_lock()) | |
100 return false; | |
101 } | |
102 while (!videobuf_ready) { | |
103 // theora is one in, one out... | |
104 if (ogg_stream_packetout(&o_tsstate, &o_packet) > 0) { | |
105 | |
106 if(pp_inc){ | |
107 pp_level+=pp_inc; | |
108 theora_control(&t_state,TH_DECCTL_SET_PPLEVEL,&pp_level,sizeof(pp_level)); | |
109 pp_inc=0; | |
110 } | |
111 if (o_packet.granulepos >= 0) { | |
112 theora_control(&t_state, TH_DECCTL_SET_GRANPOS, | |
113 &o_packet.granulepos, sizeof(o_packet.granulepos)); | |
114 } | |
115 if (theora_decode_packetin(&t_state, &o_packet) == 0) { | |
116 videobuf_granulepos = t_state.granulepos; | |
117 videobuf_time = theora_granule_time(&t_state, videobuf_granulepos); | |
118 | |
119 if (videobuf_time >= get_time()){ | |
120 videobuf_ready = true; | |
121 frame++; | |
122 } | |
123 else { | |
124 // If we are too slow, reduce the pp level. | |
125 pp_inc=pp_level>0?-1:0; | |
126 } | |
127 } | |
128 | |
129 } else | |
130 break; | |
131 } | |
132 lock.unlock(); | |
133 if(videobuf_ready!=was_ready) | |
134 video_ready_cond.notify_one(); | |
135 | |
136 return !videobuf_ready; | |
137 } | |
138 | |
139 void OggPlayer::Imp::play_loop() { | |
140 if(!file_in.is_open()) return; | |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
141 #ifdef VORBIS_SUPPORT |
2 | 142 audio_cache_ready = false; |
143 audio_bytes_played = 0; | |
144 bool audio_need_data = vorbis_p; | |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
145 #else |
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
146 bool audio_need_data = false; |
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
147 #endif |
2 | 148 bool video_need_data = theora_p; |
149 timer.restart(); | |
150 // buffer_data() will close the file on eof | |
151 while ((file_in.is_open() || !audio_need_data || !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) { | |
161 video_need_data = decode_video(); | |
162 } | |
163 | |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
164 #ifdef VORBIS_SUPPORT |
2 | 165 if (vorbis_p) { |
166 audio_need_data = decode_audio(); | |
167 } | |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
168 #endif |
2 | 169 |
170 // are we at or past time for this video frame? | |
171 if (videobuf_ready && videobuf_time <= get_time()) { | |
172 videobuf_ready = false; | |
173 } | |
174 // if no data yet for somebody, grab another page | |
175 if (file_in.is_open() && (audio_need_data || video_need_data)) { | |
176 // buffer_data() can handle eof itself | |
177 buffer_data(); | |
178 while (ogg_sync_pageout(&o_sync, &o_page) > 0) { | |
179 queue_page(&o_page); | |
180 } | |
181 audio_need_data = false; | |
182 video_need_data = false; | |
183 } | |
184 } | |
185 playing = false; | |
186 | |
187 // do not risk a lock | |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
188 #ifdef VORBIS_SUPPORT |
2 | 189 audio_ready_cond.notify_one(); |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
14
diff
changeset
|
190 #endif |
2 | 191 video_ready_cond.notify_one(); |
192 | |
193 // cleanup | |
194 close(); | |
195 } | |
196 | |
197 void OggPlayer::Imp::play() { | |
198 playing = true; | |
199 play_thread = boost::thread(boost::bind(&OggPlayer::Imp::play_loop, this)); | |
200 } | |
201 |