Beispiel #1
0
 def writeDefaultValkkaFSConfig(self):
     self.valkkafs_collection.new(
         ValkkaFSConfigRow,
         {
             # "dirname"    : default.valkkafs_config["dirname"], # not written to db for the moment
             "n_blocks": default.get_valkkafs_config()["n_blocks"],
             "blocksize": default.get_valkkafs_config()["blocksize"],
             "fs_flavor": default.get_valkkafs_config()["fs_flavor"],
             "record": default.get_valkkafs_config()["record"],
             "partition_uuid":
             default.get_valkkafs_config()["partition_uuid"]
         })
Beispiel #2
0
 def writeDefaultValkkaFSConfig(self):
     # TODO: when ValkkaFSConfigRow is changed
     # there should be no need to change the column names everywhere
     # => ValkkaFSConfigRow should define some default..
     # (it should be the only place for "ground truth")
     self.valkkafs_collection.new(
         ValkkaFSConfigRow,
         {
             # "dirname"    : default.valkkafs_config["dirname"], # not written to db for the moment
             "n_blocks": default.get_valkkafs_config()["n_blocks"],
             "blocksize": default.get_valkkafs_config()["blocksize"],
             #"fs_flavor"  : default.get_valkkafs_config()["fs_flavor"],
             #"record"     : default.get_valkkafs_config()["record"],
             #"partition_uuid" : default.get_valkkafs_config()["partition_uuid"]
         })
