| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -56,10 +56,16 @@ static const struct TightJPEGConfiguration conf[10] = {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				GetAPIMessager::GetAPIMessager(const char *passwdfile_): passwdfile(passwdfile_),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									screenW(0), screenH(0), screenHash(0),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									cachedW(0), cachedH(0), cachedQ(0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									cachedW(0), cachedH(0), cachedQ(0),
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									ownerConnected(0), activeUsers(0) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_init(&screenMutex, NULL);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_init(&userMutex, NULL);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_init(&statMutex, NULL);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_init(&frameStatMutex, NULL);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_init(&userInfoMutex, NULL);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.inprogress = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// from main thread
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -95,6 +101,78 @@ void GetAPIMessager::mainUpdateScreen(rfb::PixelBuffer *pb) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&screenMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void GetAPIMessager::mainUpdateBottleneckStats(const char userid[], const char stats[]) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_trylock(&statMutex))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					bottleneckStats[userid] = stats;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&statMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void GetAPIMessager::mainClearBottleneckStats(const char userid[]) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&statMutex))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					bottleneckStats.erase(userid);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&statMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void GetAPIMessager::mainUpdateServerFrameStats(uint8_t changedPerc,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32_t all, uint32_t jpeg, uint32_t webp, uint32_t analysis,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32_t jpegarea, uint32_t webparea,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint16_t njpeg, uint16_t nwebp,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint16_t enc, uint16_t scale, uint16_t shot,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint16_t w, uint16_t h) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&frameStatMutex))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.changedPerc = changedPerc;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.all = all;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.jpeg = jpeg;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.webp = webp;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.analysis = analysis;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.jpegarea = jpegarea;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.webparea = webparea;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.njpeg = njpeg;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.nwebp = nwebp;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.enc = enc;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.scale = scale;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.shot = shot;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.w = w;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.h = h;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&frameStatMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void GetAPIMessager::mainUpdateClientFrameStats(const char userid[], uint32_t render,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint32_t all, uint32_t ping) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&frameStatMutex))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					clientFrameStats_t s;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					s.render = render;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					s.all = all;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					s.ping = ping;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					clientFrameStats[userid] = s;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&frameStatMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void GetAPIMessager::mainUpdateUserInfo(const uint8_t ownerConn, const uint8_t numUsers) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&userInfoMutex))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ownerConnected = ownerConn;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					activeUsers = numUsers;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&userInfoMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				// from network threads
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint8_t *GetAPIMessager::netGetScreenshot(uint16_t w, uint16_t h,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					const uint8_t q, const bool dedup,
 | 
			
		
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -286,3 +364,271 @@ uint8_t GetAPIMessager::netGiveControlTo(const char name[]) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void GetAPIMessager::netGetBottleneckStats(char *buf, uint32_t len) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/*
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    "username.1": {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        "192.168.100.2:14908": [ 100, 100, 100, 100 ],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        "192.168.100.3:14918": [ 100, 100, 100, 100 ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    },
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    "username.2": {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				        "192.168.100.5:14904": [ 100, 100, 100, 100 ]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				*/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					std::map<std::string, std::string>::const_iterator it;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					const char *prev = NULL;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					FILE *f;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&statMutex)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						buf[0] = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Conservative estimate
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (len < bottleneckStats.size() * 60) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						buf[0] = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						goto out;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f = fmemopen(buf, len, "w");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					fprintf(f, "{\n");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for (it = bottleneckStats.begin(); it != bottleneckStats.end(); it++) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						// user@127.0.0.1_1627311208.791752::websocket
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const char *id = it->first.c_str();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const char *data = it->second.c_str();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const char *at = strchr(id, '@');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (!at)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							continue;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const unsigned userlen = at - id;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (prev && !strncmp(prev, id, userlen)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							// Same user
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							fprintf(f, ",\n\t\t\"%s\": %s", at + 1, data);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						} else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							// New one
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if (prev) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								fprintf(f, "\n\t},\n");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							fprintf(f, "\t\"%.*s\": {\n", userlen, id);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							fprintf(f, "\t\t\"%s\": %s", at + 1, data);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						prev = id;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (!bottleneckStats.size())
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						fprintf(f, "}\n");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						fprintf(f, "\n\t}\n}\n");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					fclose(f);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				out:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&statMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				void GetAPIMessager::netGetFrameStats(char *buf, uint32_t len) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				/*
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					"frame" : {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						"resx": 1024,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						"resy": 1280,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						"changed": 75,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						"server_time": 23
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					},
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					"server_side" : [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{ "process_name": "Analysis", "time": 20 },
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{ "process_name": "TightWEBPEncoder", "time": 20, "count": 64, "area": 12 },
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{ "process_name": "TightJPEGEncoder", "time": 20, "count": 64, "area": 12 }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					],
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					"client_side" : [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						{
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							"client": "123.1.2.1:1211",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							"client_time": 20,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							"ping": 20,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							"processes" : [
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								{ "process_name": "scanRenderQ", "time": 20 }
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							]
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				*/
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					std::map<std::string, clientFrameStats_t>::const_iterator it;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					unsigned i = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					FILE *f;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&frameStatMutex)) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						buf[0] = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					const unsigned num = clientFrameStats.size();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Conservative estimate
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (len < 1024) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						buf[0] = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						goto out;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					f = fmemopen(buf, len, "w");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					fprintf(f, "{\n");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					fprintf(f, "\t\"frame\" : {\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           "\t\t\"resx\": %u,\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           "\t\t\"resy\": %u,\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           "\t\t\"changed\": %u,\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           "\t\t\"server_time\": %u\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           "\t},\n",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.w,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.h,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.changedPerc,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.all);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					fprintf(f, "\t\"server_side\" : [\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           "\t\t{ \"process_name\": \"Analysis\", \"time\": %u },\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           "\t\t{ \"process_name\": \"Screenshot\", \"time\": %u },\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           "\t\t{ \"process_name\": \"Encoding_total\", \"time\": %u, \"videoscaling\": %u },\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           "\t\t{ \"process_name\": \"TightJPEGEncoder\", \"time\": %u, \"count\": %u, \"area\": %u },\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           "\t\t{ \"process_name\": \"TightWEBPEncoder\", \"time\": %u, \"count\": %u, \"area\": %u }\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           "\t],\n",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.analysis,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.shot,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.enc,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.scale,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.jpeg,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.njpeg,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.jpegarea,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.webp,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.nwebp,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					           serverFrameStats.webparea);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					fprintf(f, "\t\"client_side\" : [\n");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					for (it = clientFrameStats.begin(); it != clientFrameStats.end(); it++, i++) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const char *id = it->first.c_str();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						const clientFrameStats_t &s = it->second;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						fprintf(f, "\t\t\{\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						           "\t\t\t\"client\": \"%s\",\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						           "\t\t\t\"client_time\": %u,\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						           "\t\t\t\"ping\": %u,\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						           "\t\t\t\"processes\" : [\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						           "\t\t\t\t{ \"process_name\": \"scanRenderQ\", \"time\": %u }\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						           "\t\t\t]\n"
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						           "\t\t}",
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						           id,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						           s.all,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						           s.ping,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						           s.render);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if (i == num - 1)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							fprintf(f, "\n");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							fprintf(f, ",\n");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					fprintf(f, "\t]\n}\n");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					fclose(f);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					serverFrameStats.inprogress = 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				out:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&frameStatMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint8_t GetAPIMessager::netRequestFrameStats(USER_ACTION what, const char *client) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Return 1 for success
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					action_data act;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					act.action = what;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (client) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						strncpy(act.data.password, client, PASSWORD_LEN);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						act.data.password[PASSWORD_LEN - 1] = '\0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// In progress already?
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					bool fail = false;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&frameStatMutex))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (serverFrameStats.inprogress) {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						fail = true;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						vlog.error("Frame stats request already in progress, refusing another");
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					} else {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						clientFrameStats.clear();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						memset(&serverFrameStats, 0, sizeof(serverFrameStats_t));
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						serverFrameStats.inprogress = 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&frameStatMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (fail)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					// Send it in
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&userMutex))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					actionQueue.push_back(act);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&userMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint8_t GetAPIMessager::netOwnerConnected() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint8_t ret;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&userInfoMutex))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ret = ownerConnected;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&userInfoMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return ret;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint8_t GetAPIMessager::netNumActiveUsers() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint8_t ret;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&userInfoMutex))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ret = activeUsers;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&userInfoMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return ret;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint8_t GetAPIMessager::netGetClientFrameStatsNum() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint8_t ret;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&frameStatMutex))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ret = clientFrameStats.size();
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&frameStatMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return ret;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				uint8_t GetAPIMessager::netServerFrameStatsReady() {
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uint8_t ret;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if (pthread_mutex_lock(&frameStatMutex))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						return 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					ret = serverFrameStats.w != 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					pthread_mutex_unlock(&frameStatMutex);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					return ret;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				}
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |