Ejemplo n.º 1
0
void BaseOutRecording::SignalAudioStreamCapabilitiesChanged(
		StreamCapabilities *pCapabilities, AudioCodecInfo *pOld,
		AudioCodecInfo *pNew) {
	if ((pOld == NULL)&&(pNew != NULL))
		return;
	WARN("Codecs changed and the recordings does not support it. Closing recording");
	if (pOld != NULL)
		FINEST("pOld: %s", STR(*pOld));
	if (pNew != NULL)
		FINEST("pNew: %s", STR(*pNew));
	else
		FINEST("pNew: NULL");
	EnqueueForDelete();
}
Ejemplo n.º 2
0
bool BaseVariantProtocol::SignalInputData(IOBuffer &buffer) {
	if (_pProtocolHandler == NULL) {
		FATAL("This protocol is not registered to any application yet");
		return false;
	}

	if (_pFarProtocol->GetType() == PT_OUTBOUND_HTTP
			|| _pFarProtocol->GetType() == PT_INBOUND_HTTP) {
#ifdef HAS_PROTOCOL_HTTP
		//1. This is a HTTP based transfer. We only start doing stuff
		//after a complete request is made.
		BaseHTTPProtocol *pHTTPProtocol = (BaseHTTPProtocol *) _pFarProtocol;
		if (!pHTTPProtocol->TransferCompleted())
			return true;

		if (!Deserialize(GETIBPOINTER(buffer), pHTTPProtocol->GetContentLength(),
				_lastReceived)) {
			FATAL("Unable to deserialize content");
			return false;
		}
		buffer.Ignore(pHTTPProtocol->GetContentLength());

		_lastReceived.Compact();

		return _pProtocolHandler->ProcessMessage(this, _lastSent, _lastReceived);
#else
		FATAL("HTTP protocol not supported");
		return false;
#endif /* HAS_PROTOCOL_HTTP */
	} else if (_pFarProtocol->GetType() == PT_TCP) {
		while (GETAVAILABLEBYTESCOUNT(buffer) > 4) {
			uint32_t size = ENTOHLP(GETIBPOINTER(buffer));
			if (size > 4 * 1024 * 1024) {
				FATAL("Size too big: %u", size);
				return false;
			}
			if (GETAVAILABLEBYTESCOUNT(buffer) < size + 4) {
				FINEST("Need more data");
				return true;
			}

			if (!Deserialize(GETIBPOINTER(buffer) + 4, size, _lastReceived)) {
				FATAL("Unable to deserialize variant");
				return false;
			}
			buffer.Ignore(size + 4);

			_lastReceived.Compact();

			if (!_pProtocolHandler->ProcessMessage(this, _lastSent, _lastReceived)) {
				FATAL("Unable to process message");
				return false;
			}
		}
		return true;
	} else {
		FATAL("Invalid protocol stack");
		return false;
	}
}
Ejemplo n.º 3
0
bool HTTP4CLIProtocol::SignalInputData(IOBuffer &buffer) {
	//1. Get the HTTP protocol. We are sure is a PT_INBOUND_HTTP
	//because we return true inside AllowFarProtocol only when type == PT_INBOUND_HTTP
	InboundHTTPProtocol *pHTTP = (InboundHTTPProtocol *) GetFarProtocol();

	//2. Get the request headers
	Variant headers = pHTTP->GetHeaders();

	//3. Populate the input buffer for the next protocol in the stack (PT_INBOUND_JSONCLI)
	//with the data we just found out inside the headers
	URI uri;
	string dummy = "http://localhost" + (string) headers[HTTP_FIRST_LINE][HTTP_URL];
	FINEST("dummy: %s",STR(dummy));
	if (!URI::FromString(dummy, false, uri)) {
		FATAL("Invalid request");
		return false;
	}
	string fullCommand=uri.document;
	fullCommand+=" ";
	if(uri.parameters.size()!=0){
		fullCommand+=unb64(MAP_VAL(uri.parameters.begin()));
	}
	fullCommand+="\n";
	_localInputBuffer.ReadFromString(fullCommand);

	//4. Call the next protocol with the new buffer
	return GetNearProtocol()->SignalInputData(_localInputBuffer);
}
Ejemplo n.º 4
0
void ProtocolManager::EnqueueForDelete(BaseProtocol *pProtocol) {
    if (pProtocol->GetNearProtocol() == NULL) {
        FINEST("Enqueue for delete for protocol %s", STR(*pProtocol));
    }
    pProtocol->SetApplication(NULL);
    if (MAP_HAS1(_activeProtocols, pProtocol->GetId()))
        _activeProtocols.erase(pProtocol->GetId());
    if (!MAP_HAS1(_deadProtocols, pProtocol->GetId()))
        _deadProtocols[pProtocol->GetId()] = pProtocol;
}
void BaseLiveFLVAppProtocolHandler::UnRegisterProtocol(BaseProtocol *pProtocol) {
	if (!MAP_HAS1(_protocols, pProtocol->GetId())) {
		ASSERT("Protocol ID %u not registered", pProtocol->GetId());
		return;
	}
	if (pProtocol->GetType() != PT_INBOUND_LIVE_FLV) {
		ASSERT("This protocol can't be unregistered here");
		return;
	}
	_protocols.erase(pProtocol->GetId());
	FINEST("protocol %s unregistered from app %s", STR(*pProtocol), STR(GetApplication()->GetName()));
}
void BaseLiveFLVAppProtocolHandler::RegisterProtocol(BaseProtocol *pProtocol) {
	if (MAP_HAS1(_protocols, pProtocol->GetId())) {
		ASSERT("Protocol ID %u already registered", pProtocol->GetId());
		return;
	}
	if (pProtocol->GetType() != PT_INBOUND_LIVE_FLV) {
		ASSERT("This protocol can't be registered here");
		return;
	}
	_protocols[pProtocol->GetId()] = (InboundLiveFLVProtocol *) pProtocol;
	FINEST("protocol %s registered to app %s", STR(*pProtocol), STR(GetApplication()->GetName()));
}
bool InNetLiveFLVStream::FeedData(uint8_t *pData, uint32_t dataLength,
		uint32_t processedLength, uint32_t totalLength,
		double pts, double dts, bool isAudio) {
	if (isAudio) {
		_stats.audio.packetsCount++;
		_stats.audio.bytesCount += dataLength;
		if ((!_audioCapabilitiesInitialized) && (processedLength == 0)) {
			if (!InNetRTMPStream::InitializeAudioCapabilities(this,
					_streamCapabilities, _audioCapabilitiesInitialized, pData,
					dataLength)) {
				FATAL("Unable to initialize audio capabilities");
				return false;
			}
		}
		_lastAudioTime = pts;
	} else {
		_stats.video.packetsCount++;
		_stats.video.bytesCount += dataLength;
		if ((!_videoCapabilitiesInitialized) && (processedLength == 0)) {
			if (!InNetRTMPStream::InitializeVideoCapabilities(this,
					_streamCapabilities, _videoCapabilitiesInitialized, pData,
					dataLength)) {
				FATAL("Unable to initialize audio capabilities");
				return false;
			}
		}
		_lastVideoPts = pts;
		_lastVideoDts = dts;
	}

	LinkedListNode<BaseOutStream *> *pTemp = _pOutStreams;
	while (pTemp != NULL) {
		if (!pTemp->info->IsEnqueueForDelete()) {
			if (!pTemp->info->FeedData(pData, dataLength, processedLength, totalLength,
					pts, dts, isAudio)) {
				FINEST("Unable to feed OS: %p", pTemp->info);
				pTemp->info->EnqueueForDelete();
				if (GetProtocol() == pTemp->info->GetProtocol()) {
					return false;
				}
			}
		}
		pTemp = pTemp->pPrev;
	}
	return true;
}
Ejemplo n.º 8
0
bool BaseInFileStream::SignalPlay(double &absoluteTimestamp, double &length) {

  INFO("signal play");
	//0. fix absoluteTimestamp and length
	absoluteTimestamp = absoluteTimestamp < 0 ? 0 : absoluteTimestamp;
	_playLimit = length;
	FINEST("absoluteTimestamp: %.2f; _playLimit: %.2f", absoluteTimestamp, _playLimit);
	//TODO: implement the limit playback

	//1. Seek to the correct point
	if (!InternalSeek(absoluteTimestamp)) {
		FATAL("Unable to seek to %.02f", absoluteTimestamp);
		return false;
	}

	//2. Put the stream in active mode
	_streamingState = FILE_STREAMING_STATE_PLAYING;

	//3. Start the feed reaction
	ReadyForSend();

	//4. Done
	return true;
}
Ejemplo n.º 9
0
void InFileRTMPStream::SignalOutStreamDetached(BaseOutStream *pOutStream) {
	FINEST("outbound stream %u detached from inbound stream %u",
			pOutStream->GetUniqueId(), GetUniqueId());
}
bool BaseVariantAppProtocolHandler::ProcessMessage(BaseVariantProtocol *pProtocol,
		Variant &lastSent, Variant &lastReceived) {
	FINEST("lastSent:\n%s", STR(lastSent.ToString()));
	FINEST("lastReceived:\n%s", STR(lastReceived.ToString()));
	return true;
}
Ejemplo n.º 11
0
bool Initialize() {
	Logger::Init();

	if ((bool)gRs.commandLine["arguments"]["--use-implicit-console-appender"]) {
		Variant dummy;
		dummy[CONF_LOG_APPENDER_NAME] = "implicit console appender";
		dummy[CONF_LOG_APPENDER_TYPE] = CONF_LOG_APPENDER_TYPE_CONSOLE;
		dummy[CONF_LOG_APPENDER_COLORED] = (bool)true;
		dummy[CONF_LOG_APPENDER_LEVEL] = (uint32_t) 6;
		ConsoleLogLocation * pLogLocation = new ConsoleLogLocation(dummy);
		pLogLocation->SetLevel(_FINEST_);
		Logger::AddLogLocation(pLogLocation);
	}

	INFO("Reading configuration from %s", STR(gRs.commandLine["arguments"]["configFile"]));
#ifdef COMPILE_STATIC
	gRs.pConfigFile = new ConfigFile(SpawnApplication, SpawnFactory);
#else
	gRs.pConfigFile = new ConfigFile(NULL, NULL);
#endif
	string configFilePath = gRs.commandLine["arguments"]["configFile"];
	string fileName;
	string extension;
	splitFileName(configFilePath, fileName, extension);

	if (lowerCase(extension) == "xml") {
		if (!gRs.pConfigFile->LoadXmlFile(configFilePath,
				(bool)gRs.commandLine["arguments"]["--daemon"])) {
			FATAL("Unable to load file %s", STR(configFilePath));
			return false;
		}
	} else if (lowerCase(extension) == "lua") {
#ifdef HAS_LUA
		if (!gRs.pConfigFile->LoadLuaFile(configFilePath,
				(bool)gRs.commandLine["arguments"]["--daemon"])) {
			FATAL("Unable to load file %s", STR(configFilePath));
			return false;
		}
#else
		fprintf(stdout, "Lua is not supported by the current build of the server\n");
		ASSERT("Lua is not supported by the current build of the server");
		return false;
#endif /* HAS_LUA */
	} else {
		FATAL("Invalid file format: %s", STR(configFilePath));
		return false;
	}

#ifndef WIN32
	if (gRs.pConfigFile->IsDaemon()) {
		if (!gRs.daemon) {
			INFO("Daemonize...");
			pid_t pid = fork();
			if (pid < 0) {
				FATAL("Unable to start as daemon. fork() failed");
				return false;
			}

			if (pid > 0) {
				if (gRs.commandLine["arguments"].HasKey("--pid"))
					WritePidFile(pid);
				return false;
			}

			FINEST("Create a new SID for the daemon");
			pid_t sid = setsid();
			if (sid < 0) {
				FATAL("Unable to start as daemon. setsid() failed");
				return false;
			}

			int fd = open("/dev/null", O_RDWR, 0);
			if (fd < 0) {
				FATAL("Unable to start as daemon. open(/dev/null) failed");
				return false;
			}
			(void) dup2(fd, STDIN_FILENO);
			(void) dup2(fd, STDOUT_FILENO);
			(void) dup2(fd, STDERR_FILENO);
			if (fd > 2) {
				(void) close(fd);
			}

			gRs.daemon = true;

			Logger::SignalFork();
		}
	}
#endif /* WIN32 */

	INFO("Configure logger");
	if (!gRs.pConfigFile->ConfigLogAppenders()) {
		FATAL("Unable to configure log appenders");
		return false;
	}

	INFO("%s", STR(Version::GetBanner()));

	INFO("Initialize I/O handlers manager: %s", NETWORK_REACTOR);
	IOHandlerManager::Initialize();

	INFO("Configure modules");
	if (!gRs.pConfigFile->ConfigModules()) {
		FATAL("Unable to configure modules");
		return false;
	}

	INFO("Plug in the default protocol factory");
	gRs.pProtocolFactory = new DefaultProtocolFactory();
	if (!ProtocolFactoryManager::RegisterProtocolFactory(gRs.pProtocolFactory)) {
		FATAL("Unable to register default protocols factory");
		return false;
	}

	INFO("Configure factories");
	if (!gRs.pConfigFile->ConfigFactories()) {
		FATAL("Unable to configure factories");
		return false;
	}

	INFO("Configure acceptors");
	if (!gRs.pConfigFile->ConfigAcceptors()) {
		FATAL("Unable to configure acceptors");
		return false;
	}

	INFO("Configure instances");
	if (!gRs.pConfigFile->ConfigInstances()) {
		FATAL("Unable to configure instances");
		return false;
	}

	INFO("Start I/O handlers manager: %s", NETWORK_REACTOR);
	IOHandlerManager::Start();

	INFO("Configure applications");
	if (!gRs.pConfigFile->ConfigApplications()) {
		FATAL("Unable to configure applications");
		return false;
	}

	INFO("Install the quit signal");
	installQuitSignal(QuitSignalHandler);

	return true;
}
Ejemplo n.º 12
0
bool InboundRTMPProtocol::PerformHandshake(IOBuffer &buffer) {
	switch (_rtmpState) {
		case RTMP_STATE_NOT_INITIALIZED:
		{
			if (GETAVAILABLEBYTESCOUNT(buffer) < 1537) {
				return true;
			}
			uint8_t handshakeType = GETIBPOINTER(buffer)[0];
			if (!buffer.Ignore(1)) {
				FATAL("Unable to ignore one byte");
				return false;
			}

			_currentFPVersion = ENTOHLP(GETIBPOINTER(buffer) + 4);

			switch (handshakeType) {
				case 3: //plain
				{
					return PerformHandshake(buffer, false);
				}
				case 6: //encrypted
				{
					return PerformHandshake(buffer, true);
				}
				default:
				{
					FATAL("Handshake type not implemented: %hhu", handshakeType);
					return false;
				}
			}
		}
		case RTMP_STATE_SERVER_RESPONSE_SENT:
		{
			if (GETAVAILABLEBYTESCOUNT(buffer) < 1536) {
				return true;
			} else {
				//ignore the client's last handshake part
				if (!buffer.Ignore(1536)) {
					FATAL("Unable to ignore inbound data");
					return false;
				}
				_handshakeCompleted = true;
				_rtmpState = RTMP_STATE_DONE;

				if (_pKeyIn != NULL && _pKeyOut != NULL) {
					//insert the RTMPE protocol in the current protocol stack
					BaseProtocol *pFarProtocol = GetFarProtocol();
					RTMPEProtocol *pRTMPE = new RTMPEProtocol(_pKeyIn, _pKeyOut);
					ResetFarProtocol();
					pFarProtocol->SetNearProtocol(pRTMPE);
					pRTMPE->SetNearProtocol(this);
					FINEST("New protocol chain: %s", STR(*pFarProtocol));

					//decrypt the leftovers
					RC4(_pKeyIn, GETAVAILABLEBYTESCOUNT(buffer),
							GETIBPOINTER(buffer),
							GETIBPOINTER(buffer));
				}

				return true;
			}
		}
		default:
		{
			FATAL("Invalid RTMP state: %d", _rtmpState);
			return false;
		}
	}
}
Ejemplo n.º 13
0
bool MonitorRTMPProtocol::ProcessBytes(IOBuffer &buffer) {
	while (true) {
		uint32_t availableBytesCount = GETAVAILABLEBYTESCOUNT(buffer);
		if (_selectedChannel < 0) {
			if (availableBytesCount < 1) {
				return true;
			} else {
				switch (GETIBPOINTER(buffer)[0]&0x3f) {
					case 0:
					{
						if (availableBytesCount < 2) {
							FINEST("Not enough data");
							return true;
						}
						_selectedChannel = 64 + GETIBPOINTER(buffer)[1];
						_channels[_selectedChannel].lastInHeaderType = GETIBPOINTER(buffer)[0] >> 6;
						buffer.Ignore(2);
						availableBytesCount -= 2;
						break;
					}
					case 1:
					{
						//						if (availableBytesCount < 3) {
						//							FINEST("Not enough data");
						//							return true;
						//						}
						//						_selectedChannel = GETIBPOINTER(buffer)[2]*256 + GETIBPOINTER(buffer)[1] + 64;
						//						_channels[_selectedChannel].lastInHeaderType = GETIBPOINTER(buffer)[0] >> 6;
						//						buffer.Ignore(3);
						//						availableBytesCount -= 3;
						//						break;
						FATAL("The server doesn't support channel ids bigger than 319");
						return false;
					};
					default:
					{
						_selectedChannel = GETIBPOINTER(buffer)[0]&0x3f;
						_channels[_selectedChannel].lastInHeaderType = GETIBPOINTER(buffer)[0] >> 6;
						buffer.Ignore(1);
						availableBytesCount -= 1;
						break;
					}
				}
			}
		}

		Channel &channel = _channels[_selectedChannel];
		Header &header = channel.lastInHeader;
		FINEST("header: %s", STR(header));

		if (channel.state == CS_HEADER) {
			if (!header.Read(_selectedChannel, channel.lastInHeaderType,
					buffer, availableBytesCount)) {
				FATAL("Unable to read header");
				return false;
			} else {
				if (!header.readCompleted)
					return true;

				if (H_SI(header) >= _maxStreamCount) {
					FATAL("%s", STR(header));
					FATAL("buffer:\n%s", STR(buffer));
					ASSERT("invalid stream index");
				}

				if (H_CI(header) >= _maxChannelsCount) {
					FATAL("%s", STR(header));
					FATAL("buffer:\n%s", STR(buffer));
					ASSERT("invalid channel index");
				}

				switch ((uint8_t) H_MT(header)) {
					case RM_HEADER_MESSAGETYPE_ABORTMESSAGE:
					case RM_HEADER_MESSAGETYPE_ACK:
					case RM_HEADER_MESSAGETYPE_AGGREGATE:
					case RM_HEADER_MESSAGETYPE_AUDIODATA:
					case RM_HEADER_MESSAGETYPE_CHUNKSIZE:
					case RM_HEADER_MESSAGETYPE_FLEX:
					case RM_HEADER_MESSAGETYPE_FLEXSHAREDOBJECT:
					case RM_HEADER_MESSAGETYPE_FLEXSTREAMSEND:
					case RM_HEADER_MESSAGETYPE_INVOKE:
					case RM_HEADER_MESSAGETYPE_NOTIFY:
					case RM_HEADER_MESSAGETYPE_PEERBW:
					case RM_HEADER_MESSAGETYPE_SHAREDOBJECT:
					case RM_HEADER_MESSAGETYPE_USRCTRL:
					case RM_HEADER_MESSAGETYPE_VIDEODATA:
					case RM_HEADER_MESSAGETYPE_WINACKSIZE:
					{
						break;
					}
					default:
					{
						FATAL("%s", STR(header));
						FATAL("buffer:\n%s", STR(buffer));
						ASSERT("invalid message type");
					}
				}
				channel.state = CS_PAYLOAD;
				switch (channel.lastInHeaderType) {
					case HT_FULL:
					{
						channel.lastInAbsTs = H_TS(header);
						break;
					}
					case HT_SAME_STREAM:
					case HT_SAME_LENGTH_AND_STREAM:
					{
						channel.lastInAbsTs += H_TS(header);
						break;
					}
					case HT_CONTINUATION:
					{
						if (channel.lastInProcBytes == 0) {
							channel.lastInAbsTs += H_TS(header);
						}
						break;
					}
				}
			}
		}

		if (channel.state == CS_PAYLOAD) {
			uint32_t tempSize = H_ML(header) - channel.lastInProcBytes;
			tempSize = (tempSize >= _inboundChunkSize) ? _inboundChunkSize : tempSize;
			uint32_t availableBytes = GETAVAILABLEBYTESCOUNT(buffer);
			if (tempSize > availableBytes)
				return true;
			channel.state = CS_HEADER;
			_selectedChannel = -1;
			switch (H_MT(header)) {
				case RM_HEADER_MESSAGETYPE_VIDEODATA:
				{
					if (H_SI(header) >= _maxStreamCount) {
						FATAL("Incorrect stream index");
						return false;
					}

					//FINEST("Video data");

					channel.lastInProcBytes += tempSize;
					if (H_ML(header) == channel.lastInProcBytes) {
						channel.lastInProcBytes = 0;
					}
					if (!buffer.Ignore(tempSize)) {
						FATAL("V: Unable to ignore %u bytes", tempSize);
						return false;
					}
					break;
				}
				case RM_HEADER_MESSAGETYPE_AUDIODATA:
				{
					if (H_SI(header) >= _maxStreamCount) {
						FATAL("Incorrect stream index");
						return false;
					}

					//FINEST("Audio data");

					channel.lastInProcBytes += tempSize;
					if (H_ML(header) == channel.lastInProcBytes) {
						channel.lastInProcBytes = 0;
					}
					if (!buffer.Ignore(tempSize)) {
						FATAL("A: Unable to ignore %u bytes", tempSize);
						return false;
					}
					break;
				}
				default:
				{
					channel.inputData.ReadFromInputBuffer(buffer, tempSize);
					channel.lastInProcBytes += tempSize;
					if (!buffer.Ignore(tempSize)) {
						FATAL("Unable to ignore %u bytes", tempSize);
						return false;
					}
					if (H_ML(header) == channel.lastInProcBytes) {
						channel.lastInProcBytes = 0;
						Variant msg;
						if (!_rtmpProtocolSerializer.Deserialize(header, channel.inputData, msg)) {
							FATAL("Unable to deserialize message");
							return false;
						}

						if ((uint8_t) VH_MT(msg) == RM_HEADER_MESSAGETYPE_CHUNKSIZE) {
							_inboundChunkSize = (uint32_t) msg[RM_CHUNKSIZE];
						}

						if ((uint8_t) VH_MT(msg) == RM_HEADER_MESSAGETYPE_ABORTMESSAGE) {
							uint32_t channelId = (uint32_t) msg[RM_ABORTMESSAGE];
							if (channelId >= _maxChannelsCount) {
								FATAL("Invalid channel id in reset message: %" PRIu32, channelId);
								return false;
							}
							o_assert(_channels[channelId].id == channelId);
							_channels[channelId].Reset();
						}

						if (GETAVAILABLEBYTESCOUNT(channel.inputData) != 0) {
							FATAL("Invalid message! We have leftovers: %u bytes",
									GETAVAILABLEBYTESCOUNT(channel.inputData));
							return false;
						}
					}
					break;
				}
			}
		}
	}
}
Ejemplo n.º 14
0
bool PushVariant(lua_State *pLuaState,
		Variant &variant, bool substituteNullables) {
	switch ((VariantType) variant) {
		case V_UNDEFINED:
		case V_NULL:
		{
			if (substituteNullables)
				lua_pushstring(pLuaState, VAR_NULL_VALUE);
			else
				lua_pushnil(pLuaState);
			return true;
			break;
		}
		case V_STRING:
		{
			lua_pushstring(pLuaState, STR(variant));
			return true;
			break;
		}
		case V_INT8:
		case V_INT16:
		case V_INT32:
		case V_INT64:
		case V_UINT8:
		case V_UINT16:
		case V_UINT32:
		case V_UINT64:
		case V_DOUBLE:
		{
			lua_pushnumber(pLuaState, (double) variant);
			return true;
			break;
		}
		case V_BOOL:
		{
			lua_pushboolean(pLuaState, (bool)variant);
			return true;
			break;
		}
		case V_TIMESTAMP:
		{
			struct tm tempTm = (struct tm) variant;

			lua_createtable(pLuaState, 0, 0);

			lua_pushstring(pLuaState, VAR_TYPE);
			lua_pushstring(pLuaState, VAR_TIMESTAMP);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_YEAR);
			lua_pushnumber(pLuaState, tempTm.tm_year + 1900);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_MONTH);
			lua_pushnumber(pLuaState, tempTm.tm_mon+1);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_DAY);
			lua_pushnumber(pLuaState, tempTm.tm_mday);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_HOUR);
			lua_pushnumber(pLuaState, tempTm.tm_hour);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_MIN);
			lua_pushnumber(pLuaState, tempTm.tm_min);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_SEC);
			lua_pushnumber(pLuaState, tempTm.tm_sec);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_ISDST);
			lua_pushboolean(pLuaState, false);
			lua_settable(pLuaState, -3);

			return true;
			break;
		}
		case V_DATE:
		{
			struct tm tempTm = (struct tm) variant;

			lua_createtable(pLuaState, 0, 0);

			lua_pushstring(pLuaState, VAR_TYPE);
			lua_pushstring(pLuaState, VAR_DATE);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_YEAR);
			lua_pushnumber(pLuaState, tempTm.tm_year + 1900);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_MONTH);
			lua_pushnumber(pLuaState, tempTm.tm_mon);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_DAY);
			lua_pushnumber(pLuaState, tempTm.tm_mday);
			lua_settable(pLuaState, -3);
			return true;
			break;
		}
		case V_TIME:
		{
			struct tm tempTm = (struct tm) variant;

			lua_createtable(pLuaState, 0, 0);

			lua_pushstring(pLuaState, VAR_TYPE);
			lua_pushstring(pLuaState, VAR_TIME);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_YEAR);
			lua_pushnumber(pLuaState, 1970);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_MONTH);
			lua_pushnumber(pLuaState, 1);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_DAY);
			lua_pushnumber(pLuaState, 1);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_HOUR);
			lua_pushnumber(pLuaState, tempTm.tm_hour);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_MIN);
			lua_pushnumber(pLuaState, tempTm.tm_min);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_SEC);
			lua_pushnumber(pLuaState, tempTm.tm_sec);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_ISDST);
			lua_pushboolean(pLuaState, false);
			lua_settable(pLuaState, -3);

			return true;
			break;
		}
		case V_TYPED_MAP:
		case V_MAP:
		{
			lua_createtable(pLuaState, 0, 0);

			if ((VariantType) variant == V_TYPED_MAP) {
				lua_pushstring(pLuaState, VAR_MAP_NAME);
				lua_pushstring(pLuaState, STR(variant.GetTypeName()));
				lua_settable(pLuaState, -3);
			}

			FOR_MAP(variant, string, Variant, i) {
				if (MAP_KEY(i).find(VAR_INDEX_VALUE) == 0) {
					string temp = MAP_KEY(i).substr(VAR_INDEX_VALUE_LEN,
							string::npos);
					char *error = NULL;
					double index = strtod(STR(temp), &error);
					if (error == STR(temp) + temp.size()) {
						lua_pushnumber(pLuaState, index);
					} else {
						lua_pushstring(pLuaState, STR(MAP_KEY(i)));
					}
				} else {
					lua_pushstring(pLuaState, STR(MAP_KEY(i)));
				}
				if (!PushVariant(pLuaState, MAP_VAL(i), true)) {
					FINEST("Unable to push primitive");
					return false;
				}
				lua_settable(pLuaState, -3);
			}
			return true;
			break;
		}
		default:
		{
			FATAL("Unknown type %hhu", (VariantType) variant);
			return false;
			break;
		}
	}
	return true;
}
Ejemplo n.º 15
0
bool BaseInFileStream::ResolveCompleteMetadata(Variant &metaData) {
	if ((bool)metaData[CONF_APPLICATION_EXTERNSEEKGENERATOR])
		return false;
	//1. Create the document
	BaseMediaDocument *pDocument = NULL;
	if (false) {

	}
#ifdef HAS_MEDIA_FLV
	else if (metaData[META_MEDIA_TYPE] == MEDIA_TYPE_FLV ||
			metaData[META_MEDIA_TYPE] == MEDIA_TYPE_LIVE_OR_FLV) {
		pDocument = new FLVDocument(metaData);
	}
#endif /* HAS_MEDIA_FLV */
#ifdef HAS_MEDIA_MP3
	else if (metaData[META_MEDIA_TYPE] == MEDIA_TYPE_MP3) {
		pDocument = new MP3Document(metaData);
	}
#endif /* HAS_MEDIA_MP3 */
#ifdef HAS_MEDIA_MP4
	else if (metaData[META_MEDIA_TYPE] == MEDIA_TYPE_MP4
			|| metaData[META_MEDIA_TYPE] == MEDIA_TYPE_M4A
			|| metaData[META_MEDIA_TYPE] == MEDIA_TYPE_M4V
			|| metaData[META_MEDIA_TYPE] == MEDIA_TYPE_MOV
			|| metaData[META_MEDIA_TYPE] == MEDIA_TYPE_F4V) {
		pDocument = new MP4Document(metaData);
	}
#endif /* HAS_MEDIA_MP4 */
#ifdef HAS_MEDIA_NSV
	else if (metaData[META_MEDIA_TYPE] == MEDIA_TYPE_NSV) {
		pDocument = new NSVDocument(metaData);
	}
#endif /* HAS_MEDIA_NSV */

	else {
		FATAL("File type not supported yet. Partial metadata:\n%s",
				STR(metaData.ToString()));
		return false;
	}

	//2. Process the document
	FINEST("Processing file %s", STR(metaData[META_SERVER_FULL_PATH]));
	if (!pDocument->Process()) {
		FATAL("Unable to process document");
		delete pDocument;
		if ((bool)metaData[CONF_APPLICATION_RENAMEBADFILES]) {
			moveFile(metaData[META_SERVER_FULL_PATH],
					(string) metaData[META_SERVER_FULL_PATH] + ".bad");
		} else {
			WARN("File %s will not be renamed",
					STR(metaData[META_SERVER_FULL_PATH]));
		}
		return false;
	}

	//3. Get the medatada
	metaData = pDocument->GetMetadata();

	//4. cleanup
	delete pDocument;

	//5. Done
	return true;
}
Ejemplo n.º 16
0
bool BaseInFileStream::Feed() {
	//1. Are we in paused state?
	if (_paused)
		return true;

	//2. First, send audio and video codecs
	if (!_audioVideoCodecsSent) {
		if (!SendCodecs()) {
			FATAL("Unable to send audio codec");
			return false;
		}
	}

	//2. Determine if the client has enough data on the buffer and continue
	//or stay put
	uint32_t elapsedTime = (uint32_t) (time(NULL) - _startFeedingTime);
	if ((int32_t) _totalSentTime - (int32_t) elapsedTime >= _clientSideBufferLength) {
		return true;
	}

	//3. Test to see if we have sent the last frame
	if (_currentFrameIndex >= _totalFrames) {
		FINEST("Done streaming file");
		_pOutStreams->info->SignalStreamCompleted();
		_paused = true;
		return true;
	}

	//FINEST("_totalSentTime: %.2f; _playLimit: %.2f", (double) _totalSentTime, _playLimit);
	if (_playLimit >= 0) {
		if (_playLimit < (double) _totalSentTime) {
			FINEST("Done streaming file");
			_pOutStreams->info->SignalStreamCompleted();
			_paused = true;
			return true;
		}
	}

	//4. Read the current frame from the seeking file
	if (!_pSeekFile->SeekTo(_framesBaseOffset + _currentFrameIndex * sizeof (MediaFrame))) {
		FATAL("Unablt to seek inside seek file");
		return false;
	}
	if (!_pSeekFile->ReadBuffer((uint8_t *) & _currentFrame, sizeof (_currentFrame))) {
		FATAL("Unable to read frame from seeking file");
		return false;
	}

	//5. Take care of metadata
	if (_currentFrame.type == MEDIAFRAME_TYPE_DATA) {
		_currentFrameIndex++;
		if (!FeedMetaData(_pFile, _currentFrame)) {
			FATAL("Unable to feed metadata");
			return false;
		}
		return Feed();
	}

	//6. get our hands on the correct buffer, depending on the frame type: audio or video
	IOBuffer &buffer = _currentFrame.type == MEDIAFRAME_TYPE_AUDIO ? _audioBuffer : _videoBuffer;

	//7. Build the frame
	if (!BuildFrame(_pFile, _currentFrame, buffer)) {
		FATAL("Unable to build the frame");
		return false;
	}

	//8. Compute the timestamp
	_totalSentTime = (uint32_t) (_currentFrame.absoluteTime / 1000) - _totalSentTimeBase;

	//9. Do the feedeng
	if (!_pOutStreams->info->FeedData(
			GETIBPOINTER(buffer), //pData
			GETAVAILABLEBYTESCOUNT(buffer), //dataLength
			0, //processedLength
			GETAVAILABLEBYTESCOUNT(buffer), //totalLength
			(uint32_t) _currentFrame.absoluteTime, //absoluteTimestamp
			_currentFrame.type == MEDIAFRAME_TYPE_AUDIO //isAudio
			)) {
		FATAL("Unable to feed audio data");
		return false;
	}

	//10. Discard the data
	buffer.IgnoreAll();


	//11. Increment the frame index
	_currentFrameIndex++;

	//12. Done. We either feed again if frame length was 0
	//or just return true
	if (_currentFrame.length == 0) {
		return Feed();
	} else {
		return true;
	}
}
Ejemplo n.º 17
0
bool PushVariant(lua_State *pLuaState,
		Variant &variant, bool substituteNullables) {
	switch ((VariantType) variant) {
		case V_UNDEFINED:
		case V_NULL:
		{
			if (substituteNullables)
				lua_pushstring(pLuaState, VAR_NULL_VALUE);
			else
				lua_pushnil(pLuaState);
			return true;
			break;
		}
		case V_STRING:
		{
			lua_pushstring(pLuaState, STR(variant));
			return true;
			break;
		}
		case V_INT8:
		case V_INT16:
		case V_INT32:
		case V_INT64:
		case V_UINT8:
		case V_UINT16:
		case V_UINT32:
		case V_UINT64:
		case V_DOUBLE:
		{
			lua_pushnumber(pLuaState, (double) variant);
			return true;
			break;
		}
		case V_BOOL:
		{
			lua_pushboolean(pLuaState, (bool)variant);
			return true;
			break;
		}
		case V_TIMESTAMP:
		{
			struct tm tempTm = (struct tm) variant;

			lua_createtable(pLuaState, 0, 0);

			lua_pushstring(pLuaState, VAR_TYPE);
			lua_pushstring(pLuaState, VAR_TIMESTAMP);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_YEAR);
			lua_pushnumber(pLuaState, tempTm.tm_year + 1900);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_MONTH);
			lua_pushnumber(pLuaState, tempTm.tm_mon + 1);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_DAY);
			lua_pushnumber(pLuaState, tempTm.tm_mday);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_HOUR);
			lua_pushnumber(pLuaState, tempTm.tm_hour + 1);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_MIN);
			lua_pushnumber(pLuaState, tempTm.tm_min);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_SEC);
			lua_pushnumber(pLuaState, tempTm.tm_sec);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_ISDST);
			lua_pushboolean(pLuaState, false);
			lua_settable(pLuaState, -3);

			return true;
			break;
		}
		case V_DATE:
		{
			struct tm tempTm = (struct tm) variant;

			lua_createtable(pLuaState, 0, 0);

			lua_pushstring(pLuaState, VAR_TYPE);
			lua_pushstring(pLuaState, VAR_DATE);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_YEAR);
			lua_pushnumber(pLuaState, tempTm.tm_year + 1900);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_MONTH);
			lua_pushnumber(pLuaState, tempTm.tm_mon + 1);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_DAY);
			lua_pushnumber(pLuaState, tempTm.tm_mday);
			lua_settable(pLuaState, -3);
			return true;
			break;
		}
		case V_TIME:
		{
			struct tm tempTm = (struct tm) variant;

			lua_createtable(pLuaState, 0, 0);

			lua_pushstring(pLuaState, VAR_TYPE);
			lua_pushstring(pLuaState, VAR_TIME);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_YEAR);
			lua_pushnumber(pLuaState, 1970);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_MONTH);
			lua_pushnumber(pLuaState, 1);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_DAY);
			lua_pushnumber(pLuaState, 1);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_HOUR);
			lua_pushnumber(pLuaState, tempTm.tm_hour + 1);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_MIN);
			lua_pushnumber(pLuaState, tempTm.tm_min);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_SEC);
			lua_pushnumber(pLuaState, tempTm.tm_sec);
			lua_settable(pLuaState, -3);

			lua_pushstring(pLuaState, VAR_ISDST);
			lua_pushboolean(pLuaState, false);
			lua_settable(pLuaState, -3);

			return true;
			break;
		}
		case V_TYPED_MAP:
		case V_MAP:
		{
			lua_createtable(pLuaState, 0, 0);

			if ((VariantType) variant == V_TYPED_MAP) {
				lua_pushstring(pLuaState, VAR_MAP_NAME);
				lua_pushstring(pLuaState, STR(variant.GetTypeName()));
				lua_settable(pLuaState, -3);
			}

			FOR_MAP(variant, string, Variant, i) {
				const char *pKey = MAP_KEY(i).c_str();
				if ((MAP_KEY(i).length() == 10) && (pKey[0] == '0')
						&& (pKey[1] == 'x')) {
					uint32_t index = (uint32_t) strtol(pKey, NULL, 16);
					lua_pushnumber(pLuaState, index);
				} else {
					lua_pushstring(pLuaState, pKey);
				}
				if (!PushVariant(pLuaState, MAP_VAL(i), true)) {
					FINEST("Unable to push primitive");
					return false;
				}
				lua_settable(pLuaState, -3);
			}
			return true;
			break;
		}
		default:
		{
			FATAL("Unknown type %d", (VariantType) variant);
			return false;
			break;
		}
	}
}