I have a few boxes around at home, so if i do video-editing i’d like to benefit from that. We can use some avisynth plugins/enhancements to do so. There are two things we might do: a) running filters in parallel b) handing filters to another box (networking). The problem with multiple cores in Linux is that it’s not easily possible to run Avisynth on many cores in fact it’s per default just running on one core.
MT Approach
Let’s first take a look at the multiple cores issue.
3760 wdp 20 0 1573m 48m 6584 R 99 2.4 0:58.37 avs2yuv 3761 wdp 20 0 104m 57m 1336 S 4 2.8 0:01.40 x264
What you can see here is simple – I’m running avisynth using
wine avs2yuv test.avs - | x264 --demuxer y4m --output output.264 -
avs2yuv has 99% CPU where as it should have 200% (taking both cores into account) and x264 needs only 4% cpu (because the avisynth script is way too slow for x264 to even notice) – And here we got our first problem. Let’s see if we can change that behaviour. So i installed MT() and played around.
- SetMtMode(2) doesn’t change this behaviour.
- MT(, threads=2) changes this behaviour
3928 wdp 20 0 1574m 192m 6736 R 186 9.5 1:30.97 avs2yuv 3929 wdp 20 0 105m 63m 1336 S 8 3.1 0:02.78 x264
The downside of this is, that MT() might be bad for quality, and it might not work for everything. However, let’s put this into real numbers now:
Intel(R) Core(TM)2 Duo CPU T7500 @ 2.20GHz, 1001 frames, FFmpegSource2 + TNLMeans(), 2 threads
- with MT encoded 1001 frames, 2.51 fps, 279.84 kb/s
- without MT encoded 1001 frames, 1.47 fps, 278.98 kb/s
AMD Athlon(tm) II X4 645 Processor (3,1 GHz), 1001 frames, FFmpegSource2 + TNLMeans(), 4 threads
- with MT encoded 1001 frames, 6.96 fps, 279.23 kb/s
- without MT encoded 1001 frames, 2.05 fps, 279.22 kb/s
AMD Athlon(tm) II X4 630 Processor (2,8 GHz), 1001 frames, FFmpegSource2 + TNLMeans(), 4 threads
- with MT encoded 1001 frames, 6.96 fps, 279.23 kb/s
- without MT encoded 1001 frames, 2.05 fps, 279.22 kb/s
Intel Dualcore 2,2 GHz mobile cpu, 32bit system |
Amd Quad Core 3,1 GHz 32 bit system |
AMD Quadcore 2,8 GHz | |
without MT | 1.47 | 2.05 | |
with MT | 2.51 | 6.96 | |
speedup | 170% (ca 2 times) |
339% (ca 3 1/2 times) |
I’d say that’s a good improvement and worth it.
Networking Approach
The networking approach has some flaws. For example: The Concept in Avisynth works like this: You’re filtering a video, you’re handing the clip to another box using TCPServer – After TCPServer you can’t do anything anymore (thus you can’t do TCPSource to get the clip back). This means, if you want to hand it back you have to run several avisynth instances, like this:
box1 instance 1 | box2 | box1 instance 2 |
Blur(1) TCPServer() | TCPSource(„box1 instance1“) nnedi3 TCPServer() | TCPSource(box2) Sharpen |
i.e.: box 1 instance 1 (10.0.0.1 port 7777) » box 2 (10.0.0.2) port 8888 » box 1 instance 2 (10.0.0.1 port 6666)
The next flaw is, this is still only linear processing, so it doesn’t matter how many boxes you add, if your boxes are equal in power a full encode will take just as much time as it would on one box, probably due to the networking a bit more. So this makes only sense, if you have expensive filters on a fast box and the rest on your slow box. However, we can try to work around that using Crop.
box1
FFMpegSource2() _do_some_fast_filtering_ TCPServer()
box2
TCPSource().Crop() # take the upper half of the frame do some filtering TCPServer()
box3
TCPSource().Crop() # take the bottom half of the frame do some filtering TCPServer()
box1 instance2
top = TCPSource(box2) bottom = TCPSource(box3) StackVertical(top, bottom)
That’d be very basic threading. And it works fine. The problematic part is that some filters aren’t processing the edges – So you might have trouble at the edges where you cropped. Some Way to come around that, would be to crop 16px more and when setting it together, average those 16px or remove them completely.
Alltogether
Now you can use MT() also, of course if you hand your clip to another box. i.e.
TCPSource() MT("filter", threads=x) TCPServer()
But let’s see, what do i get when doing both?
Conclusion
Well well, i’m a bit disapointed, because the networking stuff is pretty complicated. Features i’m missing for example are giving filters from one box to another. i.e. some feature like:
TCPRun("Filter1().Filter2().Filter3()", "ip", port, compression)
The way it’s currently done, i have to write scripts and place them onto the specific box. In Linux it’s even more complicated (no idea how the windows guys are doing that) i have to open the .avs in virtualdub in wine first, before i can connect to em using TCPSource. Thus the administrative part behind this magic is quite high.
No Comments