0

我正在编写从套接字读取 h264 数据的代码,将其传递给 h264dec.exe(openh264 解码器),然后将 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 解码器将 Stream 对象的宽度和高度作为输入。程序挂起WaitForConnection()并且没有该功能,YUV解码器在从流中读取时抛出异常。

甚至有可能让它像这样工作吗?用管道代替参数?

4

1 回答 1

0

我已经阅读了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();
于 2015-12-22T14:33:38.143 回答