Пример #1
0
void runAsClient() {
    timeStampServerLast = Thread::getTimeStampMs();

    ThroughputReceiver tpRcvr;
	DiscoveryTimeGreeter discGreeter;

	reporter = Publisher("reports");
	reporter.setGreeter(&discGreeter);

	Subscriber tcpSub("throughput.tcp");
	tcpSub.setReceiver(&tpRcvr);

	SubscriberConfigMCast mcastConfig("throughput.mcast");
	mcastConfig.setMulticastIP("224.1.2.3");
	mcastConfig.setMulticastPortbase(22022);
	Subscriber mcastSub(&mcastConfig);
	mcastSub.setReceiver(&tpRcvr);

	SubscriberConfigRTP rtpConfig("throughput.rtp");
	//		rtpConfig.setPortbase(40042);
	Subscriber rtpSub(&rtpConfig);
	rtpSub.setReceiver(&tpRcvr);

	node.addSubscriber(tcpSub);
	node.addSubscriber(mcastSub);
	node.addSubscriber(rtpSub);
	node.addPublisher(reporter);

	disc.add(node);
	timeStampStartedPublishing = Thread::getTimeStampMs();

	// do nothing here, we reply only when we received a message
	while(true) {
#if 0
		Thread::sleepMs(1000);
#else
		// disconnect / reconnect client on key-press
		getchar();
		node.removeSubscriber(tcpSub);
		node.removeSubscriber(mcastSub);
		node.removeSubscriber(rtpSub);
		node.removePublisher(reporter);
		disc.remove(node);

		getchar();
		disc.add(node);
		node.addSubscriber(tcpSub);
		node.addSubscriber(mcastSub);
		node.addSubscriber(rtpSub);
		node.addPublisher(reporter);

#endif
	}
}
Пример #2
0
void runAsServer() {
	ThroughputGreeter tpGreeter;
	
	Publisher pub;
	switch (type) {
		case PUB_RTP: {
			PublisherConfigRTP config("throughput.rtp");
			config.setTimestampIncrement(166);
			pub = Publisher(&config);
			pub.setGreeter(&tpGreeter);
			break;
		}
		case PUB_MCAST: {
			PublisherConfigMCast config("throughput.mcast");
			config.setTimestampIncrement(166);
			//			config.setPortbase(42142);
			pub = Publisher(&config);
			pub.setGreeter(&tpGreeter);
			break;
		}
		case PUB_TCP: {
			pub = Publisher("throughput.tcp");
			pub.setGreeter(&tpGreeter);
			break;
		}
	}
	
	node.addPublisher(pub);
	
	disc.add(node);
	timeStampStartedAt = Thread::getTimeStampMs();
	
	if (duration > 0)
		duration *= 1000; // convert to ms
	
	pub.waitForSubscribers(waitForSubs);
	
	// reserve 20 bytes for timestamp, sequence number and report interval
	size_t dataSize = (std::max)(mtu, (size_t)20);
	char* data = (char*)malloc(dataSize);
	Message* msg = NULL;
	if (useZeroCopy) {
		msg = new Message(data, dataSize, doneCallback, (void*)NULL);
	} else {
		msg = new Message();
	}
	
	uint64_t lastReportAt = Thread::getTimeStampMs();

	while(1) {
		uint64_t now = Thread::getTimeStampMs();
		
		if (duration > 0 && now - timeStampStartedAt > duration)
			break;
		
		// first 16 bytes are seqNr and timestamp
		Message::write(&data[0], ++currSeqNr);
		Message::write(&data[8], now);
		Message::write(&data[16], reportInterval);
		
		if (!useZeroCopy) {
			msg->setData(data, dataSize);
		}
		
		pub.send(msg);
		
		intervalFactor = 1000.0 / (double)reportInterval;
		bytesWritten += dataSize;
		bytesTotal += dataSize;
		packetsWritten++;
		
		// sleep just enough to reach the desired bps
		{
			RScopeLock lock(mutex);
			size_t packetsPerSecond = (std::max)(bytesPerSecond / dataSize, (size_t)1);
			delay = (std::max)((1000000) / (packetsPerSecond), (size_t)1);
		}
		
		// every report interval we are recalculating bandwith
		if (now - lastReportAt > reportInterval) {
			RScopeLock lock(mutex);
			
			std::string scaleInfo("--");
			// and recalculate bytes to send
			if (reports.size() > 0) {
				double decreasePressure = 0;
				
				// print report messages
				std::map<std::string, Report>::iterator repIter = reports.begin();
				
				// bandwidth is not fixed
				if (fixedBytesPerSecond == 0) {
					while(repIter != reports.end()) {
						const Report& report = repIter->second;
						double reportPressure = 0;
						
						// see if we need to decrease bandwidth
						if (report.pktsLate > packetsWritten / 2) {
							// client is lagging more than half a second, scale back somewhat
							reportPressure = (std::max)(1.1, reportPressure);
						}
						if (report.pcntLoss > pcntLossOk) {
							// we lost packages, scale back somewhat
							reportPressure = (std::max)((double)report.pktsDropped / report.pktsRcvd, reportPressure);
							reportPressure = (std::min)(reportPressure, 1.4);
						}
						if (report.pktsLate > 3 * packetsWritten) {
							// queues explode! scale back alot!
							reportPressure = (std::max)((double)report.pktsLate / packetsWritten, reportPressure);
							reportPressure = (std::min)(reportPressure, 2.0);
						}
						
						if (reportPressure > decreasePressure)
							decreasePressure = reportPressure;
						
						repIter++;
					}
					
					if (decreasePressure > 1) {
						bytesPerSecond *= (1.0 / decreasePressure);
						bytesPerSecond = (std::max)(bytesPerSecond, (size_t)(1024));
						scaleInfo = "down " + toStr(1.0 / decreasePressure);
					} else {
						bytesPerSecond *= 1.2;
						scaleInfo = "up 1.2";
					}
					std::cout << std::endl;
				} else {
					
					if (bytesWritten * intervalFactor < fixedBytesPerSecond) {
						bytesPerSecond *= 1.05;
					} else if (bytesWritten * intervalFactor > fixedBytesPerSecond)  {
						bytesPerSecond *= 0.95;
					}
				}
			}
			currReportNr++;

			writeReports(scaleInfo);

			bytesWritten = 0;
			packetsWritten = 0;
			
			lastReportAt = Thread::getTimeStampMs();
		}

		// now we sleep until we have to send another packet
		Thread::sleepUs(delay);
	}
	
	pub.setGreeter(NULL);
	delete(msg);
}
Пример #3
0
void runAsServer() {
	ThroughputGreeter tpGreeter;

	Publisher pub;
	PublisherConfig* config = NULL;

	switch (type) {
	case PUB_RTP: {
		config = new PublisherConfigRTP("throughput.rtp");
		((PublisherConfigRTP*)config)->setTimestampIncrement(166);
		break;
	}
	case PUB_MCAST: {
		config = new PublisherConfigMCast("throughput.mcast");
		((PublisherConfigMCast*)config)->setTimestampIncrement(166);
		//			config.setPortbase(42142);
		break;
	}
	case PUB_TCP: {
		config = new PublisherConfigTCP ("throughput.tcp");
		break;
	}
	}
	if (compressionType.size() != 0)
		config->enableCompression(compressionType, compressionWithState, compressionLevel, compressionRefreshInterval);

	pub = Publisher(config);
	pub.setGreeter(&tpGreeter);
	delete config;

	node.addPublisher(pub);

	disc.add(node);
    timeStampStartedDiscovery = Thread::getTimeStampMs();

	if (duration > 0)
		duration *= 1000; // convert to ms

    // open file with data
    std::ifstream fin(streamFile, std::ios::in | std::ios::binary);
    if (fin) {
        // streamFile exists on filesyste,, slurp content into streamData
        streamData = std::string((std::istreambuf_iterator<char>(fin) ),
                                 (std::istreambuf_iterator<char>()     ));
    } else {
        // stream file is no actual file, interpret as "size:compressability"
        char* compArg = streamFile;
        
        // http://stackoverflow.com/a/53878/990120
        std::list<std::string> compArgs;
        do {
            const char *begin = compArg;
            while(*compArg != ':' && *compArg)
                compArg++;
            compArgs.push_back(std::string(begin, compArg - begin));
        } while(0 != *compArg++);

        size_t streamDataSize = 0;
        double compressibility = 50;

        if (compArgs.size() < 1)
            printUsageAndExit();
        
        streamDataSize = displayToBytes(compArgs.front());
        compArgs.pop_front();
        
        if (!compArgs.empty()) {
            compressibility = strTo<double>(compArgs.front());
            if (toStr(compressibility) != compArgs.front())
                printUsageAndExit();
            compArgs.pop_front();
        }
        
        if (!compArgs.empty()) {
            printUsageAndExit();
        }
        
        streamData.resize(streamDataSize);
        RDG_genBuffer(&streamData[0], streamDataSize, 1 - (compressibility/(double)100), 0.0, 0);
    }
    
    {
        // determine compressionActualRatio
        Message msg(streamData.data(), streamData.size());
        size_t compressMaxPayload = msg.getCompressBounds("lz4", NULL, Message::Compression::PAYLOAD);
        char* compressPayloadData = (char*)malloc(compressMaxPayload);
        
        size_t compressActualPayload = msg.compress("lz4", NULL, compressPayloadData, compressMaxPayload, Message::Compression::PAYLOAD);
        compressionActualRatio = 100 * ((double)compressActualPayload / streamData.size());
    }
    
    pub.waitForSubscribers(waitForSubs);
    timeStampStartedPublishing = Thread::getTimeStampMs();

    uint64_t lastReportAt = Thread::getTimeStampMs();
    size_t streamDataOffset = 0;

	while(1) {
        
        // fill data from stream data
        Message* msg = new Message((char*)malloc(mtu), mtu);

        size_t msgDataOffset = 0;
        while(true) {
            size_t toRead = (mtu - msgDataOffset <= streamData.size() - streamDataOffset ? mtu - msgDataOffset : streamData.size() - streamDataOffset);
            memcpy(&msg->data()[msgDataOffset], &streamData[streamDataOffset], toRead);
            msgDataOffset += toRead;
            streamDataOffset += toRead;
//            UM_LOG_WARN("%d: %d / %d", streamData.size(), msgDataOffset, streamDataOffset);
            if (msgDataOffset == mtu)
                break;
            if (streamData.size() == streamDataOffset)
                streamDataOffset = 0;
        }
//        UM_LOG_WARN("%d: %s", msg->size(), md5(msg->data(), msg->size()).c_str());
        
		uint64_t now = Thread::getTimeStampMs();
		if (duration > 0 && now - timeStampStartedPublishing > duration)
			break;

		// first 16 bytes are seqNr and timestamp
		Message::write(&msg->data()[0], ++currSeqNr);
		Message::write(&msg->data()[8], now);
		Message::write(&msg->data()[16], reportInterval);

//        msg->putMeta("md5", md5(msg->data(), msg->size()));
		intervalFactor = 1000.0 / (double)reportInterval;
		bytesWritten += msg->size();
		bytesTotal += msg->size();
		packetsWritten++;

		// sleep just enough to reach the desired bps
		{
			RScopeLock lock(mutex);
			size_t packetsPerSecond = (std::max)(bytesPerSecond / msg->size(), (size_t)1);
			delay = (std::max)((1000000) / (packetsPerSecond), (size_t)1);
		}

		// sending with compression will alter msg->size(); not anymore ...
		pub.send(msg);

		// every report interval we are recalculating bandwith
		if (now - lastReportAt > reportInterval) {
			RScopeLock lock(mutex);

			std::string scaleInfo("--");
			// and recalculate bytes to send
			if (reports.size() > 0) {
				double decreasePressure = 0;

				// print report messages
				std::map<std::string, Report>::iterator repIter = reports.begin();

				// bandwidth is fixed
				if (fixedBytesPerSecond == 0) {
					while(repIter != reports.end()) {
						const Report& report = repIter->second;
						double reportPressure = 0;

						// see if we need to decrease bandwidth
						if (report.pktsLate > packetsWritten / 2) {
							// client is lagging more than half a second, scale back somewhat
							reportPressure = (std::max)(1.1, reportPressure);
						}
						if (report.pcntLoss > pcntLossOk) {
							// we lost packages, scale back somewhat
							reportPressure = (std::max)((double)report.pktsDropped / report.pktsRcvd, reportPressure);
							reportPressure = (std::min)(reportPressure, 1.4);
						}
						if (report.pktsLate > 3 * packetsWritten) {
							// queues explode! scale back alot!
							reportPressure = (std::max)((double)report.pktsLate / packetsWritten, reportPressure);
							reportPressure = (std::min)(reportPressure, 2.0);
						}

						if (reportPressure > decreasePressure)
							decreasePressure = reportPressure;

						repIter++;
					}

					if (decreasePressure > 1) {
						bytesPerSecond *= (1.0 / decreasePressure);
						bytesPerSecond = (std::max)(bytesPerSecond, (size_t)(1024));
						scaleInfo = "down " + toStr(1.0 / decreasePressure);
					} else {
						bytesPerSecond *= 1.3;
						scaleInfo = "up 1.3";
					}
					std::cout << std::endl;
				} else if (fixedBytesPerSecond == (size_t)-1) {
					// do nothing
				} else {

					if (bytesWritten * intervalFactor < fixedBytesPerSecond) {
						bytesPerSecond *= 1.05;
					} else if (bytesWritten * intervalFactor > fixedBytesPerSecond)  {
						bytesPerSecond *= 0.95;
					}
				}
			}
			currReportNr++;

			writeReports(scaleInfo);

			bytesWritten = 0;
			packetsWritten = 0;

			lastReportAt = Thread::getTimeStampMs();
		}

        delete(msg);

		// now we sleep until we have to send another packet
		if (delay > 50 && fixedBytesPerSecond != (size_t) - 1)
			Thread::sleepUs(delay);
	}

	pub.setGreeter(NULL);
}
Пример #4
0
int main(int argc, char** argv) {
	uint16_t modulo = 1;

	Freenect::Freenect freenect;
	FreenectBridge* device;

	Discovery disc;
	Node node;
	Publisher pubDepthTCP;
	Publisher pubDepthRTP;

	Publisher pubVideoTCP;
	Publisher pubVideoRTP;

	printf("umundo-kinect-pub version " UMUNDO_VERSION " (" CMAKE_BUILD_TYPE " build)\n");

	int option;
	while ((option = getopt(argc, argv, "m:")) != -1) {
		switch(option) {
		case 'm':
			modulo = atoi(optarg);
			break;
		default:
			printUsageAndExit();
			break;
		}
	}

	std::cout << "Sending every " << modulo << ". frame..." << std::endl << std::flush;

	{
		PublisherConfigRTP pubConfigRTP("kinect.depth.rtp");
		pubConfigRTP.setTimestampIncrement(1);
		pubDepthRTP = Publisher(&pubConfigRTP);

		PublisherConfigTCP pubConfigTCP("kinect.depth.tcp");
		pubConfigTCP.enableCompression();
		pubDepthTCP = Publisher(&pubConfigTCP);
	}

	{
		PublisherConfigRTP pubConfigRTP("kinect.video.rtp");
		pubConfigRTP.setTimestampIncrement(1);
		pubVideoRTP = Publisher(&pubConfigRTP);

		PublisherConfigTCP pubConfigTCP("kinect.video.tcp");
		pubConfigTCP.enableCompression();
		pubVideoTCP = Publisher(&pubConfigTCP);
	}

	disc = Discovery(Discovery::MDNS);
	disc.add(node);

	node.addPublisher(pubDepthRTP);
	node.addPublisher(pubDepthTCP);
	node.addPublisher(pubVideoRTP);
	node.addPublisher(pubVideoTCP);

	// try to instantiate freenect device
	while(true) {
		try {
			// constructor is somewhat fragile
			device = &freenect.createDevice<FreenectBridge>(0);
			device->pubDepthRTP = pubDepthRTP;
			device->pubDepthTCP = pubDepthTCP;
			device->pubVideoRTP = pubVideoRTP;
			device->pubVideoTCP = pubVideoTCP;
			device->setModulo(modulo);

			// this is actually the default
			device->setVideoFormat(FREENECT_VIDEO_BAYER, FREENECT_RESOLUTION_MEDIUM);

			while(true) {
				try {
					device->startVideo(); // not blocking on recent versions only?
					while(true)
						Thread::sleepMs(2000);
				} catch(std::runtime_error e) {
					std::cout << "An exception occured while trying to start video: " << e.what() << " - retrying after 5s" << std::endl;
					Thread::sleepMs(5000);
				}
			}

		} catch(std::runtime_error e) {
			std::cout << "An exception occured: " << e.what() << " - retrying" << std::endl;
			Thread::sleepMs(5000);
		}
	}

	return 0;
}