Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 使用MediaMuxer对MP4文件进行编码,但调用MediaMuxer.stop()时会崩溃_Android_Video_Android Mediacodec_Mediamuxer - Fatal编程技术网

Android 使用MediaMuxer对MP4文件进行编码,但调用MediaMuxer.stop()时会崩溃

Android 使用MediaMuxer对MP4文件进行编码,但调用MediaMuxer.stop()时会崩溃,android,video,android-mediacodec,mediamuxer,Android,Video,Android Mediacodec,Mediamuxer,我使用MediaMuxer和MediaCodec将摄像机和音频中的视频(H264)数据和音频(AAC-LC)数据编码为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 +

我使用MediaMuxer和MediaCodec将摄像机和音频中的视频(H264)数据和音频(AAC-LC)数据编码为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()
的执行完全正常


当我对两首曲目进行编码时,为什么检查失败?

好的,我来回答我自己

在日以继夜地工作之后,我发现有很多因素会导致
MediaMuxer.stop()
在多路复用AAC曲目时崩溃

为了避免崩溃,您最好遵守以下实现规则:

  • 在同步模式下使用
    MediaCodec
    进行AAC编码。通过使用同步模式,您可以将音频样本(即
    DirectByteBuffer
    )从录音机快速输入到
    MediaCodec
    的inputbuffer,而无需进行任何额外的内存复制。如果丢弃的样本太多,
    MediaMuxer
    将崩溃

  • 使用同步模式的另一个原因是,您可以使用
    MediaMuxer.dequeueInputBuffer(-1)
    来确保在
    writeAudioSample
    方法中始终可以获得可用的InputBuffer,该方法用于将样本写入
    MediaCodec

  • 使用同步模式的另一个原因是,您需要在
    MediaMuxer.stop()
    之前排空AAC编码的数据。(见规则9)

  • 自行设置
    MediaFormat.KEY\u MAX\u INPUT\u SIZE
    ,该值应为2048的倍数(1024个16位样本,对于字节,长度为2048)。我通常将其设置为8192,这取决于音频源的采样率、频道数量以及应用程序和设备的性能

  • 确保输入样本中充满音频数据,长度应为设置为
    MediaFormat.KEY\u MAX\u input\u SIZE
    的值。并以微秒为单位计算演示时间。任何两个相邻输入样本之间的呈现时间间隔应相同。通过以下等式计算样本的持续时间
    1\u 000\u 000L*键\u最大值\u输入\u大小/样本率/通道数/2
    。您不需要将演示时间对齐或移动到0。我强烈推荐你 只需使用
    long initialTime=System.nanoTime()/1000L
    获取初始时间并将其传递给
    MediaCodec
    。因此,下次编写样本时,呈现时间应为
    initialTime+1_000_000L*KEY\u MAX\u INPUT\u SIZE/SAMPLE\u RATE/NUMBER\u CHANNELS/2
    ,依此类推

  • 这部分是最大的坑。在将AAC编码数据写入
    MediaMuxer
    时检查显示时间,即使您已经在将音频样本输入
    MediaCodec
    时设置了显示时间。AAC编码数据的呈现时间有时可能不是递增的。您应该记录上次写入
    MediaMuxer
    的演示文稿时间。如果发现错误排列的AAC数据,请通过
    presentationTime=++lastPresentationTime
    调整演示时间。此外,您可能会得到一些零表示时间AAC数据。别理他们。不要将它们写入
    MediaMuxer

  • 如果
    MediaMuxer
    还有其他曲目,请确保播放时间 对于每个轨迹,都在相同的范围内(允许误差持续几秒钟)

  • 一个AAC
    MediaCodec
    用于一个
    MediaMuxer
    。并且不要重用输出
    MediaFormat
    对象

  • 在执行
    MediaMuxer.stop()
    之前,停止调用
    writeAudioSample
    方法,并通过
    queueInputBuffer(索引,0,0,MediaCodec.BUFFER\u标志\u流的结束\u)将EOS发送到
    MediaCodec
    。并从
    MediaCodec
    中排出剩余的AAC数据,以写入
    MediaMuxer
    。执行
    MediaMuxer.stop()
    并查看发生了什么


  • 好的,我是来回答我自己的问题的

    在日以继夜地工作之后,我发现有很多因素会导致
    MediaMuxer.stop()
    在多路复用AAC曲目时崩溃

    为了避免崩溃,您最好遵守以下实现规则:

  • 在同步模式下使用
    MediaCodec
    进行AAC编码。通过使用同步模式,您可以将音频样本(即
    DirectByteBuffer
    )从录音机快速输入到
    MediaCodec
    的inputbuffer,而无需进行任何额外的内存复制。如果丢弃的样本太多,
    MediaMuxer
    将崩溃

  • 使用同步模式的另一个原因是,您可以使用
    MediaMuxer.dequeueInputBuffer(-1)
    来确保在
    writeAudioSample
    方法中始终可以获得可用的InputBuffer,该方法用于将样本写入
    MediaCodec

  • 使用同步模式的另一个原因是,您需要在
    MediaMuxer.stop()
    之前排空AAC编码的数据。(见规则9)

  • 自行设置
    MediaFormat.KEY\u MAX\u INPUT\u SIZE
    ,该值应为2048的倍数(1024个16位样本,对于字节,长度为2048)。我通常将其设置为8192,这取决于音频源的采样率、频道数量以及应用程序和设备的性能

  • 确保输入样本中充满音频数据,长度应为设置为
    MediaFormat.KEY\u MAX\u input\u SIZE
    的值。并以微秒为单位计算演示时间。任何两个相邻输入样本之间的呈现时间间隔应相同。计算samp的持续时间