我正在使用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()
的执行完全正常。
为什么check_lt
在编码两个音轨时失败?
好吧,我来回答我自己。
经过日以继夜的工作,我发现有很多因素会导致mediamuxer.stop()
在多路复用AAC轨道时崩溃。
为了避免崩溃,您最好按照以下规则执行:
>
在同步模式下使用mediacodec
进行AAC编码。通过使用同步模式,您可以将音频样本(即DirectByteBuffer
)从AudioRecorder快速输入到MediaCodeC
的inputbuffer中,而无需进行任何额外的内存复制。如果删除的样本太多,mediaMuxer
将崩溃。
使用同步模式的另一个原因是,您可以使用MediaMuxer.DequeueInputBuffer(-1)
来确保始终可以在WriteAudioSample
方法中获得可用的InputBuffer,该方法用于将示例写入MediaCodeC
。
使用同步模式的另一个原因是,您需要在mediamuxer.stop()
之前排出AAC编码数据。(见第9条)
自行设置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
。您不需要将演示时间对齐或移动为0。我强烈建议您只需使用long initialTime=system.nanotime()/1000L
获取初始时间并将其传递给mediaCodec
。因此,下次编写示例时,表示时间应该是initialtime+1_000_000L*KEY_MAX_INPUT_SIZE/SAMPLE_RATE/NUMBER_OF_CHANNELS/2
等等。
这部分是最大的坑。在将AAC编码数据写入MediaMuxer
时检查演示时间,即使在将音频样本输入MediaCodeC
时已经设置了演示时间。AAC编码数据的呈现时间有时可能不是递增的。您应该记录上次写入mediaMuxer
的演示时间。如果您发现错误排序的AAC数据,请通过presentationtime=++lastpresentationtime
调整演示时间。此外,您可能会得到一些零表示时间的AAC数据。别理他们。不要将它们写入mediaMuxer
。
如果mediaMuxer
有其他音轨,请确保每个音轨的呈现时间在相同的范围内(允许错误数秒)。
一个AACmediaCodec
对应一个mediaMuxer
。并且不重用outputmediaformat
对象。
在执行mediaMuxer.stop()
之前,停止调用您的writeaudiosample
方法,并通过queueinputbuffer(index,0,0,0,mediaCodeC.buffer_flag_end_of_stream)
向mediaCodeC
发送EOS。并从mediaCodeC
中排出剩余的AAC数据以写入mediaMuxer
。执行mediamuxer.stop()
并查看发生了什么。
我正在开发一个应用程序,在其中我解码视频,替换某些帧,并使用和重新编码。如果我不替换任何帧(我在下面解释的1080p视频除外),该应用程序就可以工作,但当我替换帧时,被替换帧之后的帧会被像素化,并且视频会有起伏。 此外,当我使用1920x1080个视频尝试我的应用程序时,我会得到一个奇怪的输出,其中视频没有显示任何内容,直到我滚动到视频的开头,然后视频开始显示(但与之前提到的相同问题编辑后的像素化
问题内容: 我在处理JNA中的回调时遇到问题。 我正在尝试使用C API,该API使用回调来处理多个会话事件(登录,注销,连接问题…)。 会话对象(称为)是不透明的结构。所有回调均在结构中注册。根据API,我应该声明回调对象,并将其放入创建对象时将提供的Config对象中。如果我不想使用某些回调,则应该使用对其进行初始化。API正在使用调用约定。 这是与我的问题有关的C标头的代码段: 这是我等效的
我有以下功能,它获取一个WAV(PCM)文件并使用Android的MediaCode和MediaMuxer类将其编码为AAC编码的MP4文件。这只是音频。该函数成功运行并输出一个合理的. mp4,该函数被识别为AAC编码。但它不能在Android、Web或iOS播放器上播放,并使Audacy崩溃。我错过了什么吗?代码如下所示。
我在服务器端对JSON进行了编码(使用ESAPI编码器),然后客户机检索bean的字段并进行进一步的处理。 在服务器端 编码的JSON字符串 \x7b\x22name\x22\x3a\x22sameer\x22,\x22company\x22\x3a\x22company\x22,\x22designation\x22\x3a\x22developer\x22\x7d 在客户端
问题内容: 我正在尝试使用(使用最新的Webkit)下载二进制文件,并使用以下简单功能对base64的内容进行编码: 附带说明一下,以上所有内容都是标准Javascript内容,包括和 这工作非常顺利,我什至可以使用Javascript解码base64内容: 现在,我想使用Python解码base64编码的内容,该内容使用一些JSON字符串来获取字符串值。天真的,这就是我的工作: 但是生成的文件无
我正在修改一个Android框架示例,将MediaCodec生成的基本AAC流打包成一个独立的。mp4文件。我使用的是一个实例,其中包含一个由实例生成的AAC曲目。 然而,我总是最终得到一个错误消息调用: