Tuesday
23rd September 2004, 04:40
At work recently I have had a lot of time to think and I was wondering if with the immenent approach of dual core cpus xvid would be ready to make use of the extra power.
I'm aware the usual response to this type of question is "avisynth one thread, xvid another - hence multithreded" but this is often very once sided, a simple trim,crop,resize script isn't really competition for mpeg4 encoding so one of the cpu's would be left running near idle.
Also, from reading the type of trouble the avisynth devs have been having with trying to make avisynth more multithreaded I figured there must be an easier way.
The idea - multiple instances, allow me to explain:
Suppose a movie file already filtered and in a basically ready-to-be-encodee state, 150000 frames long
At the moment we have one encoder that churns through these frames one at a time 1 - 150000, on the first pass determining the complexity of the frame, bitrate at q2 etc, then again on the second pass outputting the final encode. See figure 1.
http://www.lancs.ac.uk/ug/faulder/images/fig1.gif
This obvoisly only makes use of a single thread/cpu, wasting the potential of dual core/cpu systems.
How about this:
Take the same movie file, ready to go, 150000 frames.
When sent to the encoding app, a arbiter program is started that determines the number of cpu's in the system, and splits the movie up into an appropriote amount of chunks, say a dual core system is used so 2 chunks, 75000 frames long each.
For each chunk an instance of the xvid encoder is started and sets about in the normal way, with minor diffenerces:
1- The arbiter program mentioned earlier forces a keyframe at the start of each chunk, so no cross-chunk motion calculations would be needed.
2- When each chunk has finished its first pass, some additional rate control calculations would need to be performed by the arbiter program to determine the ratio of the final bitrate given to each chunk. Eg:
Chunk 1 has a q2 average bitrate of 1000kbps and chunk 2 has a q2 average bitrate of 2000kbps (more action at the end of the film of course :p) then say the user requested an overall final average bitrate of 900kbps chunk 1 would be assigned at desired final average bitrate of 600kbps and chunk 2 1200kbps
When all the chunks are finished the arbiter program appends them together and hands them back to the enoding app that requested the whole operation in the first place. (see figure 2)
http://www.lancs.ac.uk/ug/faulder/images/fig2.gif
This idea easily scales to many cpus (just think of the 16-way beast intel showed off a few weeks ago doign this :) ) but would not be that effective if used with "virtual cpu" systems like hyprer-threading as far as I know due to the limited number of execution units and very similar code running on each "cpu".
I'm not a programmer but from what I can imageine implementing this kind of system would be alot simpler than trying to get the current encoder to use more threads as all that is really required is a few changes to rate control and somthing to set it all up. Although the approach would obviosly be useless for on-the-fly encoding.
Hell, you could even implement this by hand using a few instances of virtualdub and a little maths if you want to test the idea, but having it all done within the codec would be an awful lot easier...
The only problem I can forsee is the "frame in - frame out" nature of vfw, but surely this could be overcome with a command line encoder without too much hastle.
Note: the ideas represented above come from a man who has never programmed, but does spend an awful lot of time with computers.
I'm aware the usual response to this type of question is "avisynth one thread, xvid another - hence multithreded" but this is often very once sided, a simple trim,crop,resize script isn't really competition for mpeg4 encoding so one of the cpu's would be left running near idle.
Also, from reading the type of trouble the avisynth devs have been having with trying to make avisynth more multithreaded I figured there must be an easier way.
The idea - multiple instances, allow me to explain:
Suppose a movie file already filtered and in a basically ready-to-be-encodee state, 150000 frames long
At the moment we have one encoder that churns through these frames one at a time 1 - 150000, on the first pass determining the complexity of the frame, bitrate at q2 etc, then again on the second pass outputting the final encode. See figure 1.
http://www.lancs.ac.uk/ug/faulder/images/fig1.gif
This obvoisly only makes use of a single thread/cpu, wasting the potential of dual core/cpu systems.
How about this:
Take the same movie file, ready to go, 150000 frames.
When sent to the encoding app, a arbiter program is started that determines the number of cpu's in the system, and splits the movie up into an appropriote amount of chunks, say a dual core system is used so 2 chunks, 75000 frames long each.
For each chunk an instance of the xvid encoder is started and sets about in the normal way, with minor diffenerces:
1- The arbiter program mentioned earlier forces a keyframe at the start of each chunk, so no cross-chunk motion calculations would be needed.
2- When each chunk has finished its first pass, some additional rate control calculations would need to be performed by the arbiter program to determine the ratio of the final bitrate given to each chunk. Eg:
Chunk 1 has a q2 average bitrate of 1000kbps and chunk 2 has a q2 average bitrate of 2000kbps (more action at the end of the film of course :p) then say the user requested an overall final average bitrate of 900kbps chunk 1 would be assigned at desired final average bitrate of 600kbps and chunk 2 1200kbps
When all the chunks are finished the arbiter program appends them together and hands them back to the enoding app that requested the whole operation in the first place. (see figure 2)
http://www.lancs.ac.uk/ug/faulder/images/fig2.gif
This idea easily scales to many cpus (just think of the 16-way beast intel showed off a few weeks ago doign this :) ) but would not be that effective if used with "virtual cpu" systems like hyprer-threading as far as I know due to the limited number of execution units and very similar code running on each "cpu".
I'm not a programmer but from what I can imageine implementing this kind of system would be alot simpler than trying to get the current encoder to use more threads as all that is really required is a few changes to rate control and somthing to set it all up. Although the approach would obviosly be useless for on-the-fly encoding.
Hell, you could even implement this by hand using a few instances of virtualdub and a little maths if you want to test the idea, but having it all done within the codec would be an awful lot easier...
The only problem I can forsee is the "frame in - frame out" nature of vfw, but surely this could be overcome with a command line encoder without too much hastle.
Note: the ideas represented above come from a man who has never programmed, but does spend an awful lot of time with computers.