Пример #1
0
	void Retry(std::string desc)
	{
		retryStack.push_back(desc);
		if(retryStack.size() > maxRetries){
			FlogW("Maximum number of retries reached, they were spent on:");

			int repeat = 0;
			std::string lastStr = "";

			for(auto str : retryStack){
				if(lastStr == str){
					repeat++;
				}else{
					if(repeat > 0)
						FlogW("(repeats " << repeat << " times)");

					FlogW(" * " << str);
					repeat = 0;
				}

				lastStr = str;
			}

			if(repeat > 0)
					FlogW("(repeats " << repeat << " times)");

			throw VideoException(VideoException::ERetries);
		}
	}
Пример #2
0
	FramePtr decodeUntilVideoFrame(){
		StreamFrameMap streamFrames;
		streamFrames[videoStream] = Frame::CreateEmpty();

		for(int i = 0; i < 100; i++){
			try {
				bool ret = decodeFrame(streamFrames);

				if(!ret){
					FlogW("failed to decode frame");
					return false;
				}

				// throw away any resulting frames
				if(streamFrames[videoStream]->finished != 0)
					return streamFrames[videoStream];
			}

			catch(VideoException e)
			{
				FlogW("While decoding video frame");
				FlogW(e.what());
			}

			Retry("not a video frame in decodeUntilVideoFrame()");
		}

		FlogD("couldn't find a video frame in 100 steps");
		return 0;
	}
Пример #3
0
int main(int argc, char** argv)
{
	Flog_Init("Testapp");

	Flog_AddTargetStream(stdout, Flog_SDebug1 |Flog_SDebug2 | Flog_SDebug3 | Flog_SVerbose | Flog_SInfo | Flog_SWarning, 1);
	Flog_AddTargetStream(stderr, Flog_SError | Flog_SFatal, 1);
	
	if( !Flog_AddTargetServer("localhost", Flog_DefaultPort, Flog_SAll) ){
		printf("couldn't connect to server\n");
		return 1;
	}

	std::string testString = "value";

	FlogExpD1(testString);

	FlogD1("debug level " << 1);
	FlogD2("debug level " << 2);
	FlogD3("debug level " << 3);
	FlogD("debug default level");
	FlogV("verbose");
	FlogI("info");
	FlogW("warning");
	FlogE("error");
	FlogF("fatal error");
	
	FlogAssert(argc == 1, "Not one arugment, exiting");
	FlogDie("DEATH");

	return 0;
}
Пример #4
0
	void HandleCommand(const Command& cmd)
	{
		switch(cmd.type){
			case CTPositionUpdate:
				if(showMessages){
					FlogD("position update: " << cmd.args[0].f);
				}
				break;
			
			case CTEof:
				FlogD("eof");
				break;
		
			case CTLogMessage:
				if(showMessages){
					FlogD("log message (" << cmd.args[0].i << "): " << Tools::WstrToStr(cmd.args[3].str));
				}
				break;
			
			case CTOutputPosition:
				FlogD("output position update: " << cmd.args[0].i << ", " 
					<< cmd.args[1].i << ", " << cmd.args[2].i << ", " << cmd.args[3].i);
				break;

			default:
				FlogW("unhandled command: " << (int)cmd.type);
				break;
		}
	}
Пример #5
0
	void HandleResponse(const Command& cmd)
	{
		switch(cmd.type){
			case CTGetBitmap:
				if(cmd.args[0].i == 1){
					FlogD("got bitmap: " << cmd.args[1].i << "x" << cmd.args[2].i << " " 
						<< cmd.args[3].buf.size() << " bytes");
				}else{
					FlogE("failed to get a bitmap");
				}
				break;

			case CTGetDimensions:
				FlogD("got video dimensions: success: " 
					<< cmd.args[0].i << ", " << cmd.args[1].i << " x " << cmd.args[2].i);
				break;

			default:
				FlogW("unhandled reponse, seq: " << cmd.seqNum << ", type: " << cmd.type);
				break;
		}
	}
