void FileEndpoint::receive(Command_ptr command){
    if(command->getCommand()=="exit" || command->getCommand()=="logout" || command->getCommand()=="close"){
        FileEndpoint_ptr this_ptr = boost::static_pointer_cast<FileEndpoint>(shared_from_this());
        close();
        command->answer("closed file "+filename+"\n", this_ptr);
    }
    else if(command->getCommand()=="restart"){
        stopPlayback();
        seek(boost::date_time::not_a_date_time);
        startPlayback();
        command->answer("playback of "+getId()+" restarted at beginning\n", this->shared_from_this());
    }
    else if(command->getCommand()=="stop"){
        stopPlayback();
        command->answer("playback of "+getId()+" stopped\n", this->shared_from_this());
    }
    else if(command->getCommand()=="play"){
        startPlayback();
        command->answer("playback of "+getId()+" started\n", this->shared_from_this());
    }
    else if(command->getCommand()=="record"){
        record();
        command->answer("record to "+getId()+" started\n", this->shared_from_this());
    }
    else{
        NMEAEndpoint::receive(command);
    }
}
Beispiel #2
0
void PlayListModel::playPrevTrack()
{
    if (mCurrentTrack <= 0)
    {
        mCurrentTrack = 0;
        startPlayback(true);
        return;
    } else if (mCurrentTrack < mTracksVector.size()) {
        mTracksVector[mCurrentTrack].setAsPlayed(false);
    }
    --mCurrentTrack;
    startPlayback(true);
    return;
}
void testApp::keyReleased(int key)
{
	switch(key)
	{
		case 'q':
			if(!record)
				playback = !playback;
			if(record)
				startRecording();
			else
				stopRecording();
			break;
		case 'r':
			if(!playback)
				record = !record;
			if(playback)
				startPlayback();
			else
				stopPlayback();
			break;
		case 'p':
			paused = !paused;
			break;
		case keyUp:
			angle += 5;
	}
	
	
}
Beispiel #4
0
void ReplayController::replayToPosition(const ReplayPosition& position, DispatchSpeed speed)
{
    ASSERT(m_sessionState != SessionState::Capturing);
    ASSERT(m_segmentState == SegmentState::Loaded || m_segmentState == SegmentState::Unloaded);
    ASSERT(position.segmentOffset < m_loadedSession->size());

    m_dispatchSpeed = speed;

    if (m_sessionState != SessionState::Replaying) {
        setSessionState(SessionState::Replaying);
        setForceDeterministicSettings(true);
    }

    if (m_segmentState == SegmentState::Unloaded)
        loadSegmentAtIndex(position.segmentOffset);
    else if (position.segmentOffset != m_currentPosition.segmentOffset || m_currentPosition.inputOffset > position.inputOffset) {
        // If the desired segment is not loaded or we have gone past the desired input
        // offset, then unload the current segment and load the appropriate segment.
        unloadSegment();
        loadSegmentAtIndex(position.segmentOffset);
    }

    ASSERT(m_currentPosition.segmentOffset == position.segmentOffset);
    ASSERT(m_loadedSession->at(position.segmentOffset) == m_loadedSegment);

    m_targetPosition = position;
    startPlayback();
}
bool OpenALMusicPlayer::playAndManageBuffer()
{
	if (!ready) {
		return false;
	}
	
	int processed;
	bool active = true;

	alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);

	while(processed--) {
		ALuint buffer;
		
		alSourceUnqueueBuffers(source, 1, &buffer);
		check();
		active = streamBuffer(buffer);
		alSourceQueueBuffers(source, 1, &buffer);
		check();
	}

	if (!active && !isPlaying()) {
		// Try to reanimate playback
		if(!startPlayback()) {
			GfError("OpenALMusicPlayer: Cannot play stream.\n");
		}
	}
	
	return true;
}
Beispiel #6
0
void PlayListModel::playNextTrack()
{
    if (mCurrentTrack < mTracksVector.size())
    {
        mTracksVector[mCurrentTrack].setAsPlayed(false);
    }
    mCurrentTrack += 1;
    startPlayback(true);
}
void ofApp::keyPressed(int key) {
	if(key == ' ') {
		switch(mode) {
			case PREVIEW: stopPreview(); startRecord(); break;
			case RECORD: stopRecord(); startPlayback(); break;
			case PLAYBACK: stopPlayback(); startPreview(); break;
		}
	}
}
Beispiel #8
0
void VideoWindow::resumePlayback()
{
    if (!m) return; // ignore if no media selected

    // stop playback & wipe player
    if(m_MediaChanged)
        startPlayback();
    else
        libvlc_media_player_pause (mp);
}
Beispiel #9
0
void PlayListModel::replayPlayList(bool skipModeCheck)
{
    if (SettingsManager::getSettingsManager()->getRepeatMode() or skipModeCheck)
    {
        mCurrentTrack = 0;
        startPlayback(true);
        return;
    } else {
        MainControler::getMainControler()->stopPlayback();
    }
}
Beispiel #10
0
int eServiceHandlerDVB::play(const eServiceReference &service, int workaround )
{
	eDVBServiceController *sapi=eDVB::getInstance()->getServiceAPI();
	if (service.type != eServiceReference::idDVB)
		return -1;
#ifndef DISABLE_FILE
	if ( !workaround )
		decoder=0;

	if (service.path.length())
	{
		if ( !workaround )
		{
			struct stat64 s;
			if (::stat64(service.path.c_str(), &s))
			{
				eDebug("file %s not exist.. don't play", service.path.c_str() );
				return -1;
			}
			if ( eDVB::getInstance()->recorder &&
				service.path == eDVB::getInstance()->recorder->getFilename() )
				startPlayback(service.path, 2);
			else
				startPlayback(service.path, 0);
		}
		else
			flags |= (flagIsSeekable|flagSupportPosition);
	}
	else
#endif
	{
		flags &= ~(flagIsSeekable|flagSupportPosition);
		serviceEvent(eServiceEvent(eServiceEvent::evtFlagsChanged) );
	}

	if (sapi)
		return sapi->switchService((const eServiceReferenceDVB&)service);

	return -1;
}
Beispiel #11
0
void PlayListModel::startPlayback(bool locRequestPlayListCheck = true)
{
    if (locRequestPlayListCheck)
    {
        if (playListChecks() == false)
        {
            return;
        }
    }

    if (mCurrentTrack == -1)
    {
        mCurrentTrack += 1;
        startPlayback(false);
        return;
    }

    if (mCurrentTrack >= (int)(mTracksVector.size()) )
    {
        replayPlayList(false);
        return;
    }

    if (mTracksVector[mCurrentTrack].fileExists() == false)
    {
        emit FileDoesNotExists();
        deleteCurrentTrackModel();
        mCurrentTrack += 1;
        startPlayback(true);
        return;
    } else {
        mTracksVector.at(mCurrentTrack).setAsPlayed(true);
        mTracksVector.at(mCurrentTrack).playThisTrack();
        emit NeedRefreshView();
        emit CurrentModelChanged(this);
        emit CurrentTrackChanged();
        return;
    }
    emit CurrentTrackChanged();
}
Beispiel #12
0
void MainWindow::fileOpen()
{
	QFileDialog ofd(this, tr("Open ILDA file"), "");
	ofd.setFileMode(QFileDialog::AnyFile);
	ofd.setFilter(tr("ILDA files (*.ild);;All files (*.*)"));
	ofd.setViewMode(QFileDialog::Detail);
	
	if (ofd.exec())
	{
		QString fileName = ofd.selectedFiles().at(0);
		QFileInfo fileInfo(fileName);
		
		if (fileInfo.exists())
		{
			ReaderWriterILDA reader;

			_sequence = QSharedPointer<Sequence>(reader.readFile(fileName));
			_sequence->setPalette(*_currentPalette);

			// Fill file statistics
			fileNameLabel->setText(fileInfo.fileName());
			fileSizeLabel->setText(getFileSize(fileInfo.size()));
			ildaFormatLabel->setText(reader.version());
			numberOfFramesLabel->setText(QString::number(_sequence->frameCount()));

			// Set the current drawing mode (FIXME: Do not query the GUI for such infos)
			if (normalRadioButton->isChecked())
				_sequence->setDrawMode(Sequence::DrawModeNormal);
			else if (diagnosticRadioButton->isChecked())
				_sequence->setDrawMode(Sequence::DrawModeDiagnostic);

			// Setup frame slider
			frameSlider->setRange(0, _sequence->frameCount()-1);

			// Build the connections
			connect(_sequence.data(), SIGNAL(frameChanged(Frame*)), this, SLOT(frameChanged(Frame*)));
			connect(firstFrameButton, SIGNAL(clicked()), _sequence.data(), SLOT(gotoFirstFrame()));
			connect(lastFrameButton, SIGNAL(clicked()), _sequence.data(), SLOT(gotoLastFrame()));
			connect(stopButton, SIGNAL(clicked()), _sequence.data(), SLOT(stopPlayback()));
			connect(playButton, SIGNAL(clicked()), _sequence.data(), SLOT(startPlayback()));
			connect(frameSlider, SIGNAL(valueChanged(int)), _sequence.data(), SLOT(setActiveFrame(int)));
			connect(normalRadioButton, SIGNAL(clicked()), this, SLOT(drawModeChanged()));
			connect(diagnosticRadioButton, SIGNAL(clicked()), this, SLOT(drawModeChanged()));

			QGraphicsScene *scene = new QGraphicsScene();
			scene->addItem(_sequence.data());
			graphicsView->setScene(scene);

			// FIXME: Need to call this until a resize event happens.
			resizeEvent(NULL);
		}
Beispiel #13
0
bool ModSystem::startPlayback(std::string filename) {
    std::ifstream filestream(filename, std::fstream::binary);
    
    if (!filestream.is_open()) {
        return false;
    }

    m_currentPlaybackData.clear();

    m_currentPlaybackData =
        std::vector<char>(std::istreambuf_iterator<char>(filestream),
                          std::istreambuf_iterator<char>());

    return startPlayback(m_currentPlaybackData.data());
}
Beispiel #14
0
void OpenALMusicPlayer::start()
{
	if (!ready) {
		if (stream->getSoundFormat() == SoundStream::FORMAT_INVALID) {
			GfError("OpenALMusicPlayer: Sound stream has invalid format\n");
			return;
		}
		
		if (initContext() && initBuffers() && initSource()) {
			ready = true;
			startPlayback();
		}
		
		return;
	}
}
Beispiel #15
0
void VideoWindow::resumePlayback()
{
#ifdef GC_VIDEO_VLC
    if (!m) return; // ignore if no media selected

    // stop playback & wipe player
    if(m_MediaChanged)
        startPlayback();
    else
        libvlc_media_player_pause (mp);
#endif

#ifdef GC_VIDEO_QT5
    mp->play();
#endif
}
Beispiel #16
0
static void executeAppCommand(void) {
	switch (appCommand) {
	case CMD_PLAY:
		if (isLooping) {
			startPlayback();
		}
		break;

	case CMD_RECORD:
		isLooping = 1;
		recordWaveFile();
		break;

	default:
		break;
	}
}
Beispiel #17
0
static int play( const char *url )
{
    cgmi_Status retStat = CGMI_ERROR_SUCCESS;
    void *pSessionId;

    // Start playback
    retStat = startPlayback(url, &pSessionId);
    CHECK_ERROR_RETURN_STAT(retStat);

    // Let it play for a few seconds.
    g_usleep(10 * 1000 * 1000);

    retStat = stopPlayback(pSessionId);
    CHECK_ERROR_RETURN_STAT(retStat);

    return retStat;
}
Beispiel #18
0
void ReplayController::didDispatchFinalInput()
{
    ASSERT(m_segmentState == SegmentState::Dispatching);

    // No more segments left to replay; stop.
    if (m_currentPosition.segmentOffset + 1 == m_loadedSession->size()) {
        // Normally the position is adjusted when loading the next segment.
        m_currentPosition.segmentOffset++;
        m_currentPosition.inputOffset = 0;

        cancelPlayback();
        return;
    }

    unloadSegment();
    loadSegmentAtIndex(m_currentPosition.segmentOffset + 1);
    startPlayback();
}
Beispiel #19
0
static void MusicCallback(void *data, QString &selection)
{
    (void) data;

    QString sel = selection.toLower();
    if (sel == "music_create_playlist")
        startDatabaseTree();
    else if (sel == "music_play")
        startPlayback();
    else if (sel == "music_rip")
    {
        startRipper();
    }
    else if (sel == "music_import")
    {
        startImport();
    }
    else if (sel == "settings_scan")
    {
        if ("" != gMusicData->startdir)
        {
            loadMusic();
            FileScanner *fscan = new FileScanner();
            fscan->SearchDir(gMusicData->startdir);
            gMusicData->reloadMusic();
            delete fscan;
        }
    }
    else if (sel == "music_set_general")
    {
        MusicGeneralSettings settings;
        settings.exec();
    }
    else if (sel == "music_set_player")
    {
        MusicPlayerSettings settings;
        settings.exec();
    }
    else if (sel == "music_set_ripper")
    {
        MusicRipperSettings settings;
        settings.exec();
    }
}
Beispiel #20
0
////////////////////////////////////////////////////////////////////////////////
// Verify section filters work as expected
////////////////////////////////////////////////////////////////////////////////
static int secfil( const char *url )
{
    cgmi_Status retStat = CGMI_ERROR_SUCCESS;
    void *pSessionId;

    retStat = startPlayback(url, &pSessionId);
    CHECK_ERROR_RETURN_STAT(retStat);

    // Wait for playback to start and demux to be created
    g_usleep(2 * 1000 * 1000);

    retStat = verifySectionFilter(pSessionId);
    CHECK_ERROR_RETURN_STAT(retStat);

    retStat = stopPlayback(pSessionId);
    CHECK_ERROR_RETURN_STAT(retStat);

    return retStat;
}
Beispiel #21
0
void BBSDelegate<T>::handleDSP(T *sound, T *onsets, T *outputTrack, T *similarTrack, size_t length, IHostController *hostController){
    for (size_t i = 0; i < length; i++) {
        // ignore signal until we have a loop size
        switch (_state) {
            case PLAYBACK:
                outputTrack[i] = _outputSelectorTrack[_trackPointer];
                similarTrack[i] = _similarTrack[_trackPointer];
                if (_onsetTrack[_trackPointer] >= BD) {
                    hostController->makeOnset();
                }
                _trackPointer = _trackPointer + 1;
                if (_trackPointer == _loopSize) {
                    _trackPointer = 0;
                    hostController->restartLoop();
                }
                break;
                
            case HALT:
                // mute
                similarTrack[i] = 0;
                break;
            case RECORD:
                bool isOnset = onsets[i] == 1;
                _segment->pushSample(sound[i], isOnset);
                if (isOnset) {
                    _lastOnsetIndex = _trackPointer;
                }
                // between here, we might receive a classified onset
                _trackPointer = _trackPointer + 1;
                if (_trackPointer >= _loopSize) {
                    hostController->restartLoop();
                    startPlayback();
                }
                // just let input run through
                outputTrack[i] = 1;
                break;
        }
    }
}
Beispiel #22
0
void TMRpcm::play(char* filename){

  pinMode(speakerPin, OUTPUT);
  stopPlayback();
  Serial.print("Playing: ");Serial.println(filename);

  if(!wavInfo(filename) ){ return; }//verify its a valid wav file
  if(sFile){sFile.close();}
  sFile = SD.open(filename);

  if(sFile){

//    wavInfo(filename); //verify its a valid wav file

    sFile.seek(44); //skip the header info
    for(int i=0; i<buffSize; i++){ buffer[0][i] = sFile.read(); }
    whichBuff = false; buffEmpty[0] = false; buffEmpty[1] = true;

    startPlayback();

    //Serial.println(cycles);
  }else{Serial.println("failed to open music file"); }

}
Beispiel #23
0
static void MusicCallback(void *data, QString &selection)
{
    (void) data;

    QString sel = selection.toLower();
    if (sel == "music_create_playlist")
        startDatabaseTree();
    else if (sel == "music_play")
        startPlayback();
    else if (sel == "stream_play")
        startStreamPlayback();
    else if (sel == "music_rip")
    {
        startRipper();
    }
    else if (sel == "music_import")
    {
        startImport();
    }
    else if (sel == "settings_scan")
    {
        runScan();
    }
    else if (sel == "settings_general")
     {
        MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
        GeneralSettings *gs = new GeneralSettings(mainStack, "general settings");

        if (gs->Create())
            mainStack->AddScreen(gs);
        else
            delete gs;
    }
    else if (sel == "settings_player")
    {
        MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
        PlayerSettings *ps = new PlayerSettings(mainStack, "player settings");

        if (ps->Create())
            mainStack->AddScreen(ps);
        else
            delete ps;
    }
    else if (sel == "settings_rating")
    {
        MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
        RatingSettings *rs = new RatingSettings(mainStack, "rating settings");

        if (rs->Create())
            mainStack->AddScreen(rs);
        else
            delete rs;
    }
    else if (sel == "settings_visualization")
    {

       MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
       VisualizationSettings *vs = new VisualizationSettings(mainStack, "visualization settings");

       if (vs->Create())
           mainStack->AddScreen(vs);
        else
            delete vs;
    }
    else if (sel == "settings_import")
    {
        MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
        ImportSettings *is = new ImportSettings(mainStack, "import settings");

        if (is->Create())
            mainStack->AddScreen(is);
        else
            delete is;
    }
}
// Set the model, this also resets the camera
void AnimationPreview::setModelNode(const scene::INodePtr& node)
{
	// Ensure that this is an MD5 model node
	model::ModelNodePtr model = Node_getModel(node);
	
	if (!model)
	{
		rError() << "AnimationPreview::setModelNode: node is not a model." << std::endl;
		_model.reset();
		return;
	}

	// Set up the scene
	if (!_entity)
	{
		setupSceneGraph();
	}

	try
	{
		dynamic_cast<const md5::IMD5Model&>(model->getIModel());
	}
	catch (std::bad_cast&)
	{
		rError() << "AnimationPreview::setModelNode: modelnode doesn't contain an MD5 model." << std::endl;
		_model.reset();
		return;
	}

	if (_model)
	{
		_entity->removeChildNode(_model);
	}

	_model = node;

	// Set the animation to play
	dynamic_cast<md5::IMD5Model&>(model->getIModel()).setAnim(_anim);

	// AddChildNode also tells the model which renderentity it is attached to
	_entity->addChildNode(_model);

	if (_model != NULL)
	{
		// Reset preview time
		stopPlayback();

		// Reset the rotation to the default one
		_rotation = Matrix4::getRotation(Vector3(0,-1,0), Vector3(0,-0.3f,1));
		_rotation.multiplyBy(Matrix4::getRotation(Vector3(0,1,0), Vector3(1,-1,0)));
		
		// Use AABB to adjust camera distance
		const AABB& bounds = _model->localAABB();

		if (bounds.isValid())
		{
			_camDist = -5.0f * static_cast<float>(bounds.getRadius());
		}
		else
		{
			// Bounds not valid, fall back to default
			_camDist = -40.0f;
		}

		// Start playback when switching particles
		startPlayback();
	}
	else
	{
		stopPlayback();
	}

	// Redraw
	queueDraw();
}
Beispiel #25
0
static void runMusicPlayback(void)
{
    GetMythUI()->AddCurrentLocation("playmusic");
    startPlayback();
    GetMythUI()->RemoveCurrentLocation();
}
void processPlay(RTSPClient *clientInfo, RTSPmsg msg)
{
	sendSuccessResponse(clientInfo->socket, msg.seq, msg.session_id);
	clientInfo->scale = msg.scale;
	startPlayback(clientInfo);
}
void ParticlePreview::setParticle(const std::string& name)
{
    std::string nameClean = name;

    if (boost::algorithm::ends_with(nameClean, ".prt"))
    {
        nameClean = nameClean.substr(0, nameClean.length() - 4);
    }

    // If the model name is empty, release the model
    if (nameClean.empty())
    {
        if (_particleNode)
        {
            _entity->removeChildNode(_particleNode);
        }

        _particleNode.reset();
        stopPlayback();
        return;
    }

    // Set up the scene
    if (!_entity)
    {
        setupSceneGraph();
    }

    if (_particleNode)
    {
        _entity->removeChildNode(_particleNode);
    }

    // Construct the particle emitter node
    _particleNode = GlobalParticlesManager().createParticleNode(nameClean);

    if (_particleNode && _lastParticle != nameClean)
    {
        _entity->addChildNode(_particleNode);

        // Reset preview time
        stopPlayback();

        // Reset the rotation to the default one
        _rotation = Matrix4::getRotation(Vector3(0,-1,0), Vector3(0,-0.3f,1));
        _rotation.multiplyBy(Matrix4::getRotation(Vector3(0,1,0), Vector3(1,-1,0)));

        // Call update(0) once to enable the bounds calculation
        _particleNode->getParticle()->update(_rotation);

        // Use particle AABB to adjust camera distance
        const AABB& particleBounds = _particleNode->getParticle()->getBounds();

        if (particleBounds.isValid())
        {
            _camDist = -2.0f * static_cast<float>(particleBounds.getRadius());
        }
        else
        {
            // Bounds not valid, fall back to default
            _camDist = -40.0f;
        }

        _lastParticle = nameClean;

        // Start playback when switching particles
        startPlayback();
    }

    // Redraw
    queueDraw();
}
Beispiel #28
0
VideoWindow::VideoWindow(Context *context, const QDir &home)  :
    GcWindow(context), home(home), context(context), m_MediaChanged(false)
{
    setControls(NULL);
    setInstanceName("Video Window");
    setProperty("color", Qt::black);

    QHBoxLayout *layout = new QHBoxLayout();
    setLayout(layout);

    // config paramaters to libvlc
    const char * const vlc_args[] = {
                    "-I", "dummy", /* Don't use any interface */
                    "--ignore-config", /* Don't use VLC's config */
                    "--disable-screensaver", /* disable screensaver during playback */
#ifdef Q_OS_LINUX
                    "--no-xlib", // avoid xlib thread error messages
#endif
                    "--verbose=-1", // -1 = no output at all
                    "--quiet"
                };

    /* create an exception handler */
    //libvlc_exception_init(&exceptions);
    //vlc_exceptions(&exceptions);

    /* Load the VLC engine */
    inst = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
    //vlc_exceptions(&exceptions);

    /* Create a new item */

    m = NULL;
    //vlc_exceptions(&exceptions);
        
    /* Create a media player playing environement */
    mp = libvlc_media_player_new (inst);
    //vlc_exceptions(&exceptions);

    //vlc_exceptions(&exceptions);

 
    /* This is a non working code that show how to hooks into a window,
     * if we have a window around */
#ifdef Q_OS_LINUX
     x11Container = new QX11EmbedContainer(this);
     layout->addWidget(x11Container);
     libvlc_media_player_set_xwindow (mp, x11Container->winId());
#endif
#ifdef WIN32
     container = new QWidget(this);
     layout->addWidget(container);
     libvlc_media_player_set_hwnd (mp, container->winId());
#endif

    connect(context, SIGNAL(stop()), this, SLOT(stopPlayback()));
    connect(context, SIGNAL(start()), this, SLOT(startPlayback()));
    connect(context, SIGNAL(pause()), this, SLOT(pausePlayback()));
    connect(context, SIGNAL(seek(long)), this, SLOT(seekPlayback(long)));
    connect(context, SIGNAL(unpause()), this, SLOT(resumePlayback()));
    connect(context, SIGNAL(mediaSelected(QString)), this, SLOT(mediaSelected(QString)));

}
Beispiel #29
0
void LLAgentPilot::updateTarget()
{
	if (mPlaying)
	{
		if (mCurrentAction < mActions.count())
		{
			if (0 == mCurrentAction)
			{
				if (gAgent.getAutoPilot())
				{
					// Wait until we get to the first location before starting.
					return;
				}
				else
				{
					if (!mStarted)
					{
						llinfos << "At start, beginning playback" << llendl;
						mTimer.reset();
						LLFrameStats::startLogging(NULL);
						mStarted = TRUE;
					}
				}
			}
			if (mTimer.getElapsedTimeF32() > mActions[mCurrentAction].mTime)
			{
				//gAgent.stopAutoPilot();
				mCurrentAction++;

				if (mCurrentAction < mActions.count())
				{
					gAgent.startAutoPilotGlobal(mActions[mCurrentAction].mTarget);
				}
				else
				{
					stopPlayback();
					LLFrameStats::stopLogging(NULL);
					mNumRuns--;
					if (sLoop)
					{
						if ((mNumRuns < 0) || (mNumRuns > 0))
						{
							llinfos << "Looping, restarting playback" << llendl;
							startPlayback();
						}
						else if (mQuitAfterRuns)
						{
							llinfos << "Done with all runs, quitting viewer!" << llendl;
							LLAppViewer::instance()->forceQuit();
						}
						else
						{
							llinfos << "Done with all runs, disabling pilot" << llendl;
							stopPlayback();
						}
					}
				}
			}
		}
		else
		{
			stopPlayback();
		}
	}
	else if (mRecording)
	{
		if (mTimer.getElapsedTimeF32() - mLastRecordTime > 1.f)
		{
			addAction(STRAIGHT);
		}
	}
}
void
FFmpegLibAvStreamImpl::run()
{
    Mutex                   lockMutex;
    ScopedLock              lock (lockMutex);

    preRun();

    // Minimal samples for time-period passed by one frame multiplied by two(speed of filling audio buffer should be faster than audio playback),
    // limited by 32767 as restriction of ffmpeg-wrapper
    const unsigned short    samplesPart = std::min((double)32767, (double)(m_audioFormat.m_bytePerSample * m_audioFormat.m_channelsNb * m_audioFormat.m_sampleRate) / m_frame_rate * 2);
    const unsigned int      minBlockSize = samplesPart * m_audioFormat.m_bytePerSample * m_audioFormat.m_channelsNb;
    unsigned char *         pAudioData = minBlockSize > 0 ? new unsigned char[minBlockSize * 2] : NULL; // ... * 2], because it could read more than minBlockSize
    try
    {
        //
        bool                videoGrabbingInProcess;
        bool                audioGrabbingInProcess;
        //
        bool                isPlaybackStarted   = false;
        size_t              drop_frame_nb       = 0;
        //
        while (m_shadowThreadStop == false)
        {
            unsigned int    videoWriteFlag = 0;
            audioGrabbingInProcess = false;
            videoGrabbingInProcess = false;
            //
            // Grab Audio Buffer
            //
            if (isHasAudio() && pAudioData != NULL)
            {
                const unsigned int space_audio_size = m_audio_buffer.freeSpaceSize();

                if (space_audio_size > minBlockSize && m_audio_buffering_finished == false)
                {
                    double  max_avail_time_micros = -1.0;
                    //
                    // Limit audio-grabbing by time to avoid video artifacts
                    //
                    if (isPlaybackStarted)
                    {
                        //
                        // 1. To avoid audio-artifacts, we should guaranty that audio-buffer filled.
                        //    So, as less audio-buffer filled, as more available time for audio grabbing.
                        //    Even if it will become to appear the video artifacts.
                        //
                        // 2. To avoid video-artifacts, we should TRY spend as less as possible time for
                        //    audio grabbing.
                        //
                        const double audio_bufferedTimeSec  = (double)(m_audio_buffer.size() - space_audio_size) / (double)(m_audioFormat.m_bytePerSample * m_audioFormat.m_channelsNb * m_audioFormat.m_sampleRate);
                        //
                        const double audio_bufferedRatio    = (double)(m_audio_buffer.size() - space_audio_size) / (double)m_audio_buffer.size();
                        if (audio_bufferedRatio > 0.25)
                        {
                            const double video_frameTimeSec = 1.0 / m_frame_rate;

                                                                                                    // audio_bufferedRatio:       0.25 ... 0.5       ... 1.0
                            double coeff = 0.25 / (audio_bufferedRatio - 0.25 + std::numeric_limits<double>::min()) - 0.333;   // +INF ... 0.7       ... 0.0
                            max_avail_time_micros = video_frameTimeSec * coeff * 1000000.0;         //                            +INF ... frame*0.7 ... 0.0
                        }
                        else
                        {
                            if (m_useRibbonTimeStrategy == false)
                                videoWriteFlag |= 1; // disable decoding during searching
                        }
                    }
                    const int bytesread = FFmpegWrapper::getAudioSamples(m_audioIndex,
                                                                            123456789,
                                                                            m_audioFormat.m_channelsNb,
                                                                            m_audioFormat.m_avSampleFormat,
                                                                            m_audioFormat.m_sampleRate,
                                                                            samplesPart,
                                                                            pAudioData,
                                                                            max_avail_time_micros) * m_audioFormat.m_bytePerSample * m_audioFormat.m_channelsNb;
                    if (bytesread > 0)
                    {
                        m_audio_buffer.write (pAudioData, bytesread);
                        audioGrabbingInProcess = true;
                    }
                    else
                    {
                        m_audio_buffering_finished = true;
                        if (bytesread < 0)
                            throw std::runtime_error("Audio failed");
                    }
                }
            }
            //
            // Grab Video Buffer
            //
            if (isHasVideo())
            {
                if (m_video_buffer.isStreamFinished() == false)
                {
                    if (m_video_buffer.isBufferFull() == false)
                    {
                        if (m_useRibbonTimeStrategy == true)
                        {
                            drop_frame_nb = 0;
                        }
                        else
                        {
                            //
                            // Provide little acceleration for video grabbing
                            // Test shows, that 20-frame buffer accelerated enough by 1-frame dropping in half of the buffer-size.
                            //
                            if (isPlaybackStarted && m_video_buffer.isStreamFinished() == false)
                            {
                                double aspect = (double)m_video_buffer.freeSpaceSize() / (double)m_video_buffer.size();
                                drop_frame_nb = aspect * 2;
                            }
                        }
                        m_video_buffer.writeFrame (videoWriteFlag, drop_frame_nb);

                        videoGrabbingInProcess = true;
                    }
                }
                else
                {
                    m_renderer.quit(false);
                }
            }
            if (isPlaybackStarted && isPlaybackFinished())
            {
                break;
            }
            //
            // If grabbings do not work(waste a time):
            //
            // 1. If it is first wasting of the time and playback did not started before, we may start playback.
            // 2. It may couse to get too many empty loops, so locks this thread till some buffer opens for writing, or interrupt for exit
            //
            if (audioGrabbingInProcess == false &&
                videoGrabbingInProcess == false)
            {
                if (isPlaybackStarted == false)
                {
                    isPlaybackStarted = true;
                    startPlayback();
                }
                if (m_shadowThreadStop == false)
                    m_threadLocker.wait (& lockMutex);
            }
        }
    }
    catch (const std::exception & error)
    {
        //OSG_WARN << "FFmpegLibAvStreamImpl::run : " << error.what() << std::endl;
        av_log(NULL, AV_LOG_WARNING, "FFmpegLibAvStreamImpl::run : %s", error.what());
    }

    catch (...)
    {
        //OSG_WARN << "FFmpegLibAvStreamImpl::run : unhandled exception" << std::endl;
        av_log(NULL, AV_LOG_WARNING, "FFmpegLibAvStreamImpl::run : unhandled exception");
    }

    if (pAudioData)
        delete []pAudioData;

    m_shadowThreadStop = true;

    postRun();
}