使用Qt的QProcess作为popen(带有ffmpeg rawvideo)

问题描述 投票:0回答:1

我在视频应用程序中插入了一些代码,以使用ffmpeg进行导出使用stdin(rawideo rgba格式)来快速测试它是否有效使用popen(),测试进行得很好,并且由于应用程序是我用Qt写过,我想用QProcess修改补丁->write()

该应用程序未显示任何错误,并且可以正常运行,但生成的视频文件不能同时使用vlc和mplayer播放用popen()生成的代码与这两种代码完美结合。我有感觉->close()->terminate()没有正确关闭ffmpeg,因此文件,但我不知道如何验证它我也没有找到结束执行命令的替代方法->waitForBytesWritten()应该等待数据被写入,建议?我做错了吗?

(显然,我无法准备一个可测试的示例,这将使我更多比补丁花费的时间)

[下面是我输入的代码,如果是#else Qt代码

初始化

#if defined(EXPORT_POPEN) && EXPORT_POPEN == 1
      pipe_frame.file = popen("/tmp/ffmpeg-rawpipe.sh", "w");
      if (pipe_frame.file == NULL) {
        return false;
      }
#else
      pipe_frame.qproc = new QProcess;
      pipe_frame.qproc->start("/tmp/ffmpeg-rawpipe.sh", QIODevice::WriteOnly);
      if(!pipe_frame.qproc->waitForStarted()) {
        return false;
      }
#endif

写框架

#if defined(EXPORT_POPEN) && EXPORT_POPEN == 1
          fwrite(pipe_frame.data, pipe_frame.width*4*pipe_frame.height , 1, pipe_frame.file);
#else
          qint64 towrite = pipe_frame.width*4*pipe_frame.height,
            written = 0, partial;
          while(written < towrite) {
            partial = pipe_frame.qproc->write(&pipe_frame.data[written], towrite-written);
            pipe_frame.qproc->waitForBytesWritten(-1);
            written += partial;
          }
#endif

终止

#if defined(EXPORT_POPEN) && EXPORT_POPEN == 1
      pclose(pipe_frame.file);
#else
      pipe_frame.qproc->terminate();
      //pipe_frame.qproc->close();
#endif

edit

ffmpeg-rawpipe.sh

#!/bin/sh
exec ffmpeg-cuda -y -f rawvideo -s 1920x1080 -pix_fmt rgba -r 25 -i - -an -c:v h264_nvenc \
        -cq:v 19 \
        -profile:v high /tmp/test.mp4

我进行了一些更改,我在打开处添加了无缓冲标志

pipe_frame.qproc->start("/tmp/ffmpeg-rawpipe.sh", QIODevice::WriteOnly|QIODevice::Unbuffered);

因此简化了编写

qint64 towrite = pipe_frame.width*4*pipe_frame.height;
pipe_frame.qproc->write(pipe_frame.data, towrite);
pipe_frame.qproc->waitForBytesWritten(-1);

我在关闭应用程序之前添加了closeWriteChannel(希望停止stdin ffmpeg管道正确结束,以防万一,我不确定是不是这样)

pipe_frame.qproc->waitForBytesWritten(-1);
pipe_frame.qproc->closeWriteChannel();
//pipe_frame.qproc->terminate();
pipe_frame.qproc->close();

但是没有任何变化,mp4文件已创建并包含数据,但是从mplayer日志中,我看到它被误解了,无法识别视频格式,并且它查找的音频不存在。

qt ffmpeg popen qprocess
1个回答
0
投票

已修复,在waitForFinished()之后添加closeWriteChannel(),关闭stdin并等待ffmpeg自行终止。

© www.soinside.com 2019 - 2024. All rights reserved.