예제 #1
0
class MyGui(QtWidgets.QMainWindow):

    debug = False

    # debug=True

    def __init__(self, pardic, parent=None):
        super(MyGui, self).__init__()
        # print(pre,"Qapp=",QtCore.QCoreApplication.instance())
        self.pardic = pardic
        self.initVars()
        self.setupUi()
        if (self.debug):
            return
        self.openValkka()
        self.start_streams()

    def initVars(self):
        pass

    def setupUi(self):
        self.desktop_handler = DesktopHandler()
        print(self.desktop_handler)

        self.setGeometry(QtCore.QRect(100, 100, 800, 800))
        self.w = QtWidgets.QWidget(self)
        self.setCentralWidget(self.w)
        self.lay = QtWidgets.QGridLayout(self.w)

        self.videoframes = []
        self.widget_pairs = []
        self.addresses = self.pardic["cams"]

    def openValkka(self):

        self.livethread = LiveThread(  # starts live stream services (using live555)
            name="live_thread",
            # verbose=True,
            verbose=False,
            affinity=self.pardic["live affinity"])

        self.gpu_handler = GPUHandler(self.pardic)

        self.chains = []

        a = self.pardic["dec affinity start"]
        cw = 0  # widget / window index
        cs = 1  # slot / stream count

        ntotal = len(self.addresses) * self.pardic["replicate"]
        nrow = self.pardic["videos per row"]
        ncol = max((ntotal // self.pardic["videos per row"]) + 1, 2)

        for address in self.addresses:
            # now livethread and openglthread are running
            if (a > self.pardic["dec affinity stop"]):
                a = self.pardic["dec affinity start"]
            print(pre, "openValkka: setting decoder thread on processor", a)

            chain = OpenFilterchain(  # decoding and branching the stream happens here
                livethread=self.livethread,
                address=address,
                slot=cs,
                affinity=a,
                # verbose     =True
                verbose=False,
                msreconnect=10000,

                # flush_when_full =True
                flush_when_full=False,

                # time_correction   =TimeCorrectionType_dummy,  # Timestamp correction type: TimeCorrectionType_none, TimeCorrectionType_dummy, or TimeCorrectionType_smart (default)
                time_correction=TimeCorrectionType_smart,
                recv_buffer_size=
                0,  # Operating system socket ringbuffer size in bytes # 0 means default
                # recv_buffer_size  =1024*800,   # 800 KB
                reordering_mstime=
                0  # Reordering buffer time for Live555 packets in MILLIseconds # 0 means default
                # reordering_mstime =300
            )

            # send stream from all OpenFilterchain to all GPUs
            for glthread in self.gpu_handler.openglthreads:
                chain.connect(glthread.name, glthread.getInput(
                ))  # OpenGLThread.getInput() returns the input FrameFilter

            self.chains.append(
                chain
            )  # important .. otherwise chain will go out of context and get garbage collected ..

            for cc in range(0, self.pardic["replicate"]):
                print(pre, "setupUi: layout index, address : ", cw // nrow,
                      cw % nrow, address)
                # self.lay.addWidget(fr,cw//nrow,cw%nrow) # floating windows instead

                container = VideoContainer(cs, self.gpu_handler)
                container.getWidget().setGeometry(
                    self.desktop_handler.getGeometry(nrow, ncol, cw % nrow,
                                                     cw // nrow))
                container.getWidget().show()

                self.videoframes.append(container)

                cw += 1

            cs += 1  # TODO: crash when repeating the same slot number ..?

            chain.decodingOn()  # tell the decoding thread to start its job
            a += 1

    def closeValkka(self):
        self.livethread.close()

        for chain in self.chains:
            chain.close()

        self.chains = []
        self.widget_pairs = []
        self.videoframes = []
        self.gpu_handler.close()

    def start_streams(self):
        pass

    def stop_streams(self):
        pass

    def closeEvent(self, e):
        print(pre, "closeEvent!")
        self.stop_streams()
        self.closeValkka()
        e.accept()
예제 #2
0
class MyGui(QtWidgets.QMainWindow):

    debug = False

    # debug=True

    def __init__(self, pardic, parent=None):
        super(MyGui, self).__init__()
        # print(pre,"Qapp=",QtCore.QCoreApplication.instance())
        self.pardic = pardic
        self.initVars()
        self.setupUi()
        if (self.debug):
            return
        self.openValkka()
        self.start_streams()

    def initVars(self):
        pass

    def setupUi(self):
        self.desktop_handler = DesktopHandler()
        print(self.desktop_handler)

        self.setGeometry(QtCore.QRect(100, 100, 800, 800))
        self.w = QtWidgets.QWidget(self)
        self.setCentralWidget(self.w)
        self.lay = QtWidgets.QGridLayout(self.w)

        self.videoframes = []
        self.widget_pairs = []
        self.addresses = self.pardic["cams"]

    def openValkka(self):
        self.livethread = LiveThread(  # starts live stream services (using live555)
            name="live_thread",
            # verbose=True,
            verbose=False,
            affinity=self.pardic["live affinity"])

        self.openglthread = OpenGLThread(  # starts frame presenting services
            name="mythread",
            n_720p=self.pardic[
                "n_720p"],  # reserve stacks of YUV video frames for various resolutions
            n_1080p=self.pardic["n_1080p"],
            n_1440p=self.pardic["n_1440p"],
            n_4K=self.pardic["n_4K"],
            # naudio  =self.pardic["naudio"], # obsolete
            # verbose =True,
            verbose=False,
            msbuftime=self.pardic["msbuftime"],
            affinity=self.pardic["gl affinity"],
            x_connection=":0.0"
            # x_connection =":0.1" # works .. video appears on the other xscreen
        )
        """ # this results in a segfault
    print("> starting second OpenGLThread")
    # testing: start another OpenGLThread
    self.openglthread2=OpenGLThread(     # starts frame presenting services
      name    ="mythread2",
      n_720p   =self.pardic["n_720p"],   # reserve stacks of YUV video frames for various resolutions
      n_1080p  =self.pardic["n_1080p"],
      n_1440p  =self.pardic["n_1440p"],
      n_4K     =self.pardic["n_4K"],
      # naudio  =self.pardic["naudio"], # obsolete
      # verbose =True,
      verbose =False,
      msbuftime=self.pardic["msbuftime"],
      affinity=self.pardic["gl affinity"],
      x_connection =":0.1" # works .. video appears on the other xscreen
      )
    print("> second OpenGLThread started")
    """

        if (self.openglthread.hadVsync()):
            w = QtWidgets.QMessageBox.warning(
                self, "VBLANK WARNING",
                "Syncing to vertical refresh enabled\n THIS WILL DESTROY YOUR FRAMERATE\n Disable it with 'export vblank_mode=0' for nvidia proprietary drivers, use 'export __GL_SYNC_TO_VBLANK=0'"
            )

        tokens = []
        self.chains = []

        a = self.pardic["dec affinity start"]
        cw = 0  # widget / window index
        cs = 1  # slot / stream count

        ntotal = len(self.addresses) * self.pardic["replicate"]
        nrow = self.pardic["videos per row"]
        ncol = max((ntotal // self.pardic["videos per row"]) + 1, 2)

        for address in self.addresses:
            # now livethread and openglthread are running
            if (a > self.pardic["dec affinity stop"]):
                a = self.pardic["dec affinity start"]
            print(pre, "openValkka: setting decoder thread on processor", a)

            chain = BasicFilterchain(  # decoding and branching the stream happens here
                livethread=self.livethread,
                openglthread=self.openglthread,
                address=address,
                slot=cs,
                affinity=a,
                # verbose     =True
                verbose=False,
                msreconnect=10000,

                # flush_when_full =True
                flush_when_full=False,

                # time_correction   =TimeCorrectionType_dummy,  # Timestamp correction type: TimeCorrectionType_none, TimeCorrectionType_dummy, or TimeCorrectionType_smart (default)
                time_correction=TimeCorrectionType_smart,
                recv_buffer_size=
                0,  # Operating system socket ringbuffer size in bytes # 0 means default
                # recv_buffer_size  =1024*800,   # 800 KB
                reordering_mstime=
                0  # Reordering buffer time for Live555 packets in MILLIseconds # 0 means default
                # reordering_mstime =300
            )

            self.chains.append(
                chain
            )  # important .. otherwise chain will go out of context and get garbage collected ..

            for cc in range(0, self.pardic["replicate"]):
                if ("no_qt" in self.pardic):
                    # create our own x-windowses
                    win_id = self.openglthread.createWindow(show=True)
                else:

                    # *** Choose one of the following sections ***

                    # (1) Let Valkka create the windows/widget # use this: we get a window with correct parametrization
                    # win_id =self.openglthread.createWindow(show=False)
                    # fr     =getForeignWidget(self.w, win_id)

                    if (valkka_xwin == False):
                        # (2) Let Qt create the widget
                        fr = TestWidget0(None)
                        win_id = int(fr.winId())
                    else:
                        # """
                        # (3) Again, let Valkka create the window, but put on top a translucent widget (that catches mouse gestures)
                        win_id = self.openglthread.createWindow(show=False)
                        widget_pair = WidgetPair(None, win_id, TestWidget0)
                        fr = widget_pair.getWidget()
                        self.widget_pairs.append(widget_pair)
                        # """

                    print(pre, "setupUi: layout index, address : ", cw // nrow,
                          cw % nrow, address)
                    # self.lay.addWidget(fr,cw//nrow,cw%nrow) # floating windows instead

                    container = VideoContainer(None, fr, n=0)
                    container.getWidget().setGeometry(
                        self.desktop_handler.getGeometry(
                            nrow, ncol, cw % nrow, cw // nrow))
                    container.getWidget().show()

                    self.videoframes.append(container)

                token = self.openglthread.connect(
                    slot=cs, window_id=win_id
                )  # present frames with slot number cs at window win_id
                tokens.append(token)
                cw += 1

            cs += 1  # TODO: crash when repeating the same slot number ..?

            chain.decodingOn()  # tell the decoding thread to start its job
            a += 1

    def closeValkka(self):
        self.livethread.close()

        for chain in self.chains:
            chain.close()

        self.chains = []
        self.widget_pairs = []
        self.videoframes = []
        self.openglthread.close()

    def start_streams(self):
        pass

    def stop_streams(self):
        pass

    def closeEvent(self, e):
        print(pre, "closeEvent!")
        self.stop_streams()
        self.closeValkka()
        e.accept()