summaryrefslogtreecommitdiff
authorllornkcor <llornkcor>2003-02-25 23:38:02 (UTC)
committer llornkcor <llornkcor>2003-02-25 23:38:02 (UTC)
commit94cb45ce60cc00d719a802baeb8acf74f42150d2 (patch) (side-by-side diff)
tree27f70d60579a5301f04986e56cf4bfa2067dad9c
parentbde9ed97c92b6f7eefa8a66d9f58aa4c78127733 (diff)
downloadopie-94cb45ce60cc00d719a802baeb8acf74f42150d2.zip
opie-94cb45ce60cc00d719a802baeb8acf74f42150d2.tar.gz
opie-94cb45ce60cc00d719a802baeb8acf74f42150d2.tar.bz2
remove libmad depending on libmpeg3, and fix crash when skin not found
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--core/multimedia/opieplayer/audiowidget.cpp8
-rw-r--r--core/multimedia/opieplayer/loopcontrol.cpp20
2 files changed, 16 insertions, 12 deletions
diff --git a/core/multimedia/opieplayer/audiowidget.cpp b/core/multimedia/opieplayer/audiowidget.cpp
index 9a55608..3dfe182 100644
--- a/core/multimedia/opieplayer/audiowidget.cpp
+++ b/core/multimedia/opieplayer/audiowidget.cpp
@@ -1,472 +1,476 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
#include <qpe/qpeapplication.h>
#include <qpe/resource.h>
#include <qpe/config.h>
#include <qwidget.h>
#include <qpixmap.h>
#include <qbutton.h>
#include <qpainter.h>
#include <qframe.h>
#include <qlayout.h>
-
+#include <qdir.h>
#include "audiowidget.h"
#include "mediaplayerstate.h"
#include <stdlib.h>
#include <stdio.h>
extern MediaPlayerState *mediaPlayerState;
static const int xo = -2; // movable x offset
static const int yo = 22; // movable y offset
struct MediaButton {
bool isToggle, isHeld, isDown;
};
//Layout information for the audioButtons (and if it is a toggle button or not)
MediaButton audioButtons[] = {
{ TRUE, FALSE, FALSE }, // play
{ FALSE, FALSE, FALSE }, // stop
{ FALSE, FALSE, FALSE }, // next
{ FALSE, FALSE, FALSE }, // previous
{ FALSE, FALSE, FALSE }, // volume up
{ FALSE, FALSE, FALSE }, // volume down
{ TRUE, FALSE, FALSE }, // repeat/loop
{ FALSE, FALSE, FALSE }, // playlist
{ FALSE, FALSE, FALSE }, // forward
{ FALSE, FALSE, FALSE } // back
};
const char *skin_mask_file_names[10] = {
"play", "stop", "next", "prev", "up",
"down", "loop", "playlist", "forward", "back"
};
static void changeTextColor( QWidget *w ) {
QPalette p = w->palette();
p.setBrush( QColorGroup::Background, QColor( 167, 212, 167 ) );
p.setBrush( QColorGroup::Base, QColor( 167, 212, 167 ) );
w->setPalette( p );
}
static const int numButtons = (sizeof(audioButtons)/sizeof(MediaButton));
AudioWidget::AudioWidget(QWidget* parent, const char* name, WFlags f) :
QWidget( parent, name, f ), songInfo( this ), slider( Qt::Horizontal, this ), time( this )
{
setCaption( tr("OpiePlayer") );
qDebug("<<<<<audioWidget");
Config cfg("OpiePlayer");
cfg.setGroup("Options");
skin = cfg.readEntry("Skin","default");
//skin = "scaleTest";
// color of background, frame, degree of transparency
// QString skinPath = "opieplayer/skins/" + skin;
- QString skinPath = "opieplayer2/skins/" + skin;
+ QString skinPath;
+ skinPath = "opieplayer2/skins/" + skin;
+ if(!QDir(skinPath).exists())
+ skinPath = "opieplayer2/skins/default";
+
qDebug("skin path "+skinPath);
pixBg = new QPixmap( Resource::loadPixmap( QString("%1/background").arg(skinPath) ) );
imgUp = new QImage( Resource::loadImage( QString("%1/skin_up").arg(skinPath) ) );
imgDn = new QImage( Resource::loadImage( QString("%1/skin_down").arg(skinPath) ) );
imgButtonMask = new QImage( imgUp->width(), imgUp->height(), 8, 255 );
imgButtonMask->fill( 0 );
for ( int i = 0; i < 10; i++ ) {
QString filename = QString(getenv("OPIEDIR")) + "/pics/" + skinPath + "/skin_mask_" + skin_mask_file_names[i] + ".png";
masks[i] = new QBitmap( filename );
if ( !masks[i]->isNull() ) {
QImage imgMask = masks[i]->convertToImage();
uchar **dest = imgButtonMask->jumpTable();
for ( int y = 0; y < imgUp->height(); y++ ) {
uchar *line = dest[y];
for ( int x = 0; x < imgUp->width(); x++ )
if ( !qRed( imgMask.pixel( x, y ) ) )
line[x] = i + 1;
}
}
}
for ( int i = 0; i < 11; i++ ) {
buttonPixUp[i] = NULL;
buttonPixDown[i] = NULL;
}
setBackgroundPixmap( *pixBg );
songInfo.setFocusPolicy( QWidget::NoFocus );
// changeTextColor( &songInfo );
// songInfo.setBackgroundColor( QColor( 167, 212, 167 ));
// songInfo.setFrameStyle( QFrame::NoFrame);
// songInfo.setFrameStyle( QFrame::WinPanel | QFrame::Sunken );
//NoFrame
// songInfo.setForegroundColor(Qt::white);
slider.setFixedHeight( 20 );
slider.setMinValue( 0 );
slider.setMaxValue( 1 );
slider.setFocusPolicy( QWidget::NoFocus );
slider.setBackgroundPixmap( *pixBg );
time.setFocusPolicy( QWidget::NoFocus );
time.setAlignment( Qt::AlignCenter );
time.setFrame(FALSE);
changeTextColor( &time );
resizeEvent( NULL );
connect( &slider, SIGNAL( sliderPressed() ), this, SLOT( sliderPressed() ) );
connect( &slider, SIGNAL( sliderReleased() ), this, SLOT( sliderReleased() ) );
connect( mediaPlayerState, SIGNAL( lengthChanged(long) ), this, SLOT( setLength(long) ) );
connect( mediaPlayerState, SIGNAL( viewChanged(char) ), this, SLOT( setView(char) ) );
connect( mediaPlayerState, SIGNAL( loopingToggled(bool) ), this, SLOT( setLooping(bool) ) );
// connect( mediaPlayerState, SIGNAL( pausedToggled(bool) ), this, SLOT( setPaused(bool) ) );
connect( mediaPlayerState, SIGNAL( playingToggled(bool) ), this, SLOT( setPlaying(bool) ) );
// Intialise state
setLength( mediaPlayerState->length() );
setPosition( mediaPlayerState->position() );
setLooping( mediaPlayerState->fullscreen() );
// setPaused( mediaPlayerState->paused() );
setPlaying( mediaPlayerState->playing() );
}
AudioWidget::~AudioWidget() {
for ( int i = 0; i < 10; i++ ) {
delete buttonPixUp[i];
delete buttonPixDown[i];
}
delete pixBg;
delete imgUp;
delete imgDn;
delete imgButtonMask;
for ( int i = 0; i < 10; i++ ) {
delete masks[i];
}
}
QPixmap *combineImageWithBackground( QImage img, QPixmap bg, QPoint offset ) {
QPixmap pix( img.width(), img.height() );
QPainter p( &pix );
p.drawTiledPixmap( pix.rect(), bg, offset );
p.drawImage( 0, 0, img );
return new QPixmap( pix );
}
QPixmap *maskPixToMask( QPixmap pix, QBitmap mask )
{
QPixmap *pixmap = new QPixmap( pix );
pixmap->setMask( mask );
return pixmap;
}
void AudioWidget::resizeEvent( QResizeEvent * ) {
int h = height();
int w = width();
songInfo.setGeometry( QRect( 2, 10, w - 4, 20 ) );
slider.setFixedWidth( w - 110 );
slider.setGeometry( QRect( 15, h - 30, w - 90, 20 ) );
slider.setBackgroundOrigin( QWidget::ParentOrigin );
time.setGeometry( QRect( w - 85, h - 30, 70, 20 ) );
xoff = ( w - imgUp->width() ) / 2;
yoff = (( h - imgUp->height() ) / 2) - 10;
QPoint p( xoff, yoff );
QPixmap *pixUp = combineImageWithBackground( *imgUp, *pixBg, p );
QPixmap *pixDn = combineImageWithBackground( *imgDn, *pixBg, p );
for ( int i = 0; i < 10; i++ ) {
if ( !masks[i]->isNull() ) {
delete buttonPixUp[i];
delete buttonPixDown[i];
buttonPixUp[i] = maskPixToMask( *pixUp, *masks[i] );
buttonPixDown[i] = maskPixToMask( *pixDn, *masks[i] );
}
}
delete pixUp;
delete pixDn;
}
static bool audioSliderBeingMoved = FALSE;
void AudioWidget::sliderPressed() {
audioSliderBeingMoved = TRUE;
}
void AudioWidget::sliderReleased() {
audioSliderBeingMoved = FALSE;
if ( slider.width() == 0 )
return;
long val = long((double)slider.value() * mediaPlayerState->length() / slider.width());
mediaPlayerState->setPosition( val );
}
void AudioWidget::setPosition( long i ) {
// qDebug("set position %d",i);
long length = mediaPlayerState->length();
updateSlider( i, length );
}
void AudioWidget::setLength( long max ) {
updateSlider( mediaPlayerState->position(), max );
}
void AudioWidget::setView( char view ) {
if (mediaPlayerState->isStreaming) {
if( !slider.isHidden()) slider.hide();
disconnect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) );
disconnect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) );
} else {
// this stops the slider from being moved, thus
// does not stop stream when it reaches the end
slider.show();
connect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) );
connect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) );
}
if ( view == 'a' ) {
startTimer( 150 );
// show();
showMaximized();
} else {
killTimers();
hide();
}
}
static QString timeAsString( long length ) {
length /= 44100;
int minutes = length / 60;
int seconds = length % 60;
return QString("%1:%2%3").arg( minutes ).arg( seconds / 10 ).arg( seconds % 10 );
}
void AudioWidget::updateSlider( long i, long max ) {
time.setText( timeAsString( i ) + " / " + timeAsString( max ) );
if ( max == 0 )
return;
// Will flicker too much if we don't do this
// Scale to something reasonable
int width = slider.width();
int val = int((double)i * width / max);
if ( !audioSliderBeingMoved ) {
if ( slider.value() != val )
slider.setValue( val );
if ( slider.maxValue() != width )
slider.setMaxValue( width );
}
}
void AudioWidget::setToggleButton( int i, bool down ) {
if ( down != audioButtons[i].isDown )
toggleButton( i );
}
void AudioWidget::toggleButton( int i ) {
audioButtons[i].isDown = !audioButtons[i].isDown;
QPainter p(this);
paintButton ( &p, i );
}
void AudioWidget::paintButton( QPainter *p, int i ) {
if ( audioButtons[i].isDown )
p->drawPixmap( xoff, yoff, *buttonPixDown[i] );
else
p->drawPixmap( xoff, yoff, *buttonPixUp[i] );
}
void AudioWidget::timerEvent( QTimerEvent * ) {
/*
int x = audioButtons[AudioPlay].xPos;
int y = audioButtons[AudioPlay].yPos;
QPainter p( this );
// Optimize to only draw the little bit of the changing images which is different
p.drawPixmap( x + 14, y + 8, *pixmaps[3], 32 * frame, 0, 32, 32 );
p.drawPixmap( x + 37, y + 37, *pixmaps[2], 18 * AudioPlay, 0, 6, 3 );
*/
/*
static int frame = 0;
if ( !mediaPlayerState->paused() && audioButtons[ AudioPlay ].isDown ) {
frame = frame >= 7 ? 0 : frame + 1;
}
*/
}
void AudioWidget::mouseMoveEvent( QMouseEvent *event ) {
for ( int i = 0; i < numButtons; i++ ) {
if ( event->state() == QMouseEvent::LeftButton ) {
// The test to see if the mouse click is inside the button or not
int x = event->pos().x() - xoff;
int y = event->pos().y() - yoff;
bool isOnButton = ( x > 0 && y > 0 && x < imgButtonMask->width()
&& y < imgButtonMask->height() && imgButtonMask->pixelIndex( x, y ) == i + 1 );
if ( isOnButton && i == AudioVolumeUp )
qDebug("on up");
if ( isOnButton && !audioButtons[i].isHeld ) {
audioButtons[i].isHeld = TRUE;
toggleButton(i);
switch (i) {
case AudioVolumeUp:
qDebug("more clicked");
emit moreClicked();
return;
case AudioVolumeDown:
qDebug("less clicked");
emit lessClicked();
return;
case AudioForward:
emit forwardClicked();
return;
case AudioBack:
emit backClicked();
return;
}
} else if ( !isOnButton && audioButtons[i].isHeld ) {
audioButtons[i].isHeld = FALSE;
toggleButton(i);
}
} else {
if ( audioButtons[i].isHeld ) {
audioButtons[i].isHeld = FALSE;
if ( !audioButtons[i].isToggle )
setToggleButton( i, FALSE );
switch (i) {
case AudioPlay:
if( mediaPlayerState->isPaused ) {
mediaPlayerState->setPaused( FALSE );
return;
} else if( !mediaPlayerState->isPaused ) {
mediaPlayerState->setPaused( TRUE );
return;
}
// case AudioPlay: mediaPlayerState->setPlaying(audioButtons[i].isDown); return;
case AudioStop: mediaPlayerState->setPlaying(FALSE); return;
// case AudioPause: mediaPlayerState->setPaused(audioButtons[i].isDown); return;
case AudioNext: mediaPlayerState->setNext(); return;
case AudioPrevious: mediaPlayerState->setPrev(); return;
case AudioLoop: mediaPlayerState->setLooping(audioButtons[i].isDown); return;
case AudioVolumeUp: emit moreReleased(); return;
case AudioVolumeDown: emit lessReleased(); return;
case AudioPlayList: mediaPlayerState->setList(); return;
}
}
}
}
}
void AudioWidget::mousePressEvent( QMouseEvent *event ) {
mouseMoveEvent( event );
}
void AudioWidget::mouseReleaseEvent( QMouseEvent *event ) {
mouseMoveEvent( event );
}
void AudioWidget::showEvent( QShowEvent* ) {
QMouseEvent event( QEvent::MouseMove, QPoint( 0, 0 ), 0, 0 );
mouseMoveEvent( &event );
}
void AudioWidget::closeEvent( QCloseEvent* ) {
mediaPlayerState->setList();
}
void AudioWidget::paintEvent( QPaintEvent * pe) {
if ( !pe->erased() ) {
// Combine with background and double buffer
QPixmap pix( pe->rect().size() );
QPainter p( &pix );
p.translate( -pe->rect().topLeft().x(), -pe->rect().topLeft().y() );
p.drawTiledPixmap( pe->rect(), *pixBg, pe->rect().topLeft() );
for ( int i = 0; i < numButtons; i++ )
paintButton( &p, i );
QPainter p2( this );
p2.drawPixmap( pe->rect().topLeft(), pix );
} else {
QPainter p( this );
for ( int i = 0; i < numButtons; i++ )
paintButton( &p, i );
}
}
void AudioWidget::keyReleaseEvent( QKeyEvent *e)
{
switch ( e->key() ) {
////////////////////////////// Zaurus keys
case Key_Home:
break;
case Key_F9: //activity
hide();
// qDebug("Audio F9");
break;
case Key_F10: //contacts
break;
case Key_F11: //menu
break;
case Key_F12: //home
break;
case Key_F13: //mail
break;
case Key_Space: {
if(mediaPlayerState->playing()) {
diff --git a/core/multimedia/opieplayer/loopcontrol.cpp b/core/multimedia/opieplayer/loopcontrol.cpp
index ba14882..8cf0a75 100644
--- a/core/multimedia/opieplayer/loopcontrol.cpp
+++ b/core/multimedia/opieplayer/loopcontrol.cpp
@@ -1,485 +1,485 @@
/**********************************************************************
** Copyright (C) 2000 Trolltech AS. All rights reserved.
**
** This file is part of Qtopia Environment.
**
** This file may be distributed and/or modified under the terms of the
** GNU General Public License version 2 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
** See http://www.trolltech.com/gpl/ for GPL licensing information.
**
** Contact info@trolltech.com if any conditions of this licensing are
** not clear to you.
**
**********************************************************************/
// L.J.Potter added changes Fri 02-15-2002
#include <qpe/qpeapplication.h>
#ifdef Q_WS_QWS
#include <qpe/qcopenvelope_qws.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include "loopcontrol.h"
#include "videowidget.h"
#include "audiodevice.h"
#include <qpe/mediaplayerplugininterface.h>
#include "mediaplayerstate.h"
extern VideoWidget *videoUI; // now only needed to tell it to play a frame
extern MediaPlayerState *mediaPlayerState;
//#define DecodeLoopDebug(x) qDebug x
#define DecodeLoopDebug(x)
static char *audioBuffer = NULL;
static AudioDevice *audioDevice = NULL;
static bool disabledSuspendScreenSaver = FALSE;
static bool previousSuspendMode = FALSE;
pthread_t audio_tid;
pthread_attr_t audio_attr;
bool threadOkToGo = FALSE;
class Mutex {
public:
Mutex() {
pthread_mutexattr_t attr;
pthread_mutexattr_init( &attr );
pthread_mutex_init( &mutex, &attr );
pthread_mutexattr_destroy( &attr );
}
~Mutex() {
pthread_mutex_destroy( &mutex );
}
void lock() {
pthread_mutex_lock( &mutex );
}
void unlock() {
pthread_mutex_unlock( &mutex );
}
private:
pthread_mutex_t mutex;
};
void *startAudioThread( void *ptr ) {
LoopControl *mpegView = (LoopControl *)ptr;
while ( TRUE ) {
if ( threadOkToGo && mpegView->moreAudio )
mpegView->startAudio();
else
usleep( 10000 ); // Semi-buzy-wait till we are playing again
}
return 0;
}
Mutex *audioMutex;
LoopControl::LoopControl( QObject *parent, const char *name )
: QObject( parent, name ) {
isMuted = FALSE;
connect( qApp, SIGNAL( volumeChanged(bool) ), this, SLOT( setMute(bool) ) );
-//qDebug("starting loopcontrol");
+qDebug("starting loopcontrol");
audioMutex = new Mutex;
pthread_attr_init(&audio_attr);
#define USE_REALTIME_AUDIO_THREAD
#ifdef USE_REALTIME_AUDIO_THREAD
// Attempt to set it to real-time round robin
if ( pthread_attr_setschedpolicy( &audio_attr, SCHED_RR ) == 0 ) {
sched_param params;
params.sched_priority = 50;
pthread_attr_setschedparam(&audio_attr,&params);
} else {
qDebug( "Error setting up a realtime thread, reverting to using a normal thread." );
pthread_attr_destroy(&audio_attr);
pthread_attr_init(&audio_attr);
}
#endif
-//qDebug("create audio thread");
+qDebug("create audio thread");
pthread_create(&audio_tid, &audio_attr, (void * (*)(void *))startAudioThread, this);
}
LoopControl::~LoopControl() {
stop();
}
static long prev_frame = 0;
static int currentSample = 0;
void LoopControl::timerEvent( QTimerEvent *te ) {
if ( te->timerId() == videoId )
startVideo();
if ( te->timerId() == sliderId ) {
if ( hasAudioChannel && !hasVideoChannel && moreAudio ) {
mediaPlayerState->updatePosition( audioSampleCounter );
} else if ( hasVideoChannel && moreVideo ) {
mediaPlayerState->updatePosition( current_frame );
}
}
if ( !moreVideo && !moreAudio ) {
mediaPlayerState->setPlaying( FALSE );
mediaPlayerState->setNext();
}
}
void LoopControl::setPosition( long pos ) {
audioMutex->lock();
// qDebug("Loop control %d", pos);
if ( hasVideoChannel && hasAudioChannel ) {
playtime.restart();
playtime = playtime.addMSecs( long((double)-pos * 1000.0 / framerate) );
current_frame = pos + 1;
mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
prev_frame = current_frame - 1;
currentSample = (int)( (double)current_frame * freq / framerate );
mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
audioSampleCounter = currentSample - 1;
} else if ( hasVideoChannel ) {
playtime.restart();
playtime = playtime.addMSecs( long((double)-pos * 1000.0 / framerate) );
current_frame = pos + 1;
mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
prev_frame = current_frame - 1;
} else if ( hasAudioChannel ) {
playtime.restart();
playtime = playtime.addMSecs( long((double)-pos * 1000.0 / freq) );
currentSample = pos + 1;
mediaPlayerState->curDecoder()->audioSetSample( currentSample, stream );
audioSampleCounter = currentSample - 1;
}
audioMutex->unlock();
}
void LoopControl::startVideo() {
if ( moreVideo ) {
if ( mediaPlayerState->curDecoder() ) {
if ( hasAudioChannel && !isMuted ) {
current_frame = long( playtime.elapsed() * framerate / 1000 );
if ( prev_frame != -1 && current_frame <= prev_frame )
return;
} else {
// Don't skip
current_frame++;
}
if ( prev_frame == -1 || current_frame > prev_frame ) {
if ( current_frame > prev_frame + 1 ) {
mediaPlayerState->curDecoder()->videoSetFrame( current_frame, stream );
}
moreVideo = videoUI->playVideo();
prev_frame = current_frame;
}
} else {
moreVideo = FALSE;
killTimer( videoId );
}
}
}
void LoopControl::startAudio() {
audioMutex->lock();
if ( moreAudio ) {
if ( !isMuted && mediaPlayerState->curDecoder() ) {
currentSample = audioSampleCounter + 1;
if ( currentSample != audioSampleCounter + 1 )
qDebug("out of sync with decoder %i %i", currentSample, audioSampleCounter);
long samplesRead = 0;
bool readOk=mediaPlayerState->curDecoder()->audioReadSamples( (short*)audioBuffer, channels, 1024, samplesRead, stream );
long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000;
long sampleWaitTime = currentSample - sampleWeShouldBeAt;
// this causes drop outs not sure why its even here
if ( hasVideoChannel ) {
if ( ( sampleWaitTime > 2000 ) && ( sampleWaitTime < 20000 ) ) {
usleep( (long)((double)sampleWaitTime * 1000000.0 / freq) );
}
else if ( sampleWaitTime <= -5000 ) {
qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt );
// //mediaPlayerState->curDecoder()->audioSetSample( sampleWeShouldBeAt, stream );
currentSample = sampleWeShouldBeAt;
}
}
audioDevice->write( audioBuffer, samplesRead * 2 * channels );
if( mediaPlayerState->isStreaming == FALSE)
audioSampleCounter = currentSample + samplesRead - 1;
moreAudio = readOk && (audioSampleCounter <= total_audio_samples);
} else {
moreAudio = FALSE;
}
}
audioMutex->unlock();
}
void LoopControl::killTimers() {
audioMutex->lock();
if ( hasVideoChannel )
killTimer( videoId );
killTimer( sliderId );
threadOkToGo = FALSE;
audioMutex->unlock();
}
void LoopControl::startTimers() {
audioMutex->lock();
moreVideo = FALSE;
moreAudio = FALSE;
if ( hasVideoChannel ) {
moreVideo = TRUE;
int mSecsBetweenFrames = (int)(100 / framerate); // 10% of the real value
videoId = startTimer( mSecsBetweenFrames );
}
if ( hasAudioChannel ) {
moreAudio = TRUE;
threadOkToGo = TRUE;
}
sliderId = startTimer( 300 ); // update slider every 1/3 second
audioMutex->unlock();
}
void LoopControl::setPaused( bool pause ) {
if ( !mediaPlayerState->curDecoder() || !mediaPlayerState->curDecoder()->isOpen() )
return;
if ( pause ) {
killTimers();
} else {
// Force an update of the position
mediaPlayerState->setPosition( mediaPlayerState->position() + 1 );
mediaPlayerState->setPosition( mediaPlayerState->position() - 1 );
// Just like we never stopped
startTimers();
}
}
void LoopControl::stop( bool willPlayAgainShortly ) {
#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
if ( !willPlayAgainShortly && disabledSuspendScreenSaver ) {
disabledSuspendScreenSaver = FALSE;
// Re-enable the suspend mode
QCopEnvelope("QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
}
#endif
if ( mediaPlayerState->curDecoder() && mediaPlayerState->curDecoder()->isOpen() ) {
killTimers();
audioMutex->lock();
mediaPlayerState->curDecoder()->close();
if ( audioDevice ) {
delete audioDevice;
delete audioBuffer;
audioDevice = 0;
audioBuffer = 0;
}
audioMutex->unlock();
}
audioSampleCounter=0;
current_frame=0;
total_audio_samples=0;
}
bool LoopControl::init( const QString& filename ) {
stop();
audioMutex->lock();
fileName = filename;
stream = 0; // only play stream 0 for now
current_frame = total_video_frames = total_audio_samples = 0;
qDebug( "Using the %s decoder", mediaPlayerState->curDecoder()->pluginName() );
// ### Hack to use libmpeg3plugin to get the number of audio samples if we are using the libmad plugin
- if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibMadPlugin") ) {
- if ( mediaPlayerState->libMpeg3Decoder() && mediaPlayerState->libMpeg3Decoder()->open( filename )) {
- total_audio_samples = mediaPlayerState->libMpeg3Decoder()->audioSamples( 0 );
- mediaPlayerState->libMpeg3Decoder()->close();
- }
- }
+// if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibMadPlugin") ) {
+// if ( mediaPlayerState->libMpeg3Decoder() && mediaPlayerState->libMpeg3Decoder()->open( filename )) {
+// total_audio_samples = mediaPlayerState->libMpeg3Decoder()->audioSamples( 0 );
+// mediaPlayerState->libMpeg3Decoder()->close();
+// }
+// }
if ( !mediaPlayerState->curDecoder()|| !mediaPlayerState->curDecoder()->open( filename ) ) {
audioMutex->unlock();
return FALSE;
}
hasAudioChannel = mediaPlayerState->curDecoder()->audioStreams() > 0;
hasVideoChannel = mediaPlayerState->curDecoder()->videoStreams() > 0;
if ( hasAudioChannel ) {
int astream = 0;
if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibMpeg3Plugin") )
channels = 2; //dont akx me why, but it needs this hack
else
channels = mediaPlayerState->curDecoder()->audioChannels( astream );
qDebug( "LC- channels = %d", channels );
- if ( !total_audio_samples )
+// if ( !total_audio_samples )
total_audio_samples = mediaPlayerState->curDecoder()->audioSamples( astream );
total_audio_samples += 1000;
-
+ qDebug("total samples %d", total_audio_samples);
mediaPlayerState->setLength( total_audio_samples );
freq = mediaPlayerState->curDecoder()->audioFrequency( astream );
qDebug( "LC- frequency = %d", freq );
audioSampleCounter = 0;
int bits_per_sample;
if ( mediaPlayerState->curDecoder()->pluginName() == QString("LibWavPlugin") ) {
bits_per_sample =(int) mediaPlayerState->curDecoder()->getTime();
qDebug("using stupid hack");
} else {
bits_per_sample=0;
}
audioDevice = new AudioDevice( freq, channels, bits_per_sample);
audioBuffer = new char[ audioDevice->bufferSize() ];
channels = audioDevice->channels();
//### must check which frequency is actually used.
static const int size = 1;
short int buf[size];
long samplesRead = 0;
mediaPlayerState->curDecoder()->audioReadSamples( buf, channels, size, samplesRead, stream );
}
if ( hasVideoChannel ) {
total_video_frames = mediaPlayerState->curDecoder()->videoFrames( stream );
mediaPlayerState->setLength( total_video_frames );
framerate = mediaPlayerState->curDecoder()->videoFrameRate( stream );
DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames ));
if ( framerate <= 1.0 ) {
DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" ));
framerate = 25;
}
if ( total_video_frames == 1 ) {
DecodeLoopDebug(( "Cannot seek to frame" ));
}
}
current_frame = 0;
prev_frame = -1;
connect( mediaPlayerState, SIGNAL( positionChanged( long ) ), this, SLOT( setPosition( long ) ) );
connect( mediaPlayerState, SIGNAL( pausedToggled( bool ) ), this, SLOT( setPaused( bool ) ) );
audioMutex->unlock();
return TRUE;
}
void LoopControl::play() {
qDebug("LC- play");
mediaPlayerState->setPosition( 0); //uglyhack
#if defined(Q_WS_QWS) && !defined(QT_NO_COP)
if ( !disabledSuspendScreenSaver || previousSuspendMode != hasVideoChannel ) {
disabledSuspendScreenSaver = TRUE;
previousSuspendMode = hasVideoChannel;
// Stop the screen from blanking and power saving state
QCopEnvelope("QPE/System", "setScreenSaverMode(int)" )
<< ( hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend );
}
#endif
playtime.start();
startTimers();
}
void LoopControl::setMute( bool on ) {
if ( on != isMuted ) {
isMuted = on;
if ( !on ) {
// Force an update of the position
mediaPlayerState->setPosition( mediaPlayerState->position() + 1 );
mediaPlayerState->setPosition( mediaPlayerState->position() - 1 );
// Resume playing audio
moreAudio = TRUE;
}
}
}