jluce50 122 Posted February 27, 2015 Author Posted February 27, 2015 Can I just say that getting ffmpeg to build on Windows is a NIGHTMARE! I've been at it all day and it's just one error after another. If I had any hair I'd have pulled it all out by now. GAAAHHH!!! I'm this close --> <-- to loading up linux on a flash drive and running that... Sorry, just had to vent.
Luke 40071 Posted February 28, 2015 Posted February 28, 2015 This is the best place to go for windows builds: http://ffmpeg.zeranoe.com/builds/ You might find some volunteers to help there. They also post their build scripts publicly.
Luke 40071 Posted February 28, 2015 Posted February 28, 2015 well i put in a windows-based throttle via process suspension and can confirm that it works. this really should only be a temporary solution until the ffmpeg changes are complete. I know others have been able to pause ffmpeg processes with success, but it's generally not a recommended practice for multi-threaded apps because this only pauses the main thread i believe. So if ffmpeg hasn't been designed for this, it's child threads may continue to operate which could create unexpected results.
Carlo 4552 Posted February 28, 2015 Posted February 28, 2015 On windows if you suspend the process it should suspend all threads belonging to that process. I've never heard of it only suspending the main or first thread as that would be kind of dumb IMHO. But if this is the way it presently works, we can easily create a function that will suspend all threads for the program. Would not be much harder to do if needed. Glad to hear you're making good progress on this!
Luke 40071 Posted February 28, 2015 Posted February 28, 2015 well that is what i know based on Msdn documentation. it seems to be fine so we might as well just test it out for a while. since the ffmpeg change is considerably better i think that's where more time should be spent. also i've asked one developer to test a linux port of it. from there i'll check with our Bsd guys to see if the linux version will work. Osx will take some research though.
Luke 40071 Posted March 1, 2015 Posted March 1, 2015 actually it might be fairly comprehensive foreach (ProcessThread thread in process.Threads) { var pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)thread.Id); if (pOpenThread == IntPtr.Zero) { break; } SuspendThread(pOpenThread); }
jluce50 122 Posted March 1, 2015 Author Posted March 1, 2015 This is the best place to go for windows builds: http://ffmpeg.zeranoe.com/builds/ You might find some volunteers to help there. They also post their build scripts publicly. Great, thanks. I'll check it out...
denethor 90 Posted March 1, 2015 Posted March 1, 2015 well i put in a windows-based throttle via process suspension and can confirm that it works. this really should only be a temporary solution until the ffmpeg changes are complete. I know others have been able to pause ffmpeg processes with success, but it's generally not a recommended practice for multi-threaded apps because this only pauses the main thread i believe. So if ffmpeg hasn't been designed for this, it's child threads may continue to operate which could create unexpected results. I think this is implemented in 5537 Alpha. Although it dramatically improved the CPU usage it has broke the multi stream transcoding stability. If I start second stream on another device first one got hangs. Sometimes it completely stops, sometimes hangs for a long time etc. It is practically impossible to stream multiple files to multiple device. But one stream works stable.
jabbera 23 Posted March 1, 2015 Posted March 1, 2015 While the thread schedulers are an unknown, instead of suspending why don't we just lower the priority of ffmpeg processes to idle that has more then 120 seconds of content buffered. It's easy to implement on all platforms and should accomplish the goal of giving "starving" ffmpeg processes priority. It will also allow idle time to be used to continue to transcode.
Luke 40071 Posted March 1, 2015 Posted March 1, 2015 I think this is implemented in 5537 Alpha. Although it dramatically improved the CPU usage it has broke the multi stream transcoding stability. If I start second stream on another device first one got hangs. Sometimes it completely stops, sometimes hangs for a long time etc. It is practically impossible to stream multiple files to multiple device. But one stream works stable. can someone else confirm that? if that's the case then we'll have to just wait for ffmpeg.
jluce50 122 Posted March 1, 2015 Author Posted March 1, 2015 (edited) I think this is implemented in 5537 Alpha. Although it dramatically improved the CPU usage it has broke the multi stream transcoding stability. If I start second stream on another device first one got hangs. Sometimes it completely stops, sometimes hangs for a long time etc. It is practically impossible to stream multiple files to multiple device. But one stream works stable. can someone else confirm that? if that's the case then we'll have to just wait for ffmpeg. Wouldn't this just be a matter of how it's implemented? I would be surprised if was impossible to suspend one process without affecting the others. When an ffmpeg process is kicked off, doesn't the code retain a handle of some sort? If not, perhaps we can create some sort of process pool to keep track... Edited March 1, 2015 by jluce50
Luke 40071 Posted March 1, 2015 Posted March 1, 2015 Feel free to play with it https://github.com/MediaBrowser/MediaBrowser/blob/dev/MediaBrowser.ServerApplication/Native/WindowsProcessManager.cs
jluce50 122 Posted March 1, 2015 Author Posted March 1, 2015 Feel free to play with it https://github.com/MediaBrowser/MediaBrowser/blob/dev/MediaBrowser.ServerApplication/Native/WindowsProcessManager.cs Might be a day or two, but I'll definitely take a look.
Nologic 30 Posted March 1, 2015 Posted March 1, 2015 (edited) hmm going back to command line...there are two ways of seeking, fast & accuarate. When you use -ss prior to the input file it's fast...when it's used after the input its accuarate...and well you can use them both. [Linky] [Linky] Edited March 1, 2015 by Nologic
FredipusRex 12 Posted March 2, 2015 Posted March 2, 2015 Glancing over the ffmpeg code, it seems to me that you can implement a pause step pretty easily with about 4-5 lines of code. You just need to tap into the pre-existing output availability checking. If output is (temporarily) unavailable, it already pauses to give it a chance to recover. Tap into that existing system and you don't have to understand the ramifications of every change. 1. Create a new "global" int variable named "paused" in ffmpeg.c. It only needs to be file-scope. Default it to zero. 2. In check_keyboard_interaction(), add: if (key == 'p') paused ^= 1; // Toggle pause 3. In transcode_step(), the first bit of code checks for a problem with the output streams, attempts to reset them, does an internal pause and returns 0 (success), which allows the outer code loop (including key press detection) some cycles. Hijack this by adding some code to the beginning of the procedure: if (paused) { av_usleep(1000); // Shorter sleep duration to be more responsive to unpause return 0; } That should be it. This won't start/stop things on a dime, but it should allow fairly responsive throttling without making wholesale changes to ffmpeg. Which should make it easier to get a pull request approved. 1
FredipusRex 12 Posted March 2, 2015 Posted March 2, 2015 You might need to let any keystroke unpause to avoid side-effects. So 'p' could be used by MB3 to both pause and unpause while any non-'p' key would clear the pause flag and do what it already does. Keeps everything backward compatible.
Luke 40071 Posted March 2, 2015 Posted March 2, 2015 Glancing over the ffmpeg code, it seems to me that you can implement a pause step pretty easily with about 4-5 lines of code. You just need to tap into the pre-existing output availability checking. If output is (temporarily) unavailable, it already pauses to give it a chance to recover. Tap into that existing system and you don't have to understand the ramifications of every change. 1. Create a new "global" int variable named "paused" in ffmpeg.c. It only needs to be file-scope. Default it to zero. 2. In check_keyboard_interaction(), add: if (key == 'p') paused ^= 1; // Toggle pause 3. In transcode_step(), the first bit of code checks for a problem with the output streams, attempts to reset them, does an internal pause and returns 0 (success), which allows the outer code loop (including key press detection) some cycles. Hijack this by adding some code to the beginning of the procedure: if (paused) { av_usleep(1000); // Shorter sleep duration to be more responsive to unpause return 0; } That should be it. This won't start/stop things on a dime, but it should allow fairly responsive throttling without making wholesale changes to ffmpeg. Which should make it easier to get a pull request approved. Would you mind helping but doing a little differently? I would forget about the "check for output stream problem" and just allow the pause value to be set via accepting an stdin key.
Luke 40071 Posted March 2, 2015 Posted March 2, 2015 You might need to let any keystroke unpause to avoid side-effects. So 'p' could be used by MB3 to both pause and unpause while any non-'p' key would clear the pause flag and do what it already does. Keeps everything backward compatible. Well when we send commands it doesn't have to be a single key. we can easily send a string, so we could actually send the word pause and unpause. it just would be inconsistent with the naming of what they currently accept.
FredipusRex 12 Posted March 2, 2015 Posted March 2, 2015 ffmpeg's stdin processing is largely single keystroke based (there is a 'command' variant, but that's complicated), so 'p' is easy while 'pause' is hard(er). I was just thinking that if we limited the modification to a single character and preserved backward compatibility by not compromising other keystrokes, you'd be more likely to get accepted into the main trunk. Oh, and the output stream problem was just an example. Really, what I'm suggesting is setting/unsettling the pause flag via the preexisting stdin processing ('s' already acts as a flag toggle, so it's consistent with how they do things). Then checking that flag at the top of transcode_step(), which currently has an "output stream problem" check at the top. If we do something very similar to what's done for output stream problems (wait a while and then hand back to the outer loop), again it's a very minimalist change that mimics their code style. I'd love to help, but I'm currently without a development computer (mine died a few months ago and I don't have the funds to replace it now). But I'm happy to look at code and help out that way.
Carlo 4552 Posted March 2, 2015 Posted March 2, 2015 hmm going back to command line...there are two ways of seeking, fast & accuarate. When you use -ss prior to the input file it's fast...when it's used after the input its accuarate...and well you can use them both. [Linky] [Linky] The biggest problem with the command lines is that you can't "copy" the video and seek accurately YET. So for example: -c:v copy is a no go.
jluce50 122 Posted March 2, 2015 Author Posted March 2, 2015 I'd love to help, but I'm currently without a development computer (mine died a few months ago and I don't have the funds to replace it now). But I'm happy to look at code and help out that way. That is much appreciated and I'll definitely take you up on that. I like the approach you've outlined, but I'll need to get ffmpeg building on my Windows machine first. After that headache, making and testing the changes should be a breeze by comparison...
ebr 15664 Posted March 2, 2015 Posted March 2, 2015 I would suggest specific pause and unpause commands. Using a toggle opens the door for something to get out of sync.
jluce50 122 Posted March 2, 2015 Author Posted March 2, 2015 can someone else confirm that? if that's the case then we'll have to just wait for ffmpeg. I haven't started messing with the code yet, but I thought I'd provide a little more detail. It looks like what's happening is that the first process started works fine. When starting a second process, it will transcode until it reaches the threshold and then then suspends but never resumes. Meanwhile the first process continues suspending/resuming appropriately. Also, when closing the respective video players the ffmpeg process continue to hang around in a suspended state. If I start up another stream a third ffmpeg is created.
jabbera 23 Posted March 2, 2015 Posted March 2, 2015 (edited) Please consider using process priority instead of thread suspension for controlling this. It's platform independent and allows transcoding to continue while the cpu is idle. It also doesn't require ffmpeg changes. https://github.com/MediaBrowser/MediaBrowser/pull/1031 Edited March 2, 2015 by jabbera
Luke 40071 Posted March 2, 2015 Posted March 2, 2015 Please consider using process priority instead of thread suspension for controlling this. It's platform independent and allows transcoding to continue while the cpu is idle. It also doesn't require ffmpeg changes. https://github.com/MediaBrowser/MediaBrowser/pull/1031 how much cpu savings?
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now