我使用MediaMuxer和MediaCodec将视频(H264)数据和音频(AAC)数据从摄像机和音频编码到MP4文件。但是MediaMuxer对象有时会在mediaMuxer.stop()上崩溃,错误日志是
11-03 16:28:36.956: A/DEBUG(711): Abort message: 'frameworks/av/media/libstagefright/MPEG4Writer.cpp:2983 CHECK_LT( mCodecSpecificDataSize + 23,128) failed: 399 vs. 128'
11-03 16:28:36.957: A/DEBUG(711): x0 0000000000000000 x1 0000000000001184 x2 0000000000000006 x3 0000000000000000
11-03 16:28:36.957: A/DEBUG(711): x4 0000000000000000 x5 0000000000000001 x6 0000000000000000 x7 0000000000000000
11-03 16:28:36.957: A/DEBUG(711): x8 0000000000000083 x9 0000000000000000 x10 0000000000000000 x11 0000007f91bb0df8
11-03 16:28:36.958: A/DEBUG(711): x12 0000007f91bb0cd0 x13 0000000000000077 x14 0000007f91bb0ea8 x15 0000000000000000
11-03 16:28:36.958: A/DEBUG(711): x16 0000007faca8d6a8 x17 0000007faca4fb2c x18 0000007face14418 x19 0000007f91bb3510
11-03 16:28:36.959: A/DEBUG(711): x20 0000007f91bb3450 x21 000000000000000b x22 0000000000000006 x23 00000055a17fd260
11-03 16:28:36.959: A/DEBUG(711): x24 0000007f91bb1c58 x25 0000007f91bb18b4 x26 0000007f91bb1f90 x27 0000007fa9715000
11-03 16:28:36.960: A/DEBUG(711): x28 0000007f91bb1898 x29 0000007f91bb0d60 x30 0000007faca4d2c8
11-03 16:28:36.960: A/DEBUG(711): sp 0000007f91bb0d60 pc 0000007faca4fb34 pstate 0000000020000000我多次尝试只编码一个音轨(视频或音频)。mediaMuxer.stop()的执行完全没有问题。
为什么CHECK_LT在我编码两首曲目时失败了?
发布于 2017-11-10 16:08:38
好吧,我是来回答我自己的。
在24小时工作之后,我发现有许多因素会导致MediaMuxer.stop()在调整AAC轨道时发生碰撞。
为了避免崩溃,您最好在实现时遵循以下规则:
MediaCodec进行AAC编码。通过使用同步模式,您可以快速地将音频示例(即DirectByteBuffer)从AudioRecorder输入到MediaCodec的输入缓冲区,而不需要进行任何额外的内存复制。如果拖放太多的示例,MediaMuxer就会崩溃。MediaMuxer.dequeueInputBuffer(-1)确保始终可以在writeAudioSample方法中获得可用的InputBuffer,该方法用于将示例写入MediaCodec。MediaFormat.KEY_MAX_INPUT_SIZE,值应该是2048的倍数(1024 16位示例,字节数,长度为2048)。我通常将其设置为8192,这取决于音频源的采样率、通道数以及应用程序和设备的性能。MediaFormat.KEY_MAX_INPUT_SIZE的值。并以微秒为单位计算演示时间。任意两个相邻输入样本之间的表示时间间隔应该是相同的。通过这个方程1_000_000L * KEY_MAX_INPUT_SIZE / SAMPLE_RATE / NUMBER_OF_CHANNELS / 2计算样本的持续时间。您不需要对齐或将演示时间转移到。我强烈建议您只使用long initialTime = System.nanoTime() / 1000L获取初始时间并将其传递给MediaCodec。因此,下次编写示例时,演示的时间应该是initialTime + 1_000_000L * KEY_MAX_INPUT_SIZE / SAMPLE_RATE / NUMBER_OF_CHANNELS / 2等等。MediaMuxer时,请检查演示时间,即使您在将音频示例输入到MediaCodec时已经设置了演示时间。AAC编码数据的表示时间有时可能不是增量的。您应该记录上一次向MediaMuxer写入演示文稿的时间。如果发现错误排序的AAC数据,请通过presentationTime = ++lastPresentationTime调整演示时间。此外,您可能会得到一些零表示时间的AAC数据.别理他们。不要将它们写到MediaMuxer。MediaMuxer有其他音轨,请确保每个曲目的演示时间在相同的范围内(允许错误持续几秒钟)。MediaCodec为一个MediaMuxer。并且不要重用输出MediaFormat对象。MediaMuxer.stop()之前,停止调用writeAudioSample方法,并通过queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM)向MediaCodec发送EOS。并将剩余的AAC数据从MediaCodec中排出以写入MediaMuxer。执行MediaMuxer.stop()并查看发生了什么。https://stackoverflow.com/questions/47165734
复制相似问题