|
Valkka
1.6.1
OpenSource Video Management
|
Writing, reading and caching frames
The level 2 API Python class ValkkaFSManager, uses several level 1 API (core) Python class objects
The logic of requesting certain blocks in order to show (and buffer) frames for a certain time instant is handled completely at the python side
This orchestration is handled by the level 2 API Python class ValkkaFSManager.
Let's use the following pseudocode notation, to see how objects are contained within other objects:
classname(init parameter) {
classnames of contained objects
}
This is how it looks like. Let's hope you'll get the big picture. :)
- cpp threads run & originate python callbacks
- core.ValkkaFSWriterThread "drives" core.ValkkaFS which emits callbacks
api2.ValkkaFSManager(api2.ValkkaFS) {
1: api2.ValkkaFS {
core.ValkkaFS
# c++ => python callbacks
def new_block_cb__(propagate, par):
- launched from cpp core.ValkkaFS.writeBlock (pycall) when a block is finished
- propagate indicates if further callbacks should be evoked
- par is an integer (block number) or an error string
- calls self.block_cb for callback propagation
# python => c++ calls
def getBlockTable():
- updates python side blocktable (numpy array)
- calls cpp-side core.ValkkaFS.setArrayCall(self.blocktable_)
- returns self.blocktable_
}
2: core.ValkkaFSReaderThread {
core.ValkkaFS
- writes to framefilter that is got from core.FileCacherThread.getFrameFilter() [4]
- frames are requested on per-block basis
# python => c++ calls
pullBlocksPyCall(block_list) => [signal to thread]
=> pullBlocks
- Writes frames to its outgoing framefilter
(typically connected to FileCacherThread::getFrameFilter())
- results in launching core.FileCacherThread.switchCache => pyfunc2
=> timeLimitsCallback__
}
3: core.ValkkaFSWriterThread {
core.ValkkaFS
- input framefilter can be requested with getFrameFilter()
}
4: core.FileCacherThread {
- gets frames from core.ValkkaFSReaderThread via input framefilter
- caches frames
- receives seek, play, stop, operations
- send batches of frames downstream (to output filter)
}
# c++ => python callbacks
def timeCallback__(mstime: int):
- originates from core.FileCacherThread.run (pyfunc)
- once per 300 ms
- calls:
=> self.readBlockTableIf()
=> if necessary, calls self.readBlockTable()
=> self.blocktable = api2.ValkkaFS.getBlockTable() [1]
=> cpp core.ValkkaFS.setArrayCall(self.blocktable_)
=> self.reqBlocks(mstimestamp)
=> core.ValkkaFSReaderThread.pullBlocksPyCall(block_list)
def timeLimitsCallback__(tup: tuple):
- originates from core.FileCacherThread.switchCache (pyfunc2)
- sent when frame cache has been updated
# some important methods:
def setBlockCallback(cb):
define how api2.ValkkaFS.new_block_cb__ is continued
(by default, no callback chain)
def setOutput(_id, slot, framefilter [**]):
"""Set id => slot mapping. Set output framefilter
"""
core.ValkkaFSReaderThread.setSlotIdCall(slot, _id) # ID-TO-SLOT MAPPING
ctx = core.FileStreamContext(slot, framefilter) # SLOT-TO-FRAMEFILTER MAPPING [**]
core.FileCacherThread.registerStreamCall(ctx)
def setInput(_id, slot):
core.ValkkaFSWriterThread.setSlotIdCall(_id, slot)
def getInputFrameFilter():
return ValkkaFSWriterThread.getFrameFilter()
}Frames are transported like this:
outgoing frames:
core.ValkkaFSReaderThread [2] --> core.FileCacherThread [4] --> output framefilter [**]
- Request blocks of frames - Set seek point, play,
to be sent downstream stop, etc.
- Uses shared core.ValkkaFS
instance
incoming frames:
--> core.ValkkaFSWriterThread.getFrameFilter() --> core.ValkkaFSWriterThread
- Updates shared core.ValkkaFS
instance