Exemplo n.º 1
0
Arquivo: events.c Projeto: darylc/fpp
/*
 * Trigger an event
 */
int TriggerEventByID(char *id)
{
	LogDebug(VB_EVENT, "TriggerEventByID(%s)\n", id);

	if (getFPPmode() == MASTER_MODE)
		SendEventPacket(id);

	FPPevent *event = LoadEvent(id);

	if (!event)
	{
		LogWarn(VB_EVENT, "Unable to load event %s\n", id);
		return 0;
	}

	if (event->effect)
		StartEffect(event->effect, event->startChannel);

	if (event->script)
		RunEventScript(event);

	FreeEvent(event);

	return 1;
}
Exemplo n.º 2
0
int omxplayer_StartPlaying(const char *filename)
{
	char  fullVideoPath[2048];

	LogDebug(VB_MEDIAOUT, "omxplayer_StartPlaying(%s)\n", filename);

	bzero(&mediaOutputStatus, sizeof(mediaOutputStatus));

	if (snprintf(fullVideoPath, 2048, "%s/%s", getVideoDirectory(), filename)
		>= 2048)
	{
		LogErr(VB_MEDIAOUT, "Unable to play %s, full path name too long\n",
			filename);
		return 0;
	}

	if (getFPPmode() == REMOTE_MODE)
		CheckForHostSpecificFile(getSetting("HostName"), fullVideoPath);

	if (!FileExists(fullVideoPath))
	{
		LogErr(VB_MEDIAOUT, "%s does not exist!\n", fullVideoPath);
		return 0;
	}

	// Create Pipes to/from omxplayer
	pid_t omxplayerPID = forkpty(&pipeFromOMX[0], 0, 0, 0);
	if (omxplayerPID == 0)			// omxplayer process
	{
		ShutdownControlSocket();

		seteuid(1000); // 'pi' user

		execl("/opt/fpp/scripts/omxplayer", "/opt/fpp/scripts/omxplayer", fullVideoPath, NULL);

		LogErr(VB_MEDIAOUT, "omxplayer_StartPlaying(), ERROR, we shouldn't "
			"be here, this means that execl() failed\n");

		exit(EXIT_FAILURE);
	}
	else							// Parent process
	{
		mediaOutput->childPID = omxplayerPID;
	}

	// Clear active file descriptor sets
	FD_ZERO (&omx_active_fd_set);
	// Set description for reading from omxplayer
	FD_SET (pipeFromOMX[0], &omx_active_fd_set);

	mediaOutputStatus.status = MEDIAOUTPUTSTATUS_PLAYING;

	omxVolumeShift = omxplayer_GetVolumeShift(getVolume());

	return 1;
}
Exemplo n.º 3
0
void Sequence::SendBlankingData(void) {
	LogDebug(VB_SEQUENCE, "SendBlankingData()\n");
	usleep(100000);

	if (getFPPmode() == MASTER_MODE)
		SendBlankingDataPacket();

	BlankSequenceData();
	ProcessSequenceData(0);
	SendSequenceData();
}
Exemplo n.º 4
0
Arquivo: Player.cpp Projeto: dkulp/fpp
void Player::SendBlankingData(void)
{
	usleep(100000); // FIXME, figure out a way to not need this delay
	                // possibly by just starting thread up once more

	bzero(m_seqData, FPPD_MAX_CHANNELS);

	if (getFPPmode() == MASTER_MODE)
		SendBlankingDataPacket();

	ProcessChannelData();
	SendChannelData(m_seqData);
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
/*
 * Initialize effects constructs
 */
int InitEffects(void)
{
    std::string localFilename = getEffectDirectory();
    localFilename += "/background.eseq";

	if ((getFPPmode() == REMOTE_MODE) &&
		CheckForHostSpecificFile(getSetting("HostName"), localFilename)) {
        localFilename = "background_";
		localFilename += getSetting("HostName");

		LogInfo(VB_EFFECT, "Automatically starting background effect "
			"sequence %s\n", localFilename.c_str());

		StartEffect(localFilename.c_str(), 0, 1);
	} else if (FileExists(localFilename)) {
		LogInfo(VB_EFFECT, "Automatically starting background effect sequence "
			"background.eseq\n");
		StartEffect("background", 0, 1);
	}

	pauseBackgroundEffects = getSettingInt("pauseBackgroundEffects");
	return 1;
}
Exemplo n.º 7
0
Arquivo: Player.cpp Projeto: dkulp/fpp
/*
 * Calculate the new sync offset based on the current position reported
 * by the media player.
 */
void Player::CalculateNewChannelOutputDelay(float mediaPosition)
{
	static float nextSyncCheck = 0.5;

	if (getFPPmode() == REMOTE_MODE)
		return;

	if ((mediaPosition <= nextSyncCheck) &&
		(nextSyncCheck < (mediaPosition + 2.0)))
		return;

	float offsetMediaPosition = mediaPosition - m_mediaOffset;

	int expectedFramesSent = (int)(offsetMediaPosition * m_refreshRate);

	mediaElapsedSeconds = mediaPosition;

	LogDebug(VB_PLAYER | VB_CHANNELOUT,
		"Media Position: %.2f, Offset: %.3f, Frames Sent: %d, Expected: %d, Diff: %d\n",
		mediaPosition, m_mediaOffset, channelOutputFrame, expectedFramesSent,
		channelOutputFrame - expectedFramesSent);

	CalculateNewChannelOutputDelayForFrame(expectedFramesSent);
}
Exemplo n.º 8
0
void ogg123Output::ParseTimes()
{
	static int lastRemoteSync = 0;
	int result;
	int secs;
	int mins;
	int subSecs;
	char tmp[3];
	tmp[2]= '\0';

	// Mins
	tmp[0] = m_ogg123_strTime[1];
	tmp[1] = m_ogg123_strTime[2];
	sscanf(tmp,"%d",&mins);

	// Secs
	tmp[0] = m_ogg123_strTime[4];
	tmp[1] = m_ogg123_strTime[5];
	sscanf(tmp,"%d",&secs);
	m_mediaOutputStatus->secondsElapsed = 60*mins + secs;

	// Subsecs
	tmp[0] = m_ogg123_strTime[7];
	tmp[1] = m_ogg123_strTime[8];
	sscanf(tmp,"%d",&m_mediaOutputStatus->subSecondsElapsed);

	// Mins Remaining
	tmp[0] = m_ogg123_strTime[11];
	tmp[1] = m_ogg123_strTime[12];
	sscanf(tmp,"%d",&mins);

	// Secs Remaining
	tmp[0] = m_ogg123_strTime[14];
	tmp[1] = m_ogg123_strTime[15];
	sscanf(tmp,"%d",&secs);
	m_mediaOutputStatus->secondsRemaining = 60*mins + secs;

	// Subsecs remaining
	tmp[0] = m_ogg123_strTime[17];
	tmp[1] = m_ogg123_strTime[18];
	sscanf(tmp,"%d",&m_mediaOutputStatus->subSecondsRemaining);

	// Total Mins
	tmp[0] = m_ogg123_strTime[24];
	tmp[1] = m_ogg123_strTime[25];
	sscanf(tmp,"%d",&m_mediaOutputStatus->minutesTotal);

	// Total Secs
	tmp[0] = m_ogg123_strTime[27];
	tmp[1] = m_ogg123_strTime[28];
	sscanf(tmp,"%d",&m_mediaOutputStatus->secondsTotal);

	m_mediaOutputStatus->mediaSeconds = (float)((float)m_mediaOutputStatus->secondsElapsed + ((float)m_mediaOutputStatus->subSecondsElapsed/(float)100));

	if (getFPPmode() == MASTER_MODE)
	{
		if ((m_mediaOutputStatus->secondsElapsed > 0) &&
			(lastRemoteSync != m_mediaOutputStatus->secondsElapsed))
		{
			SendMediaSyncPacket(m_mediaFilename.c_str(), 0,
				m_mediaOutputStatus->mediaSeconds);
			lastRemoteSync = m_mediaOutputStatus->secondsElapsed;
		}
	}

	if ((sequence->IsSequenceRunning()) &&
		(m_mediaOutputStatus->secondsElapsed > 0))
	{
		LogExcess(VB_MEDIAOUT,
			"Elapsed: %.2d.%.2d  Remaining: %.2d Total %.2d:%.2d.\n",
			m_mediaOutputStatus->secondsElapsed,
			m_mediaOutputStatus->subSecondsElapsed,
			m_mediaOutputStatus->secondsRemaining,
			m_mediaOutputStatus->minutesTotal,
			m_mediaOutputStatus->secondsTotal);

		CalculateNewChannelOutputDelay(m_mediaOutputStatus->mediaSeconds);
	}
}
Exemplo n.º 9
0
void omxplayer_ProcessPlayerData(int bytesRead)
{
	int        ticks = 0;
	static int lastSyncCheck = 0;
	static int lastRemoteSync = 0;
	int        mins = 0;
	int        secs = 0;
	int        subsecs = 0;
	int        totalCentiSecs = 0;
	char      *ptr = NULL;

	if ((mediaOutputStatus.secondsTotal == 0) &&
		(mediaOutputStatus.minutesTotal == 0) &&
		(ptr = strstr(omxBuffer, "Duration: ")))
	{
		// Sample line format:
		// (whitespace)Duration: 00:00:37.91, start: 0.000000, bitrate: 2569 kb/s
		char *ptr2 = strchr(ptr, ',');
		if (ptr2)
		{
			*ptr2 = '\0';
			ptr = ptr + 10;

			int hours = strtol(ptr, NULL, 10);
			ptr += 3;
			mediaOutputStatus.minutesTotal = strtol(ptr, NULL, 10) + (hours * 60);
			ptr += 3;
			mediaOutputStatus.secondsTotal = strtol(ptr, NULL, 10);
		}
	}

	// Data is line buffered so all stats lines should start with "M: "
	if ((!strncmp(omxBuffer, "M:", 2)) &&
		(bytesRead > 20))
	{
		errno = 0;
		ticks = strtol(&omxBuffer[2], NULL, 10);
		if (errno) {
			LogErr(VB_MEDIAOUT, "Error parsing omxplayer output.\n");
			return;
		}
	} else {
		return;
	}

	totalCentiSecs = ticks / 10000;
	mins = totalCentiSecs / 6000;
	secs = totalCentiSecs % 6000 / 100;
	subsecs = totalCentiSecs % 100;

	mediaOutputStatus.secondsElapsed = 60 * mins + secs;

	mediaOutputStatus.subSecondsElapsed = subsecs;

	mediaOutputStatus.secondsRemaining = (mediaOutputStatus.minutesTotal * 60)
		+ mediaOutputStatus.secondsTotal - mediaOutputStatus.secondsElapsed;
	// FIXME, can we get this?
	// mediaOutputStatus.subSecondsRemaining = subsecs;

	mediaOutputStatus.mediaSeconds = (float)((float)mediaOutputStatus.secondsElapsed + ((float)mediaOutputStatus.subSecondsElapsed/(float)100));

	if (getFPPmode() == MASTER_MODE)
	{
		if ((mediaOutputStatus.secondsElapsed > 0) &&
			(lastRemoteSync != mediaOutputStatus.secondsElapsed))
		{
			SendMediaSyncPacket(mediaOutput->filename, 0,
				mediaOutputStatus.mediaSeconds);
			lastRemoteSync = mediaOutputStatus.secondsElapsed;
		}
	}

	if ((sequence->IsSequenceRunning()) &&
		(mediaOutputStatus.secondsElapsed > 0) &&
		(lastSyncCheck != mediaOutputStatus.secondsElapsed))
	{
		LogDebug(VB_MEDIAOUT,
			"Elapsed: %.2d.%.2d  Remaining: %.2d Total %.2d:%.2d.\n",
			mediaOutputStatus.secondsElapsed,
			mediaOutputStatus.subSecondsElapsed,
			mediaOutputStatus.secondsRemaining,
			mediaOutputStatus.minutesTotal,
			mediaOutputStatus.secondsTotal);

		CalculateNewChannelOutputDelay(mediaOutputStatus.mediaSeconds);
		lastSyncCheck = mediaOutputStatus.secondsElapsed;
	}
}
Exemplo n.º 10
0
Arquivo: command.c Projeto: dkulp/fpp
  void ProcessCommand(char *command)
  {
    char *s;
    char *s2;
    char *s3;
    char *s4;
    char *response2 = NULL;
    int i;
		char NextPlaylist[128] = "No playlist scheduled.";
		char NextScheduleStartText[64] = "";
		char CommandStr[64];
		LogExcess(VB_COMMAND, "CMD: %s\n", command);
		s = strtok(command,",");
		strcpy(CommandStr, s);
		if (!strcmp(CommandStr, "s"))
		{
				Json::Value info = player->GetCurrentPlaylistInfo();
				char currentEntryType = 'u'; // Unknown
				const char *currentSequenceName = NULL;
				const char *currentMediaName = NULL;

				if (info["currentEntry"].isMember("sequenceName"))
					currentSequenceName = info["currentEntry"]["sequenceName"].asString().c_str();

				if (info["currentEntry"].isMember("mediaFilename"))
					currentMediaName = info["currentEntry"]["mediaFilename"].asString().c_str();

				if (info["currentEntry"].isMember("type"))
				{
					std::string type = info["currentEntry"]["type"].asString();
					if (type == "both")
						currentEntryType = 'b';
					else if (type == "event")
						currentEntryType = 'e';
					else if (type == "media")
						currentEntryType = 'm';
					else if (type == "pause")
						currentEntryType = 'p';
					else if (type == "plugin")
						currentEntryType = 'P';
					else if (type == "sequence")
						currentEntryType = 's';
				}

				player->GetNextScheduleStartText(NextScheduleStartText);
				player->GetNextPlaylistText(NextPlaylist);
				if(FPPstatus==FPP_STATUS_IDLE)
				{
					if (getFPPmode() == REMOTE_MODE)
					{
						sprintf(response,"%d,%d,%d,%s,%s,%d,%d\n",
							getFPPmode(), 0, getVolume(),
							currentSequenceName,
							currentMediaName,
							player->GetPlaybackSecondsElapsed(),
							player->GetPlaybackSecondsRemaining());
					}
					else
					{
						sprintf(response,"%d,%d,%d,%s,%s\n",
							getFPPmode(),0,getVolume(),
							NextPlaylist,NextScheduleStartText);
					}
				}
				else
				{
					sprintf(response,"%d,%d,%d,%s,%c,%s,%s,%d,%d,%d,%d,%s,%s,%d\n",
							getFPPmode(),FPPstatus,getVolume(),
							info["name"].asString().c_str(),
							currentEntryType,
							currentSequenceName,
							currentMediaName,
							info["currentPosition"].asInt() + 1,
							info["size"].asInt(),
							info["currentEntry"]["secondsElapsed"].asInt(),
							info["currentEntry"]["secondsRemaining"].asInt(),
							NextPlaylist,NextScheduleStartText,
							info["repeat"].asInt());
				}
		}
		else if ((!strcmp(CommandStr, "p")) ||
				 (!strcmp(CommandStr, "P")))
		{
				if(FPPstatus==FPP_STATUS_PLAYLIST_PLAYING || FPPstatus==FPP_STATUS_STOPPING_GRACEFULLY)
				{
					player->PlaylistStopNow();
					sleep(1);
				}
	
				s = strtok(NULL,",");
				if (s)
				{
					std::string playlistName(s);
					int repeat = !strcmp(CommandStr, "p") ? 1 : 0;
					int position = 0;

					s = strtok(NULL,",");
					if (s)
						position = atoi(s);

					if (player->PlaylistStart(playlistName, position, repeat))
					{
						sprintf(response,"%d,%d,Playlist Started,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
					}
					else
					{
						sprintf(response,"%d,%d,Playlist Start Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
					}
				}
				else
				{
					sprintf(response,"%d,%d,Unknown Playlist,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
				}
		}
		else if (!strcmp(CommandStr, "S"))
		{
				if(FPPstatus==FPP_STATUS_PLAYLIST_PLAYING)
				{
					player->PlaylistStopGracefully();
					player->ReLoadCurrentScheduleInfo();
					sprintf(response,"%d,%d,Playlist Stopping Gracefully,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
				}
				else
				{
					sprintf(response,"%d,Not playing,,,,,,,,,,,\n",COMMAND_FAILED);
				}
		}
		else if (!strcmp(CommandStr, "d"))
		{
				if(FPPstatus==FPP_STATUS_PLAYLIST_PLAYING || FPPstatus==FPP_STATUS_STOPPING_GRACEFULLY)
				{
					player->PlaylistStopNow();
					player->ReLoadCurrentScheduleInfo();
					sprintf(response,"%d,%d,Playlist Stopping Now,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
				}
				else
				{
					sprintf(response,"%d,%d,Not playing,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
				}
		}
		else if (!strcmp(CommandStr, "R"))
		{
				if(FPPstatus==FPP_STATUS_IDLE)
				{
					player->ReLoadCurrentScheduleInfo();
				}
				player->ReLoadNextScheduleInfo();
				
				
				sprintf(response,"%d,%d,Reloading Schedule,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
		}
		else if (!strcmp(CommandStr, "v"))
		{
				s = strtok(NULL,",");
				if (s)
				{
					setVolume(atoi(s));
					sprintf(response,"%d,%d,Setting Volume,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
				}
				else
				{
					sprintf(response,"%d,%d,Invalid Volume,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
				}
		}
		else if (!strcmp(CommandStr, "w"))
		{
				LogInfo(VB_SETTING, "Sending Falcon hardware config\n");
				if (!DetectFalconHardware(1))
					SendFPDConfig();
		}
		else if (!strcmp(CommandStr, "r"))
		{
				WriteBytesReceivedFile();
				sprintf(response,"true\n");
		}
		else if (!strcmp(CommandStr, "q"))
		{
			// Quit/Shutdown fppd
			ShutdownFPPD();
		}
		else if (!strcmp(CommandStr, "e"))
		{
			// Start an Effect
			s = strtok(NULL,",");
			s2 = strtok(NULL,",");
			s3 = strtok(NULL,",");
			if (s && s2)
			{
				i = StartEffect(s, atoi(s2), atoi(s3));
				if (i >= 0)
					sprintf(response,"%d,%d,Starting Effect,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i);
				else
					sprintf(response,"%d,%d,Invalid Effect,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
			}
			else
				sprintf(response,"%d,%d,Invalid Effect,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
		}
		else if (!strcmp(CommandStr, "t"))
		{
			// Trigger an event
			s = strtok(NULL,",");
			pluginCallbackManager.eventCallback(s, "command");
			i = TriggerEventByID(s);
			if (i >= 0)
				sprintf(response,"%d,%d,Event Triggered,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i);
			else
				sprintf(response,"%d,%d,Event Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
		}
		else if (!strcmp(CommandStr, "GetTestMode"))
		{
			strcpy(response, channelTester->GetConfig().c_str());
			strcat(response, "\n");
		}
		else if (!strcmp(CommandStr, "SetTestMode"))
		{
			if (channelTester->SetupTest(std::string(s + strlen(s) + 1)))
			{
				sprintf(response, "0,%d,Test Mode Activated,,,,,,,,,\n",
					COMMAND_SUCCESS);
			}
			else
			{
				sprintf(response, "0,%d,Test Mode Deactivated,,,,,,,,,\n",
					COMMAND_SUCCESS);
			}
		}
		else if (!strcmp(CommandStr, "LogLevel"))
		{
			s = strtok(NULL,",");

			if (SetLogLevel(s)) {
				sprintf(response,"%d,%d,Log Level Updated,%d,%d,,,,,,,,,\n",
					getFPPmode(),COMMAND_SUCCESS,logLevel,logMask);
			} else {
				sprintf(response,"%d,%d,Error Updating Log Level,%d,%d,,,,,,,,,\n",
					getFPPmode(),COMMAND_FAILED,logLevel,logMask);
			}
		}
		else if (!strcmp(CommandStr, "LogMask"))
		{
			s = strtok(NULL,",");

			if ((s && SetLogMask(s)) || SetLogMask("")) {
				sprintf(response,"%d,%d,Log Mask Updated,%d,%d,,,,,,,,,\n",
					getFPPmode(),COMMAND_SUCCESS,logLevel,logMask);
			} else {
				sprintf(response,"%d,%d,Error Updating Log Mask,%d,%d,,,,,,,,,\n",
					getFPPmode(),COMMAND_FAILED,logLevel,logMask);
			}
		}
		else if (!strcmp(CommandStr, "SetSetting"))
		{
			char name[128];

			s = strtok(NULL,",");
			if (s)
			{
				strcpy(name, s);
				s = strtok(NULL,",");
				if (s)
					parseSetting(name, s);
			}
		}
		else if (!strcmp(CommandStr, "StopAllEffects"))
		{
			StopAllEffects();
			sprintf(response,"%d,%d,All Effects Stopped,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
		}
		else if (!strcmp(CommandStr, "StopEffectByName"))
		{
			s = strtok(NULL,",");
			if (strlen(s))
			{
				if (StopEffect(s))
						sprintf(response,"%d,%d,Stopping Effect,%s,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,s);
				else
						sprintf(response,"%d,%d,Stop Effect Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
			}
		}
		else if (!strcmp(CommandStr, "StopEffect"))
		{
			s = strtok(NULL,",");
			i = atoi(s);
			if (StopEffect(i))
					sprintf(response,"%d,%d,Stopping Effect,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i);
			else
					sprintf(response,"%d,%d,Stop Effect Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
		}
		else if (!strcmp(CommandStr, "GetRunningEffects"))
		{
			sprintf(response,"%d,%d,Running Effects",getFPPmode(),COMMAND_SUCCESS);
			GetRunningEffects(response, &response2);
		}
		else if (!strcmp(CommandStr, "ReloadChannelRemapData"))
		{
			if ((FPPstatus==FPP_STATUS_IDLE) &&
				(LoadChannelRemapData())) {
				sprintf(response,"%d,%d,Channel Remap Data Reloaded,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
			} else {
				sprintf(response,"%d,%d,Failed to reload Channel Remap Data,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
			}
		}
		else if (!strcmp(CommandStr, "GetFPPDUptime"))
		{
			sprintf(response,"%d,%d,FPPD Uptime,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS, time(NULL) - fppdStartTime);
		}
		else if (!strcmp(CommandStr, "StartSequence"))
		{
			s = strtok(NULL,",");
			s2 = strtok(NULL,",");
			if (s && s2)
			{
				i = atoi(s2);
				player->StartSequence(s, 0, i);
				sprintf(response,"%d,%d,Sequence Started,,,,,,,,,,,,\n",
					getFPPmode(), COMMAND_SUCCESS);
			}
			else
			{
				LogErr(VB_COMMAND, "Tried to start a sequence when a playlist or "
						"sequence is already running\n");
				sprintf(response,"%d,%d,Sequence Failed,,,,,,,,,,,,\n",
					getFPPmode(), COMMAND_FAILED);
			}
		}
		else if (!strcmp(CommandStr, "StopSequence"))
		{
			s = strtok(NULL,",");
			if (s)
			{
				player->StopSequence(s);
				sprintf(response,"%d,%d,Sequence Stopped,,,,,,,,,,,,\n",
					getFPPmode(), COMMAND_SUCCESS);
			}
			else
			{
				LogDebug(VB_COMMAND, "Invalid command: %s\n", command);
				sprintf(response,"%d,%d,Sequence Name Missing,,,,,,,,,,,,\n",
					getFPPmode(), COMMAND_FAILED);
			}
		}
		else if (!strcmp(CommandStr, "ToggleSequencePause"))
		{
			if ((player->SequencesRunning()) &&
				((FPPstatus == FPP_STATUS_IDLE) ||
				 (FPPstatus != FPP_STATUS_IDLE)))
			{
				player->ToggleSequencePause();
			}
		}
		else if (!strcmp(CommandStr, "SingleStepSequence"))
		{
			if ((player->SequencesRunning()) &&
				(player->SequencesArePaused()) &&
				((FPPstatus == FPP_STATUS_IDLE) ||
				 ((FPPstatus != FPP_STATUS_IDLE))))
			{
				player->SingleStepSequences();
			}
		}
		else if (!strcmp(CommandStr, "SingleStepSequenceBack"))
		{
			if ((player->SequencesRunning()) &&
				(player->SequencesArePaused()) &&
				((FPPstatus == FPP_STATUS_IDLE) ||
				 ((FPPstatus != FPP_STATUS_IDLE))))
			{
				player->SingleStepSequencesBack();
			}
		}
		else if (!strcmp(CommandStr, "NextPlaylistItem"))
		{
			switch (FPPstatus)
			{
				case FPP_STATUS_IDLE:
					sprintf(response,"%d,%d,No playlist running\n",getFPPmode(),COMMAND_FAILED);
					break;
				case FPP_STATUS_PLAYLIST_PLAYING:
					sprintf(response,"%d,%d,Skipping to next playlist item\n",getFPPmode(),COMMAND_SUCCESS);
					player->NextPlaylistItem();
					break;
				case FPP_STATUS_STOPPING_GRACEFULLY:
					sprintf(response,"%d,%d,Playlist is stopping gracefully\n",getFPPmode(),COMMAND_FAILED);
					break;
			}
		}
		else if (!strcmp(CommandStr, "PrevPlaylistItem"))
		{
			switch (FPPstatus)
			{
				case FPP_STATUS_IDLE:
					sprintf(response,"%d,%d,No playlist running\n",getFPPmode(),COMMAND_FAILED);
					break;
				case FPP_STATUS_PLAYLIST_PLAYING:
					sprintf(response,"%d,%d,Skipping to previous playlist item\n",getFPPmode(),COMMAND_SUCCESS);
					player->PrevPlaylistItem();
					break;
				case FPP_STATUS_STOPPING_GRACEFULLY:
					sprintf(response,"%d,%d,Playlist is stopping gracefully\n",getFPPmode(),COMMAND_FAILED);
					break;
			}
		}
		else if (!strcmp(CommandStr, "SetupExtGPIO"))
		{
			// Configure the given GPIO to the given mode
			s = strtok(NULL,",");
			s2 = strtok(NULL,",");
			if (s && s2)
			{
				
				if (!SetupExtGPIO(atoi(s), s2))
				{
					sprintf(response, "%d,%d,Configuring GPIO,%d,%s,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,atoi(s),s2);
				}
				else
				{
					sprintf(response, "%d,%d,Configuring GPIO,%d,%s,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED,atoi(s),s2);
				}
			}
		}
		else if (!strcmp(CommandStr, "ExtGPIO"))
		{
			s = strtok(NULL,",");
			s2 = strtok(NULL,",");
			s3 = strtok(NULL,",");
			if (s && s2 && s3)
			{
				i = ExtGPIO(atoi(s), s2, atoi(s3));
				if (i >= 0) 
				{
					sprintf(response, "%d,%d,Setting GPIO,%d,%s,%d,%d,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,atoi(s),s2,atoi(s3),i);
				}
				else
				{
					sprintf(response, "%d,%d,Setting GPIO,%d,%s,%d,,,,,,,,\n",getFPPmode(),COMMAND_FAILED,atoi(s),s2,atoi(s3));
				}
			}
		}
		else
		{
			sprintf(response,"Invalid command: '%s'\n", CommandStr);
		}

		if (response2)
		{
			bytes_sent = sendto(socket_fd, response2, strlen(response2), 0,
                          (struct sockaddr *) &(client_address), sizeof(struct sockaddr_un));
			LogDebug(VB_COMMAND, "%s %s", CommandStr, response2);
			free(response2);
			response2 = NULL;
		}
		else
		{
			bytes_sent = sendto(socket_fd, response, strlen(response), 0,
                          (struct sockaddr *) &(client_address), sizeof(struct sockaddr_un));
			LogDebug(VB_COMMAND, "%s %s", CommandStr, response);
		}
  }
Exemplo n.º 11
0
int main(int argc, char *argv[])
{
	initSettings(argc, argv);
	initMediaDetails();

	if (DirectoryExists("/home/fpp"))
		loadSettings("/home/fpp/media/settings");
	else
		loadSettings("/home/pi/media/settings");

	wiringPiSetupGpio(); // would prefer wiringPiSetupSys();

	// Parse our arguments first, override any defaults
	parseArguments(argc, argv);

	if (loggingToFile())
		logVersionInfo();

	printVersionInfo();

	// Start functioning
	if (getDaemonize())
		CreateDaemon();

	scheduler = new Scheduler();
	playlist  = new Playlist();
	sequence  = new Sequence();
	channelTester = new ChannelTester();

#ifndef NOROOT
	struct sched_param param;
	param.sched_priority = 99;
	if (sched_setscheduler(0, SCHED_FIFO, &param) != 0)
	{
		perror("sched_setscheduler");
		exit(EXIT_FAILURE);
	}
#endif

	MainLoop();

	if (getFPPmode() != BRIDGE_MODE)
	{
		CleanupMediaOutput();
	}

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

		CloseChannelDataMemoryMap();
		CloseEffects();
	}

	CloseChannelOutputs();

	delete channelTester;
	delete scheduler;
	delete playlist;
	delete sequence;

	return 0;
}
Exemplo n.º 12
0
void MainLoop(void)
{
	int            commandSock = 0;
	int            controlSock = 0;
	int            bridgeSock = 0;
	int            prevFPPstatus = FPPstatus;
	int            sleepms = 50000;
	fd_set         active_fd_set;
	fd_set         read_fd_set;
	struct timeval timeout;
	int            selectResult;

	LogDebug(VB_GENERAL, "MainLoop()\n");

	FD_ZERO (&active_fd_set);

	CheckExistanceOfDirectoriesAndFiles();

	piFaceSetup(200); // PiFace inputs 1-8 == wiringPi 200-207

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

	pluginCallbackManager.init();

	InitializeChannelOutputs();
	sequence->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();

		scheduler->CheckIfShouldBePlayingNow();

		if (getAlwaysTransmit())
			StartChannelOutputThread();
	}

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

	while (runMainFPPDLoop)
	{
		timeout.tv_sec  = 0;
		timeout.tv_usec = sleepms;

		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_GENERAL, "Main select() failed: %s\n",
					strerror(errno));
				runMainFPPDLoop = 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_GRACEFULLY))
			{
				if (prevFPPstatus == FPP_STATUS_IDLE)
				{
					playlist->PlayListPlayingInit();
					sleepms = 10000;
				}

				// 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_GRACEFULLY))
				{
					playlist->PlayListPlayingProcess();
				}
			}

			int reactivated = 0;
			if (FPPstatus == FPP_STATUS_IDLE)
			{
				if ((prevFPPstatus == FPP_STATUS_PLAYLIST_PLAYING) ||
					(prevFPPstatus == FPP_STATUS_STOPPING_GRACEFULLY))
				{
					playlist->PlayListPlayingCleanup();

					if (FPPstatus != FPP_STATUS_IDLE)
						reactivated = 1;
					else
						sleepms = 50000;
				}
			}

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

			scheduler->ScheduleProc();
		}
		else if (getFPPmode() == REMOTE_MODE)
		{
			if(mediaOutputStatus.status == MEDIAOUTPUTSTATUS_PLAYING)
			{
				playlist->PlaylistProcessMediaData();
			}
		}

		CheckGPIOInputs();
	}

	StopChannelOutputThread();
	ShutdownControlSocket();

	if (getFPPmode() == BRIDGE_MODE)
		Bridge_Shutdown();

	LogInfo(VB_GENERAL, "Main Loop complete, shutting down.\n");
}
Exemplo n.º 13
0
int Sequence::OpenSequenceFile(const char *filename, int startSeconds) {
	LogDebug(VB_SEQUENCE, "OpenSequenceFile(%s, %d)\n", filename, startSeconds);

	if (!filename || !filename[0])
	{
		LogErr(VB_SEQUENCE, "Empty Sequence Filename!\n", filename);
		return 0;
	}

	size_t bytesRead = 0;

	m_seqFileSize = 0;

	if (IsSequenceRunning())
		CloseSequenceFile();

	m_seqStarting = 1;
	m_seqPaused   = 0;
	m_seqDuration = 0;
	m_seqSecondsElapsed = 0;
	m_seqSecondsRemaining = 0;

	strcpy(m_seqFilename, filename);

	char tmpFilename[2048];
	unsigned char tmpData[2048];
	strcpy(tmpFilename,(const char *)getSequenceDirectory());
	strcat(tmpFilename,"/");
	strcat(tmpFilename, filename);

	if (getFPPmode() == REMOTE_MODE)
		CheckForHostSpecificFile(getSetting("HostName"), tmpFilename);

	if (!FileExists(tmpFilename))
	{
		LogErr(VB_SEQUENCE, "Sequence file %s does not exist\n", tmpFilename);
		m_seqStarting = 0;
		return 0;
	}

	m_seqFile = fopen((const char *)tmpFilename, "r");
	if (m_seqFile == NULL) 
	{
		LogErr(VB_SEQUENCE, "Error opening sequence file: %s. fopen returned NULL\n",
			tmpFilename);
		m_seqStarting = 0;
		return 0;
	}

	if (getFPPmode() == MASTER_MODE)
	{
		SendSeqSyncStartPacket(filename);

		// Give the remotes a head start spining up so they are ready
		usleep(100000);
	}

	///////////////////////////////////////////////////////////////////////
	// Check 4-byte File format identifier
	char seqFormatID[5];
	strcpy(seqFormatID, "    ");
	bytesRead = fread(seqFormatID, 1, 4, m_seqFile);
	seqFormatID[4] = 0;
	if ((bytesRead != 4) || (strcmp(seqFormatID, "PSEQ") && strcmp(seqFormatID, "FSEQ")))
	{
		LogErr(VB_SEQUENCE, "Error opening sequence file: %s. Incorrect File Format header: '%s', bytesRead: %d\n",
			filename, seqFormatID, bytesRead);

		fseek(m_seqFile, 0L, SEEK_SET);
		bytesRead = fread(tmpData, 1, DATA_DUMP_SIZE, m_seqFile);
		HexDump("Sequence File head:", tmpData, bytesRead);

		fclose(m_seqFile);
		m_seqFile = NULL;
		m_seqStarting = 0;
		return 0;
	}

	///////////////////////////////////////////////////////////////////////
	// Get Channel Data Offset
	bytesRead = fread(tmpData, 1, 2, m_seqFile);
	if (bytesRead != 2)
	{
		LogErr(VB_SEQUENCE, "Sequence file %s too short, unable to read channel data offset value\n", filename);

		fseek(m_seqFile, 0L, SEEK_SET);
		bytesRead = fread(tmpData, 1, DATA_DUMP_SIZE, m_seqFile);
		HexDump("Sequence File head:", tmpData, bytesRead);

		fclose(m_seqFile);
		m_seqFile = NULL;
		m_seqStarting = 0;
		return 0;
	}
	m_seqChanDataOffset = tmpData[0] + (tmpData[1] << 8);

	///////////////////////////////////////////////////////////////////////
	// Now that we know the header size, read the whole header in one shot
	fseek(m_seqFile, 0L, SEEK_SET);
	bytesRead = fread(tmpData, 1, m_seqChanDataOffset, m_seqFile);
	if (bytesRead != m_seqChanDataOffset)
	{
		LogErr(VB_SEQUENCE, "Sequence file %s too short, unable to read fixed header size value\n", filename);

		fseek(m_seqFile, 0L, SEEK_SET);
		bytesRead = fread(tmpData, 1, DATA_DUMP_SIZE, m_seqFile);
		HexDump("Sequence File head:", tmpData, bytesRead);

		fclose(m_seqFile);
		m_seqFile = NULL;
		m_seqStarting = 0;
		return 0;
	}

	m_seqVersionMinor = tmpData[6];
	m_seqVersionMajor = tmpData[7];
	m_seqVersion      = (m_seqVersionMajor * 256) + m_seqVersionMinor;

	m_seqFixedHeaderSize =
		(tmpData[8])        + (tmpData[9] << 8);

	m_seqStepSize =
		(tmpData[10])       + (tmpData[11] << 8) +
		(tmpData[12] << 16) + (tmpData[13] << 24);

	m_seqNumPeriods =
		(tmpData[14])       + (tmpData[15] << 8) +
		(tmpData[16] << 16) + (tmpData[17] << 24);

	m_seqStepTime =
		(tmpData[18])       + (tmpData[19] << 8);

	m_seqNumUniverses = 
		(tmpData[20])       + (tmpData[21] << 8);

	m_seqUniverseSize = 
		(tmpData[22])       + (tmpData[23] << 8);

	m_seqGamma         = tmpData[24];
	m_seqColorEncoding = tmpData[25];

	// End of v1.0 fields
	if (m_seqVersion > 0x0100)
	{
	}

	m_seqRefreshRate = 1000 / m_seqStepTime;

	fseek(m_seqFile, 0L, SEEK_END);
	m_seqFileSize = ftell(m_seqFile);
	m_seqDuration = (int)((float)(m_seqFileSize - m_seqChanDataOffset)
		/ ((float)m_seqStepSize * (float)m_seqRefreshRate));
	m_seqSecondsRemaining = m_seqDuration;
	fseek(m_seqFile, m_seqChanDataOffset, SEEK_SET);
	m_seqFilePosition = m_seqChanDataOffset;

	LogDebug(VB_SEQUENCE, "Sequence File Information\n");
	LogDebug(VB_SEQUENCE, "seqFilename           : %s\n", m_seqFilename);
	LogDebug(VB_SEQUENCE, "seqVersion            : %d.%d\n",
		m_seqVersionMajor, m_seqVersionMinor);
	LogDebug(VB_SEQUENCE, "seqFormatID           : %s\n", seqFormatID);
	LogDebug(VB_SEQUENCE, "seqChanDataOffset     : %d\n", m_seqChanDataOffset);
	LogDebug(VB_SEQUENCE, "seqFixedHeaderSize    : %d\n", m_seqFixedHeaderSize);
	LogDebug(VB_SEQUENCE, "seqStepSize           : %d\n", m_seqStepSize);
	LogDebug(VB_SEQUENCE, "seqNumPeriods         : %d\n", m_seqNumPeriods);
	LogDebug(VB_SEQUENCE, "seqStepTime           : %dms\n", m_seqStepTime);
	LogDebug(VB_SEQUENCE, "seqNumUniverses       : %d *\n", m_seqNumUniverses);
	LogDebug(VB_SEQUENCE, "seqUniverseSize       : %d *\n", m_seqUniverseSize);
	LogDebug(VB_SEQUENCE, "seqGamma              : %d *\n", m_seqGamma);
	LogDebug(VB_SEQUENCE, "seqColorEncoding      : %d *\n", m_seqColorEncoding);
	LogDebug(VB_SEQUENCE, "seqRefreshRate        : %d\n", m_seqRefreshRate);
	LogDebug(VB_SEQUENCE, "seqFileSize           : %lu\n", m_seqFileSize);
	LogDebug(VB_SEQUENCE, "seqDuration           : %d\n", m_seqDuration);
	LogDebug(VB_SEQUENCE, "'*' denotes field is currently ignored by FPP\n");

	m_seqPaused = 0;
	m_seqSingleStep = 0;
	m_seqSingleStepBack = 0;

	int frameNumber = 0;

	if (startSeconds)
	{
		int frameNumber = startSeconds * m_seqRefreshRate;
		int newPos = m_seqChanDataOffset + (frameNumber * m_seqStepSize);
		LogDebug(VB_SEQUENCE, "Seeking to byte %d in %s\n", newPos, m_seqFilename);

		fseek(m_seqFile, newPos, SEEK_SET);
	}

	ReadSequenceData();

	SetChannelOutputFrameNumber(frameNumber);

	SetChannelOutputRefreshRate(m_seqRefreshRate);
	StartChannelOutputThread();

	m_seqStarting = 0;

	return m_seqFileSize;
}
Exemplo n.º 14
0
int InitializeChannelOutputs(void) {
	Json::Value root;
	Json::Reader reader;
	int i = 0;

	channelOutputFrame = 0;

	for (i = 0; i < FPPD_MAX_CHANNEL_OUTPUTS; i++) {
		bzero(&channelOutputs[i], sizeof(channelOutputs[i]));
	}

	// Reset index so we can start populating the outputs array
	i = 0;

	if (FPDOutput.isConfigured())
	{
		channelOutputs[i].startChannel = getSettingInt("FPDStartChannelOffset");
		channelOutputs[i].outputOld = &FPDOutput;

		if (FPDOutput.open("", &channelOutputs[i].privData)) {
			channelOutputs[i].channelCount = channelOutputs[i].outputOld->maxChannels(channelOutputs[i].privData);

			i++;
		} else {
			LogErr(VB_CHANNELOUT, "ERROR Opening FPD Channel Output\n");
		}
	}

	if (((getFPPmode() != BRIDGE_MODE) ||
		 (getSettingInt("E131Bridging"))) &&
		(E131Output.isConfigured()))
	{
		channelOutputs[i].startChannel = 0;
		channelOutputs[i].outputOld  = &E131Output;

		if (E131Output.open("", &channelOutputs[i].privData)) {
			channelOutputs[i].channelCount = channelOutputs[i].outputOld->maxChannels(channelOutputs[i].privData);

			i++;
		} else {
			LogErr(VB_CHANNELOUT, "ERROR Opening E1.31 Channel Output\n");
		}
	}

	FILE *fp;
	char filename[1024];
	char buf[2048];

	// Parse the channeloutputs.json config file
	strcpy(filename, getMediaDirectory());
	strcat(filename, "/config/channeloutputs.json");

	LogDebug(VB_CHANNELOUT, "Loading %s\n", filename);

	if (FileExists(filename))
	{
		std::ifstream t(filename);
		std::stringstream buffer;

		buffer << t.rdbuf();

		std::string config = buffer.str();

		bool success = reader.parse(buffer.str(), root);
		if (!success)
		{
			LogErr(VB_CHANNELOUT, "Error parsing %s\n", filename);
			return 0;
		}

		const Json::Value outputs = root["channelOutputs"];
		std::string type;
		int start = 0;
		int count = 0;

		for (int c = 0; c < outputs.size(); c++)
		{
			type = outputs[c]["type"].asString();

			if (!outputs[c]["enabled"].asInt())
			{
				LogDebug(VB_CHANNELOUT, "Skipping Disabled Channel Output: %s\n", type.c_str());
				continue;
			}

			start = outputs[c]["startChannel"].asInt();
			count = outputs[c]["channelCount"].asInt();

			// internally we start channel counts at zero
			start -= 1;

			channelOutputs[i].startChannel = start;
			channelOutputs[i].channelCount = count;

			if (type == "LEDPanelMatrix") {
#if defined(PLATFORM_PI) || defined(PLATFORM_ODROID)
				if (outputs[c]["subType"] == "RGBMatrix")
					channelOutputs[i].output = new RGBMatrixOutput(start, count);
				else
				{
					LogErr(VB_CHANNELOUT, "%s subType not valid on Pi\n", outputs[c]["subType"].asString().c_str());
					continue;
				}
#endif
#ifdef PLATFORM_BBB
				if (outputs[c]["subType"] == "LEDscapeMatrix")
					channelOutputs[i].output = new LEDscapeMatrixOutput(start, count);
				else
				{
					LogErr(VB_CHANNELOUT, "%s subType not valid on BBB\n", outputs[c]["subType"].asString().c_str());
					continue;
				}
			} else if (type == "BBB48String") {
				channelOutputs[i].output = new BBB48StringOutput(start, count);
			} else if (type == "BBBSerial") {
				channelOutputs[i].output = new BBBSerialOutput(start, count);
#endif
#ifdef USEOLA
			} else if (type == "OLA") {
				channelOutputs[i].output = new OLAOutput(start, count);
#endif
			} else if (type == "USBRelay") {
				channelOutputs[i].output = new USBRelayOutput(start, count);
#if defined(PLATFORM_PI)
			} else if (type == "Hill320") {
				channelOutputs[i].output = new Hill320Output(start, count);
#endif
#ifdef USE_X11Matrix
			} else if (type == "X11Matrix") {
				channelOutputs[i].output = new X11MatrixOutput(start, count);
#endif
			} else {
				LogErr(VB_CHANNELOUT, "Unknown Channel Output type: %s\n", type.c_str());
				continue;
			}

			if (channelOutputs[i].output->Init(outputs[c])) {
				i++;
			} else {
				LogErr(VB_CHANNELOUT, "ERROR Opening %s Channel Output\n", type.c_str());
			}
		}
	}

	// Parse the channeloutputs config file
	strcpy(filename, getMediaDirectory());
	strcat(filename, "/channeloutputs");

	if (FileExists(filename))
	{
		LogDebug(VB_CHANNELOUT, "Loading %s\n", filename);

		fp = fopen(filename, "r");

		if (fp == NULL)
		{
			LogErr(VB_CHANNELOUT,
				"Could not open Channel Outputs config file %s: %s\n",
				filename, strerror(errno));
			channelOutputCount = 0;

			return 0;
		}

		while(fgets(buf, 2048, fp) != NULL)
		{
			int  enabled = 0;
			char type[32];
			int  start = 0;
			int  count = 0;
			char deviceConfig[160];

			if (buf[0] == '#') // Allow # comments for testing
				continue;

			int fields = sscanf(buf, "%d,%[^,],%d,%d,%s",
				&enabled, type, &start, &count, deviceConfig);

			if (fields != 5) {
				LogErr(VB_CHANNELOUT,
					"Invalid line in channeloutputs config file: %s\n", buf);
				continue;
			}

			if (!enabled) {
				LogDebug(VB_CHANNELOUT, "Skipping disabled channel output: %s", buf);
				continue;
			}

			if (count > (FPPD_MAX_CHANNELS - start)) {
				LogWarn(VB_CHANNELOUT,
					"Channel Output config, start (%d) + count (%d) exceeds max (%d) channel\n",
					start, count, FPPD_MAX_CHANNELS);

				count = FPPD_MAX_CHANNELS - start;

				LogWarn(VB_CHANNELOUT,
					"Count suppressed to %d for config line: %s\n", count, buf);
			}

			if (strlen(deviceConfig))
				strcat(deviceConfig, ";");

			strcat(deviceConfig, "type=");
			strcat(deviceConfig, type);

			LogDebug(VB_CHANNELOUT, "ChannelOutput: %d %s %d %d %s\n", enabled, type, start, count, deviceConfig);

			// internally we start channel counts at zero
			start -= 1;

			channelOutputs[i].startChannel = start;
			channelOutputs[i].channelCount = count;


			if ((!strcmp(type, "Pixelnet-Lynx")) ||
				(!strcmp(type, "Pixelnet-Open")))
			{
				channelOutputs[i].output = new USBPixelnetOutput(start, count);
			} else if ((!strcmp(type, "DMX-Pro")) ||
					   (!strcmp(type, "DMX-Open"))) {
				channelOutputs[i].output = new USBDMXOutput(start, count);
			} else if ((!strcmp(type, "VirtualMatrix")) ||
						(!strcmp(type, "FBMatrix"))) {
				channelOutputs[i].output = new FBMatrixOutput(start, count);
			} else if (!strcmp(type, "GPIO")) {
				channelOutputs[i].output = new GPIOOutput(start, count);
			} else if (!strcmp(type, "GenericSerial")) {
				channelOutputs[i].output = new GenericSerialOutput(start, count);
			} else if (!strcmp(type, "LOR")) {
				channelOutputs[i].outputOld = &LOROutput;
			} else if (!strcmp(type, "Renard")) {
				channelOutputs[i].outputOld = &USBRenardOutput;
#ifdef PLATFORM_PI
			} else if (!strcmp(type, "RPIWS281X")) {
				channelOutputs[i].output = new RPIWS281xOutput(start, count);
#endif
			} else if (!strcmp(type, "SPI-WS2801")) {
				channelOutputs[i].output = new SPIws2801Output(start, count);
			} else if (!strcmp(type, "SPI-nRF24L01")) {
				channelOutputs[i].outputOld = &SPInRF24L01Output;
			} else if (!strcmp(type, "Triks-C")) {
				channelOutputs[i].outputOld = &TriksCOutput;
			} else if (!strcmp(type, "GPIO-595")) {
				channelOutputs[i].output = new GPIO595Output(start, count);
			} else if (!strcmp(type, "Debug")) {
				channelOutputs[i].output = new DebugOutput(start, count);
			} else {
				LogErr(VB_CHANNELOUT, "Unknown Channel Output type: %s\n", type);
				continue;
			}

			if ((channelOutputs[i].outputOld) &&
				(channelOutputs[i].outputOld->open(deviceConfig, &channelOutputs[i].privData)))
			{
				if (channelOutputs[i].channelCount > channelOutputs[i].outputOld->maxChannels(channelOutputs[i].privData)) {
					LogWarn(VB_CHANNELOUT,
						"Channel Output config, count (%d) exceeds max (%d) channel for configured output\n",
						channelOutputs[i].channelCount, channelOutputs[i].outputOld->maxChannels(channelOutputs[i].privData));

					channelOutputs[i].channelCount = channelOutputs[i].outputOld->maxChannels(channelOutputs[i].privData);

					LogWarn(VB_CHANNELOUT,
						"Count suppressed to %d for config: %s\n", channelOutputs[i].channelCount, buf);
				}
				i++;
			} else if ((channelOutputs[i].output) &&
					   (channelOutputs[i].output->Init(deviceConfig))) {
				i++;
			} else {
				LogErr(VB_CHANNELOUT, "ERROR Opening %s Channel Output\n", type);
			}
		}
	}

	channelOutputCount = i;

	LogDebug(VB_CHANNELOUT, "%d Channel Outputs configured\n", channelOutputCount);

	LoadChannelRemapData();

	return 1;
}
Exemplo n.º 15
0
Arquivo: command.c Projeto: ihbar/fpp
char *ProcessCommand(char *command, char *response)
{
    char *s;
    char *s2;
    char *s3;
    char *s4;
    char *response2 = NULL;
    int i;
    char NextPlaylist[128] = "No playlist scheduled.";
    char NextScheduleStartText[64] = "";
    char CommandStr[64];
    LogExcess(VB_COMMAND, "CMD: %s\n", command);
    s = strtok(command,",");
    strcpy(CommandStr, s);
    if (!strcmp(CommandStr, "s")) {
        scheduler->GetNextScheduleStartText(NextScheduleStartText);
        scheduler->GetNextPlaylistText(NextPlaylist);
        if(FPPstatus==FPP_STATUS_IDLE) {
            if (getFPPmode() == REMOTE_MODE) {
                int secsElapsed = 0;
                int secsRemaining = 0;
                char seqFilename[1024];
                char mediaFilename[1024];

                if (sequence->IsSequenceRunning()) {
                    strcpy(seqFilename, sequence->m_seqFilename);
                    secsElapsed = sequence->m_seqSecondsElapsed;
                    secsRemaining = sequence->m_seqSecondsRemaining;
                } else {
                    strcpy(seqFilename, "");
                }

                if (mediaOutput) {
                    strcpy(mediaFilename, mediaOutput->m_mediaFilename.c_str());
                    secsElapsed = mediaOutputStatus.secondsElapsed;
                    secsRemaining = mediaOutputStatus.secondsRemaining;
                } else {
                    strcpy(mediaFilename, "");
                }

                sprintf(response,"%d,%d,%d,%s,%s,%d,%d\n",
                        getFPPmode(), 0, getVolume(), seqFilename,
                        mediaFilename, secsElapsed, secsRemaining);
            } else if (sequence->IsSequenceRunning()) {
                sprintf(response,"%d,%d,%d,,,%s,,0,0,%d,%d,%s,%s,0\n",
                        getFPPmode(),
                        1,
                        getVolume(),
                        sequence->m_seqFilename,
                        sequence->m_seqSecondsElapsed,
                        sequence->m_seqSecondsRemaining,
                        NextPlaylist,
                        NextScheduleStartText);
            } else {
                sprintf(response,"%d,%d,%d,%s,%s\n",getFPPmode(),0,getVolume(),NextPlaylist,NextScheduleStartText);
            }
        } else {
            Json::Value pl = playlist->GetInfo();
            if (pl["currentEntry"].isMember("dynamic"))
                pl["currentEntry"] = pl["currentEntry"]["dynamic"];

            if ((pl["currentEntry"]["type"] == "both") ||
                (pl["currentEntry"]["type"] == "media")) {
                //printf(" %s\n", pl.toStyledString().c_str());
                sprintf(response,"%d,%d,%d,%s,%s,%s,%s,%d,%d,%d,%d,%s,%s,%d\n",
                    getFPPmode(),
                    FPPstatus,
                    getVolume(),
                    pl["name"].asString().c_str(),
                    pl["currentEntry"]["type"].asString().c_str(),
                    pl["currentEntry"]["type"].asString() == "both" ? pl["currentEntry"]["sequence"]["sequenceName"].asString().c_str() : "",
                    pl["currentEntry"]["type"].asString() == "both"
                        ? pl["currentEntry"]["media"]["mediaFilename"].asString().c_str()
                        : pl["currentEntry"]["mediaFilename"].asString().c_str() ,
//							pl["currentEntry"]["entryID"].asInt() + 1,
                    playlist->GetPosition(),
                    pl["size"].asInt(),
                    pl["currentEntry"]["type"].asString() == "both"
                        ? pl["currentEntry"]["media"]["secondsElapsed"].asInt()
                        : pl["currentEntry"]["secondsElapsed"].asInt(),
                    pl["currentEntry"]["type"].asString() == "both"
                        ? pl["currentEntry"]["media"]["secondsRemaining"].asInt()
                        : pl["currentEntry"]["secondsRemaining"].asInt(),
                    NextPlaylist,
                    NextScheduleStartText,
                    pl["repeat"].asInt());
            } else if (pl["currentEntry"]["type"] == "sequence") {
                sprintf(response,"%d,%d,%d,%s,%s,%s,%s,%d,%d,%d,%d,%s,%s,%d\n",
                    getFPPmode(),
                    FPPstatus,
                    getVolume(),
                    pl["name"].asString().c_str(),
                    pl["currentEntry"]["type"].asString().c_str(),
                    pl["currentEntry"]["sequenceName"].asString().c_str(),
                    "",
//							pl["currentEntry"]["entryID"].asInt() + 1,
                    playlist->GetPosition(),
                    pl["size"].asInt(),
                    sequence->m_seqSecondsElapsed,
                    sequence->m_seqSecondsRemaining,
                    NextPlaylist,
                    NextScheduleStartText,
                    pl["repeat"].asInt());
            } else {
                sprintf(response,"%d,%d,%d,%s,%s,%s,%s,%d,%d,%d,%d,%s,%s,%d\n",
                    getFPPmode(),
                    FPPstatus,
                    getVolume(),
                    pl["name"].asString().c_str(),
                    pl["currentEntry"]["type"].asString().c_str(),
                    "",
                    "",
//							pl["currentEntry"]["entryID"].asInt() + 1,
                    playlist->GetPosition(),
                    pl["size"].asInt(),
                    pl["currentEntry"]["type"].asString() == "pause" ? pl["currentEntry"]["duration"].asInt() - pl["currentEntry"]["remaining"].asInt() : 0,
                    pl["currentEntry"]["type"].asString() == "pause" ? pl["currentEntry"]["remaining"].asInt() : 0,
                    NextPlaylist,
                    NextScheduleStartText,
                    pl["repeat"].asInt());
            }
        }
    } else if ((!strcmp(CommandStr, "P")) || (!strcmp(CommandStr, "p"))) {
        s = strtok(NULL,",");
        s2 = strtok(NULL,",");

        int entry = 0;
        if (s2 && s2[0])
            entry = atoi(s2);

        if (s)
        {
            int repeat = strcmp(CommandStr, "p") ? 0 : 1;
            int scheduledRepeat = 0;
            std::string playlistName = scheduler->GetPlaylistThatShouldBePlaying(scheduledRepeat);

            if ((playlistName == s) && (repeat == scheduledRepeat)) {
                // Use CheckIfShouldBePlayingNow() so the scheduler knows when
                // to stop the playlist
                scheduler->CheckIfShouldBePlayingNow(1);
                sprintf(response,"%d,%d,Playlist Started,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
            } else if (playlist->Play(s, entry, repeat, 0)) {
                FPPstatus = FPP_STATUS_PLAYLIST_PLAYING;
                sprintf(response,"%d,%d,Playlist Started,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
		    } else {
                sprintf(response,"%d,%d,Error Starting Playlist,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
            }
        } else {
            sprintf(response,"%d,%d,Unknown Playlist,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
        }
    } else if ((!strcmp(CommandStr, "S")) ||
               (!strcmp(CommandStr, "StopGracefully"))) {
        if (FPPstatus==FPP_STATUS_PLAYLIST_PLAYING) {
            playlist->StopGracefully(1);
            scheduler->ReLoadCurrentScheduleInfo();
            sprintf(response,"%d,%d,Playlist Stopping Gracefully,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
        } else {
            sprintf(response,"%d,Not playing,,,,,,,,,,,\n",COMMAND_FAILED);
        }
    } else if ((!strcmp(CommandStr, "d")) ||
               (!strcmp(CommandStr, "StopNow"))) {
        if (FPPstatus==FPP_STATUS_PLAYLIST_PLAYING || FPPstatus==FPP_STATUS_STOPPING_GRACEFULLY) {
            playlist->StopNow(1);
            scheduler->ReLoadCurrentScheduleInfo();
            sprintf(response,"%d,%d,Playlist Stopping Now,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
        } else if ((FPPstatus == FPP_STATUS_IDLE) &&
                   (sequence->IsSequenceRunning())) {
            sequence->CloseSequenceFile();
            sprintf(response,"%d,%d,Sequence Stopping Now,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
        } else {
            sprintf(response,"%d,%d,Not playing,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
        }
    } else if (!strcmp(CommandStr, "R")) {
        scheduler->ReLoadNextScheduleInfo();
        if (FPPstatus==FPP_STATUS_IDLE) {
            scheduler->ReLoadCurrentScheduleInfo();
            scheduler->CheckIfShouldBePlayingNow();
        }
        sprintf(response,"%d,%d,Reloading Schedule,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
    } else if (!strcmp(CommandStr, "v")) {
        s = strtok(NULL,",");
        if (s) {
            setVolume(atoi(s));
            sprintf(response,"%d,%d,Setting Volume,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
        } else {
            sprintf(response,"%d,%d,Invalid Volume,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
        }
    } else if (!strcmp(CommandStr, "q")) {
        // Quit/Shutdown fppd
        if ((FPPstatus == FPP_STATUS_PLAYLIST_PLAYING) ||
            (FPPstatus == FPP_STATUS_STOPPING_GRACEFULLY)) {
            playlist->StopNow(1);
            sleep(2);
        }

        ShutdownFPPD();

        sleep(1);
    } else if (!strcmp(CommandStr, "e")) {
        // Start an Effect
        s = strtok(NULL,",");
        s2 = strtok(NULL,",");
        s3 = strtok(NULL,",");
        if (s && s2) {
            i = StartEffect(s, atoi(s2), atoi(s3));
            if (i >= 0)
                sprintf(response,"%d,%d,Starting Effect,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i);
            else
                sprintf(response,"%d,%d,Invalid Effect,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
        } else
            sprintf(response,"%d,%d,Invalid Effect,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
    } else if (!strcmp(CommandStr, "t")) {
        // Trigger an event
        s = strtok(NULL,",");
        pluginCallbackManager.eventCallback(s, "command");
        i = TriggerEventByID(s);
        if (i >= 0)
            sprintf(response,"%d,%d,Event Triggered,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i);
        else
            sprintf(response,"%d,%d,Event Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
    } else if (!strcmp(CommandStr, "GetTestMode")) {
        strcpy(response, channelTester->GetConfig().c_str());
        strcat(response, "\n");
    } else if (!strcmp(CommandStr, "SetTestMode")) {
        if (channelTester->SetupTest(std::string(s + strlen(s) + 1)))
        {
            sprintf(response, "0,%d,Test Mode Activated,,,,,,,,,\n",
                COMMAND_SUCCESS);
        } else {
            sprintf(response, "0,%d,Test Mode Deactivated,,,,,,,,,\n",
                COMMAND_SUCCESS);
        }
    } else if (!strcmp(CommandStr, "LogLevel")) {
        s = strtok(NULL,",");

        if (SetLogLevel(s)) {
            sprintf(response,"%d,%d,Log Level Updated,%d,%d,,,,,,,,,\n",
                getFPPmode(),COMMAND_SUCCESS,logLevel,logMask);
        } else {
            sprintf(response,"%d,%d,Error Updating Log Level,%d,%d,,,,,,,,,\n",
                getFPPmode(),COMMAND_FAILED,logLevel,logMask);
        }
    } else if (!strcmp(CommandStr, "LogMask")) {
        s = strtok(NULL,",");

        if ((s && SetLogMask(s)) || SetLogMask("")) {
            sprintf(response,"%d,%d,Log Mask Updated,%d,%d,,,,,,,,,\n",
                getFPPmode(),COMMAND_SUCCESS,logLevel,logMask);
        } else {
            sprintf(response,"%d,%d,Error Updating Log Mask,%d,%d,,,,,,,,,\n",
                getFPPmode(),COMMAND_FAILED,logLevel,logMask);
        }
    } else if (!strcmp(CommandStr, "SetSetting")) {
        char name[128];

        s = strtok(NULL,",");
        if (s) {
            strcpy(name, s);
            s = strtok(NULL,",");
            if (s)
                parseSetting(name, s);
        }
    } else if (!strcmp(CommandStr, "StopAllEffects")) {
        StopAllEffects();
        sprintf(response,"%d,%d,All Effects Stopped,,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS);
    } else if (!strcmp(CommandStr, "StopEffectByName")) {
        s = strtok(NULL,",");
        if (strlen(s)) {
            if (StopEffect(s))
                sprintf(response,"%d,%d,Stopping Effect,%s,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,s);
            else
                sprintf(response,"%d,%d,Stop Effect Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
        }
    } else if (!strcmp(CommandStr, "StopEffect")) {
        s = strtok(NULL,",");
        i = atoi(s);
        if (StopEffect(i))
            sprintf(response,"%d,%d,Stopping Effect,%d,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,i);
        else
            sprintf(response,"%d,%d,Stop Effect Failed,,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED);
    } else if (!strcmp(CommandStr, "GetRunningEffects")) {
        sprintf(response,"%d,%d,Running Effects",getFPPmode(),COMMAND_SUCCESS);
        GetRunningEffects(response, &response2);
    } else if (!strcmp(CommandStr, "GetFPPDUptime")) {
        sprintf(response,"%d,%d,FPPD Uptime,%ld,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS, time(NULL) - fppdStartTime);
    } else if (!strcmp(CommandStr, "StartSequence")) {
        if ((FPPstatus == FPP_STATUS_IDLE) &&
            (!sequence->IsSequenceRunning())) {
            s = strtok(NULL,",");
            s2 = strtok(NULL,",");
            if (s && s2) {
                i = atoi(s2);
                sequence->OpenSequenceFile(s, 0, i);
            } else {
                LogDebug(VB_COMMAND, "Invalid command: %s\n", command);
            }
        } else {
            LogErr(VB_COMMAND, "Tried to start a sequence when a playlist or "
                    "sequence is already running\n");
        }
    } else if (!strcmp(CommandStr, "StopSequence")) {
        if ((FPPstatus == FPP_STATUS_IDLE) &&
            (sequence->IsSequenceRunning())) {
            sequence->CloseSequenceFile();
        } else {
            LogDebug(VB_COMMAND,
                "Tried to stop a sequence when no sequence is running\n");
        }
    } else if (!strcmp(CommandStr, "ToggleSequencePause")) {
        if ((sequence->IsSequenceRunning()) &&
            ((FPPstatus == FPP_STATUS_IDLE) ||
             ((FPPstatus != FPP_STATUS_IDLE) &&
              (playlist->GetInfo()["currentEntry"]["type"] == "sequence")))) {
            sequence->ToggleSequencePause();
        }
    } else if (!strcmp(CommandStr, "SingleStepSequence")) {
        if ((sequence->IsSequenceRunning()) &&
            (sequence->SequenceIsPaused()) &&
            ((FPPstatus == FPP_STATUS_IDLE) ||
             ((FPPstatus != FPP_STATUS_IDLE) &&
              (playlist->GetInfo()["currentEntry"]["type"] == "sequence")))) {
            sequence->SingleStepSequence();
        }
    } else if (!strcmp(CommandStr, "SingleStepSequenceBack")) {
        if ((sequence->IsSequenceRunning()) &&
            (sequence->SequenceIsPaused()) &&
            ((FPPstatus == FPP_STATUS_IDLE) ||
             ((FPPstatus != FPP_STATUS_IDLE) &&
              (playlist->GetInfo()["currentEntry"]["type"] == "sequence")))) {
            sequence->SingleStepSequenceBack();
        }
    } else if (!strcmp(CommandStr, "NextPlaylistItem")) {
        switch (FPPstatus)
        {
            case FPP_STATUS_IDLE:
                sprintf(response,"%d,%d,No playlist running\n",getFPPmode(),COMMAND_FAILED);
                break;
            case FPP_STATUS_PLAYLIST_PLAYING:
                sprintf(response,"%d,%d,Skipping to next playlist item\n",getFPPmode(),COMMAND_SUCCESS);
                playlist->NextItem();
                break;
            case FPP_STATUS_STOPPING_GRACEFULLY:
                sprintf(response,"%d,%d,Playlist is stopping gracefully\n",getFPPmode(),COMMAND_FAILED);
                break;
        }
    } else if (!strcmp(CommandStr, "PrevPlaylistItem")) {
        switch (FPPstatus) {
            case FPP_STATUS_IDLE:
                sprintf(response,"%d,%d,No playlist running\n",getFPPmode(),COMMAND_FAILED);
                break;
            case FPP_STATUS_PLAYLIST_PLAYING:
                sprintf(response,"%d,%d,Skipping to previous playlist item\n",getFPPmode(),COMMAND_SUCCESS);
                playlist->PrevItem();
                break;
            case FPP_STATUS_STOPPING_GRACEFULLY:
                sprintf(response,"%d,%d,Playlist is stopping gracefully\n",getFPPmode(),COMMAND_FAILED);
                break;
        }
    } else if (!strcmp(CommandStr, "SetupExtGPIO")) {
        // Configure the given GPIO to the given mode
        s = strtok(NULL,",");
        s2 = strtok(NULL,",");
        if (s && s2)
        {
            
            if (!SetupExtGPIO(atoi(s), s2))
            {
                sprintf(response, "%d,%d,Configuring GPIO,%d,%s,,,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,atoi(s),s2);
            } else {
                sprintf(response, "%d,%d,Configuring GPIO,%d,%s,,,,,,,,,\n",getFPPmode(),COMMAND_FAILED,atoi(s),s2);
            }
        }
    } else if (!strcmp(CommandStr, "ExtGPIO")) {
        s = strtok(NULL,",");
        s2 = strtok(NULL,",");
        s3 = strtok(NULL,",");
        if (s && s2 && s3)
        {
            i = ExtGPIO(atoi(s), s2, atoi(s3));
            if (i >= 0)
            {
                sprintf(response, "%d,%d,Setting GPIO,%d,%s,%d,%d,,,,,,,\n",getFPPmode(),COMMAND_SUCCESS,atoi(s),s2,atoi(s3),i);
            } else {
                sprintf(response, "%d,%d,Setting GPIO,%d,%s,%d,,,,,,,,\n",getFPPmode(),COMMAND_FAILED,atoi(s),s2,atoi(s3));
            }
        }
    } else {
        sprintf(response,"Invalid command: '%s'\n", CommandStr);
    }

    return response2;
}
Exemplo n.º 16
0
/*
 * Start a new effect offset at the specified channel number
 */
int StartEffect(const std::string &effectName, int startChannel, int loop)
{
	int   effectID = -1;
    int   frameTime = 50;
	LogInfo(VB_EFFECT, "Starting effect %s at channel %d\n", effectName.c_str(), startChannel);

    std::unique_lock<std::mutex> lock(effectsLock);
	if (effectCount >= MAX_EFFECTS) {
		LogErr(VB_EFFECT, "Unable to start effect %s, maximum number of effects already running\n", effectName.c_str());
		return effectID;
	}

    std::string filename = getEffectDirectory();
    filename += "/";
    filename += effectName;
    filename += ".eseq";

    FSEQFile *fseq = FSEQFile::openFSEQFile(filename);
	if (!fseq) {
		LogErr(VB_EFFECT, "Unable to open effect: %s\n", filename.c_str());
		return effectID;
	}
    V2FSEQFile *v2fseq = dynamic_cast<V2FSEQFile*>(fseq);
    if (!v2fseq) {
        delete fseq;
        LogErr(VB_EFFECT, "Effect file not a correct eseq file: %s\n", filename.c_str());
        return effectID;
    }

	if (v2fseq->m_sparseRanges.size() == 0){
		LogErr(VB_EFFECT, "eseq file must have at least one model range.");
        delete fseq;
		return effectID;
	}

	if (startChannel != 0) {
		// This will need to change if/when we support multiple models per file
        v2fseq->m_sparseRanges[0].first = startChannel - 1;
	}
    frameTime = v2fseq->getStepTime();
	effectID = GetNextEffectID();

	if (effectID < 0) {
		LogErr(VB_EFFECT, "Unable to start effect %s, unable to determine next effect ID\n", effectName.c_str());
        delete fseq;
		return effectID;
	}

	effects[effectID] = new FPPeffect;
	effects[effectID]->name = effectName;
	effects[effectID]->fp = v2fseq;
	effects[effectID]->loop = loop;
	effects[effectID]->background = 0;

	if (effectName == "background") {
		effects[effectID]->background = 1;
	} else if ((getFPPmode() == REMOTE_MODE) &&
			 (effectName.find("background_") == 0)) {
        std::string localFilename = "background_";
		localFilename += getSetting("HostName");

        if (localFilename == effectName) {
			effects[effectID]->background = 1;
        }
	}
	effectCount++;
    int tmpec = effectCount;
    lock.unlock();

	StartChannelOutputThread();
    
    if (!sequence->IsSequenceRunning()
        && tmpec == 1) {
        //first effect running, no sequence running, set the refresh rate
        //to the rate of the effect
        SetChannelOutputRefreshRate(1000 / frameTime);
    }


	return effectID;
}
Exemplo n.º 17
0
Arquivo: Player.cpp Projeto: dkulp/fpp
/*
 * Kick off the channel output thread
 */
int Player::StartChannelOutputThread(void)
{
	LogDebug(VB_PLAYER | VB_CHANNELOUT, "StartChannelOutputThread()\n");
	if (!ChannelOutputThreadIsRunning())
	{
		// Give a little time in case we were shutting down
		usleep(200000);
		if (ChannelOutputThreadIsRunning())
		{
			LogDebug(VB_PLAYER | VB_CHANNELOUT, "Channel Output thread is already running\n");
			return 1;
		}
	}

	int mediaOffsetInt = getSettingInt("mediaOffset");
	if (mediaOffsetInt)
		m_mediaOffset = (float)mediaOffsetInt * 0.001;
	else
		m_mediaOffset = 0.0;

	LogDebug(VB_PLAYER | VB_MEDIAOUT, "Using mediaOffset of %.3f\n", m_mediaOffset);

	int E131BridgingInterval = getSettingInt("E131BridgingInterval");

	if ((getFPPmode() == BRIDGE_MODE) && (E131BridgingInterval))
		m_defaultLightDelay = E131BridgingInterval * 1000;
	else
		m_defaultLightDelay = 1000000 / m_refreshRate;

	m_lightDelay = m_defaultLightDelay;

	m_runOutputThread = 1;
	int result = pthread_create(&m_outputThreadID, NULL, &ChannelOutputThread, this);

	if (result)
	{
		char msg[256];

		m_runOutputThread = 0;

		switch (result)
		{
			case EAGAIN: strcpy(msg, "Insufficient Resources");
				break;
			case EINVAL: strcpy(msg, "Invalid settings");
				break;
			case EPERM : strcpy(msg, "Invalid Permissions");
				break;
		}

		LogErr(VB_PLAYER | VB_CHANNELOUT, "ERROR creating channel output thread: %s\n", msg );
		return 0;
	}
	else
	{
		pthread_detach(m_outputThreadID);
	}

	// Wait for thread to start
	while (!ChannelOutputThreadIsRunning())
		usleep(10000);

	return 1;
}
Exemplo n.º 18
0
Arquivo: Player.cpp Projeto: dkulp/fpp
/*
 * Main loop in channel output thread
 */
void Player::RunChannelOutputThread(void)
{
	static long long lastStatTime = 0;
	long long startTime;
	long long sendTime;
	long long readTime;
	int onceMore = 0;
	struct timespec ts;
	int syncFrameCounter = 0;

	LogDebug(VB_PLAYER | VB_CHANNELOUT, "RunChannelOutputThread() starting\n");

	m_outputThreadIsRunning = 1;

	if ((getFPPmode() == REMOTE_MODE) &&
		(!IsEffectRunning()) &&
		(!UsingMemoryMapInput()) &&
		(!channelTester->Testing()) &&
		(!getAlwaysTransmit()))
	{
		// Sleep about 2 seconds waiting for the master
		int loops = 0;
		while ((m_masterFramesPlayed < 0) && (loops < 200))
		{
			usleep(10000);
			loops++;
		}

		// Stop playback if the master hasn't sent any sync packets yet
		if (m_masterFramesPlayed < 0)
			m_runOutputThread = 0;
	}

	StartOutputThreads();

	while (m_runOutputThread)
	{
		startTime = GetTime();

		pthread_mutex_lock(&m_sequenceLock);
		int runningSequences = m_sequence.size();

		if ((getFPPmode() == MASTER_MODE) && (runningSequences))
		{
			if (syncFrameCounter & 0x10)
			{
				// Send sync every 16 frames (use 16 to make the check simpler)
				syncFrameCounter = 1;

				for (int i = 0; i < m_sequence.size(); i++)
					SendSeqSyncPacket( m_sequence[i]->m_seqFilename,
						channelOutputFrame, mediaElapsedSeconds);
			}
			else
			{
				syncFrameCounter++;
			}
		}

		if (m_outputFrames)
		{
			if (getFPPmode() == BRIDGE_MODE)
			{
				memcpy(m_seqData, e131Data, FPPD_MAX_CHANNELS);
			}
			else
			{
				for (int i = 0; i < m_sequence.size(); i++)
					m_sequence[i]->OverlayNextFrame(m_seqData);
			}

			SendChannelData(m_seqData);
		}

		sendTime = GetTime();

		if ((getFPPmode() != BRIDGE_MODE) &&
			(runningSequences))
		{
			// Close any sequences that aren't open anymore
			for (int i = m_sequence.size() - 1; i >= 0; i--)
			{
				if (!m_sequence[i]->SequenceFileOpen())
				{
					Sequence *seq = m_sequence[i];
					m_sequence.erase(m_sequence.begin() + i);
					delete seq;
				}
			}

			runningSequences = m_sequence.size();

			// Loop through sequences pre-reading next frame of data
			for (int i = 0; i < m_sequence.size(); i++)
			{
				m_sequence[i]->ReadSequenceData();
			}
		}

		ProcessChannelData();

		readTime = GetTime();

		pthread_mutex_unlock(&m_sequenceLock);

		if ((runningSequences) ||
			(IsEffectRunning()) ||
			(UsingMemoryMapInput()) ||
			(channelTester->Testing()) ||
			(getAlwaysTransmit()) ||
			(getFPPmode() == BRIDGE_MODE))
		{
			onceMore = 1;

			if (startTime > (lastStatTime + 1000000)) {
				int sleepTime = m_lightDelay - (GetTime() - startTime);
				if (sleepTime < 0)
					sleepTime = 0;
				lastStatTime = startTime;
				LogDebug(VB_PLAYER | VB_CHANNELOUT,
					"Output Thread: Loop: %dus, Send: %lldus, Read: %lldus, Sleep: %dus, FrameNum: %ld\n",
					m_lightDelay, sendTime - startTime,
					readTime - sendTime, sleepTime, channelOutputFrame);
			}
		}
		else
		{
			m_lightDelay = m_defaultLightDelay;

			if (onceMore)
				onceMore = 0;
			else
				m_runOutputThread = 0;
		}

		// Calculate how long we need to nanosleep()
		ts.tv_sec = 0;
		ts.tv_nsec = (m_lightDelay - (GetTime() - startTime)) * 1000;
		nanosleep(&ts, NULL);
	}

	StopOutputThreads();

	m_outputThreadIsRunning = 0;

	LogDebug(VB_PLAYER | VB_CHANNELOUT, "RunChannelOutputThread() completed\n");

	pthread_exit(NULL);
}