Можем ли мы разместить несколько серверов vnc (используя библиотеку LibVNCServer) в одном процессе?
В библиотеке LibVNCServer есть пример camera.c, который захватывает снимки камеры и заполняет буфер кадров, используемый сервером vnc через определенные промежутки времени. Мое требование состоит в том, чтобы сделать то же самое с транспортными потоками mpeg (много источников вместо единственного источника как камера). Поэтому для каждого транспортного потока требуется один VNC-сервер.
Я прочитал в протоколе RFB, что мы можем разместить несколько серверов vnc на одном хосте по портам, начиная с 5900 (5900+x). Однако было бы лучше разместить несколько серверов vnc в одном процессе, чтобы избежать нежелательных операций ввода-вывода между серверами vnc и процессом, генерирующим данные.
Поддерживает ли LibVNCServer этот сценарий использования или мне нужно запускать процесс vnc-сервера для каждого видеопотока?
Примечание: я просмотрел библиотеку и увидел, что rfbScreenInfoPtr распространяется везде и не является статичным. Но не могу прийти к выводу, является ли LibVNCServer потокобезопасным, потому что я не знаком с C.
1 ответ
Я пытался написать vnc-сервер с возможностью масштабирования на стороне сервера, который является одним из нескольких потоков.
int main(int argc, char** argv)
{
...
rfbScreenInfoPtr rfbScreen_1080 = rfbGetScreen(&argc,argv,1920,1080,8,3,bpp);
rfbScreenInfoPtr rfbScreen_720 = rfbGetScreen(&argc,argv,1280,720,8,3,bpp);
rfbScreen_1080->frameBuffer = (char*)_aligned_malloc(1920*1080*bpp,256);
rfbScreen_720->frameBuffer = (char*)_aligned_malloc(1280*720*bpp,256);
rfbScreen_1080->progressiveSliceHeight = 1080/2;
rfbScreen_720->progressiveSliceHeight = 720/2;
rfbScreen_1080->cursor = rfbMakeXCursor(0,0,NULL,NULL);
rfbScreen_720->cursor = rfbMakeXCursor(0,0,NULL,NULL);
rfbScreen_1080->port = 5900;
rfbScreen_720->port = 5901;
rfbScreen_1080->alwaysShared = 1;
rfbScreen_720->alwaysShared = 1;
rfbInitServer(rfbScreen_1080);
rfbInitServer(rfbScreen_720);
int begin = clock();
while(rfbIsActive(rfbScreen_1080) || rfbIsActive(rfbScreen_720))
{
int end = clock();
if(end - begin >= UPDATE_INTERVAL)
{
//printf("%d\n",end-begin);
begin = clock()-(end - begin - UPDATE_INTERVAL);
CaptureScreen(rfbScreen_1080, rfbScreen_720);
rfbMarkRectAsModified(rfbScreen_1080,0,0,1920,1080);
rfbMarkRectAsModified(rfbScreen_720,0,0,1280,720);
}
rfbProcessEvents(rfbScreen_1080,40);
rfbProcessEvents(rfbScreen_720,40);
//Sleep(1);
}
...
}
void CaptureScreen(rfbScreenInfoPtr rfbScreen1, rfbScreenInfoPtr rfbScreen2)
{
//capture screen to bmp, resize and copy data to rfbScreen->frameBuffer;
}