summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/loopcontrol_threaded.cpp
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/loopcontrol_threaded.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/loopcontrol_threaded.cpp578
1 files changed, 289 insertions, 289 deletions
diff --git a/core/multimedia/opieplayer/loopcontrol_threaded.cpp b/core/multimedia/opieplayer/loopcontrol_threaded.cpp
index e99c97b..364e77b 100644
--- a/core/multimedia/opieplayer/loopcontrol_threaded.cpp
+++ b/core/multimedia/opieplayer/loopcontrol_threaded.cpp
@@ -49,88 +49,88 @@ extern MediaPlayerState *mediaPlayerState;
49 49
50 50
51#define DecodeLoopDebug(x) qDebug x 51#define DecodeLoopDebug(x) qDebug x
52//#define DecodeLoopDebug(x) 52//#define DecodeLoopDebug(x)
53 53
54 54
55 static char *audioBuffer = NULL; 55static char *audioBuffer = NULL;
56static AudioDevice *audioDevice = NULL; 56static AudioDevice *audioDevice = NULL;
57 static bool disabledSuspendScreenSaver = FALSE; 57static bool disabledSuspendScreenSaver = FALSE;
58 58
59 59
60 pthread_tvideo_tid; 60pthread_t video_tid;
61pthread_attr_t video_attr; 61pthread_attr_t video_attr;
62 pthread_taudio_tid; 62pthread_t audio_tid;
63pthread_attr_t audio_attr; 63pthread_attr_t audio_attr;
64 64
65 65
66bool emitPlayFinished = FALSE; 66bool emitPlayFinished = FALSE;
67bool emitChangePos = FALSE; 67bool emitChangePos = FALSE;
68 68
69 69
70class Mutex { 70class Mutex {
71public: 71public:
72 Mutex() { 72 Mutex() {
73 pthread_mutexattr_t attr; 73 pthread_mutexattr_t attr;
74 pthread_mutexattr_init( &attr ); 74 pthread_mutexattr_init( &attr );
75 pthread_mutex_init( &mutex, &attr ); 75 pthread_mutex_init( &mutex, &attr );
76 pthread_mutexattr_destroy( &attr ); 76 pthread_mutexattr_destroy( &attr );
77 } 77 }
78 78
79 ~Mutex() { 79 ~Mutex() {
80 pthread_mutex_destroy( &mutex ); 80 pthread_mutex_destroy( &mutex );
81 } 81 }
82 82
83 void lock() { 83 void lock() {
84 pthread_mutex_lock( &mutex ); 84 pthread_mutex_lock( &mutex );
85 } 85 }
86 86
87 void unlock() { 87 void unlock() {
88 pthread_mutex_unlock( &mutex ); 88 pthread_mutex_unlock( &mutex );
89 } 89 }
90/* 90/*
91 bool locked() { 91 bool locked() {
92 switch ( pthread_mutex_trylock( &mutex ) ) { 92 switch ( pthread_mutex_trylock( &mutex ) ) {
93 case EBUSY: 93 case EBUSY:
94 return TRUE; 94 return TRUE;
95 case 0: 95 case 0:
96 pthread_mutex_unlock( &mutex ); 96 pthread_mutex_unlock( &mutex );
97 default: 97 default:
98 return FALSE; 98 return FALSE;
99 } 99 }
100 } 100 }
101*/ 101*/
102private: 102private:
103 pthread_mutex_t mutex; 103 pthread_mutex_t mutex;
104}; 104};
105 105
106 106
107class currentFrameObj { 107class currentFrameObj {
108public: 108public:
109 currentFrameObj() : value( 0 ) { } 109 currentFrameObj() : value( 0 ) { }
110 void set( long f ) { 110 void set( long f ) {
111 mutex.lock(); 111 mutex.lock();
112 value = f; 112 value = f;
113 mediaPlayerState->curDecoder()->videoSetFrame( f, 0 ); 113 mediaPlayerState->curDecoder()->videoSetFrame( f, 0 );
114 mutex.unlock(); 114 mutex.unlock();
115 } 115 }
116 long get() { 116 long get() {
117 return value; 117 return value;
118 } 118 }
119private: 119private:
120 long value; 120 long value;
121 Mutex mutex; 121 Mutex mutex;
122}; 122};
123 123
124 124
125Mutex *videoMutex; 125Mutex *videoMutex;
126Mutex *audioMutex; 126Mutex *audioMutex;
127Mutex *globalMutex; 127Mutex *globalMutex;
128 128
129 129
130 clock_tbegin; 130clock_t begin;
131 131
132 132
133LoopControl::LoopControl( QObject *parent, const char *name ) 133LoopControl::LoopControl( QObject *parent, const char *name )
134 : QObject( parent, name ) { 134 : QObject( parent, name ) {
135 isMuted = FALSE; 135 isMuted = FALSE;
136 connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( setMute(bool) ) ); 136 connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( setMute(bool) ) );
@@ -155,76 +155,76 @@ static int currentSample = 0;
155 155
156void LoopControl::timerEvent( QTimerEvent* ) { 156void LoopControl::timerEvent( QTimerEvent* ) {
157 // We need to emit playFinished from the main thread, not one of the 157 // We need to emit playFinished from the main thread, not one of the
158 // decoding threads else we'll have all kinds of yucky things happen (reentrance). 158 // decoding threads else we'll have all kinds of yucky things happen (reentrance).
159 // playFinished will eventually call stop() which stops these threads. 159 // playFinished will eventually call stop() which stops these threads.
160 if ( emitPlayFinished ) { 160 if ( emitPlayFinished ) {
161 emitPlayFinished = FALSE; 161 emitPlayFinished = FALSE;
162 mediaPlayerState->setPlaying( FALSE ); 162 mediaPlayerState->setPlaying( FALSE );
163 } 163 }
164 164
165 if ( emitChangePos ) { 165 if ( emitChangePos ) {
166 166
167 emitChangePos = FALSE; 167 emitChangePos = FALSE;
168 168
169 if ( hasVideoChannel && hasAudioChannel ) { 169 if ( hasVideoChannel && hasAudioChannel ) {
170 sendingNewPos = TRUE; 170 sendingNewPos = TRUE;
171 mediaPlayerState->setPosition( current_frame ); 171 mediaPlayerState->setPosition( current_frame );
172 } else if ( hasVideoChannel ) { 172 } else if ( hasVideoChannel ) {
173 sendingNewPos = TRUE; 173 sendingNewPos = TRUE;
174 mediaPlayerState->setPosition( current_frame ); 174 mediaPlayerState->setPosition( current_frame );
175 } else if ( hasAudioChannel ) { 175 } else if ( hasAudioChannel ) {
176 sendingNewPos = TRUE; 176 sendingNewPos = TRUE;
177 mediaPlayerState->setPosition( audioSampleCounter ); 177 mediaPlayerState->setPosition( audioSampleCounter );
178 } 178 }
179 179
180 } 180 }
181} 181}
182 182
183 183
184 184
185 185
186void LoopControl::setPosition( long pos ) { 186void LoopControl::setPosition( long pos ) {
187 if ( sendingNewPos ) { 187 if ( sendingNewPos ) {
188 sendingNewPos = FALSE; 188 sendingNewPos = FALSE;
189 return; 189 return;
190 } 190 }
191 191
192 if ( hasVideoChannel && hasAudioChannel ) { 192 if ( hasVideoChannel && hasAudioChannel ) {
193 videoMutex->lock(); 193 videoMutex->lock();
194 audioMutex->lock(); 194 audioMutex->lock();
195qDebug("setting position"); 195 //qDebug("setting position");
196 playtime.restart(); 196 playtime.restart();
197 playtime = playtime.addMSecs( -pos * 1000 / framerate ); 197 playtime = playtime.addMSecs( -pos * 1000 / framerate );
198 //begin = clock() - (double)pos * CLOCKS_PER_SEC / framerate; 198 //begin = clock() - (double)pos * CLOCKS_PER_SEC / framerate;
199 current_frame = pos + 1; 199 current_frame = pos + 1;
200 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream ); 200 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
201 prev_frame = current_frame - 1; 201 prev_frame = current_frame - 1;
202 currentSample = (int)( current_frame * freq / framerate ); 202 currentSample = (int)( current_frame * freq / framerate );
203 mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream ); 203 mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
204 audioSampleCounter = currentSample - 1; 204 audioSampleCounter = currentSample - 1;
205 audioMutex->unlock(); 205 audioMutex->unlock();
206 videoMutex->unlock(); 206 videoMutex->unlock();
207 } else if ( hasVideoChannel ) { 207 } else if ( hasVideoChannel ) {
208 videoMutex->lock(); 208 videoMutex->lock();
209 playtime.restart(); 209 playtime.restart();
210 playtime = playtime.addMSecs( -pos * 1000 / framerate ); 210 playtime = playtime.addMSecs( -pos * 1000 / framerate );
211 //begin = clock() - (double)pos * CLOCKS_PER_SEC / framerate; 211 //begin = clock() - (double)pos * CLOCKS_PER_SEC / framerate;
212 current_frame = pos + 1; 212 current_frame = pos + 1;
213 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream ); 213 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
214 videoMutex->unlock(); 214 videoMutex->unlock();
215 prev_frame = current_frame - 1; 215 prev_frame = current_frame - 1;
216 } else if ( hasAudioChannel ) { 216 } else if ( hasAudioChannel ) {
217 audioMutex->lock(); 217 audioMutex->lock();
218 playtime.restart(); 218 playtime.restart();
219 playtime = playtime.addMSecs( -pos * 1000 / freq ); 219 playtime = playtime.addMSecs( -pos * 1000 / freq );
220 //begin = clock() - (double)pos * CLOCKS_PER_SEC / freq; 220 //begin = clock() - (double)pos * CLOCKS_PER_SEC / freq;
221 currentSample = pos + 1; // (int)( current_frame * freq / framerate ); 221 currentSample = pos + 1; // (int)( current_frame * freq / framerate );
222 mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream ); 222 mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
223 audioSampleCounter = currentSample - 1; 223 audioSampleCounter = currentSample - 1;
224 audioMutex->unlock(); 224 audioMutex->unlock();
225 } 225 }
226} 226}
227 227
228 228
229void *startVideoThread( void *ptr ) { 229void *startVideoThread( void *ptr ) {
230 LoopControl *mpegView = (LoopControl *)ptr; 230 LoopControl *mpegView = (LoopControl *)ptr;
@@ -242,341 +242,341 @@ void LoopControl::startVideo() {
242 moreVideo = TRUE; 242 moreVideo = TRUE;
243 243
244 while ( moreVideo ) { 244 while ( moreVideo ) {
245 245
246 if ( mediaPlayerState->curDecoder() && hasVideoChannel ) { 246 if ( mediaPlayerState->curDecoder() && hasVideoChannel ) {
247 247
248 if ( hasAudioChannel && !isMuted ) { 248 if ( hasAudioChannel && !isMuted ) {
249 249
250 bool done = FALSE; 250 bool done = FALSE;
251 251
252 do { 252 do {
253 253
254 254
255/* 255/*
256 videoMutex->lock(); 256 videoMutex->lock();
257 current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 ); 257 current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 );
258 //current_frame = ( clock() - begin ) * (double)framerate / CLOCKS_PER_SEC; 258 //current_frame = ( clock() - begin ) * (double)framerate / CLOCKS_PER_SEC;
259 259
260 // Sync to Audio 260 // Sync to Audio
261 // current_frame = (long)((double)(audioSampleCounter - 1000) * framerate / (double)freq); 261// current_frame = (long)((double)(audioSampleCounter - 1000) * framerate / (double)freq);
262 262
263 long mSecsToNextFrame = 0; 263 long mSecsToNextFrame = 0;
264 264
265 if ( current_frame == prev_frame ) { 265 if ( current_frame == prev_frame ) {
266 int nf = current_frame + 1; 266 int nf = current_frame + 1;
267 if ( nf > 0 && nf != total_video_frames ) 267 if ( nf > 0 && nf != total_video_frames )
268 // mSecsToNextFrame = long(double(nf * CLOCKS_PER_SEC) / framerate) - ( clock() - begin ); 268 // mSecsToNextFrame = long(double(nf * CLOCKS_PER_SEC) / framerate) - ( clock() - begin );
269 mSecsToNextFrame = long(double(nf * 1000) / framerate) - ( playtime.elapsed() ); 269 mSecsToNextFrame = long(double(nf * 1000) / framerate) - ( playtime.elapsed() );
270 } 270 }
271 videoMutex->unlock(); 271 videoMutex->unlock();
272 272
273 if ( mSecsToNextFrame ) { 273 if ( mSecsToNextFrame ) {
274 usleep( mSecsToNextFrame ); // wait a bit 274 usleep( mSecsToNextFrame ); // wait a bit
275 275
276 videoMutex->lock(); 276 videoMutex->lock();
277 // This should now be the next frame 277 // This should now be the next frame
278 current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 ); 278 current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 );
279 //current_frame = ( clock() - begin ) * (double)framerate / CLOCKS_PER_SEC; 279 //current_frame = ( clock() - begin ) * (double)framerate / CLOCKS_PER_SEC;
280 videoMutex->unlock(); 280 videoMutex->unlock();
281 } 281 }
282 282
283 videoMutex->lock(); 283 videoMutex->lock();
284 done = current_frame >= prev_frame; 284 done = current_frame >= prev_frame;
285 videoMutex->unlock(); 285 videoMutex->unlock();
286*/ 286*/
287 videoMutex->lock(); 287 videoMutex->lock();
288 current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 ); 288 current_frame = int( (double)playtime.elapsed() * (double)framerate / 1000.0 );
289 done = current_frame >= prev_frame; 289 done = current_frame >= prev_frame;
290 videoMutex->unlock(); 290 videoMutex->unlock();
291 if ( !done ) 291 if ( !done )
292 usleep( 1000 ); // wait a bit 292 usleep( 1000 ); // wait a bit
293 293
294 } while ( !done ); 294 } while ( !done );
295 295
296 // qDebug("elapsed: %i %i (%f)", int( playtime.elapsed() ), current_frame, framerate ); 296// qDebug("elapsed: %i %i (%f)", int( playtime.elapsed() ), current_frame, framerate );
297 297
298 } else { 298 } else {
299 videoMutex->lock(); 299 videoMutex->lock();
300 current_frame++; 300 current_frame++;
301 videoMutex->unlock(); 301 videoMutex->unlock();
302 } 302 }
303 303
304 videoMutex->lock(); 304 videoMutex->lock();
305 bool check = current_frame && current_frame > prev_frame; 305 bool check = current_frame && current_frame > prev_frame;
306 videoMutex->unlock(); 306 videoMutex->unlock();
307 307
308 if ( check ) { 308 if ( check ) {
309 videoMutex->lock(); 309 videoMutex->lock();
310 if ( current_frame > prev_frame + 1 ) { 310 if ( current_frame > prev_frame + 1 ) {
311 qDebug("skipped a frame"); 311 // qDebug("skipped a frame");
312 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream ); 312 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
313 } 313 }
314 prev_frame = current_frame; 314 prev_frame = current_frame;
315 if ( moreVideo = videoUI->playVideo() ) 315 if ( moreVideo = videoUI->playVideo() )
316 emitChangePos = TRUE; 316 emitChangePos = TRUE;
317 videoMutex->unlock(); 317 videoMutex->unlock();
318 } 318 }
319 319
320 } else 320 } else
321 moreVideo = FALSE; 321 moreVideo = FALSE;
322 322
323 } 323 }
324 324
325 if ( !moreVideo && !moreAudio ) 325 if ( !moreVideo && !moreAudio )
326 emitPlayFinished = TRUE; 326 emitPlayFinished = TRUE;
327 327
328 pthread_exit(NULL); 328 pthread_exit(NULL);
329} 329}
330 330
331void LoopControl::startAudio() { 331void LoopControl::startAudio() {
332 moreAudio = TRUE; 332 moreAudio = TRUE;
333 333
334 while ( moreAudio ) { 334 while ( moreAudio ) {
335 335
336 if ( !isMuted && mediaPlayerState->curDecoder() && hasAudioChannel ) { 336 if ( !isMuted && mediaPlayerState->curDecoder() && hasAudioChannel ) {
337 337
338 audioMutex->lock(); 338 audioMutex->lock();
339 currentSample = mediaPlayerState->curDecoder()->audioGetSample( stream ); 339 currentSample = mediaPlayerState->curDecoder()->audioGetSample( stream );
340 340
341 if ( currentSample == 0 ) 341 if ( currentSample == 0 )
342 currentSample = audioSampleCounter + 1; 342 currentSample = audioSampleCounter + 1;
343 343
344 if ( currentSample != audioSampleCounter + 1 ) 344// if ( currentSample != audioSampleCounter + 1 )
345 qDebug("out of sync with decoder %i %i", currentSample, audioSampleCounter); 345// qDebug("out of sync with decoder %i %i", currentSample, audioSampleCounter);
346 audioMutex->unlock(); 346 audioMutex->unlock();
347 347
348/* 348/*
349 int sampleWeShouldBeAt = int( playtime.elapsed() ) * freq / 1000; 349 int sampleWeShouldBeAt = int( playtime.elapsed() ) * freq / 1000;
350 350
351 if ( sampleWeShouldBeAt - currentSample > 20000 ) { 351 if ( sampleWeShouldBeAt - currentSample > 20000 ) {
352 mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream ); 352 mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream );
353 currentSample = sampleWeShouldBeAt; 353 currentSample = sampleWeShouldBeAt;
354 } 354 }
355*/ 355*/
356 long samplesRead = 0; 356 long samplesRead = 0;
357 357
358 const long samples = 1024; 358 const long samples = 1024;
359 359
360 moreAudio = !mediaPlayerState->curDecoder()->audioReadSamples( (short*)audioBuffer, channels, samples, samplesRead, stream ); 360 moreAudio = !mediaPlayerState->curDecoder()->audioReadSamples( (short*)audioBuffer, channels, samples, samplesRead, stream );
361 361
362 audioMutex->lock(); 362 audioMutex->lock();
363 long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000; 363 long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000;
364 //long sampleWeShouldBeAt = long( clock() - begin ) * (double) freq / CLOCKS_PER_SEC; 364 //long sampleWeShouldBeAt = long( clock() - begin ) * (double) freq / CLOCKS_PER_SEC;
365 long sampleWaitTime = currentSample - sampleWeShouldBeAt; 365 long sampleWaitTime = currentSample - sampleWeShouldBeAt;
366 audioMutex->unlock(); 366 audioMutex->unlock();
367 367
368 if ( sampleWaitTime >= 0 && sampleWaitTime <= 2000 ) { 368 if ( sampleWaitTime >= 0 && sampleWaitTime <= 2000 ) {
369 //qDebug("sampleWaitTime: %i", sampleWaitTime); 369 //qDebug("sampleWaitTime: %i", sampleWaitTime);
370 usleep( ( sampleWaitTime * 1000000 ) / ( freq ) ); 370 usleep( ( sampleWaitTime * 1000000 ) / ( freq ) );
371 } else { 371 } else {
372 audioMutex->lock(); 372 audioMutex->lock();
373 if ( sampleWaitTime <= -2000 ) { 373 if ( sampleWaitTime <= -2000 ) {
374 qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt ); 374 // qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt );
375 mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream ); 375 mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream );
376 currentSample = sampleWeShouldBeAt; 376 currentSample = sampleWeShouldBeAt;
377 } 377 }
378 audioMutex->unlock(); 378 audioMutex->unlock();
379 } 379 }
380 380
381 audioDevice->write( audioBuffer, samplesRead * 2 * channels ); 381 audioDevice->write( audioBuffer, samplesRead * 2 * channels );
382 382
383 audioMutex->lock(); 383 audioMutex->lock();
384 // audioSampleCounter += samplesRead; 384// audioSampleCounter += samplesRead;
385 audioSampleCounter = currentSample + samplesRead - 1; 385 audioSampleCounter = currentSample + samplesRead - 1;
386 audioMutex->unlock(); 386 audioMutex->unlock();
387 387
388 if ( !hasVideoChannel ) 388 if ( !hasVideoChannel )
389 emitChangePos = TRUE; 389 emitChangePos = TRUE;
390 390
391 //qDebug("currentSample: %i audioSampleCounter: %i total_audio_samples: %i", currentSample, audioSampleCounter, total_audio_samples); 391 //qDebug("currentSample: %i audioSampleCounter: %i total_audio_samples: %i", currentSample, audioSampleCounter, total_audio_samples);
392 // qDebug("current: %i counter: %i total: %i", currentSample, audioSampleCounter, (int)total_audio_samples); 392// qDebug("current: %i counter: %i total: %i", currentSample, audioSampleCounter, (int)total_audio_samples);
393 moreAudio = audioSampleCounter <= total_audio_samples; 393 moreAudio = audioSampleCounter <= total_audio_samples;
394 394
395 } else { 395 } else {
396 396
397 if ( mediaPlayerState->curDecoder() && hasAudioChannel ) 397 if ( mediaPlayerState->curDecoder() && hasAudioChannel )
398 usleep( 100000 ); // Check every 1/10 sec to see if mute is off 398 usleep( 100000 ); // Check every 1/10 sec to see if mute is off
399 else 399 else
400 moreAudio = FALSE; 400 moreAudio = FALSE;
401 401
402 } 402 }
403 } 403 }
404 404
405 qDebug( "End of file" ); 405 // qDebug( "End of file" );
406 406
407 if ( !moreVideo && !moreAudio ) 407 if ( !moreVideo && !moreAudio )
408 emitPlayFinished = TRUE; 408 emitPlayFinished = TRUE;
409 409
410 pthread_exit(NULL); 410 pthread_exit(NULL);
411} 411}
412 412
413void LoopControl::killTimers() { 413void LoopControl::killTimers() {
414 if ( hasVideoChannel ) { 414 if ( hasVideoChannel ) {
415 if ( pthread_self() != video_tid ) { 415 if ( pthread_self() != video_tid ) {
416 if ( pthread_cancel(video_tid) == 0 ) { 416 if ( pthread_cancel(video_tid) == 0 ) {
417 void *thread_result = 0; 417 void *thread_result = 0;
418 if ( pthread_join(video_tid,&thread_result) != 0 ) 418 if ( pthread_join(video_tid,&thread_result) != 0 )
419 qDebug("thread join error 1"); 419 // qDebug("thread join error 1");
420 pthread_attr_destroy(&video_attr); 420 pthread_attr_destroy(&video_attr);
421 } 421 }
422 } 422 }
423 } 423 }
424 if ( hasAudioChannel ) { 424 if ( hasAudioChannel ) {
425 if ( pthread_self() != audio_tid ) { 425 if ( pthread_self() != audio_tid ) {
426 if ( pthread_cancel(audio_tid) == 0 ) { 426 if ( pthread_cancel(audio_tid) == 0 ) {
427 void *thread_result = 0; 427 void *thread_result = 0;
428 if ( pthread_join(audio_tid,&thread_result) != 0 ) 428 if ( pthread_join(audio_tid,&thread_result) != 0 )
429 qDebug("thread join error 2"); 429 // qDebug("thread join error 2");
430 pthread_attr_destroy(&audio_attr); 430 pthread_attr_destroy(&audio_attr);
431 } 431 }
432 } 432 }
433 } 433 }
434} 434}
435 435
436void LoopControl::startTimers() { 436void LoopControl::startTimers() {
437 moreVideo = FALSE; 437 moreVideo = FALSE;
438 moreAudio = FALSE; 438 moreAudio = FALSE;
439 439
440 if ( hasVideoChannel ) { 440 if ( hasVideoChannel ) {
441 moreVideo = TRUE; 441 moreVideo = TRUE;
442 pthread_attr_init(&video_attr); 442 pthread_attr_init(&video_attr);
443 pthread_create(&video_tid, &video_attr, (void * (*)(void *))startVideoThread, this); 443 pthread_create(&video_tid, &video_attr, (void * (*)(void *))startVideoThread, this);
444 } 444 }
445 445
446 if ( hasAudioChannel ) { 446 if ( hasAudioChannel ) {
447 moreAudio = TRUE; 447 moreAudio = TRUE;
448 pthread_attr_init(&audio_attr); 448 pthread_attr_init(&audio_attr);
449#ifdef USE_REALTIME_AUDIO_THREAD 449#ifdef USE_REALTIME_AUDIO_THREAD
450 pthread_attr_setschedpolicy(&audio_attr,SCHED_RR); // Real-time round robin 450 pthread_attr_setschedpolicy(&audio_attr,SCHED_RR); // Real-time round robin
451 //qDebug("min: %i, max: %i", sched_get_priority_min( SCHED_RR ), sched_get_priority_max( SCHED_RR ) ); 451 //qDebug("min: %i, max: %i", sched_get_priority_min( SCHED_RR ), sched_get_priority_max( SCHED_RR ) );
452 sched_param params; 452 sched_param params;
453 params.sched_priority = 50; 453 params.sched_priority = 50;
454 pthread_attr_setschedparam(&audio_attr,&params); 454 pthread_attr_setschedparam(&audio_attr,&params);
455#endif 455#endif
456 pthread_create(&audio_tid, &audio_attr, (void * (*)(void *))startAudioThread, this); 456 pthread_create(&audio_tid, &audio_attr, (void * (*)(void *))startAudioThread, this);
457 } 457 }
458} 458}
459 459
460 460
461 461
462 462
463void LoopControl::setPaused( bool pause ) { 463void LoopControl::setPaused( bool pause ) {
464 static int whenPaused = 0; 464 static int whenPaused = 0;
465 465
466 if ( !mediaPlayerState->curDecoder() || !mediaPlayerState->curDecoder()->isOpen() ) 466 if ( !mediaPlayerState->curDecoder() || !mediaPlayerState->curDecoder()->isOpen() )
467 return; 467 return;
468 468
469 if ( pause ) { 469 if ( pause ) {
470 // Remember where we are 470 // Remember where we are
471 whenPaused = playtime.elapsed(); 471 whenPaused = playtime.elapsed();
472 killTimers(); 472 killTimers();
473 } else { 473 } else {
474 // Just like we never stopped 474 // Just like we never stopped
475 playtime.restart(); 475 playtime.restart();
476 playtime = playtime.addMSecs( -whenPaused ); 476 playtime = playtime.addMSecs( -whenPaused );
477 whenPaused = 0; 477 whenPaused = 0;
478 startTimers(); 478 startTimers();
479 } 479 }
480} 480}
481 481
482 482
483void LoopControl::stop( bool willPlayAgainShortly ) { 483void LoopControl::stop( bool willPlayAgainShortly ) {
484 484
485#if defined(Q_WS_QWS) && !defined(QT_NO_COP) 485#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
486 if ( !willPlayAgainShortly && disabledSuspendScreenSaver ) { 486 if ( !willPlayAgainShortly && disabledSuspendScreenSaver ) {
487 disabledSuspendScreenSaver = FALSE; 487 disabledSuspendScreenSaver = FALSE;
488 // Re-enable the suspend mode 488 // Re-enable the suspend mode
489 QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable; 489 QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
490 } 490 }
491#endif 491#endif
492 492
493 if ( mediaPlayerState->curDecoder() && mediaPlayerState->curDecoder()->isOpen() ) { 493 if ( mediaPlayerState->curDecoder() && mediaPlayerState->curDecoder()->isOpen() ) {
494 494
495 killTimers(); 495 killTimers();
496 496
497 mediaPlayerState->curDecoder()->close(); 497 mediaPlayerState->curDecoder()->close();
498 498
499 if ( audioDevice ) { 499 if ( audioDevice ) {
500 delete audioDevice; 500 delete audioDevice;
501 delete audioBuffer; 501 delete audioBuffer;
502 audioDevice = 0; 502 audioDevice = 0;
503 audioBuffer = 0; 503 audioBuffer = 0;
504 } 504 }
505 505
506 } 506 }
507} 507}
508 508
509 509
510bool LoopControl::init( const QString& filename ) { 510bool LoopControl::init( const QString& filename ) {
511 stop(); 511 stop();
512 fileName = filename; 512 fileName = filename;
513 stream = 0; // only play stream 0 for now 513 stream = 0; // only play stream 0 for now
514 current_frame = total_video_frames = total_audio_samples = 0; 514 current_frame = total_video_frames = total_audio_samples = 0;
515 515
516 qDebug( "Using the %s decoder", mediaPlayerState->curDecoder()->pluginName() ); 516 // qDebug( "Using the %s decoder", mediaPlayerState->curDecoder()->pluginName() );
517 517
518 // ### Hack to use libmpeg3plugin to get the number of audio samples if we are using the libmad plugin 518 // ### Hack to use libmpeg3plugin to get the number of audio samples if we are using the libmad plugin
519 if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibMadPlugin") ) { 519 if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibMadPlugin") ) {
520 if ( mediaPlayerState->libMpeg3Decoder() && mediaPlayerState->libMpeg3Decoder()->open( filename ) ) { 520 if ( mediaPlayerState->libMpeg3Decoder() && mediaPlayerState->libMpeg3Decoder()->open( filename ) ) {
521 total_audio_samples = mediaPlayerState->libMpeg3Decoder()->audioSamples( 0 ); 521 total_audio_samples = mediaPlayerState->libMpeg3Decoder()->audioSamples( 0 );
522 mediaPlayerState->libMpeg3Decoder()->close(); 522 mediaPlayerState->libMpeg3Decoder()->close();
523 } 523 }
524 } 524 }
525 525
526 if ( !mediaPlayerState->curDecoder()|| !mediaPlayerState->curDecoder()->open( filename ) ) 526 if ( !mediaPlayerState->curDecoder()|| !mediaPlayerState->curDecoder()->open( filename ) )
527 return FALSE; 527 return FALSE;
528 528
529 hasAudioChannel = mediaPlayerState->curDecoder()->audioStreams() > 0; 529 hasAudioChannel = mediaPlayerState->curDecoder()->audioStreams() > 0;
530 hasVideoChannel = mediaPlayerState->curDecoder()->videoStreams() > 0; 530 hasVideoChannel = mediaPlayerState->curDecoder()->videoStreams() > 0;
531 531
532 if ( hasAudioChannel ) { 532 if ( hasAudioChannel ) {
533 int astream = 0; 533 int astream = 0;
534 534
535 channels = mediaPlayerState->curDecoder()->audioChannels( astream ); 535 channels = mediaPlayerState->curDecoder()->audioChannels( astream );
536 DecodeLoopDebug(( "channels = %d\n", channels )); 536 DecodeLoopDebug(( "channels = %d\n", channels ));
537 537
538 if ( !total_audio_samples ) 538 if ( !total_audio_samples )
539 total_audio_samples = mediaPlayerState->curDecoder()->audioSamples( astream ); 539 total_audio_samples = mediaPlayerState->curDecoder()->audioSamples( astream );
540 540
541 mediaPlayerState->setLength( total_audio_samples ); 541 mediaPlayerState->setLength( total_audio_samples );
542 542
543 freq = mediaPlayerState->curDecoder()->audioFrequency( astream ); 543 freq = mediaPlayerState->curDecoder()->audioFrequency( astream );
544 DecodeLoopDebug(( "frequency = %d\n", freq )); 544 DecodeLoopDebug(( "frequency = %d\n", freq ));
545 545
546 audioSampleCounter = 0; 546 audioSampleCounter = 0;
547 547
548 static const int bytes_per_sample = 2; //16 bit 548 static const int bytes_per_sample = 2; //16 bit
549 549
550 audioDevice = new AudioDevice( freq, channels, bytes_per_sample ); 550 audioDevice = new AudioDevice( freq, channels, bytes_per_sample );
551 audioBuffer = new char[ audioDevice->bufferSize() ]; 551 audioBuffer = new char[ audioDevice->bufferSize() ];
552 channels = audioDevice->channels(); 552 channels = audioDevice->channels();
553 553
554 //### must check which frequency is actually used. 554 //### must check which frequency is actually used.
555 static const int size = 1; 555 static const int size = 1;
556 short int buf[size]; 556 short int buf[size];
557 long samplesRead = 0; 557 long samplesRead = 0;
558 mediaPlayerState->curDecoder()->audioReadSamples( buf, channels, size, samplesRead, stream ); 558 mediaPlayerState->curDecoder()->audioReadSamples( buf, channels, size, samplesRead, stream );
559 } 559 }
560 560
561 if ( hasVideoChannel ) { 561 if ( hasVideoChannel ) {
562 total_video_frames = mediaPlayerState->curDecoder()->videoFrames( stream ); 562 total_video_frames = mediaPlayerState->curDecoder()->videoFrames( stream );
563 563
564 mediaPlayerState->setLength( total_video_frames ); 564 mediaPlayerState->setLength( total_video_frames );
565 565
566 framerate = mediaPlayerState->curDecoder()->videoFrameRate( stream ); 566 framerate = mediaPlayerState->curDecoder()->videoFrameRate( stream );
567 DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames )); 567 DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames ));
568 568
569 if ( framerate <= 1.0 ) { 569 if ( framerate <= 1.0 ) {
570 DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" )); 570 DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" ));
571 framerate = 25; 571 framerate = 25;
572 } 572 }
573 573
574 if ( total_video_frames == 1 ) { 574 if ( total_video_frames == 1 ) {
575 DecodeLoopDebug(( "Cannot seek to frame" )); 575 DecodeLoopDebug(( "Cannot seek to frame" ));
576 } 576 }
577 577
578 } 578 }
579 579
580 videoMutex->lock(); 580 videoMutex->lock();
581 current_frame = 0; 581 current_frame = 0;
582 prev_frame = -1; 582 prev_frame = -1;
@@ -591,35 +591,35 @@ bool LoopControl::init( const QString& filename ) {
591 591
592 592
593void LoopControl::play() { 593void LoopControl::play() {
594 594
595#if defined(Q_WS_QWS) && !defined(QT_NO_COP) 595#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
596 if ( !disabledSuspendScreenSaver ) { 596 if ( !disabledSuspendScreenSaver ) {
597 disabledSuspendScreenSaver = TRUE; 597 disabledSuspendScreenSaver = TRUE;
598 // Stop the screen from blanking and power saving state 598 // Stop the screen from blanking and power saving state
599 QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) 599 QCopEnvelope("QPE/System", "setScreenSaverMode(int)" )
600 << ( hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend ); 600 << ( hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend );
601 } 601 }
602#endif 602#endif
603 603
604 //begin = clock(); 604 //begin = clock();
605 playtime.start(); 605 playtime.start();
606 startTimers(); 606 startTimers();
607 //updateGeometry(); 607 //updateGeometry();
608} 608}
609 609
610 610
611void LoopControl::setMute( bool on ) { 611void LoopControl::setMute( bool on ) {
612 if ( isMuted != on ) { 612 if ( isMuted != on ) {
613 isMuted = on; 613 isMuted = on;
614 if ( isMuted ) { 614 if ( isMuted ) {
615 } else { 615 } else {
616 int frame = current_frame; // mediaPlayerState->curDecoder()->videoGetFrame( stream ); 616 int frame = current_frame; // mediaPlayerState->curDecoder()->videoGetFrame( stream );
617 playtime.restart(); 617 playtime.restart();
618 playtime = playtime.addMSecs( -frame * 1000 / framerate ); 618 playtime = playtime.addMSecs( -frame * 1000 / framerate );
619 //begin = clock() - (double)frame * CLOCKS_PER_SEC / framerate; 619 //begin = clock() - (double)frame * CLOCKS_PER_SEC / framerate;
620 mediaPlayerState->curDecoder()->audioSetSample( frame*freq/framerate, stream ); 620 mediaPlayerState->curDecoder()->audioSetSample( frame*freq/framerate, stream );
621 } 621 }
622 } 622 }
623} 623}
624 624
625 625