2

我正在阅读有关 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() 返回之间的时间差吗?我想要微秒的准确度/精度。感谢您的想法和想法。

4

1 回答 1

2

(合并评论并略微扩展)

您不能简单地计算单个缓冲区提交需要多长时间,因为编解码器可能希望在执行任何操作之前将多个缓冲区排队。您将需要对其进行总体测量,并使用 .计时整个文件解码的持续时间System.nanoTime()。如果您将copy_of操作变为无操作并丢弃解码的数据,则将输出端(将解码的数据写入磁盘)排除在计算之外。

从输入端排除 I/O 更加困难。如 MediaCodec 文档中所述,编码的输入/输出“不是字节流,而是访问单元流”。因此,您必须在 MediaFormat 中填充任何必要的编解码器特定数据键,然后识别各个输入帧,以便您可以正确输入编解码器。

一种更简单但不太准确的方法是进行单独的传递,在其中计算读取输入数据所需的时间,然后从总时间中减去。在您的示例代码中,您将保持操作extractor(如readSampleData),但不执行任何操作codec(可能将一个缓冲区出列并每次都重新使用它)。这样你只测量MediaExtractor开销。这里的诀窍是在完整测试之前立即运行两次,并忽略第一次的结果——第一次通过“预热”磁盘缓存。

如果您对设备之间的性能差异感兴趣,可能是输入 I/O 时间的差异,尤其是来自“暖”缓存的差异,足够相似且足够小,您可以忽略它而不经历所有额外的体操。

于 2013-09-09T20:25:01.603 回答