Android MediaCodec不解码所有输入缓冲区

Android 4.4.2中,我使用MediaCodec解码mp3文件.
我使用queueInputBuffer()来排队输入mp3编码的帧和dequeueOutputBuffer()来获得解码的帧.
但是解码器从第8帧开始(基于bufferInfo.presentationTimeUs)提供解码输出,并跳过初始7帧.这种情况只发生在几个流中,但不适用于所有流.此外,这种行为在许多运行中是一致的.

我想要所有帧的解码输出,我不想跳过任何帧.任何人都可以帮助我了解为什么框架被跳过?我保证流不会被破坏.因为我收到INFO_TRY_AGAIN到第7帧,当有效的缓冲区索引被’dequeueOutputBuffer’返回时,它的呈现时间总是第8帧.

以下是排队码:

Log.e(TAG,"audptOffset = "+audptOffset+"input PT = "+audpt);
                audcodec.queueInputBuffer(audInbufIndex,audchunkSize,audpt,0);

以下是我如何调用dequeue并写入AudioTrack:

if(!audoutputDone ){
                if(!waitForAudioRelease){
                    auoutBufIndex  = audcodec.dequeueOutputBuffer(auinfo,100);
                    Log.e(TAG,"Output PT = " + auinfo.presentationTimeUs+"auoutBufIndex = "+auoutBufIndex);
                }
                if (auoutBufIndex >= 0) {
                    waitForAudioRelease = true;
                } else if (auoutBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                    auddecOutBufArray = audcodec.getoutputBuffers();
                } else if (auoutBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                    MediaFormat newFormat = audcodec.getoutputFormat();
                    int sampleRate1 = newFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
                    int channelCount1 =newFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
                    Log.e(TAG,"INFO_OUTPUT_FORMAT_CHANGED");
                    int minBufSize1 = AudioTrack.getMinBufferSize(sampleRate1,(channelCount1==2)?
                            AudioFormat.CHANNEL_OUT_STEREO:AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_16BIT);
                    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRate1,(channelCount1==2)?AudioFormat.CHANNEL_OUT_STEREO:AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_16BIT,minBufSize1,AudioTrack.MODE_STREAM);
                    audioTrack.play();
                    waitForAudioRelease = false;
                }
                audioNowUs = System.currentTimeMillis();
                if (auoutBufIndex >= 0) {               
                    auwhenRealUs = (auinfo.presentationTimeUs/1000) + mStartTimeRealMs - (audptOffset/1000);
                    aulateByUs = audioNowUs - auwhenRealUs;


                    if(!audioWaitTillStartTime){
                        while((mStartTimeRealMs+((auinfo.presentationTimeUs/1000) - (audptOffset/1000))) >= audioNowUs){
                            try {
                                Thread.sleep(10);
                            } catch (InterruptedException e) {
                                // Todo Auto-generated catch block
                                e.printstacktrace();
                            }
                            audioNowUs = System.currentTimeMillis();
                        }
                        Log.e(TAG,"Play is going to start PT Difference = "+((auinfo.presentationTimeUs/1000) - (audptOffset/1000)));
                    }

添加更多日志:

02-22 17:46:03.164: E/CL(28650): received play command from server
02-22 17:46:03.209: E/RealTimeClient(28650): created decoder for audio/mpeg
02-22 17:46:03.234: E/Music(28650): Output PT = 0
02-22 17:46:03.234: E/Music(28650): pt of first frame received 1215000
02-22 17:46:03.234: E/Music(28650): Input PT = 1215000
02-22 17:46:03.234: E/Music(28650): Output PT = 0
02-22 17:46:03.234: E/Music(28650): Input PT = 1241122
02-22 17:46:03.239: E/Music(28650): Output PT = 0
02-22 17:46:03.239: E/Music(28650): Input PT = 1267244
02-22 17:46:03.239: E/Music(28650): Output PT = 0
02-22 17:46:03.239: E/Music(28650): Input PT = 1293367
02-22 17:46:03.239: E/Music(28650): Output PT = 0
02-22 17:46:03.239: E/Music(28650): Input PT = 1319489
02-22 17:46:03.239: E/Music(28650): Output PT = 0
02-22 17:46:03.244: E/Music(28650): INFO_OUTPUT_FORMAT_CHANGED
02-22 17:46:03.249: I/Reverb(28650):  getpid() 28650,IPCThreadState::self()->getCallingPid() 28650
02-22 17:46:03.249: E/Reverb(28650): Reverb::StartElementHandler,wrong element or attributes: boolean
02-22 17:46:03.249: E/Music(28650): Input PT = 1345612
02-22 17:46:03.254: E/Music(28650): Output PT = 1293367
02-22 17:46:03.259: E/Music(28650): Input PT = 1371734
02-22 17:46:03.259: E/Music(28650): Input PT = 1397857
02-22 17:46:03.259: E/Music(28650): Input PT = 1423979
02-22 17:46:03.259: E/Music(28650): Input PT = 1450102
02-22 17:46:03.264: E/Music(28650): Input PT = 1476224
02-22 17:46:03.269: E/Music(28650): Input PT = 1502346
02-22 17:46:03.269: E/Music(28650): Input PT = 1528469
02-22 17:46:03.269: E/Music(28650): Input PT = 1554591
02-22 17:46:03.269: E/Music(28650): Input PT = 1580714
02-22 17:46:03.269: E/Music(28650): Input PT = 1606836
02-22 17:46:03.269: E/Music(28650): Input PT = 1632959
02-22 17:46:03.269: E/Music(28650): Input PT = 1659081
02-22 17:46:04.124: W/AudioTrack(28650): releaseBuffer() track 0x5e2faf28 name=0x3 disabled,restarting
02-22 17:46:04.129: E/Music(28650): Output PT = 1319489
02-22 17:46:04.129: E/Music(28650): Input PT = 1685204
02-22 17:46:04.159: E/Music(28650): Output PT = 1345612

解决方法

MPEG-1 Layer III(MP3)具有从属帧,您不能从任何像Layer I或Layer II这样的帧开始.从提供的 link引用,“在最坏的情况下,可能需要9个输入帧才能解码一个单一的帧.这很可能是你看到的.尽管前7帧中的每一帧都具有与之相关联的PTS,但直到到达第8帧,解码器实际上才能完全解码帧并开始播放.播放从第8帧PTS开始.您需要手动解析所讨论的流的字节,才能完全验证这是发生了什么,但我怀疑您实际上是在播放所有的帧.

相关文章

这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的...
这篇文章主要介绍“Android岛屿数量算法怎么使用”的相关知识...
本篇内容主要讲解“Android如何开发MQTT协议的模型及通信”,...
本文小编为大家详细介绍“Android数据压缩的方法是什么”,内...