Аргумент подстановки с трубами
Я пишу код, который читает данные 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();