Пример #6
0
	void ProcessMessages(PlatformPtr platform, IpcMessageQueuePtr hostQueue, bool waitReady, int timeout){
		for(auto& plugin : plugins){
			if(!plugin.started)
				continue;
		
			bool done = false;

			while(!done){
				bool ret = false;
				bool isRunning = true; // = false;
				const int period = 100;
				int deadSincePeriods = 0;
				
				for(int i = 0; i < timeout / period; i++){
					if(i > period * 10)
						FlogW("waiting for slow plugin: " << plugin.executable);

					ret = plugin.messageQueue->GetReadBuffer([&](const std::string& type, const char* buffer, size_t size){
						if(Tools::StartsWith(type, "results")){
							// results message, relay to host
							FlogD("relaying results from: " << plugin.executable);

							if(hostQueue->GetWriteQueueSize() >= (int)size){
								char* outBuffer = hostQueue->GetWriteBuffer();
								memcpy(outBuffer, buffer, size);
								hostQueue->ReturnWriteBuffer(Str(type << " " << plugin.name), &outBuffer, size);
							}else{
								hostQueue->WriteMessage(Str("error 0 " << plugin.name), "result too big for frameserver/host message queue");
								FlogW("result too big for frameserver/host message queue, plugin: " << plugin.executable << " " << plugin.name);
							}

							if(!waitReady)
								done = true;
						}

						else if(type == "status"){
							// plugin is ready for next frame
							// TODO actually check if the message says "ready"
							if(waitReady)
								done = true;
						}

						else if(Tools::StartsWith(type, "error")){
							// error
							FlogD("relaying error from: " << plugin.executable);
							done = true;
							plugin.started = false;
							hostQueue->WriteMessage(Str(type << " " << plugin.name), buffer);
						}
						
						else{
							// unknown
							FlogW("unknown message type: " << type << " from plugin: " << plugin.name);
							done = true;
							plugin.started = false;
						}
					}, period);

					// The deadSincePeriods counter exists to prevent a race condition where the frameserver queue read times out
					// because the plugin has acquired a buffer for writing a result. If the plugin then manages to terminate
					// before the process->IsRunning check in the frameserver, the reported result (or other message) would be ignored.

					// If the process has been dead the last 10 periods (1 is probably enough) we can safely assume that there are no
					// result messages in the queue waiting for us, and since the plugin process is dead, we can exit the loop.

					deadSincePeriods += plugin.process->IsRunning() ? 0 : 1;
					isRunning = deadSincePeriods < 10;

					if(ret || !isRunning)
						break;
				}


				if(!isRunning){
					// process exited
					hostQueue->WriteMessage(Str("error 0 " << plugin.name), "process exited");
					FlogW("process exited, plugin: " << plugin.executable << " " << plugin.name);

					plugin.started = false;
					break;
				}

				else if(!ret){
					// timeout occured
					hostQueue->WriteMessage(Str("error 0 " << plugin.name), "timeout while processing frames");
					FlogW("timeout, plugin: " << plugin.executable << " " << plugin.name);

					plugin.started = false;
					break;
				}
			}
		}
	}
Пример #7
0
	bool seekInternal(double t, int depth)
	{
		ResetRetries();
		emptyFrameQueue();
		audioHandler->clearQueue();

		int64_t firstTs = getFirstSeekTs();

		double backSeek = (double)depth * 2.0f + 1.0f;

		int64_t minTs = tsFromTime(t - backSeek - 2.5) + firstTs;
		int64_t ts = tsFromTime(t - backSeek) + firstTs;
		int64_t maxTs = tsFromTime(t - backSeek) + firstTs;

		// There is no discernible way to determine if negative timestamps are allowed
		// (or even required) to seek to low timestamps.
		// On some files you must seek to negative timestamps to be able to seek to 0
		// but on other files you get weird results from seeking to below 0.

		// So, every other try, we will allow seeking to negative timestamps.

		if((depth % 2) == 1){
			minTs = std::max((int64_t)0, minTs);
			ts = std::max((int64_t)0, minTs);
			maxTs = std::max((int64_t)0, minTs);
		}

		FlogD("Trying to seek to minTs: " << minTs << " ts: " << ts << " maxTs: " << maxTs << " with firsTs: " << firstTs);

		int flags = 0;
		
		if(ts < pFormatCtx->streams[videoStream]->cur_dts)
			flags |= AVSEEK_FLAG_BACKWARD;

		int seekRet = avformat_seek_file(pFormatCtx, videoStream, minTs, ts, maxTs, flags);

		if(seekRet > 0){
			FlogD("avformat_seek_file failed, returned " << seekRet);
			return false;
		}

		avcodec_flush_buffers(pCodecCtx);

		double newTime = t + timeFromTs(firstPts);
		double actualTime = skipToTs(newTime);

		// consider the seek failed and try again if the actual time diffs more than .5 seconds
		// from the desired new time. 
		
		FlogD("wanted to seek to " << newTime << " and ended up at " << actualTime);

		bool ret = true;

		if(fabsf(newTime - actualTime) > .5){
			if(depth < 5){
				FlogD("not good enough, trying again");
				return seekInternal(t, depth + 1);
			}
			else{
				ret = false;
				FlogW("seek failed, wanted to seek to " << newTime << " and ended up at " << actualTime);
			}
		}

		timeHandler->SetTime(actualTime);

		stepIntoQueue = true;

		audioHandler->onSeek();

		return ret;
	}