【问题标题】:MediaMuxer.nativeWriteSampleData always peroidically blocks for about one second during video recordingMediaMuxer.nativeWriteSampleData 在视频录制期间总是周期性地阻塞大约一秒钟
【发布时间】:2015-11-30 22:01:12
【问题描述】:

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

【问题讨论】:

  • 哪个设备?什么版本的安卓?
  • AllWinner A80,擎天柱,Android 4.4.2
  • 谁能给我一个提示如何解决这种问题?也欢迎提供一般方法。
  • 亲爱的fadden,我发现这个线程中报告了类似的问题:question link。但是我已经将函数drainEncoder() 放在一个单独的线程中,但问题仍然存在。我的录制视频分辨率为 1920x1080,比特率为 10Mbps。

标签: android video recording android-mediacodec mediamuxer


【解决方案1】:

此问题主要发生在写入闪存速度较低的设备上,或者您尝试写入 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。如果我们可以重新使用一个大的循环缓冲区来对新数据进行入队和出队会更好。我已经写了一篇关于这个问题的帖子,并提出了一个解决方案,在这里解释起来相当冗长。你可以read it here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多