Beispiel #3
0
    def openValkka(self):
        self.cpu_scheme = CPUScheme()
        
        # singleton.data_model.camera_collection
        try:
            memory_config = next(singleton.data_model.config_collection.get({"classname" : MemoryConfigRow.__name__}))
        except StopIteration:
            print(pre, "Using default mem config")
            singleton.data_model.writeDefaultMemoryConfig()
            memory_config = default.get_memory_config()

        try:
            valkkafs_config = next(singleton.data_model.valkkafs_collection.get({"classname" : ValkkaFSConfigRow.__name__}))
        except StopIteration:
            print(pre, "Using default valkkafs config")
            singleton.data_model.writeDefaultValkkaFSConfig()
            valkkafs_config = default.get_valkkafs_config()

        n_frames = round(memory_config["msbuftime"] * default.fps / 1000.) # accumulated frames per buffering time = n_frames

        if (memory_config["bind"]):
            self.cpu_scheme = CPUScheme()
        else:
            self.cpu_scheme = CPUScheme(n_cores = -1)

        self.gpu_handler = GPUHandler(
            n_720p  = memory_config["n_720p"] * n_frames, # n_cameras * n_frames
            n_1080p = memory_config["n_1080p"] * n_frames,
            n_1440p = memory_config["n_1440p"] * n_frames,
            n_4K    = memory_config["n_4K"] * n_frames,
            msbuftime = memory_config["msbuftime"],
            verbose = False,
            cpu_scheme = self.cpu_scheme
        )

        self.livethread = LiveThread(
            name = "live_thread",
            verbose = False,
            affinity = self.cpu_scheme.getLive()
        )
        
        self.usbthread = USBDeviceThread(
            name = "usb_thread",
            verbose = False,
            affinity = self.cpu_scheme.getUSB()
        )

        # see datamodel.row.ValkkaFSConfigRow
        blocksize = valkkafs_config["blocksize"]
        n_blocks  = valkkafs_config["n_blocks"]
        fs_flavor = valkkafs_config["fs_flavor"] 
        record    = valkkafs_config["record"]

        # TODO: activate this if ValkkaFS changed in config!
        if fs_flavor == "file":
            partition_uuid = None
        else:
            partition_uuid = valkkafs_config["partition_uuid"]
            
        create_new_fs = False

        if self.valkkafs is None: # first time
            create_new_fs = False # try to load initially from disk
        else:
            print("openValkka: checking ValkkaFS")
            create_new_fs = not self.valkkafs.is_same( # has changed, so must recreate
                partition_uuid = partition_uuid, # None or a string
                blocksize = blocksize * 1024*1024,
                n_blocks = n_blocks
            )
            if create_new_fs: print("openValkka: ValkkaFS changed!")
        
        if not create_new_fs: # let's try to load it
            print("openValkka: trying to load ValkkaFS")
            try:
                self.valkkafs = ValkkaFS.loadFromDirectory(
                    dirname = singleton.valkkafs_dir.get()
                )
            except ValkkaFSLoadError as e:
                print("openValkka: loading ValkkaFS failed with", e)
                create_new_fs = True # no luck, must recreate

        if create_new_fs:
            print("openValkka: (re)create ValkkaFS")
            self.valkkafs = ValkkaFS.newFromDirectory(
                dirname = singleton.valkkafs_dir.get(),
                blocksize = valkkafs_config["blocksize"] * 1024*1024, # MB
                n_blocks = valkkafs_config["n_blocks"],
                partition_uuid = partition_uuid,
                verbose = True
            )
            # to keep things consistent..
            singleton.data_model.valkkafs_collection.new(
                ValkkaFSConfigRow,
                {
                    # "dirname"    : default.valkkafs_config["dirname"], # not written to db for the moment
                    "n_blocks"       : default.get_valkkafs_config()["n_blocks"],
                    "blocksize"      : valkkafs_config["blocksize"],
                    "fs_flavor"      : valkkafs_config["fs_flavor"],
                    "record"         : record,
                    "partition_uuid" : partition_uuid
                })


        """
        else:
            self.valkkafs = None
        """

        # if no recording selected, set self.valkkafsmanager = None
        self.valkkafsmanager = ValkkaFSManager(
            self.valkkafs,
            write = record, # True or False
            read = record,
            cache = record
            )
        self.playback_controller = PlaybackController(valkkafs_manager = self.valkkafsmanager)

        self.filterchain_group = LiveFilterChainGroup(
            datamodel     = singleton.data_model, 
            livethread    = self.livethread, 
            usbthread     = self.usbthread,
            gpu_handler   = self.gpu_handler, 
            cpu_scheme    = self.cpu_scheme)
        self.filterchain_group.read()

        if record:
            print("openValkka: ValkkaFS **RECORDING ACTIVATED**")
            self.filterchain_group.setRecording(RecordType.always, self.valkkafsmanager)
        
        # self.filterchain_group.update() # TODO: use this once fixed
        
        self.filterchain_group_play = PlaybackFilterChainGroup(
            datamodel     = singleton.data_model,
            valkkafsmanager
                        = self.valkkafsmanager,
            gpu_handler   = self.gpu_handler, 
            cpu_scheme    = self.cpu_scheme)
        self.filterchain_group_play.read()

        try:
            from valkka.mvision import multiprocess
        except ImportError:
            pass
        """
Beispiel #4
0
class ValkkaFSConfigRow(Row):
    def getValkkaFSDevices():
        lis = []  # tuples of (name, key)
        for key, value in findBlockDevices().items():
            # they look like this: {'27f5e5d8-9e20-4bc1-84aa-6a3cbab498c8': ('/dev/sdc1', 500107862016)}
            lis.append((
                value[0] + " (" + str(int(value[1] / 1024 / 1024)) +
                " MB)",  # shown in dropdown
                key  # data to be saved
            ))
        return lis

    """
    "dirname"    : singleton.valkkafs_dir.get(),
    "n_blocks"   : 10,
    "blocksize"  : 10
    """

    columns = [
        # TODO: for valkkafs metadata directory: (1) add a non-editable column
        ColumnSpec(CheckBoxColumn,
                   key_name="record",
                   label_name="Activate recording & playback",
                   def_value=False),
        ColumnSpec(
            SpinBoxIntegerColumn,
            key_name="blocksize",
            label_name="Blocksize (MB)",
            min_value=1,
            max_value=1024 * 1024 * 1024,  # 1 GB
            def_value=default.get_valkkafs_config()["blocksize"]),
        ColumnSpec(SpinBoxIntegerColumn,
                   key_name="n_blocks",
                   label_name="Number of Blocks",
                   min_value=5,
                   max_value=999999999,
                   def_value=default.get_valkkafs_config()["n_blocks"]),
        # Calculate Total Size (MB)
        ColumnSpec(ConstantRadioButtonColumn,
                   key_name="fs_flavor",
                   label_name="ValkkaFS type",
                   list=[("Normal file", "file"),
                         ("Dedicated block device", "valkkafs")]),
        ColumnSpec(ConstantComboBoxColumn,
                   key_name="partition_uuid",
                   label_name="Available Devices",
                   callback=getValkkaFSDevices)
    ]

    # TODO:
    # Actions (buttons): format, save, cancel (exit without applying changes)

    def makeWidget(self):
        """Subclassed from Row : custom form.  Add a total disk space field.
        """
        self.widget = FormWidget()
        self.lay = QtWidgets.QGridLayout(self.widget)

        cc = 0
        self.placeWidget(cc, "record")
        cc += 1
        self.placeWidget(cc, "blocksize")
        cc += 1
        self.placeWidget(cc, "n_blocks")
        cc += 1

        self.label_total_size = QtWidgets.QLabel("Total Size (MB)",
                                                 self.widget)
        self.label_total_size_value = QtWidgets.QLabel("", self.widget)
        self.placeWidgetPair(
            cc, (self.label_total_size, self.label_total_size_value))
        cc += 1

        self.placeWidget(cc, "fs_flavor")
        cc += 1
        self.placeWidget(cc, "partition_uuid")
        cc += 1

        self.connectNotifications()

        def fs_size_changed():
            total_size_mb = self["blocksize"].getValue(
            ) * self["n_blocks"].getValue()
            self.label_total_size_value.setText(str(total_size_mb))

        def block_device_slot():
            self["partition_uuid"].updateWidget()
            n_devs = self["partition_uuid"].widget.count()  # QComboBox.count()
            if n_devs < 1:
                self["fs_flavor"]["file"].setChecked(True)

        self["blocksize"].widget.valueChanged.connect(fs_size_changed)
        self["n_blocks"].widget.valueChanged.connect(fs_size_changed)
        self["fs_flavor"]["valkkafs"].clicked.connect(block_device_slot)

        fs_size_changed()
        block_device_slot()
        """
