Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
|
|
Thread Tools | Search this Thread | Display Modes |
|
28th April 2014, 16:52 | #1 | Link |
unsigned int
Join Date: Oct 2012
Location: 🇪🇺
Posts: 760
|
WWXD: Faster Xvid-like scene change detection for VapourSynth
Code:
WWXD is basically Xvid's frame type decision code stuffed into a VapourSynth plugin. The output is somewhat different from Scxvid's, because Xvid's decisions are also affected by data calculated while encoding frames. WWXD may miss more scene changes than Scxvid. It may also detect some that Scxvid missed. WWXD is considerably faster than Scxvid, possibly about six times. There is no log file. Instead, the frames are tagged with the property "SceneChange" (1 or 0). The license is the same as Xvid's, i.e. GPL2. To compile: gcc -o libwwxd.so -fPIC -shared -O2 -Wall -Wextra -Wno-unused-parameter $(pkg-config --cflags vapoursynth) src/wwxd.c src/detection.c To use: core.wwxd.WWXD(clip=src)
__________________
Buy me a "coffee" and/or hire me to write code! |
17th August 2017, 16:37 | #4 | Link |
Excessively jovial fellow
Join Date: Jun 2004
Location: rude
Posts: 1,100
|
Getting it to execute would still require requesting all frames, you know. But this is VS, not Avisynth. We're in a Python script, we have way nicer tools available. If you want to generate a list of scene changes before running the rest of the script, you are free to recursively exec vspipe on your script and pass in the generated frame list as a command line argument to yourself, or something along those lines. You'll have to decode the source file twice but eh who cares.
|
17th August 2017, 18:55 | #5 | Link | |
Registered User
Join Date: Sep 2006
Posts: 1,657
|
Quote:
Code:
sample_range = range(1,10001) my_list = [] def test_recursion(num, sc_list): print(str(num)) if (num == 0): return sc_list if (num % 2 == 0): sc_list.append(num) test_recursion(num-1, sc_list) my_sc_list = test_recursion(len(sample_range), my_list) print(my_sc_list) |
|
17th August 2017, 19:59 | #6 | Link |
Excessively jovial fellow
Join Date: Jun 2004
Location: rude
Posts: 1,100
|
Not like that. I mean, you can use the subprocess module (or if you're feeling adventurous, os.execl) from your .vpy to run another instance of vspipe (on the same script, if you want - use the --arg stuff in vspipe to determine which mode to operate in) which gets the frame numbers for you. You can retrieve them from that other instance simply by printing them to stdout, for example in a FrameEval, and reading them back in your main script. Or write them to a file, or something.
|
18th August 2017, 19:38 | #7 | Link |
Registered User
Join Date: Sep 2006
Posts: 1,657
|
That's a lot of stuffs to learn...
So I'm trying to get the subprocess on vspipe working first, I did a simple caller and child script, but I don't know how to catch the returned video. I'm getting the error "AttributeError: 'bytes' object has no attribute 'set_output'". caller.vpy Code:
import vapoursynth as vs import subprocess core = vs.get_core(accept_lowercase=True) command = "vspipe child.vpy -" child = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) child_clip = child.stdout child_clip.output() Code:
import vapoursynth as vs core = vs.get_core(accept_lowercase=True) clip = core.std.BlankClip(width=640, height=480, length=1000) clip.set_output() |
18th August 2017, 22:35 | #8 | Link |
Excessively jovial fellow
Join Date: Jun 2004
Location: rude
Posts: 1,100
|
No that way won't work. vspipe normally writes frame data to stdout (assuming you use - as the output filename) and status/progress messages to stderr. You don't want raw frame data though, that's of no use to you. What you do want is frame numbers. My idea was that to capture the WWXD scene change numbers you'd tack on a FrameEval after WWXD and inspect the frame props in there. Once you have a frame number you can either make a list of them in python and write that to a file or something, or you can go with my original idea and just print() them. print() writes to stdout, so normally you don't want to do that in a .vpy since it'd get mixed in with your actual frame data that vspipe is writing to stdout at the same time, so you'd have to use . as the output filename to get vspipe to leave stdout alone. When you do that, you can read the frame numbers from the stdout pipe in caller.vpy by calling child.stdout.readlines(). You'll get them back as a line of strings.
|
19th August 2017, 02:53 | #9 | Link | |
Registered User
Join Date: Sep 2006
Posts: 1,657
|
Quote:
caller Code:
import vapoursynth as vs import subprocess core = vs.get_core(accept_lowercase=True) command = "vspipe child.vpy ." sc_list = [] child = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) while True: line = child.stdout.readline() if line == '': break sc_list.append(line) Code:
import vapoursynth as vs core = vs.get_core(accept_lowercase=True) clip = core.ffms2.Source(r"abc.avi") clip = core.wwxd.WWXD(clip) def PrintSC(n,f,clip): if f.props.Scenechange: print(n) return clip sc_clip = core.std.FrameEval(clip, functools.partial(PrintSC, clip=clip), clip) sc_clip.set_output() |
|
Thread Tools | Search this Thread |
Display Modes | |
|
|