MediaMuxer.nativeWriteSampleData视频录制过程中始终peroidically块约一秒钟 [英] MediaMuxer.nativeWriteSampleData always peroidically blocks for about one second during video recording

查看:3303
本文介绍了MediaMuxer.nativeWriteSampleData视频录制过程中始终peroidically块约一秒钟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做利用媒体codeC + mediamuxer Android的视频录制,现在我可以录制视频并生成可播放mp4文件。问题是,我发现录制的视频将抓住约一秒钟一段时间。所以我发起traceview我发现MediaMuxer.nativeWriteSampleData()导致此问题。有时这个功能是非常快的和几微秒内的回报,但有时该功能是很慢的并且会消耗大约一秒钟左右,而当时的视频块。我不知道为什么这个功能会不时进行如此变化的时间。记录目标文件位于外部SD卡或内部存储和媒体都对这个问题存在。

I am doing android video recording using mediacodec + mediamuxer, and now I can record video and generate mp4 file which can be played. The problem is that I find the recorded video will seize for about one second some time. So I launched traceview and I find MediaMuxer.nativeWriteSampleData() cause the problem. Sometimes this function is very fast and returns within several micro-seconds, but sometimes this function is very slow and will consume about one second or so, and the video blocks at that time. I do not know why this function will perform so varying from time to time. The recording target file is located at external SDCard or internal storage, and the problem exist on both media.

推荐答案

这是发生主要是在低书写闪光速度或如果您尝试写入SD卡的设备有问题。该解决方案是将EN codeD数据复制到一个临时的ByteBuffer,释放数据回媒体codeC和一个专门的线程异步调用writeSampleData。

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.

因此​​,假设你有排水媒体codeC的输出中,一个用于喂养MediaMuxer一个线程,这是一个可能的解决方案:

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

使用这种方法的问题是,我们分配一个新的ByteBuffer每个传入分组。它会更好,如果我们可以重新使用一个大的循环缓冲区来排队和deque新的数据。我已经写了这件事情后,也提出解决方案这是相当长的在这里解释。您可以这里阅读。

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.

这篇关于MediaMuxer.nativeWriteSampleData视频录制过程中始终peroidically块约一秒钟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