我正在尝试从文件中解码视频并使用新的异步模式(Asynchronous Mode),在API Level 21及以上(安卓5.0 Lollipop)中支持的MediaCodec
将其编码为不同的格式。
有许多关于在站点如Big Flake、Google的Grafika和StackOverflow上执行同步模式(Synchronous Mode)操作的示例,但是它们都不支持异步模式。
我不需要在过程中显示视频。
我相信一般的流程是用MediaExtractor
读取文件作为MediaCodec
(解码器)的输入,在解码器输出时渲染到一个Surface
中,该表面也是共享输入进入MediaCodec
(编码器),最后通过MediaMuxer
写入编码器输出文件。这个Surface
是在设置编码器时创建并与解码器共享的。
我可以将视频解码到TextureView
中,但将Surface
与编码器共享而不是显示屏并不成功。
我为我的两个编解码器设置了 MediaCodec.Callback()
,但我认为问题在于我不知道如何在编码器回调的 onInputBufferAvailable()
函数中执行操作。我不知道该如何将数据从 Surface
复制到编码器中 - 这应该自动发生(就像使用 codec.releaseOutputBuffer(outputBufferId, true);
在解码器输出上所做的那样)。然而,我认为在 onInputBufferAvailable
中需要调用 codec.queueInputBuffer
才能正常工作。我只是不知道如何设置参数,而不必像解码时使用 MediaExtractor
之类的东西来获取数据。
如果您有一个示例可以打开视频文件,使用异步的 MediaCodec
回调解码并将其编码为不同的分辨率或格式,然后保存为文件,请分享您的代码。
=== 编辑 ===
这里有一个在同步模式下运行的示例,它展示了我正在尝试在异步模式下完成的内容:ExtractDecodeEditEncodeMuxTest.java:https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java 这个示例在我的应用程序中可以正常工作。
MediaCodec.Callback
方法转换到了编码器和解码器中,正如我所期望的。看起来你的所有更改都限于 “ExtractDecodeEditEncodeMuxTest.java” 文件。在我实施之后,我会再回复你。谢谢。 - David ManpearlassertEquals("encoded and decoded video frame counts should match", mVideoDecodedFrameCount, mVideoEncodedFrameCount);
因为编码计数始终比解码计数少一个。 - David Manpearl