android 4.1 (API 16) 中捕获的缓冲区到缓冲区 encode/decode

buffer-to-buffer encode/decode from capture in android 4.1 (API 16)

我搜索了几个小时.. 我只想要录制电影的工作 decode/encode。 这甚至可能在 android 4.1 上实现吗? 现在我只写了几 kb 到我的 mp4 文件。没有错误。

这会工作后,我将使用 KEY_FRAME_RATE 和 KEY_I_FRAME_INTERVAL 将其放慢。

我使用 mediaExtractor 来配置 MediaCodec。 我看到 3 个步骤(完整代码见要点):

1./

encoder.dequeueInputBuffer(5000);
extractor.readSampleData(inputBuf, offset);
ptsUsec2 = extractor.getSampleTime();
encoder.queueInputBuffer(inputBufIndex, ...);

2./

encoder.dequeueOutputBuffer(info, 5000);
ByteBuffer encodedData = encoderOutputBuffers[encoderStatus];
//i write encodedData to a FileOutputStream (to save the MP4);
decoder.queueInputBuffer(inputBufIndex, ...);

3./

decoder.dequeueOutputBuffer(info, 5000);
decoder.releaseOutputBuffer(decoderStatus, ...);

这是我从 google 的 EncodeDecodeTest 文件中修改的完整函数: gist

感谢您的帮助, 菲利克斯

bigflake. In particular, FAQ item #9 上提供了一些额外信息。

不保证从 MediaCodec 解码器输出的帧格式有用。许多流行的设备将数据解码为专有的 YUV 格式,这就是缓冲区到缓冲区测试中的 checkFrame() 函数不能始终验证结果的原因。您希望 MediaCodec 编码器能够接受解码器输出的帧,但这并不能保证。

针对 API 18+ 的编码通常要容易得多,因为您可以使用 Surface 而不是 ByteBuffer。

当然,如果您只需要慢动作视频,则无需对 H.264 流进行解码和重新编码。您需要做的就是更改 .mp4 包装器中的演示时间戳。在 API 18+ 上,您可以使用 MediaExtractor 提取并立即使用 MediaMuxer 进行编码,而根本不涉及 MediaCodec。在 API 16 上,MediaMuxer 不存在,因此您需要一些其他方法将 H.264 包装为 .mp4。

当然,除非您对可变帧率视频有些反感,在这种情况下,您需要使用重复的 "slow motion" 帧(并适当调整时间戳)对其进行重新编码。 KEY_FRAME_RATEKEY_I_FRAME_INTERVAL 值对您没有帮助——它们是在配置编码器时设置的,对帧时序没有影响。