📄 loopcontrol.cpp
字号:
prev_frame = current_frame; } } } else { moreVideo = FALSE; killTimer( videoId ); videoId = 0; } } else { killTimer( videoId ); videoId = 0; }}void LoopControl::startAudio(){ if ( moreAudio ) { if ( mediaPlayerState->decoder() ) { currentSample = audioSampleCounter + 1; long samplesRead = 0; bool readOkay = mediaPlayerState->decoder()->audioReadSamples( (short*)audioBuffer, channels, 4096, samplesRead, astream ); long sampleWeShouldBeAt = long( playtime.elapsed() ) * freq / 1000; long sampleWaitTime = currentSample - sampleWeShouldBeAt; if ( hasVideoChannel ) { if ( ( sampleWaitTime > 2000 ) && ( sampleWaitTime < 20000 ) ) { usleep( (long)((double)sampleWaitTime * 1000000 / freq) ); } else if ( sampleWaitTime <= -5000 ) { qDebug("need to catch up by: %li (%i,%li)", -sampleWaitTime, currentSample, sampleWeShouldBeAt ); //mediaPlayerState->decoder()->audioSetSample( sampleWeShouldBeAt, astream ); currentSample = sampleWeShouldBeAt; } } else { if ( ( sampleWaitTime > 2000 ) && ( sampleWaitTime < 20000 ) ) usleep( (long)((long long)sampleWaitTime * 100000 / freq) ); } // ### expand samples here before writing if ( readOkay ) audioDevice->write( audioBuffer, samplesRead * 2 * channels ); audioSampleCounter = currentSample + samplesRead - 1; // If we open a file and use a good decoder, we will know // how many samples are in the file and to play if ( total_audio_samples > 1000 ) moreAudio = audioSampleCounter <= total_audio_samples; // However if it is streamed data or the decoder can not // tell how long the stream is, just keep playing until // audioReadSamples() returns FALSE else moreAudio = readOkay; } else { moreAudio = FALSE; } }}void LoopControl::killTimers(){ audioMutex->lock(); if ( hasVideoChannel ) { killTimer( videoId ); videoId = 0; } killTimer( sliderId ); sliderId = 0; 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// mSecsBetweenFrames = 0; if ( videoId ) killTimer( videoId ); videoId = startTimer( mSecsBetweenFrames ); } if ( hasAudioChannel ) { moreAudio = TRUE; threadOkToGo = TRUE; pthread_cond_signal( &(audioCond) ); } if ( mediaPlayerState->decoderVersion() == Decoder_1_6 ) { MediaPlayerDecoder_1_6 *decoder = (MediaPlayerDecoder_1_6 *)mediaPlayerState->decoder(); mediaPlayerState->updatePosition( decoder->tell() ); if ( decoder->tellAvailable() ) { if (!sliderId) sliderId = startTimer( 300 ); // update slider every 1/3 second } else { //disableSlider(); } } else { if (!sliderId) sliderId = startTimer( 300 ); // update slider every 1/3 second } audioMutex->unlock();}void LoopControl::setPaused( bool pause ){ if ( !mediaPlayerState->decoder() || !mediaPlayerState->decoder()->isOpen() ) return; if ( pause ) { killTimers(); } else { mediaPlayerState->startTemporaryMute(); // Force an update of the position mediaPlayerState->setPosition( mediaPlayerState->position() + 1 ); mediaPlayerState->setPosition( mediaPlayerState->position() - 1 ); // Just like we never stopped startTimers(); mediaPlayerState->stopTemporaryMute( 1000 ); }}void LoopControl::stop( bool willPlayAgainShortly ){#if defined(Q_WS_QWS) && !defined(QT_NO_COP) if ( !willPlayAgainShortly && disabledSuspendScreenSaver ) { disabledSuspendScreenSaver = FALSE; // Re-enable the suspend mode QPEApplication::setTempScreenSaverMode(QPEApplication::Enable); }#endif if ( mediaPlayerState->decoder() && mediaPlayerState->decoder()->isOpen() ) { killTimers(); audioMutex->lock(); mediaPlayerState->decoder()->close(); if ( audioDevice ) { delete audioDevice; delete []audioBuffer; audioDevice = 0; audioBuffer = 0; } audioMutex->unlock(); }}bool LoopControl::init( const QString& filename, const QString& mimetype, bool isURL ){ stop(); audioMutex->lock(); fileName = filename; current_frame = 0; if ( !mediaPlayerState->decoder() ) { audioMutex->unlock(); return FALSE; } if ( isURL ) { if ( mediaPlayerState->decoderVersion() == Decoder_1_6 ) { MediaPlayerDecoder_1_6 *decoder = (MediaPlayerDecoder_1_6 *)mediaPlayerState->decoder(); if ( !decoder->openURL( filename, mimetype ) ) { audioMutex->unlock(); return FALSE; } } else { qDebug( "This shouldn't happen: %s decoder isn't a 1.6 plugin", mediaPlayerState->decoder()->pluginName() ); audioMutex->unlock(); return FALSE; } } else { if ( !mediaPlayerState->decoder()->open( filename ) ) { audioMutex->unlock(); return FALSE; } } qDebug( "Using the %s decoder", mediaPlayerState->decoder()->pluginName() ); hasAudioChannel = mediaPlayerState->decoder()->audioStreams() > 0; hasVideoChannel = mediaPlayerState->decoder()->videoStreams() > 0; if ( hasAudioChannel ) { astream = 0; channels = mediaPlayerState->decoder()->audioChannels( astream ); DecodeLoopDebug(( "channels = %d\n", channels )); // No tr total_audio_samples = mediaPlayerState->decoder()->audioSamples( astream ); if ( total_audio_samples ) // give it one extra iteration through the // audio decoding loop after the expected EOF total_audio_samples += 1000; freq = mediaPlayerState->decoder()->audioFrequency( astream ); DecodeLoopDebug(( "frequency = %d\n", freq )); // No tr audioSampleCounter = 0; static const int bytes_per_sample = 2; //16 bit audioDevice = new AudioDevice( freq, channels, bytes_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->decoder()->audioReadSamples( buf, channels, size, samplesRead, astream );*/ } if ( hasVideoChannel ) { vstream = 0; total_video_frames = mediaPlayerState->decoder()->videoFrames( vstream ); framerate = (float)mediaPlayerState->decoder()->videoFrameRate( vstream ); DecodeLoopDebug(( "Frame rate %g total %ld", framerate, total_video_frames )); // No tr if ( framerate <= 1.0 ) { DecodeLoopDebug(( "Crazy frame rate, resetting to sensible" )); // No tr framerate = 25; } } if ( mediaPlayerState->decoderVersion() == Decoder_1_6 ) { MediaPlayerDecoder_1_6 *decoder = (MediaPlayerDecoder_1_6 *)mediaPlayerState->decoder(); if ( decoder->lengthAvailable() ) mediaPlayerState->setLength( decoder->length() ); else mediaPlayerState->setLength( 0 ); mediaPlayerState->setSeekable( decoder->seekAvailable() ); } else { if ( hasVideoChannel ) mediaPlayerState->setLength( total_video_frames ); else mediaPlayerState->setLength( total_audio_samples ); // Can we set the audio sample? If we can, then the decoder and stream are seekable bool audioSeekable = hasAudioChannel ? mediaPlayerState->decoder()->audioSetSample( 0, 0 ) : TRUE; // Can we set the video frame? If we can, then the decoder and stream are seekable bool videoSeekable = hasVideoChannel ? mediaPlayerState->decoder()->videoSetFrame( 0, 0 ) : TRUE; qDebug("audio seekable: %s, video seekable: %s", audioSeekable ? "true" : "false", videoSeekable ? "true" : "false" ); mediaPlayerState->setSeekable( audioSeekable && videoSeekable ); } if ( !mediaPlayerState->hasLength() ) DecodeLoopDebug(( "Decoder can not query length" )); // No tr current_frame = 0; prev_frame = -1; audioMutex->unlock(); return TRUE;}void LoopControl::play(){#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 QPEApplication::setTempScreenSaverMode(hasVideoChannel ? QPEApplication::Disable : QPEApplication::DisableSuspend); }#endif if ( hasVideo() ) mediaPlayerState->videoUI(); // create it else mediaPlayerState->audioUI(); // create it mediaPlayerState->setView( hasVideo() ? VideoView : AudioView ); playtime.start(); startTimers();}void LoopControl::setMute( bool on ){ isMuted = on;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -