views:

240

answers:

1

ffmpeg feels like its taking a long time. I then look at my output file and i see it stops between 6 and 8mbs. A fully encoded file is about 14mb. Why does ffmpeg stop? My code locks up on StandardOutput.ReadToEnd();. I had to kill the process (after seeing it not move for more then 10 seconds when i see it update every second previously) then i get the results of stdout and err. stdout is "" stderr is below.

The output msg shows the filesize ended. I also see a drop in my CPU usage when it stops. I copyed the argument from visual studios. CD to the same working directory and ran the cmd (bin/ffmpeg) and pasted the argument. It was able to complete.

NOTE: I must get std out and err to check for failures.

    int soundProcess(string infn, string outfn)
    {
        string aa, aa2;
        aa = aa2 = "DEAD";

        var app = new Process();

        app.StartInfo.UseShellExecute = false;
        app.StartInfo.RedirectStandardOutput = true;
        app.StartInfo.RedirectStandardError = true;
        //*/
        app.StartInfo.FileName = @"bin\ffmpeg.exe";
        app.StartInfo.Arguments = string.Format(@"-i ""{0}"" -ab 192k -y {2} ""{1}""", infn, outfn, param);
        app.Start();
        try
        {
            app.PriorityClass = ProcessPriorityClass.BelowNormal;
        }
        catch (Exception ex)
        {
            if (!Regex.IsMatch(ex.Message, @"Cannot process request because the process .*has exited"))
                throw ex;
        }

        aa = app.StandardOutput.ReadToEnd();
        aa2 = app.StandardError.ReadToEnd();

        app.WaitForExit();

        if (aa2.IndexOf("could not find codec parameters") != -1)
            return 1;
        else if (aa == "DEAD" || aa2 == "DEAD")
            return -1;
        else if (aa2.Length != 0)
            return -2;
        else
            return 0;
    }

The output of stderr. stdout is empty.

FFmpeg version SVN-r15815, Copyright (c) 2000-2008 Fabrice Bellard, et al.
  configuration: --enable-memalign-hack --enable-postproc --enable-swscale --enable-gpl --enable-libfaac --enable-libfaad --enable-libgsm --enable-libmp3lame --enable-libvorbis --enable-libtheora --enable-libx264 --enable-libxvid --disable-ffserver --disable-vhook --enable-avisynth --enable-pthreads
  libavutil     49.12. 0 / 49.12. 0
  libavcodec    52. 3. 0 / 52. 3. 0
  libavformat   52.23. 1 / 52.23. 1
  libavdevice   52. 1. 0 / 52. 1. 0
  libswscale     0. 6. 1 /  0. 6. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on Nov 13 2008 10:28:29, gcc: 4.2.4 (TDM-1 for MinGW)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'C:\dev\src\trunk\prjname\prjname\App_Data/temp/m/o/6304266424778814852':
  Duration: 00:12:53.36, start: 0.000000, bitrate: 154 kb/s
    Stream #0.0(und): Audio: aac, 44100 Hz, stereo, s16
Output #0, ipod, to 'C:\dev\src\trunk\prjname\prjname\App_Data\temp\m\o\2.m4a':
    Stream #0.0(und): Audio: libfaac, 44100 Hz, stereo, s16, 192 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
