예제 #1
0
파일: Sequence.cpp 프로젝트: jcochran/fpp
void Sequence::CloseSequenceFile(void) {
	LogDebug(VB_SEQUENCE, "CloseSequenceFile() %s\n", m_seqFilename);

	if (getFPPmode() == MASTER_MODE)
		SendSeqSyncStopPacket(m_seqFilename);

	pthread_mutex_lock(&m_sequenceLock);

	if (m_seqFile) {
		fclose(m_seqFile);
		m_seqFile = NULL;
	}

	m_seqFilename[0] = '\0';
	m_seqPaused = 0;

	if ((getFPPmode() != REMOTE_MODE) &&
		(!IsEffectRunning()) &&
		(FPPstatus != FPP_STATUS_PLAYLIST_PLAYING))
		SendBlankingData();

	pthread_mutex_unlock(&m_sequenceLock);
}
예제 #2
0
파일: Player.cpp 프로젝트: dkulp/fpp
void Player::MainLoop(void)
{
	int            commandSock = 0;
	int            controlSock = 0;
	int            bridgeSock = 0;
	int            prevFPPstatus = FPPstatus;
	int            sleepUs = MAIN_LOOP_SLEEP_US;
	fd_set         active_fd_set;
	fd_set         read_fd_set;
	struct timeval timeout;
	int            selectResult;

	LogDebug(VB_PLAYER, "Player::MainLoop()\n");

	if (getFPPmode() & PLAYER_MODE)
	{
		m_scheduler = new Scheduler(this);

		if (!m_scheduler)
		{
			LogErr(VB_PLAYER, "Error creating Scheduler\n");
			return;
		}

		m_playlist = new Playlist(this);

		if (!m_playlist)
		{
			LogErr(VB_PLAYER, "Error creating Playlist\n");
			return;
		}
	}

	m_runMainLoop = 1;

	FD_ZERO (&active_fd_set);

	CheckExistanceOfDirectoriesAndFiles();

#ifdef USEWIRINGPI
	wiringPiSetupGpio(); // would prefer wiringPiSetupSys();
	piFaceSetup(200); // PiFace inputs 1-8 == wiringPi 200-207
#endif

	if (getFPPmode() == BRIDGE_MODE)
	{
		bridgeSock = Bridge_Initialize();
		if (bridgeSock)
			FD_SET (bridgeSock, &active_fd_set);
	}
	else
	{
		InitMediaOutput();
	}

	pluginCallbackManager.init();

	InitializeChannelOutputs();
	SendBlankingData();

	InitEffects();
	InitializeChannelDataMemoryMap();

	commandSock = Command_Initialize();
	if (commandSock)
		FD_SET (commandSock, &active_fd_set);

#ifdef USEHTTPAPI
	APIServer apiServer;
	apiServer.Init();
#endif

	controlSock = InitControlSocket();
	FD_SET (controlSock, &active_fd_set);

	SetupGPIOInput();

	if (getFPPmode() & PLAYER_MODE)
	{
		if (getFPPmode() == MASTER_MODE)
			InitSyncMaster();

		m_scheduler->CheckIfShouldBePlayingNow();
	}

	if ((getAlwaysTransmit()) ||
		(UsingMemoryMapInput()) ||
		(getFPPmode() & BRIDGE_MODE))
		StartChannelOutputThread();

	LogInfo(VB_PLAYER, "Starting main processing loop\n");

	while (m_runMainLoop)
	{
		timeout.tv_sec  = 0;
		timeout.tv_usec = sleepUs;

		read_fd_set = active_fd_set;


		selectResult = select(FD_SETSIZE, &read_fd_set, NULL, NULL, &timeout);
		if (selectResult < 0)
		{
			if (errno == EINTR)
			{
				// We get interrupted when media players finish
				continue;
			}
			else
			{
				LogErr(VB_PLAYER, "Main select() failed: %s\n",
					strerror(errno));
				m_runMainLoop = 0;
				continue;
			}
		}

		if (commandSock && FD_ISSET(commandSock, &read_fd_set))
			CommandProc();

		if (bridgeSock && FD_ISSET(bridgeSock, &read_fd_set))
			Bridge_ReceiveData();

		if (controlSock && FD_ISSET(controlSock, &read_fd_set))
			ProcessControlPacket();

		// Check to see if we need to start up the output thread.
		// FIXME, possibly trigger this via a fpp command to fppd
		if ((!ChannelOutputThreadIsRunning()) &&
			(getFPPmode() != BRIDGE_MODE) &&
			((UsingMemoryMapInput()) ||
			 (channelTester->Testing()) ||
			 (getAlwaysTransmit()))) {
			int E131BridgingInterval = getSettingInt("E131BridgingInterval");
			if (!E131BridgingInterval)
				E131BridgingInterval = 50;
			SetChannelOutputRefreshRate(1000 / E131BridgingInterval);
			StartChannelOutputThread();
		}

		if (getFPPmode() & PLAYER_MODE)
		{
			if ((FPPstatus == FPP_STATUS_PLAYLIST_PLAYING) ||
				(FPPstatus == FPP_STATUS_STOPPING_NOW) ||
				(FPPstatus == FPP_STATUS_STOPPING_GRACEFULLY_AFTER_LOOP) ||
				(FPPstatus == FPP_STATUS_STOPPING_GRACEFULLY))
			{
//				if (prevFPPstatus == FPP_STATUS_IDLE)
//				{
//					m_playlist->Start();
//					sleepUs = 10000;
// FIXME PLAYLIST
// sleepUs = 500000;
//				}

				// Check again here in case PlayListPlayingInit
				// didn't find anything and put us back to IDLE
				if ((FPPstatus == FPP_STATUS_PLAYLIST_PLAYING) ||
					(FPPstatus == FPP_STATUS_STOPPING_NOW) ||
					(FPPstatus == FPP_STATUS_STOPPING_GRACEFULLY_AFTER_LOOP) ||
					(FPPstatus == FPP_STATUS_STOPPING_GRACEFULLY))
				{
					m_playlist->Process();
				}
			}

			int reactivated = 0;
			if (FPPstatus == FPP_STATUS_IDLE)
			{
				if ((prevFPPstatus == FPP_STATUS_PLAYLIST_PLAYING) ||
					(prevFPPstatus == FPP_STATUS_STOPPING_NOW) ||
					(prevFPPstatus == FPP_STATUS_STOPPING_GRACEFULLY_AFTER_LOOP) ||
					(prevFPPstatus == FPP_STATUS_STOPPING_GRACEFULLY))
				{
					m_playlist->Cleanup();

					m_scheduler->ReLoadCurrentScheduleInfo();

					if (FPPstatus != FPP_STATUS_IDLE)
						reactivated = 1;
					else
						sleepUs = MAIN_LOOP_SLEEP_US;
				}
			}

			if (reactivated)
				prevFPPstatus = FPP_STATUS_IDLE;
			else
				prevFPPstatus = FPPstatus;

			m_scheduler->ScheduleProc();
		}
		else if (getFPPmode() == REMOTE_MODE)
		{
			if(mediaOutputStatus.status == MEDIAOUTPUTSTATUS_PLAYING)
			{
// FIXME PLAYLIST
// when in remote mode, who owns the sequences and mediaoutputs we are playing?
//				playlist->PlaylistProcessMediaData();
LogDebug(VB_PLAYER, "FIXME PLAYLIST\n");
			}
		}

		CheckGPIOInputs();
	}

	StopChannelOutputThread();
	ShutdownControlSocket();

	if (getFPPmode() == BRIDGE_MODE)
	{
		Bridge_Shutdown();
	}
	else if (getFPPmode() & PLAYER_MODE)
	{
		delete m_scheduler;
		delete m_playlist;
	}

	LogInfo(VB_PLAYER, "Main Loop complete, shutting down.\n");
}