Disclaimer: I don't have much experience with multithreading (I played with it long ago in python).
In a different forum thread, we were talking about the need of setupForeignThreadGc() on the top of a callback called by C.
In the same context, I aiming to do this in Nim.
Should I use threads? Should I use something else given that the threads are created elsewhere in C?
import locks
type
FrameRequest {.bycopy.} = object
numFrames*: int # Total number of frames
nthreads*: int # Number of threads available
completedFrames*: int # Number of frames already processed
requestedFrames*: int # Number of frames already requested
var
reqs:FrameRequest
lock: Lock
cond : Cond
proc callback( reqsData: pointer,
frame: ptr VSFrameRef,
n: cint,
node: ptr VSNodeRef,
errorMsg: cstring) {.cdecl.} =
#[
Function of the client application called by the core when a requested frame is ready, after a call to getFrameAsync().
If multiple frames were requested, they can be returned in any order. Client applications must take care of reordering them.
This function is only ever called from one thread at a time.
getFrameAsync() may be called from this function to request more frames.
]#
setupForeignThreadGc()
# Do something with the frame
API.freeFrame( frame )
reqs.completedFrames += 1
# Once a frame is completed, we request another frame while there are available
if reqs.requestedFrames < reqs.numFrames:
API.getFrameAsync( reqs.requestedFrames.cint, node, callback, reqsData)
reqs.requestedFrames += 1
if (reqs.completedFrames == reqs.numFrames):
cond.signal()
proc NullAsync*(vsmap:ptr VSMap):int =
reqs.nthreads = getNumThreads() # Get the number of threads
echo "Number of threads: ", reqs.nthreads
let node = getFirstNode(vsmap)
let vinfo = API.getVideoInfo(node) # video info pointer
reqs.numFrames = vinfo.numFrames
reqs.completedFrames = 0
reqs.requestedFrames = 0
let initialRequest = min(reqs.nthreads, reqs.numFrames)
initLock(lock)
for i in 0..<initialRequest: #
API.getFrameAsync( i.cint, node, callback, nil) #dataInHeap)
reqs.requestedFrames += 1
cond.wait(lock)
API.freeMap(vsmap)
API.freeNode(node)
return reqs.numFrames