从Java应用程序发送原始像素数据时,FFMpeg以错误的帧速率进行压缩

Mar*_*rco 2 java ffmpeg frame-rate pipe

我正在尝试根据一系列原始的rgb24像素数据创建一个压缩的h264视频文件。像素数据从Java应用程序流式传输到其子进程ffmpeg.exe。

为了进行测试,我创建了一个带有rgb24像素数据的字节数组,然后将其发送到ffmpeg的输入流。

除了一个问题,一切都正常。

看起来编码文件的帧速率不正确。FFMpeg应该以30fps的速率(-r 30)压缩视频文件。

我正在发送30 * 20帧。因此,我应该获得一个长度为20秒的视频文件。但与此相反,视频文件的长度是24秒。当我检查压缩文件的属性时,它按预期显示30fps。

看起来预期帧速率与实际帧速率之间的比率为5到6(20-> 24,30-> 36)。我也尝试流式传输rgb32像素数据,但结果相同。

码:

    ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
    //building the frame
    for (int i=0; i<1024*800; i++)
    {
        byteArray.write(i&0xFF);    //r
        byteArray.write(i&0xFF);    //g
        byteArray.write(i&0xFF);    //b
    }

    byte pixelData[] = byteArray.toByteArray();

    File ffmpeg_output_msg = new File("ffmpeg_output_msg.txt");

    ProcessBuilder pb = new ProcessBuilder("ffmpeg.exe","-vcodec","rawvideo","-f","rawvideo","-pix_fmt","rgb24","-s","1024x800","-i","pipe:0","-r","30","-y","-c:v","libx264","out.mkv");

    pb.redirectErrorStream(true);
    pb.redirectOutput(ffmpeg_output_msg);

    Process p = pb.start();
    OutputStream ffmpegInput = p.getOutputStream();

    //30fps, 20secs
    for(int i=0;i<30*20;i++)
    {
        ffmpegInput.write(pixelData);
    }
    ffmpegInput.flush();
    ffmpegInput.close();
Run Code Online (Sandbox Code Playgroud)

有什么想法可能是这个问题的根源吗?提前致谢

更新 我已将帧速率更改为其他值,并且看起来ffmpeg完全忽略了该参数。它始终使用25fps。仅对文件属性中写入的数据使用“ -r 30”效果(视频:MPEG4视频(H264)1024x800 30fps [视频])

编码文件中是否可能有两种不同的帧率?

Mar*_*rco 5

好,解决了

我不得不在输出和输入强制使用fps 。在-i之前加上-r 30,将告诉ffmpeg输入流的速率为30 fps。

最终的ffmpeg:

ffmpeg.exe -r 30 -vcodec rawvideo -f rawvideo -pix_fmt rgb24 -s 1024x800 -i pipe:0 -y -c:v libx264 -r 30 out.mkv
Run Code Online (Sandbox Code Playgroud)