MediaMuxer.nativeWriteSampleData always peroidically blocks for about one second during video recording

末鹿安然 提交于 2019-12-06 08:36:52

This is a problem that occurs mostly on devices with lower writing flash speeds or if you try to write to the SD card. The solution is to copy the encoded data to a temporary ByteBuffer, release the data back to MediaCodec and call writeSampleData asynchronously on a dedicated thread.

So, assuming that you have a thread for draining MediaCodec's ouput and one for feeding MediaMuxer, this is a possible solution:

// 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
        });
}

The problem with this approach is that we allocate a new ByteBuffer for every incoming packet. It would be better if we could re-use a big circular buffer to enqueue and deque the new data. I have written a post about this matter and also propose a solution which is rather lengthy to explain here. You can read it here.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!