5

Im trying to send a lot of desktop captured images to an encoders (FFmpeg) stdin.

The following code example works.

the CaptureScreen() function provides an image in 5-10 ms.

If I save the image in a MemoryStream it takes almost no time.

But I can only save 1 image every 45 ms to proc.StandardInput.BaseStream.

public void Start(string bitrate, string buffer, string fps, string rtmp, string resolution, string preset)
{
    proc.StartInfo.FileName = myPath + "\\ffmpeg.exe";
    proc.StartInfo.Arguments = "-f image2pipe -i pipe:.bmp -vcodec libx264 -preset " + preset + " -maxrate " + bitrate + "k -bufsize " +
    buffer + "k -bt 10 -r " + fps + " -an -y test.avi"; //+ rtmp;
    proc.StartInfo.UseShellExecute = false;
    proc.StartInfo.RedirectStandardInput = true;
    proc.StartInfo.RedirectStandardOutput = true;

    proc.Start();

    Stopwatch st = new Stopwatch();
    BinaryWriter writer = new BinaryWriter(proc.StandardInput.BaseStream);
    System.Drawing.Image img;

    st.Reset();
    st.Start();

    for (int z = 0; z < 100; z++)
    {
        img = ScrCap.CaptureScreen();
        img.Save(writer.BaseStream, System.Drawing.Imaging.ImageFormat.Bmp);
        img.Dispose();
    }

    st.Stop();
    System.Windows.Forms.MessageBox.Show(st.ElapsedMilliseconds.ToString());
}

The question is:

Can I do the saving process faster?

I try to get stable 60 fps this way

John Saunders
  • 160,644
  • 26
  • 247
  • 397
Hasibii
  • 51
  • 1
  • 2

1 Answers1

2

The bottleneck here is that ffmpeg reads data at the same speed it compresses it to .avi, which is slow. So your img.Save method blocks until there is some space in the stream's buffer to write its data.

There is not much you can do. Compressing 60 fps HD video in real time require a huge processing power.

Nicolas Repiquet
  • 9,097
  • 2
  • 31
  • 53
  • 1
    is there a way to tell ffmpeg to speed things up? i mean it should be possible because i did realtime 60 fps hd in the past and ffmpeg is only using like 7 % cpu power. – Hasibii Sep 04 '12 at 14:59
  • 1
    You have to find out what is blocking the chain. Capturing image ? Encoding it to BMP ? Sending it to ffmpeg ? Compressing it to a .avi ? Writing the resulting video to the hard disk ? – Nicolas Repiquet Sep 04 '12 at 15:11
  • it has to be sending it to ffmpeg.. i tried writing th bmp to another stream and it took almost no time. Could it be faster to use a named pipe? – Hasibii Sep 04 '12 at 15:16
  • Ok. Maybe you can try to wrap `writer.BaseStream` in a `BufferedStream` to ease the thing. – Nicolas Repiquet Sep 04 '12 at 15:24
  • that did not do much unfortunatly – Hasibii Sep 04 '12 at 15:36
  • it seems like ffmpeg is not using enough cpu power, when i record no motion pictures (low ffmpeg processing) i need 37 for a frame, in high motion 45ms -50ms – Hasibii Sep 04 '12 at 15:43