【问题标题】:Fastest way to encode a frame twice (duplicate, h264 format) using JavaCV ffmpeg?使用JavaCV ffmpeg对帧进行两次编码(重复,h264格式)的最快方法?
【发布时间】:2014-12-03 21:35:53
【问题描述】:

我想尽可能快地使用 FFmpegFrameRecorder 在具有恒定帧速率的同一输出视频中加入编码多个具有不同帧速率的视频。我正在考虑复制帧以防我想增加帧速率,并在我需要降低帧速率时跳过帧。我正在使用 JavaCV。


除了调用 record(image) 两次之外,有没有更好的复制帧的方法? (输出总是以 mp4 文件格式存储的 h264)类似于 h264 流中的标志,指示当前帧是上一帧的副本,或者跳过冗余编码的其他内容。

【问题讨论】:

    标签: android ffmpeg h.264 javacv


    【解决方案1】:
    1. FrameGrabber 是一个为您提供音频帧、视频帧、帧率、采样率等信息的类。您只需使用视频文件的路径作为参数创建此类的实例。

    2. 然后,FrameGrabber.grab() 将以与输入视频相同的帧速率为您提供音频帧。如果 FrameGrabber.grab() 返回 null,则表示视频已迭代到最后一帧。

    3. 现在您可以设置一个新的grabberObject,将第二个视频的路径作为其构造函数的参数,然后重复步骤2

    4. 您可以重复第 3 步,直到您的所有视频都已阅读完毕。

    5. 现在开始录制视频;您可以使用从 FrameGrabber 返回的参数初始化记录器。它的高度、宽度、帧率、采样率都可以精确设置以匹配抓取对象。您还需要设置录像机保存视频的路径。每次FrameGrabber.grab()之后,需要调用recorder.record(FrameGrabber.grab())。

    6. 现在将新视频输入到 FrameGrabber() 的点,将是质量滞后的原因:

    a) frameGrabber 需要时间来设置。将分配给采集器的新视频路径的转换/转换不会是瞬时的。这可能需要几秒钟的时间。

    b) 这种过渡/转移到新的视频路径,还必须更改记录器的参数-Framerate、SampleRate、Height & Width。

    要处理这两个问题,您需要处理在过渡/转换到新视频路径后添加的第一帧,作为一种特殊情况。在这里,您将重置 recoderFramerate、SampleRate、Height 和 Width 的属性以匹配新的 frameGrabber 属性。

    这个实现应该可以正常工作。

    此外,如果您想提高帧速率,请复制帧,并在需要降低帧速率时跳过帧。这两种都会完全扭曲视频。您永远无法达到视频的原始质量。视频帧和声音的滞后将更加明显。

    【讨论】:

    • 感谢您抽出宝贵时间回答这个问题。我没有使用 FrameGrabber,而是使用 MediaCodec 来解码视频/音频。我还将音频重新采样为所需的输出采样率,这可能与当前视频不同。我所需要的只是改变视频的帧速率,以防视频 2 fps 与 video1 fps 不同,我正在尝试尽可能优化。最明显的情况是在当前帧上调用两次记录。你知道有什么更好的方法吗?
    • MediaCodec 将非常有效地处理这个问题,但仍然不清楚通过复制帧可以获得什么好处。
    • 通过复制帧,如果原始视频中的fps低于输出fps,我可以提高帧率,以便混合到视频中的动画具有流畅的运动。我使用的是 JavaCV,因为 MediaCodec 编码器需要支持多种颜色格式,如果从 Buffer 而不是 Surface 编码,我需要支持 android 4.1 设备。
    猜你喜欢
    • 2014-01-24
    • 2018-09-01
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2020-11-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多