2015-12-20 8 views
0

Я пишу код, который считывает данные h264 из сокета, передает его на h264dec.exe (openh264 decoder), а затем обрабатывает данные YUV в декодере YUV-RGB. Моя проблема в том, что openh264dec работает как «h264dec video.h264 out.yuv».Подставить аргумент с трубками

И я действительно не знаю, как обращаться с аргументами в коде, чтобы служить им в качестве потоков. Для целей обучения я пытался h264dec video.h264 \\.\pipe\h264input, но он не работает, код, как показано ниже:

NamedPipeServerStream pipeServ = new NamedPipeServerStream(Utility.DecoderOutputPipeName, PipeDirection.InOut); 

Openh264.Openh264 openh264 = new Openh264.Openh264(); 
openh264.Start(); 
pipeServ.WaitForConnection(); 
Openh264.YUVDecoder decoder = new Openh264.YUVDecoder(pipeServ, 640, 480); 
decoder.NewFrame += Decoder_NewFrame; 
decoder.Start(); 

Процесс:

public Openh264() 
{ 
    string args; 
    //args = @" \\.\pipe\" + Utility.DecoderInputPipeName; 
    args = @"C:\test\vid.h264"; 
    args += @" \\.\pipe\" + Utility.DecoderOutputPipeName; 
    openh264 = new Process(); 
    openh264.StartInfo.CreateNoWindow = true; 
    openh264.StartInfo.UseShellExecute = false; 
    openh264.StartInfo.FileName = "h264dec.exe"; 
    openh264.StartInfo.Arguments = args; 
} 

YUV декодер принимает в качестве объекта входного потока, ширина и высота. Программа зависает на WaitForConnection() и без этой функции декодер YUV выдает исключение при чтении из потока.

Возможно ли это сделать так? Заменить аргументы с помощью труб?

ответ

0

Я прочитал Openh264 source code и от того, что я понимаю, в этой конкретной ситуации не представляется возможным заменить аргумент файла с трубой, потому что он пытается загрузить весь файл в память для обработки:

if (fread (pBuf, 1, iFileSize, pH264File) != (uint32_t)iFileSize) { 
    fprintf (stderr, "Unable to read whole file\n"); 
    goto label_exit; 
    } 

Я решили перейти на FFmpeg и она прекрасно работает: использование

class FFmpeg 
{ 
    Process ffmpeg; 

    public FFmpeg() 
    { 
     String args = ""; 
     ffmpeg = new Process(); 
     ffmpeg.StartInfo.CreateNoWindow = true; 
     ffmpeg.StartInfo.UseShellExecute = false; 
     ffmpeg.StartInfo.RedirectStandardInput = true; 
     ffmpeg.StartInfo.RedirectStandardOutput = true; 
     ffmpeg.StartInfo.FileName = @"C:\test\ffmpeg.exe"; 
     args = @" -i C:\test\video.h264 -c:v rawvideo -pix_fmt yuv420p -f rawvideo -"; 
     ffmpeg.StartInfo.Arguments = args; 
    } 

    public void Start() 
    { 
     ffmpeg.Start(); 
    } 

    public void End() 
    { 
     ffmpeg.Kill(); 
    } 

    public BinaryWriter InputStream 
    { 
     get 
     { 
      return new BinaryWriter(ffmpeg.StandardInput.BaseStream); 
     } 
    } 

    public Stream OutputStream 
    { 
     get 
     { 
      return ffmpeg.StandardOutput.BaseStream; 
     } 
    } 
} 

Пример:

 FFmpeg.FFmpeg ffmpeg = new FFmpeg.FFmpeg(); 
     ffmpeg.Start(); 
     Utils.YUVDecoder decoder = new Utils.YUVDecoder(ffmpeg.OutputStream, 640, 480); 
     decoder.NewFrame += Decoder_NewFrame; 
     decoder.Start();