2012-09-04 27 views
5

Im tratando de enviar muchas imágenes capturadas en el escritorio a un codificador (FFmpeg) stdin.Forma más rápida de escribir imágenes en Process.StandardInput.BaseStream

El siguiente ejemplo de código funciona.

la función CaptureScreen() proporciona una imagen en 5-10 ms.

Si guardo la imagen en un MemoryStream, no tardará casi nada.

Pero solo puedo guardar 1 imagen cada 45 ms en 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()); 
} 

La pregunta es:

¿Puedo hacer el proceso más rápido de ahorro?

intento conseguir 60 fps estables de esta manera

+0

¿Ha intentado utilizar 'ImageFormat.png' para reducir la cantidad real de datos que se leen/escriben? – PhonicUK

+0

Lo intenté. Es incluso más lento ... como 130 ms – Hasibii

Respuesta

2

El cuello de botella es que ffmpeg lee los datos a la misma velocidad que lo comprime a .avi, que es lento. Entonces su método img.Save bloquea hasta que haya espacio en el búfer de la secuencia para escribir sus datos.

No hay mucho que pueda hacer. La compresión de video HD de 60 fps en tiempo real requiere una gran potencia de procesamiento.

+1

¿hay alguna manera de decirle a ffmpeg que acelere las cosas? Quiero decir que debería ser posible porque lo hice en tiempo real 60 fps hd en el pasado y ffmpeg solo usa 7% de potencia de la CPU. – Hasibii

+1

Tienes que averiguar qué está bloqueando la cadena. ¿Capturar imagen? ¿Codificándolo a BMP? ¿Enviarlo a ffmpeg? Comprimirlo a un .avi? ¿Escribir el video resultante en el disco duro? –

+0

tiene que estar enviándolo a ffmpeg .. intenté escribir th bmp en otra transmisión y casi no me llevó tiempo. ¿Podría ser más rápido usar un tubo con nombre? – Hasibii

Cuestiones relacionadas