【问题标题】:Android MediaCodec not decoding all input buffersAndroid MediaCodec 未解码所有输入缓冲区
【发布时间】:2016-05-01 14:47:56
【问题描述】:

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

我想要所有帧的解码输出,我不想跳过任何帧。谁能帮我理解为什么会跳过这些帧?我保证流没有损坏。因为直到第 7 帧我才得到INFO_TRY_AGAIN,当 `dequeueOutputBuffer' 返回有效的缓冲区索引时,它的呈现时间始终是第 8 帧。

以下是排队代码:

Log.e(TAG, "audptOffset = "+audptOffset+"input PT = "+audpt);
                audcodec.queueInputBuffer(audInbufIndex, 0, 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

【问题讨论】:

  • 你有日志输出吗?有时解码器会在日志输出中返回消息。
  • @GabrielBursztyn 解码器并没有在这方面专门抛出任何消息,无论如何我会尽快模拟并发布日志
  • @GabrielBursztyn,添加了更多日志,这可能会有所帮助

标签: android android-mediacodec audiotrack


【解决方案1】:

MPEG-1 第三层 (MP3) 具有相关帧,您不能只从第一层或第二层之类的任何帧开始。引用提供的link,“在最坏的情况下,可能需要 9 个输入帧才能解码一个帧。”这很可能是您所看到的。尽管前 7 帧中的每一帧都有一个与之关联的 PTS,但直到您到达第 8 帧,解码器才真正能够完全解码一帧并开始播放。播放从第 8 帧 PTS 开始。您需要手动解析有问题的流的字节以完全验证正在发生的事情,但我怀疑您实际上正在播放所有帧。

【讨论】:

  • Playback begins with the 8th frame's PTS - 这是否意味着,第一帧输出的 PTS 更新为第 8 帧的 PTS?
  • 在最坏的情况下,您无法播放前 8 帧,因为没有足够的信息来创建完全解码的帧。这些 PTS 将被忽略,并且要输出的第一个 PTS 将与可以传递到音频播放器的第一个完全解码的帧(它可以是前 9 帧中的任何一个)相关联。如果您将带有 PTS 的部分解码帧输入到播放器中,您将听到垃圾。在您获得第一个完全解码的帧后,您将看到您输入的每个 PTS 作为输出。这似乎正是日志中正在发生的事情。
猜你喜欢
  • 1970-01-01
  • 2017-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-15
  • 2014-10-06
  • 1970-01-01
  • 2014-11-30
相关资源
最近更新 更多