我正在阅读有关 MediaCodec 的 Android 文档和其他在线教程/示例。据我了解,MediaCodec的使用方式是这样的(伪代码中的解码器示例):
//-------- prepare audio decoder, format, buffers, and files --------
MediaExtractor extractor;
MediaCodec codec;
ByteBuffer[] codecInputBuffers;
ByteBuffer[] codecOutputBuffers;
extractor = new MediaExtractor();
extractor.setDataSource();
MediaFormat format = extractor.getTrackFormat(0);
//---------------- start decoding ----------------
codec = MediaCodec.createDecoderByType(mime);
codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
codec.start();
codecInputBuffers = codec.getInputBuffers();
codecOutputBuffers = codec.getOutputBuffers();
extractor.selectTrack(0);
//---------------- decoder loop ----------------
while (MP3_file_not_EOS) {
//-------- grasp control of input buffer from codec --------
codec.dequeueInputBuffer();
//---- fill input buffer with data from MP3 file ----
extractor.readSampleData();
//-------- release input buffer so codec can have it --------
codec.queueInputBuffer();
//-------- grasp control of output buffer from codec --------
codec.dequeueOutputBuffer();
//-- copy PCM samples from output buffer into another buffer --
short[] PCMoutBuffer = copy_of(OutputBuffer);
//-------- release output buffer so codec can have it --------
codec.releaseOutputBuffer();
//-------- write PCMoutBuffer into a file, or play it -------
}
//---------------- stop decoding ----------------
codec.stop();
codec.release();
这是使用 MediaCodec 的正确方法吗?如果没有,请赐教我正确的方法。如果这是正确的方法,我如何衡量 MediaCodec 的性能?是 codec.dequeueOutputBuffer() 返回和 codec.queueInputBuffer() 返回之间的时间差吗?我想要微秒的准确度/精度。感谢您的想法和想法。
最佳答案
(合并评论并稍微扩展)
您不能简单地计算单个缓冲区提交所需的时间,因为编解码器可能希望在执行任何操作之前对多个缓冲区进行排队。您需要对其进行总体测量,并使用 System.nanoTime() 计时整个文件解码的持续时间。如果将 copy_of
操作转变为无操作并仅丢弃解码的数据,则可以将输出端(将解码的数据写入磁盘)排除在计算之外。
从输入端排除 I/O 更加困难。正如 MediaCodec 文档中所述,编码的输入/输出“不是字节流,而是访问单元流”。因此,您必须在 MediaFormat 中填充任何必要的编解码器特定数据键,然后识别各个输入帧,以便您可以正确地提供编解码器。
一种更简单但不太准确的方法是进行一次单独的传递,计算读取输入数据所需的时间,然后从总时间中减去该时间。在示例代码中,您将保留 extractor
上的操作(如 readSampleData
),但对 codec
不执行任何操作(可能使一个缓冲区出列,然后仅每次都重复使用)。这样您只需测量 MediaExtractor
开销。这里的技巧是在完整测试之前运行它两次,并忽略第一次的结果——第一遍“预热”磁盘缓存。
如果您对设备之间的性能差异感兴趣,那么输入 I/O 时间的差异(尤其是来自“热”缓存的输入 I/O 时间的差异)可能足够相似且足够小,以至于您可以忽略它并不需要进行所有额外的体操。
关于android - 媒体编解码器 : how to measure performance?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18665172/