2

我正在使用 mediacodec + mediamuxer 进行 android 视频录制,现在我可以录制视频并生成可以播放的 mp4 文件。问题是我发现录制的视频会占用大约一秒钟的时间。所以我启动了 traceview,我发现 MediaMuxer.nativeWriteSampleData() 导致了问题。有时这个函数很快,在几微秒内返回,但有时这个函数很慢,会消耗大约一秒左右,此时视频块。我不知道为什么这个功能会时不时地执行如此不同。录制的目标文件位于外部 SDCard 或内部存储,两个媒体都存在问题。

4

1 回答 1

3

这个问题主要发生在写入闪存速度较低的设备上,或者您尝试写入 SD 卡时。解决方案是将编码数据复制到临时 ByteBuffer,将数据释放回 MediaCodec,并在专用线程上异步调用 writeSampleData。

因此,假设您有一个线程用于排空 MediaCodec 的输出和一个用于馈送 MediaMuxer 的线程,这是一个可能的解决方案:

// this runs on the MediaCodec's draining thread
public void writeSampleData(final MediaCodec mediaCodec, final int trackIndex, final int bufferIndex, final ByteBuffer encodedData, final MediaCodec.BufferInfo bufferInfo) {
    final ByteBuffer data = ByteBuffer.allocateDirect(bufferInfo.size); // allocate a temp ByteBuffer
    data.put(encodedData);  // copy the data over
    mediaCodec.releaseOutputBuffer(bufferIndex, false); // return the packet to MediaCodec

    mWriterHandler.post(new Runnable() {
        // this runs on the Muxer's writing thread
        @Override
        public void run() {
            mMuxer.writeSampleData(trackIndex, data, bufferInfo); // feed the packet to MediaMuxer
        });
}

这种方法的问题是我们为每个传入的数据包分配一个新的 ByteBuffer。如果我们可以重新使用一个大的循环缓冲区来对新数据进行入队和出队会更好。我已经写了一篇关于这个问题的帖子,并提出了一个在这里解释起来相当冗长的解决方案。你可以在这里阅读

于 2015-11-30T14:01:12.083 回答