View Full Version : Frameserving on a different Machine, possible??
Scorpion_fg
4th February 2004, 15:45
First of all I'd like to say hi to everyone, as this Forum has helped me a lot in the past, and it's my first post.
As i have recently done a couple of encodes using a lot of filtering (SharpRresize, ...), i was wondering if it would be possible to have Avisynth doing the filtering and frameserving on one machine, and then do the encoding on another machine over a LAN.
Thanks in advance.
sh0dan
4th February 2004, 15:57
No. :(
I've started yesterday working on transmitting frames using TCP over LAN's. It's still far from a working implementation. But it's in the works, but since I don't know anything about TCP, Multithreading or GUI's (which this hopefully will include) it may take a while.
First version will probably only support one client per open script (which also is a good thing for many reasons).
Richard Berg
5th February 2004, 14:32
As you know, my very first Avisynth mod was to turn it into a servlet. I found the easiest way was to use the OS's internal HTTP server, but can see how this tactic would potentially cause installation nightmares -- everything since 98 has one, but they are structured very differently with regard to plugins, permissions, default connection types, etc. My skills with raw sockets aren't very solid at the moment, but because this feature has been in the back of my mind since essentially the first day poptones & I started hacking, I'm willing to do what I can.
The main problem is that the most important + hardest part is the very first step: designing a protocol. (Copy this thread to the dev forum if you like).
sh0dan
5th February 2004, 20:00
Transmitting via TCP is pretty much byte-pushing. You send a binary array (packet) of a certain size, and it will be recieved by the client as it is.
I haven't planned going into rocket science here, which is why I dropped UDP, as it might be a tad faster, but give you no guarrantee that your packets aren't dropped or recieved out-of-order.
Basicly I plan - 1 byte "type information" - up to 1024 bytes data at the time. I started a winsock2 (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/getting_started_with_winsock.asp) implementation, but I plan to scrap it in favour of a C++ WFC (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/HTML/_core_windows_sockets.3a_.using_class_casyncsocket.asp) implementation that seems much nicer.
My main problem right now is doing threading. The server should start in a separate thread and pretty much not influence the script output of the server. This basicly means that you just need to open the script in vdub, and you're flying. Threads do however still confuse me a bit, as it seems strange to have to invoke static functions to spawn them.
I would also like to do the client as a threaded program, as this would allow the next frame to be requested/transfered, while the last one is being sent futher up the chain and being compressed. Ideally the server would also be able to request frames ahead.
This will also enable "frameserving" to other platforms, if anyone cares to do a Linux client.
I furthermore plan adding a simple huffyuv predict gradiant left, as it is fast and works on any type of data.
I can commit my current code, even though it is pretty useless for now. It is designed as a plugin for AviSynth (to be installed alongside AviSynth).
timecop
6th February 2004, 05:09
>> but I plan to scrap it in favour of a C++ WFC implementation that seems much nicer.
AVISynth currently does not depend on MFC does it?
There's nothing special about CAsyncSocket, if you know winsock you can do everything CAsyncSocket does for you, and you don't need to be
using MFC either.
Any particular reason for dumping winsock version?
How does this "frameserver" work anyway, do you just put your plugin as the last "filter" in the chain and then play the .avs file?
And then have something like TCPSource(host, port) or something to
receive to another Avisynth script on the remote machine?
(that would be kind of cool, and if it supported random access etc.. HmmMmm).
Mug Funky
6th February 2004, 13:41
this could be extremely useful for long and complicated scripts - rather like how a "renderfarm" works - you have a whole bunch of computers doing different frames, and sending them all back to be encoded.
how cool would something like realtime MFtoon be? got a 1 fps script? use 25 or 30 computers on it :)
this would be a nightmare for developers, but i see no problem in dreaming :)
mf
6th February 2004, 13:59
Originally posted by Mug Funky
how cool would something like realtime MFtoon be? got a 1 fps script? use 25 or 30 computers on it :)
Ladida, bottleneck, ludidu, 168MByte/s... *whistle*
MfA
6th February 2004, 14:32
No whistling on the job, you are distracting yourself ... b not B. For slightly below realtime processing fast-ethernet sufficies for 720*x processing, for realtime you need lower resolution or gigabit ethernet.
mf
6th February 2004, 17:52
Originally posted by MfA
No whistling on the job, you are distracting yourself ... b not B. For slightly below realtime processing fast-ethernet sufficies for 720*x processing, for realtime you need lower resolution or gigabit ethernet.
That's the idea. mfToon does 2560x1920. 2560x1920x12x24/8/1024/1024=168.75MByte/s. If you do the up->down sampling step on 1 pc, you already have a bottleneck of 8fps regardless of network speed.
But you could indeed get mfToon up to 4fps using 2 PC distributed processing, but using more PC's you're gonna get abovementioned bottlenecks.
Richard Berg
7th February 2004, 08:38
Even with TCP you need handshaking. Telling a machine "hi, I'm Avisynth client v. XXX requesting frame YYY from script ZZZ on port PPP" needs some dialogue back & forth with lots of error checking. (With networks, anything that can go wrong, or out of order, or whatever, will).
The protocol I'm most familiar with is DC++, which while pretty extensive by now is also essentially about connecting to peers that send/receive raw bytes. We don't need the searching or chatting features, but it's an interesting counterpoint.
The server should start in a separate thread and pretty much not influence the script output of the server. This basicly means that you just need to open the script in vdub, and you're flying.
I think the most logical way to write a server is as a standalone app using Invoke, or perhaps a component of AVSEditor. Someone using v1.0 might not care whether the DLL was loaded via Vdub or not, but keeping it separate lets you add future features that wouldn't be possible otherwise (e.g. the ability to run as an NT service).
I know a decent bit about threading, but nothing on the Windows platform unfortunately :(
timecop
8th February 2004, 14:32
> or perhaps a component of AVSEditor
Since AVSEditor is written using VB.NET, I don't think you want any "components" from there.
sh0dan
8th February 2004, 15:57
@timecop: Strike. You have been warned earlier (http://forum.doom9.org/showthread.php?s=&threadid=69132) about flamebaits. Followup to PM - ONLY!
Richard Berg
12th February 2004, 00:25
I've done some reading. Threads on Win32 are done pretty similarly to what I've used on Unix, but there are also some APIs that have the potential to handle threading for us. WSAAsyncSelect (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winsock/winsock/wsaasyncselect_2.asp) lets the Win32 event architecture handle the asynchronous requests, or IO Completion Ports (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/base/i_o_completion_ports.asp) manage the thread pool entirely. (There are .NET APIs too but I assume we don't want that dependency).
Kentamanos
24th February 2004, 08:57
Forgive my ignorance if any of this doesn't make sense. I'm a fairly "experienced" Win32 developer (C/C++, Java, and lots of C# recently), but I'm very new to AVISynth (new, but very excited about it...very cool stuff). I've done lots of multi-threaded stuff before and quite a bit of socket code. In my experience, using the MFC socket libraries doesn't really buy you that much, and sticking to straight winsock code would probably be just about as easy.
If I understand how AVISynth works, doesn't the plugin only ever request a single frame at a time? If that's the case, wouldn't you basically "broadcast" (most likely using an actual broadcast) your request to all machines, and have each machine handle every nth frame (preparing them ahead of time)?
For instance, if you had 3 machines, one machine would do frame 0, 3, 6, etc., the second machine would do 1, 4, 7, etc., and the third would do 2, 5, 8, etc (figuring out which frames each machine handles would be a simple mod operation). When machine two sees someone ask for frame 0, he would know that the request for frame 1 should be coming soon, so he'd start preparing that frame (and the next one he's doing). Machine three would see the request for 0 and start preparing frame 2 ahead of time. When each broadcast request for a frame comes in, they simply return it as fast as they can. The downfall of this super simple delegation of work is your bottleneck is the slowest machine handling requests. You'd probably want something a bit more complicated as the actual work delegation method because of this.
As you are probably fully aware, TCP is guaranteed to be delivered in order, but slower (due to handshaking type stuff) than UDP (sometimes referred to as the "Unreliable Data Protocol" ;)). If you want to avoid the complications of out of order data and having to request chunks you somehow missed, definitely stick to TCP. UDP out of order packets probably wouldn't be an issue at all on a LAN, but I think there's still a chance you could not read a buffer quick enough and lose some data (correct me if I'm wrong on this please).
As far as the protocol goes, I think you should roll your own. It's pretty easy to design your own protocol. The easiest way I've found in the past is have all of the "chunks" (not a single chunk that goes across the wire, but a chunk inside the grander scheme of your protocol) be length prefixed. Send out an unsigned int (or 64 bit number if you need more than 4GB..which you shouldn't) as a length prefix. That way the machine receiving it knows exactly how many bytes to expect to receive and he knows that while reading a chunk he doesn't have to inspect the chunk for protocol type stuff. Just read the data and stick it in a buffer. This is similar to the RIFF format that WAV files use. "I'm sending you a chunk of type X (an enum type, possibly a 32-bit int) and it's Y bytes long". Have the highest level chunk contain all the "sub" chunks.
If I'm missing something (very possible) please feel free to correct me and accept my apology in advance :).
sh0dan
24th February 2004, 10:48
I've got a working implementation, but it's still in a testing/tuning/rewriting state. I've purposely not posted anything, as basic things are still being rewritten.
If you are interested you can follow the development in avisynth cvs (http://cvs.sourceforge.net/viewcvs.py/avisynth2/avisynth/src/plugins/TCPDeliver/?sortby=date&only_with_tag=MAIN). It is still under heavy development, so don't expect each commit to work optimally. My main goal for the time being is 100% CPU utilization, when running it locally. Binaries will be supplied when it is ready for testing.
Edit: The "viewcvs" above isn't completely updated. But you should get the idea anyway.
Regarding you scenario above, it is not really optimal to run several clients, since non-linear access isn't something compressed video sources (MPEG2, MPEG4, etc) like very much. But let's not worry ahead of time.
The biggest "missing" feature by now is a frame-request thread. The send thread is blocked while a frame is requested from the filters above, which is not really optimal. But finetuning can be done in time. GUI and better faulthandling is another thing on the TODO list.
Kentamanos
24th February 2004, 11:34
Cool deal...
I'll try it out tomorrow (once I relearn how to use cvs again :)). Just browsing the source so far, I only have one comment:
"I" before "E" except after "C" ;).
sh0dan
24th February 2004, 13:49
As mentioned, it is not finished. Compared to the viewcvs version I did some housecleaning for simplifying requests.
I'd be happy to hear your observations.
My current plans:
- Split large packets automatically and automatically rejoin them.
- Handshaking. (version info, etc).
- Make clients able to prefetch frames while computer is processing the current.
- Make large data transfers interuptible.
This is however a "learn-as-you-implement" project. I have done some UDP-based work previously, but in java, so this is rather new to me.
So I've expected some rewrites and reimplementations.
Edit: F*ck !"#/"¤/#¤%¤/ The stupid CVS just killed my updates... ¤%&%/&%¤%#¤# A big THANK YOU! to Sourceforge for killing three hours of work. :angry: :angry:
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.