Only 50% CPU usage
Infiziert90 opened this issue · 3 comments
Hiho,
when i'm using wwxd for keyframe generation, i only got 50% on every core ... i tested it on an i5 4690k, Xeon 1245v3 and on new Ryzen 1700.
Is there any chance that you can fix that problem?
For the test i used a 1080p Episode(24min) and this script:
core = vs.get_core(accept_lowercase=True)
clip = core.resize.Bilinear(clip, 640, 360) # speed up the analysis by resizing first
clip = core.wwxd.WWXD(clip)
outtxt = ""
for i in range(clip.num_frames):
if clip.get_frame(i).props.Scenechange == 1:
outtxt += "%d I -1\\n" % i
To be honest, this filter is rather shitty. You'll get better results with xvid.
The low CPU usage is due to get_frame. It's synchronous, so WWXD will only process one frame at a time. Try get_frame_async, though don't ask me how to use it. I don't understand that "Future" stuff.
I already use get_frame_async in one of my other scripts ... but i got the same problem
def get_frame(clip, frameno):
with _cache_lock:
if frameno in _frame_cache:
return _frame_cache[frameno]
fut = clip.get_frame_async(frameno)
_frame_cache[frameno] = fut
return fut
def find_keyframes(clip, frame, epsilon=7):
"""Output frames when scenechange == True"""
_waiting = {}
for frameno in range(frame - epsilon, frame + epsilon):
if not (0 <= frameno < len(clip)):
continue
with _cache_lock:
if frameno in _keyframe_cache:
if _keyframe_cache[frameno]:
yield frameno
continue
future = get_frame(clip, frameno)
_waiting[future] = frameno
for future in as_completed(_waiting):
frameno = _waiting[future]
frame = future.result()
with _cache_lock:
change = _keyframe_cache[frameno] = frame.props.Scenechange
del _frame_cache[frameno]
if change:
yield frameno
def get_nearest_scenechange(clip, start, end, epsilon=7):
"""Resize frame and start check the frame with wwxd for scenechanges
A resized clip is faster ... but with a resolution under 640x360 wwxd cant work really good and will give you a lot
of bullshit.
"""
core = vs.get_core(accept_lowercase=True)
clip = core.resize.Bilinear(clip, 640, 360) # speed up the analysis by resizing first
clip = core.wwxd.WWXD(clip)
start = tuple(find_keyframes(clip, start, epsilon))
end = tuple(find_keyframes(clip, end, epsilon))
return TimeFrame(start, end)
But still the same problem ... only 50% Usage
I will try your xvid Vapoursynth Port ...
The normal scxvid for arch linux is 20-30s slower for the ~same result.
I just checked the code and... I remembered wrong. This filter will run in a single thread no matter what.