Exemple #1
0
class MemoryConfigRow(Row):
    # A general collection for misc. stuff: configuration, etc.
    columns = [
        ColumnSpec(IntegerColumn,
                   key_name="msbuftime",
                   label_name="Buffering time (ms)",
                   min_value=50,
                   max_value=1000,
                   def_value=default.get_memory_config()["msbuftime"]),
        ColumnSpec(IntegerColumn,
                   key_name="n_720p",
                   label_name="Number of 720p streams",
                   min_value=0,
                   max_value=1024,
                   def_value=default.get_memory_config()["n_720p"]),
        ColumnSpec(IntegerColumn,
                   key_name="n_1080p",
                   label_name="Number of 1080p streams",
                   min_value=0,
                   max_value=1024,
                   def_value=default.get_memory_config()["n_1080p"]),
        ColumnSpec(IntegerColumn,
                   key_name="n_1440p",
                   label_name="Number of 2K streams",
                   min_value=0,
                   max_value=1024,
                   def_value=default.get_memory_config()["n_1440p"]),
        ColumnSpec(IntegerColumn,
                   key_name="n_4K",
                   label_name="Number of 4K streams",
                   min_value=0,
                   max_value=1024,
                   def_value=default.get_memory_config()["n_4K"]),
        ColumnSpec(CheckBoxColumn,
                   key_name="bind",
                   label_name="Bind decoding thread to single core",
                   def_value=default.get_memory_config()["bind"]),
        ColumnSpec(
            CheckBoxColumn,
            key_name="overwrite_timestamps",
            label_name="Overwrite timestamps",
            def_value=default.get_memory_config()["overwrite_timestamps"])
    ]

    def getNFrames(self, key):
        """Get number of necessary frames for certain camera resolution

        :param key:   n720p, n1080p, etc.
        """

        buftime = self["buftime"]
        ncam = self[key]

        # assume 25 fps cameras
        return int((buftime / 1000) * 25 * ncam)
Exemple #2
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
        """
Exemple #3
0
 def writeDefaultMemoryConfig(self):
     self.config_collection.new(MemoryConfigRow,
                                default.get_memory_config())
Exemple #4
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)