Beispiel #5
0
    def openValkka(self):
        self.cpu_scheme = CPUScheme()

        # singleton.data_model.camera_collection
        try:
            memory_config = next(
                singleton.data_model.config_collection.get(
                    {"classname": MemoryConfigRow.__name__}))
        except StopIteration:
            print(pre, "Using default mem config")
            singleton.data_model.writeDefaultMemoryConfig()
            memory_config = default.get_memory_config()

        try:
            valkkafs_config = next(
                singleton.data_model.valkkafs_collection.get(
                    {"classname": ValkkaFSConfigRow.__name__}))
        except StopIteration:
            print(pre, "Using default valkkafs config")
            singleton.data_model.writeDefaultValkkaFSConfig()
            valkkafs_config = default.get_valkkafs_config()

        n_frames = round(
            memory_config["msbuftime"] * default.fps /
            1000.)  # accumulated frames per buffering time = n_frames

        if (memory_config["bind"]):
            self.cpu_scheme = CPUScheme()
        else:
            self.cpu_scheme = CPUScheme(n_cores=-1)

        self.gpu_handler = GPUHandler(
            n_720p=memory_config["n_720p"] * n_frames,  # n_cameras * n_frames
            n_1080p=memory_config["n_1080p"] * n_frames,
            n_1440p=memory_config["n_1440p"] * n_frames,
            n_4K=memory_config["n_4K"] * n_frames,
            msbuftime=memory_config["msbuftime"],
            verbose=False,
            cpu_scheme=self.cpu_scheme)

        self.livethread = LiveThread(name="live_thread",
                                     verbose=False,
                                     affinity=self.cpu_scheme.getLive())

        self.usbthread = USBDeviceThread(name="usb_thread",
                                         verbose=False,
                                         affinity=self.cpu_scheme.getUSB())

        # see datamodel.row.ValkkaFSConfigRow
        blocksize = valkkafs_config["blocksize"]
        n_blocks = valkkafs_config["n_blocks"]
        #fs_flavor = valkkafs_config["fs_flavor"]
        #record    = valkkafs_config["record"]

        self.filterchain_group = LiveFilterChainGroup(
            datamodel=singleton.data_model,
            livethread=self.livethread,
            usbthread=self.usbthread,
            gpu_handler=self.gpu_handler,
            cpu_scheme=self.cpu_scheme)
        self.filterchain_group.read()

        # TODO: RecordType..?
        if singleton.use_playback:
            print("openValkka: ValkkaFS **PLAYBACK & RECORDING ACTIVATED**")
            # ValkkaSingleFSHandler:
            # directory handling and valkkafs <-> stream id association
            self.valkka_fs_handler = ValkkaSingleFSHandler(
                basedir=singleton.valkkafs_dir.get(),
                blocksize=blocksize * 1024 * 1024,  # MB
                n_blocks=n_blocks)
            if self.valkkafs_modified:
                print("openValkka: removing all recorded streams")
                self.valkka_fs_handler.clear()
                self.valkka_fs_handler.wipe()

            for row in singleton.data_model.camera_collection.get():
                _id = row["_id"]  # get stream id
                slot = row["slot"]
                classname = row["classname"]
                if classname != "EmptyRow":
                    # print(">", row)
                    self.valkka_fs_handler.load(_id)
                    # ..creates new valkka if doesn't exist
            self.valkkafsmanager = ValkkaFSManager(
                self.valkka_fs_handler.tolist())
            self.valkkafsmanager.start()
            #self.filterchain_group.setRecording(RecordType.always, self.valkkafsmanager)# OLD
            # self.filterchain_group: source for live stream
            # self.filterchain_group_play: sink where the playback/saved stream should
            # be sent
            self.filterchain_group_play = PlaybackFilterChainGroup(
                datamodel=singleton.data_model,
                gpu_handler=self.gpu_handler,
                cpu_scheme=self.cpu_scheme)
            self.filterchain_group_play.read()
            # print("openValkka: self.filterchain_group_play: len=", len(self.filterchain_group_play))
            # connect live & playback filterchains with the manager
            for valkkafs, inputfilter in self.valkkafsmanager.iterateFsInput():
                _id = self.valkka_fs_handler.getId(valkkafs)
                if _id is None:
                    print("WARNING: main: could not get id for", valkkafs)
                    continue
                playback_fc = self.filterchain_group_play.get(_id=_id)
                if playback_fc is None:
                    print("WARNING: main: could not find _id", _id,\
                        "in playback filterchain group")
                    """
                    for chain in self.filterchain_group_play.chains:
                        print(">>", chain)
                        for key, getter in chain.iterateGetters():
                            print(">", key, getter())
                    """
                    continue
                live_fc = self.filterchain_group.get(_id=_id)
                if live_fc is None:
                    print("WARNING: main: could not find _id", _id,\
                        "in live filterchain group")
                    continue
                self.valkkafsmanager.map_(
                    valkkafs=valkkafs,
                    # read & cached stream is sent/output'd here:
                    framefilter=playback_fc.getInputFilter(),
                    write_slot=live_fc.slot,
                    read_slot=playback_fc.slot,
                    _id=_id)
                # frames coming from the live stream are sent to
                # valkkafsmanager's correct inputfilter
                # (there is one corresponding to each valkkafs)
                live_fc.connectRecTo(inputfilter, RecordType.always)
                # TODO: disconnect at exit..?

            # self.filterchain_group.update() # TODO: use this once fixed
            self.playback_controller = PlaybackController(
                valkkafs_manager=self.valkkafsmanager)