Press [q] to stop encoding
size=      87kB time=4.74 bitrate= 150.7kbits/s    
size=     168kB time=9.06 bitrate= 151.9kbits/s    
size=     265kB time=14.28 bitrate= 151.8kbits/s    
size=     377kB time=20.29 bitrate= 152.1kbits/s    
size=     487kB time=26.22 bitrate= 152.1kbits/s    
size=     594kB time=32.02 bitrate= 152.1kbits/s    
size=     699kB time=37.64 bitrate= 152.1kbits/s    
size=     808kB time=43.54 bitrate= 152.0kbits/s    
size=     930kB time=50.09 bitrate= 152.2kbits/s    
size=    1058kB time=57.05 bitrate= 152.0kbits/s    
size=    1193kB time=64.23 bitrate= 152.1kbits/s    
size=    1329kB time=71.63 bitrate= 152.0kbits/s    
size=    1450kB time=78.16 bitrate= 152.0kbits/s    
size=    1578kB time=85.05 bitrate= 152.0kbits/s    
size=    1706kB time=92.00 bitrate= 152.0kbits/s    
size=    1836kB time=98.94 bitrate= 152.0kbits/s    
size=    1971kB time=106.25 bitrate= 151.9kbits/s    
size=    2107kB time=113.57 bitrate= 152.0kbits/s    
size=    2214kB time=119.33 bitrate= 152.0kbits/s    
size=    2345kB time=126.39 bitrate= 152.0kbits/s    
size=    2479kB time=133.56 bitrate= 152.0kbits/s    
size=    2611kB time=140.76 bitrate= 152.0kbits/s    
size=    2745kB time=147.91 bitrate= 152.1kbits/s    
size=    2880kB time=155.20 bitrate= 152.0kbits/s    
size=    3013kB time=162.40 bitrate= 152.0kbits/s    
size=    3146kB time=169.58 bitrate= 152.0kbits/s    
size=    3277kB time=176.61 bitrate= 152.0kbits/s    
size=    3412kB time=183.90 bitrate= 152.0kbits/s    
size=    3540kB time=190.80 bitrate= 152.0kbits/s    
size=    3670kB time=197.81 bitrate= 152.0kbits/s    
size=    3805kB time=205.08 bitrate= 152.0kbits/s    
size=    3932kB time=211.93 bitrate= 152.0kbits/s    
size=    4052kB time=218.38 bitrate= 152.0kbits/s    
size=    4171kB time=224.82 bitrate= 152.0kbits/s    
size=    4277kB time=230.55 bitrate= 152.0kbits/s    
size=    4378kB time=235.96 bitrate= 152.0kbits/s    
size=    4486kB time=241.79 bitrate= 152.0kbits/s    
size=    4592kB time=247.50 bitrate= 152.0kbits/s    
size=    4698kB time=253.21 bitrate= 152.0kbits/s    
size=    4804kB time=258.95 bitrate= 152.0kbits/s    
size=    4906kB time=264.41 bitrate= 152.0kbits/s    
size=    5012kB time=270.09 bitrate= 152.0kbits/s    
size=    5118kB time=275.85 bitrate= 152.0kbits/s    
size=    5234kB time=282.10 bitrate= 152.0kbits/s    
size=    5331kB time=287.39 bitrate= 151.9kbits/s    
size=    5445kB time=293.55 bitrate= 152.0kbits/s    
size=    5555kB time=299.40 bitrate= 152.0kbits/s    
size=    5665kB time=305.37 bitrate= 152.0kbits/s    
size=    5766kB time=310.80 bitrate= 152.0kbits/s    
size=    5876kB time=316.70 bitrate= 152.0kbits/s    
size=    5984kB time=322.50 bitrate= 152.0kbits/s    
size=    6094kB time=328.49 bitrate= 152.0kbits/s    
size=    6212kB time=334.76 bitrate= 152.0kbits/s    
size=    6327kB time=340.99 bitrate= 152.0kbits/s    
+3  A: 

Suppose you caught a deadlock here.

A reference from MSDN:

There is a similar issue when you read all text from both the standard output and standard error streams. The following C# code, for example, performs a read operation on both streams.

 // Do not perform a synchronous read to the end of both
 // redirected streams.
 // string output = p.StandardOutput.ReadToEnd();
 // string error = p.StandardError.ReadToEnd();
 // p.WaitForExit();
 // Use asynchronous read operations on at least one of the streams.
 p.BeginOutputReadLine();
 string error = p.StandardError.ReadToEnd();
 p.WaitForExit();

The code example avoids the deadlock condition by performing asynchronous read operations on the StandardOutput stream. A deadlock condition results if the parent process calls p.StandardOutput.ReadToEnd followed by p.StandardError.ReadToEnd and the child process writes enough text to fill its error stream. The parent process would wait indefinitely for the child process to close its StandardOutput stream. The child process would wait indefinitely for the parent to read from the full StandardError stream.

You can use asynchronous read operations to avoid these dependencies and their deadlock potential. Alternately, you can avoid the deadlock condition by creating two threads and reading the output of each stream on a separate thread.

UPDATE: when I worked with ffmpeg, I wrote a wrapper to it. The main idea was to parse each output line from stderr. Due to this I was able to recognize conversion deadlocks and manually kill the conversion process when necessary. It also useful to obtain additional media information like duration and codecs used.

UPDATE2(guess the last ;) ): as I mentioned above I used stderr in async mode to parse output. In addition stdout was used in normal(mean, not async) mode to get the result of video preview generation (a feature of ffmpeg) to get result without using of temporary file.

Hope, this helps.

Alex
OMG THANK YOU! you saved me. I would have never known this.
acidzombie24
You're welcome :)
Alex
you wrote me this answer too!?! wow thanks. You been a life saver (and yes all those upvotes today were from me after seeing your pipe code :))
acidzombie24
Thank you too :)
Alex