summaryrefslogtreecommitdiff
path: root/core/multimedia/opieplayer/loopcontrol.cpp
Unidiff
Diffstat (limited to 'core/multimedia/opieplayer/loopcontrol.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/multimedia/opieplayer/loopcontrol.cpp34
1 files changed, 20 insertions, 14 deletions
diff --git a/core/multimedia/opieplayer/loopcontrol.cpp b/core/multimedia/opieplayer/loopcontrol.cpp
index 90a7cc6..cb8de8a 100644
--- a/core/multimedia/opieplayer/loopcontrol.cpp
+++ b/core/multimedia/opieplayer/loopcontrol.cpp
@@ -13,49 +13,49 @@
13** 13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information. 14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15** 15**
16** Contact info@trolltech.com if any conditions of this licensing are 16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you. 17** not clear to you.
18** 18**
19**********************************************************************/ 19**********************************************************************/
20// L.J.Potter added changes Fri 02-15-2002 20// L.J.Potter added changes Fri 02-15-2002
21 21
22 22
23#include <qpe/qpeapplication.h> 23#include <qpe/qpeapplication.h>
24 24
25#ifdef Q_WS_QWS 25#ifdef Q_WS_QWS
26#include <qpe/qcopenvelope_qws.h> 26#include <qpe/qcopenvelope_qws.h>
27#endif 27#endif
28#include <stdio.h> 28#include <stdio.h>
29#include <stdlib.h> 29#include <stdlib.h>
30#include <string.h> 30#include <string.h>
31#include <pthread.h> 31#include <pthread.h>
32#include <errno.h> 32#include <errno.h>
33#include <unistd.h> 33#include <unistd.h>
34#include "loopcontrol.h" 34#include "loopcontrol.h"
35#include "videowidget.h" 35#include "videowidget.h"
36#include "audiodevice.h" 36#include "audiodevice.h"
37#include "mediaplayerplugininterface.h" 37#include <qpe/mediaplayerplugininterface.h>
38#include "mediaplayerstate.h" 38#include "mediaplayerstate.h"
39 39
40 40
41extern VideoWidget *videoUI; // now only needed to tell it to play a frame 41extern VideoWidget *videoUI; // now only needed to tell it to play a frame
42extern MediaPlayerState *mediaPlayerState; 42extern MediaPlayerState *mediaPlayerState;
43 43
44 44
45//#define DecodeLoopDebug(x) qDebug x 45//#define DecodeLoopDebug(x) qDebug x
46#define DecodeLoopDebug(x) 46#define DecodeLoopDebug(x)
47 47
48 48
49static char *audioBuffer = NULL; 49static char *audioBuffer = NULL;
50static AudioDevice *audioDevice = NULL; 50static AudioDevice *audioDevice = NULL;
51static bool disabledSuspendScreenSaver = FALSE; 51static bool disabledSuspendScreenSaver = FALSE;
52static bool previousSuspendMode = FALSE; 52static bool previousSuspendMode = FALSE;
53 53
54 54
55pthread_t audio_tid; 55pthread_t audio_tid;
56pthread_attr_t audio_attr; 56pthread_attr_t audio_attr;
57bool threadOkToGo = FALSE; 57bool threadOkToGo = FALSE;
58 58
59 59
60class Mutex { 60class Mutex {
61public: 61public:
@@ -80,65 +80,66 @@ public:
80private: 80private:
81 pthread_mutex_t mutex; 81 pthread_mutex_t mutex;
82}; 82};
83 83
84 84
85void *startAudioThread( void *ptr ) { 85void *startAudioThread( void *ptr ) {
86 LoopControl *mpegView = (LoopControl *)ptr; 86 LoopControl *mpegView = (LoopControl *)ptr;
87 while ( TRUE ) { 87 while ( TRUE ) {
88 if ( threadOkToGo && mpegView->moreAudio ) 88 if ( threadOkToGo && mpegView->moreAudio )
89 mpegView->startAudio(); 89 mpegView->startAudio();
90 else 90 else
91 usleep( 10000 ); // Semi-buzy-wait till we are playing again 91 usleep( 10000 ); // Semi-buzy-wait till we are playing again
92 } 92 }
93 return 0; 93 return 0;
94} 94}
95 95
96 96
97Mutex *audioMutex; 97Mutex *audioMutex;
98 98
99 99
100LoopControl::LoopControl( QObject *parent, const char *name ) 100LoopControl::LoopControl( QObject *parent, const char *name )
101 : QObject( parent, name ) { 101 : QObject( parent, name ) {
102 isMuted = FALSE; 102 isMuted = FALSE;
103 connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( setMute(bool) ) ); 103 connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( setMute(bool) ) );
104 104//qDebug("starting loopcontrol");
105 audioMutex = new Mutex; 105 audioMutex = new Mutex;
106 106
107 pthread_attr_init(&audio_attr); 107 pthread_attr_init(&audio_attr);
108#define USE_REALTIME_AUDIO_THREAD 108#define USE_REALTIME_AUDIO_THREAD
109#ifdef USE_REALTIME_AUDIO_THREAD 109#ifdef USE_REALTIME_AUDIO_THREAD
110 // Attempt to set it to real-time round robin 110 // Attempt to set it to real-time round robin
111 if ( pthread_attr_setschedpolicy( &audio_attr, SCHED_RR ) == 0 ) { 111 if ( pthread_attr_setschedpolicy( &audio_attr, SCHED_RR ) == 0 ) {
112 sched_param params; 112 sched_param params;
113 params.sched_priority = 50; 113 params.sched_priority = 50;
114 pthread_attr_setschedparam(&audio_attr,&params); 114 pthread_attr_setschedparam(&audio_attr,&params);
115 } else { 115 } else {
116 qDebug( "Error setting up a realtime thread, reverting to using a normal thread." ); 116 qDebug( "Error setting up a realtime thread, reverting to using a normal thread." );
117 pthread_attr_destroy(&audio_attr); 117 pthread_attr_destroy(&audio_attr);
118 pthread_attr_init(&audio_attr); 118 pthread_attr_init(&audio_attr);
119 } 119 }
120#endif 120#endif
121//qDebug("create audio thread");
121 pthread_create(&audio_tid, &audio_attr, (void * (*)(void *))startAudioThread, this); 122 pthread_create(&audio_tid, &audio_attr, (void * (*)(void *))startAudioThread, this);
122} 123}
123 124
124 125
125LoopControl::~LoopControl() { 126LoopControl::~LoopControl() {
126 stop(); 127 stop();
127} 128}
128 129
129 130
130static long prev_frame = 0; 131static long prev_frame = 0;
131static int currentSample = 0; 132static int currentSample = 0;
132 133
133 134
134void LoopControl::timerEvent( QTimerEvent *te ) { 135void LoopControl::timerEvent( QTimerEvent *te ) {
135 136
136 if ( te->timerId() == videoId ) 137 if ( te->timerId() == videoId )
137 startVideo(); 138 startVideo();
138 139
139 if ( te->timerId() == sliderId ) { 140 if ( te->timerId() == sliderId ) {
140 if ( hasAudioChannel && !hasVideoChannel && moreAudio ) { 141 if ( hasAudioChannel && !hasVideoChannel && moreAudio ) {
141 mediaPlayerState->updatePosition( audioSampleCounter ); 142 mediaPlayerState->updatePosition( audioSampleCounter );
142 } else if ( hasVideoChannel && moreVideo ) { 143 } else if ( hasVideoChannel && moreVideo ) {
143 mediaPlayerState->updatePosition( current_frame ); 144 mediaPlayerState->updatePosition( current_frame );
144 } 145 }
@@ -199,72 +200,72 @@ void LoopControl::startVideo() {
199 current_frame++; 200 current_frame++;
200 } 201 }
201 202
202 if ( prev_frame == -1 || current_frame > prev_frame ) { 203 if ( prev_frame == -1 || current_frame > prev_frame ) {
203 if ( current_frame > prev_frame + 1 ) { 204 if ( current_frame > prev_frame + 1 ) {
204 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream ); 205 mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
205 } 206 }
206 moreVideo = videoUI->playVideo(); 207 moreVideo = videoUI->playVideo();
207 prev_frame = current_frame; 208 prev_frame = current_frame;
208 } 209 }
209 210
210 } else { 211 } else {
211 212
212 moreVideo = FALSE; 213 moreVideo = FALSE;
213 killTimer( videoId ); 214 killTimer( videoId );
214 215
215 } 216 }
216 217
217 } 218 }
218} 219}
219 220
220 221
221void LoopControl::startAudio() { 222void LoopControl::startAudio() {
222 223
224//qDebug("start audio");
223 audioMutex->lock(); 225 audioMutex->lock();
224
225 if ( moreAudio ) { 226 if ( moreAudio ) {
226 227
227 if ( !isMuted && mediaPlayerState->curDecoder() ) { 228 if ( !isMuted && mediaPlayerState->curDecoder() ) {
228 229
229 currentSample = audioSampleCounter + 1; 230 currentSample = audioSampleCounter + 1;
230 231
231 if ( currentSample != audioSampleCounter + 1 ) 232 if ( currentSample != audioSampleCounter + 1 )
232 qDebug("out of sync with decoder %i %i", currentSample, audioSampleCounter); 233 qDebug("out of sync with decoder %i %i", currentSample, audioSampleCounter);
233 234
234 long samplesRead = 0; 235 long samplesRead = 0;
235 bool readOk=mediaPlayerState->curDecoder()->audioReadSamples( (short*)audioBuffer, channels, 1024, samplesRead, stream ); 236 bool readOk=mediaPlayerState->curDecoder()->audioReadSamples( (short*)audioBuffer, channels, 1024, samplesRead, stream );
236 long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000; 237 long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000;
237 long sampleWaitTime = currentSample - sampleWeShouldBeAt; 238 long sampleWaitTime = currentSample - sampleWeShouldBeAt;
238 239
239 if ( ( sampleWaitTime > 2000 ) && ( sampleWaitTime < 20000 ) ) { 240// if ( ( sampleWaitTime > 2000 ) && ( sampleWaitTime < 20000 ) ) {
240 usleep( (long)((double)sampleWaitTime * 1000000.0 / freq) ); 241// usleep( (long)((double)sampleWaitTime * 1000000.0 / freq) );
241 } 242// }
242 else if ( sampleWaitTime <= -5000 ) { 243// else if ( sampleWaitTime <= -5000 ) {
243 qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt ); 244// qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt );
244 //mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream ); 245// //mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream );
245 currentSample = sampleWeShouldBeAt; 246// currentSample = sampleWeShouldBeAt;
246 } 247// }
247 248
248 audioDevice->write( audioBuffer, samplesRead * 2 * channels ); 249 audioDevice->write( audioBuffer, samplesRead * 2 * channels );
249 audioSampleCounter = currentSample + samplesRead - 1; 250 audioSampleCounter = currentSample + samplesRead - 1;
250 251
251 moreAudio = readOk && (audioSampleCounter <= total_audio_samples); 252 moreAudio = readOk && (audioSampleCounter <= total_audio_samples);
252 253
253 } else { 254 } else {
254 255
255 moreAudio = FALSE; 256 moreAudio = FALSE;
256 257
257 } 258 }
258 259
259 } 260 }
260 261
261 audioMutex->unlock(); 262 audioMutex->unlock();
262} 263}
263 264
264 265
265void LoopControl::killTimers() { 266void LoopControl::killTimers() {
266 267
267 audioMutex->lock(); 268 audioMutex->lock();
268 269
269 if ( hasVideoChannel ) 270 if ( hasVideoChannel )
270 killTimer( videoId ); 271 killTimer( videoId );
@@ -370,95 +371,100 @@ bool LoopControl::init( const QString& filename ) {
370 audioMutex->unlock(); 371 audioMutex->unlock();
371 return FALSE; 372 return FALSE;
372 } 373 }
373 374
374 hasAudioChannel = mediaPlayerState->curDecoder()->audioStreams() > 0; 375 hasAudioChannel = mediaPlayerState->curDecoder()->audioStreams() > 0;
375 hasVideoChannel = mediaPlayerState->curDecoder()->videoStreams() > 0; 376 hasVideoChannel = mediaPlayerState->curDecoder()->videoStreams() > 0;
376 377
377 if ( hasAudioChannel ) { 378 if ( hasAudioChannel ) {
378 int astream = 0; 379 int astream = 0;
379 380
380 channels = mediaPlayerState->curDecoder()->audioChannels( astream ); 381 channels = mediaPlayerState->curDecoder()->audioChannels( astream );
381 qDebug( "LC- channels = %d", channels ); 382 qDebug( "LC- channels = %d", channels );
382 383
383 if ( !total_audio_samples ) 384 if ( !total_audio_samples )
384 total_audio_samples = mediaPlayerState->curDecoder()->audioSamples( astream ); 385 total_audio_samples = mediaPlayerState->curDecoder()->audioSamples( astream );
385 386
386// total_audio_samples += 1000; 387// total_audio_samples += 1000;
387 388
388 mediaPlayerState->setLength( total_audio_samples ); 389 mediaPlayerState->setLength( total_audio_samples );
389 390
390 freq = mediaPlayerState->curDecoder()->audioFrequency( astream ); 391 freq = mediaPlayerState->curDecoder()->audioFrequency( astream );
391 qDebug( "LC- frequency = %d", freq ); 392 qDebug( "LC- frequency = %d", freq );
392 393
393 audioSampleCounter = 0; 394 audioSampleCounter = 0;
394 395 int bits_per_sample;
395 int bits_per_sample = mediaPlayerState->curDecoder()->audioBitsPerSample( astream); 396 if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibWavPlugin") ) {
397 bits_per_sample =(int) mediaPlayerState->curDecoder()->getTime();
398 qDebug("using stupid hack");
399 } else {
400 bits_per_sample=0;
401 }
396 402
397 audioDevice = new AudioDevice( freq, channels, bits_per_sample); 403 audioDevice = new AudioDevice( freq, channels, bits_per_sample);
398 audioBuffer = new char[ audioDevice->bufferSize() ]; 404 audioBuffer = new char[ audioDevice->bufferSize() ];
399 channels = audioDevice->channels(); 405 channels = audioDevice->channels();
400 406
401 //### must check which frequency is actually used. 407 //### must check which frequency is actually used.
402 static const int size = 1; 408 static const int size = 1;
403 short int buf[size]; 409 short int buf[size];
404 long samplesRead = 0; 410 long samplesRead = 0;
405 mediaPlayerState->curDecoder()->audioReadSamples( buf, channels, size, samplesRead, stream ); 411 mediaPlayerState->curDecoder()->audioReadSamples( buf, channels, size, samplesRead, stream );
406 } 412 }
407 413
408 if ( hasVideoChannel ) { 414 if ( hasVideoChannel ) {
409 total_video_frames = mediaPlayerState->curDecoder()->videoFrames( stream ); 415 total_video_frames = mediaPlayerState->curDecoder()->videoFrames( stream );
410 416
411 mediaPlayerState->setLength( total_video_frames ); 417 mediaPlayerState->setLength( total_video_frames );
412 418
413 framerate = mediaPlayerState->curDecoder()->videoFrameRate( stream ); 419 framerate = mediaPlayerState->curDecoder()->videoFrameRate( stream );
414 DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames )); 420 DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames ));
415 421
416 if ( framerate <= 1.0 ) { 422 if ( framerate <= 1.0 ) {
417 DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" )); 423 DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" ));
418 framerate = 25; 424 framerate = 25;
419 } 425 }
420 426
421 if ( total_video_frames == 1 ) { 427 if ( total_video_frames == 1 ) {
422 DecodeLoopDebug(( "Cannot seek to frame" )); 428 DecodeLoopDebug(( "Cannot seek to frame" ));
423 } 429 }
424 430
425 } 431 }
426 432
427 current_frame = 0; 433 current_frame = 0;
428 prev_frame = -1; 434 prev_frame = -1;
429 435
430 connect( mediaPlayerState, SIGNAL( positionChanged( long ) ), this, SLOT( setPosition( long ) ) ); 436 connect( mediaPlayerState, SIGNAL( positionChanged( long ) ), this, SLOT( setPosition( long ) ) );
431 connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( setPaused( bool ) ) ); 437 connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( setPaused( bool ) ) );
432 438
433 audioMutex->unlock(); 439 audioMutex->unlock();
434 440
435 return TRUE; 441 return TRUE;
436} 442}
437 443
438 444
439void LoopControl::play() { 445void LoopControl::play() {
440 446 qDebug("LC- play");
441#if defined(Q_WS_QWS) && !defined(QT_NO_COP) 447#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
442 if ( !disabledSuspendScreenSaver || previousSuspendMode != hasVideoChannel ) { 448 if ( !disabledSuspendScreenSaver || previousSuspendMode != hasVideoChannel ) {
443 disabledSuspendScreenSaver = TRUE; 449 disabledSuspendScreenSaver = TRUE;
444 previousSuspendMode = hasVideoChannel; 450 previousSuspendMode = hasVideoChannel;
445 // Stop the screen from blanking and power saving state 451 // Stop the screen from blanking and power saving state
446 QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) 452 QCopEnvelope("QPE/System", "setScreenSaverMode(int)" )
447 << ( hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend ); 453 << ( hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend );
448 } 454 }
449#endif 455#endif
450 456
451 playtime.start(); 457 playtime.start();
452 startTimers(); 458 startTimers();
453} 459}
454 460
455 461
456void LoopControl::setMute( bool on ) { 462void LoopControl::setMute( bool on ) {
457 if ( on != isMuted ) { 463 if ( on != isMuted ) {
458 isMuted = on; 464 isMuted = on;
459 if ( !on ) { 465 if ( !on ) {
460 // Force an update of the position 466 // Force an update of the position
461 mediaPlayerState->setPosition( mediaPlayerState->position() + 1 ); 467 mediaPlayerState->setPosition( mediaPlayerState->position() + 1 );
462 mediaPlayerState->setPosition( mediaPlayerState->position() - 1 ); 468 mediaPlayerState->setPosition( mediaPlayerState->position() - 1 );
463 // Resume playing audio 469 // Resume playing audio
464 moreAudio = TRUE; 470 moreAudio = TRUE;