Mercurial > hg > forks > bilotrip-mj12
annotate liboggplayer-src/src/oggplayer.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 | 105513a2e3c9 |
children | 9c63b355c82b |
rev | line source |
---|---|
2 | 1 #include <oggplayer.h> |
2 #include "imp.hpp" | |
3 | |
4 OggPlayer::~OggPlayer() { | |
5 imp->refs--; | |
6 if(imp->refs==0){ | |
7 close(); | |
8 delete imp; | |
9 } | |
10 } | |
11 | |
12 OggPlayer::OggPlayer() { | |
13 imp = new Imp; | |
14 } | |
15 | |
16 OggPlayer::OggPlayer(OggPlayer& os) { | |
17 imp = os.imp; | |
18 imp->refs++; | |
19 } | |
20 | |
21 OggPlayer& OggPlayer::operator =(OggPlayer& os){ | |
22 if(this==&os) return *this; | |
23 imp->refs--; | |
24 if(imp->refs==0){ | |
25 close(); | |
26 delete imp; | |
27 } | |
28 imp = os.imp; | |
29 imp->refs++; | |
30 return *this; | |
31 } | |
32 | |
33 OggPlayer::OggPlayer(std::string path, AudioFormat audio_format, int channels, | |
34 int rate, VideoFormat video_format){ | |
35 imp = new Imp; | |
36 open(path, audio_format, channels, rate, video_format); | |
37 } | |
38 | |
39 void OggPlayer::open(std::string path, AudioFormat audio_format, int channels, | |
40 int rate, VideoFormat video_format) { | |
41 if(playing()) close(); | |
42 imp->open(path, audio_format, channels, rate, video_format); | |
43 } | |
44 | |
45 void OggPlayer::close() { | |
46 imp->playing = false; | |
47 // wait for play thread to terminate (if any) | |
48 imp->play_thread.join(); | |
49 } | |
50 | |
51 bool OggPlayer::fail() { | |
52 return imp->failbit; | |
53 } | |
54 | |
55 void OggPlayer::play() { | |
56 imp->play(); | |
57 } | |
58 | |
59 bool OggPlayer::playing() { | |
60 return imp->playing; | |
61 } | |
62 | |
63 | |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
64 #ifdef VORBIS_SUPPORT |
2 | 65 int OggPlayer::audio_read(char* buf, unsigned int size) { |
66 if(NULL==buf || !imp->vorbis_p || !playing() || !imp->ready()) return 0; | |
67 boost::unique_lock<boost::mutex> lock(imp->audio_mut); | |
68 | |
69 while ((imp->cirbuf.size() < size) && playing()) { | |
70 if(imp->cirbuf.capacity()< size) | |
71 { | |
72 imp->cirbuf.set_capacity(2*size); | |
73 } | |
74 imp->audio_ready_cond.wait(lock); | |
75 } | |
76 | |
77 unsigned int k = 0; | |
78 while (k < size && !imp->cirbuf.empty()) { | |
79 buf[k++] = imp->cirbuf.front(); | |
80 imp->cirbuf.pop_front(); | |
81 } | |
82 imp->audio_bytes_played+=k; | |
83 | |
84 return k; | |
85 } | |
59
3eacedd172ab
Fence some lingering audio code, based on fixes from visy.
Matti Hamalainen <ccr@tnsp.org>
parents:
2
diff
changeset
|
86 #endif |
2 | 87 |
88 bool OggPlayer::yuv_buffer_try_lock(YUVBuffer *buffer) { | |
89 if (!playing() || !imp->theora_p || !imp->ready()) | |
90 return false; | |
91 // no new data, no reason to lock | |
92 if(imp->last_frame_read==imp->frame) | |
93 return false; | |
94 imp->video_lock.lock(); | |
95 while (!imp->videobuf_ready && playing()) { | |
96 imp->video_ready_cond.wait(imp->video_lock); | |
97 } | |
98 //ready and locked! | |
99 yuv_buffer yuv; | |
100 theora_decode_YUVout(&(imp->t_state), &yuv); | |
101 | |
102 buffer->y_width = yuv.y_width; | |
103 buffer->y_height = yuv.y_height; | |
104 buffer->y_stride = yuv.y_stride; | |
105 buffer->uv_width = yuv.uv_width; | |
106 buffer->uv_height = yuv.uv_height; | |
107 buffer->uv_stride = yuv.uv_stride; | |
108 buffer->y = yuv.y; | |
109 buffer->u = yuv.u; | |
110 buffer->v = yuv.v; | |
111 | |
112 imp->last_frame_read = imp->frame; | |
113 return true; | |
114 } | |
115 | |
116 void OggPlayer::yuv_buffer_unlock() { | |
117 imp->video_lock.unlock(); | |
118 } | |
119 | |
120 inline int clamp(int val){ | |
121 if(val<0) return 0; | |
122 if(val>255) return 255; | |
123 return val; | |
124 } | |
125 | |
126 bool OggPlayer::video_read(char* buf, int stride) { | |
127 YUVBuffer yuv; | |
128 if(NULL==buf) return false; | |
129 if (!yuv_buffer_try_lock(&yuv)) | |
130 return false; | |
131 | |
132 if(0==stride) stride=width()*imp->pixel_format.bpp; | |
133 int h = height(), w = width(); | |
134 | |
135 int uv_ki=yuv.y_width/yuv.uv_width; | |
136 int uv_kj=yuv.y_height/yuv.uv_height; | |
137 | |
138 int y_offset = offset_x() + yuv.y_stride * offset_y(); | |
139 int uv_offset = offset_x()/uv_ki+yuv.uv_stride * offset_y()/uv_kj; | |
140 int y_p,uv_p,b_p; | |
141 | |
142 for(int j=0;j<h;j++){ | |
143 y_p=y_offset+j*yuv.y_stride; | |
144 b_p=j*stride; | |
145 uv_p=uv_offset+j/uv_kj*yuv.uv_stride; | |
146 | |
147 for(int i=0;i<w;i++){ | |
148 //http://en.wikipedia.org/wiki/YUV | |
149 int y = yuv.y[y_p]-16; | |
150 int u = yuv.u[uv_p]-128; | |
151 int v = yuv.v[uv_p]-128; | |
152 int r =clamp((y*298+409*v+128)>>8); | |
153 int g =clamp((y*298-100*v-208*u+128)>>8); | |
154 int b =clamp((y*298+516*u+128)>>8); | |
155 buf[b_p+imp->pixel_format.r_offset]=r; | |
156 buf[b_p+imp->pixel_format.g_offset]=g; | |
157 buf[b_p+imp->pixel_format.b_offset]=b; | |
158 if(4==imp->pixel_format.bpp) | |
159 buf[b_p+3]=255; | |
160 | |
161 b_p+=imp->pixel_format.bpp; | |
162 y_p++; | |
163 if( i%uv_ki == uv_ki-1 ) uv_p++; | |
164 } | |
165 } | |
166 yuv_buffer_unlock(); | |
167 return true; | |
168 } | |
169 | |
170 int OggPlayer::width() { | |
171 return imp->t_info.width; | |
172 } | |
173 int OggPlayer::height() { | |
174 return imp->t_info.height; | |
175 } | |
176 int OggPlayer::offset_x() { | |
177 return imp->t_info.offset_x; | |
178 } | |
179 int OggPlayer::offset_y() { | |
180 return imp->t_info.offset_y; | |
181 } | |
182 |