Аргумент подстановки с трубами

Я пишу код, который читает данные h264 из сокета, передает их в h264dec.exe ( декодер openh264), а затем передает данные YUV в декодер YUV-RGB. Моя проблема в том, что openh264 dec работает как "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 принимает в качестве входного объекта Stream, ширину и высоту. Программа висит на WaitForConnection() и без этой функции, YUV декодер выдает исключение при чтении из потока.

Можно ли вообще так заставить работать? Подставлять аргументы трубами?

1 ответ

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

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();
Другие вопросы по тегам