cvnc-serverrfb-protocol

Can we host multiple vnc servers (using LibVNCServer library) in the same process?


There is an example called camera.c in the LibVNCServer library which captures camera snapshots and populates the framebuffer used by vnc server in intervals. My requirement is to do the same with mpeg transport streams (many sources instead of a single source like camera). Therefore, one vnc server per transport stream is required.

I read in the RFB protocol that we can host multiple vnc servers on the same host on ports starting from 5900 (5900+x). However, it would be better to host multiple vnc servers in the same process so that unwanted I/O between the vnc servers and the process generating the data can be avoided.

Does LibVNCServer support that use case or do I have to launch a vnc server process per video stream?

Note: I went through the library and saw that the rfbScreenInfoPtr is circulated everywhere and is not static. But could not conclude if LibVNCServer is thread safe because I am not familiar with C.


Solution

  • I tried to write a vnc server with server-side-downscale ability, which is one source multi-stream.

    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;
    }