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, 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

person nmxprime    schedule 25.01.2016    source источник
comment
у вас есть вывод журнала? иногда декодер возвращает сообщения в выводе журнала.   -  person Gabriel Bursztyn    schedule 19.02.2016
comment
@GabrielBursztyn Decoder специально не выдавал никаких сообщений по этому поводу, в любом случае я смоделирую и опубликую журналы как можно скорее.   -  person nmxprime    schedule 22.02.2016
comment
@GabrielBursztyn, добавлено больше журналов, это может помочь   -  person nmxprime    schedule 24.02.2016


Ответы (1)


MPEG-1 Layer III (MP3) имеет зависимые кадры, вы не можете просто начать с любого кадра, такого как Layer I или Layer II. Цитата из предоставленной ссылки: "В худшем случае 9 входных кадров могут быть необходимо, прежде чем можно будет декодировать один единственный кадр». Это, скорее всего, то, что вы видите. Хотя с каждым из первых 7 кадров связана PTS, только когда вы достигнете 8-го кадра, декодер действительно сможет полностью декодировать кадр и начать воспроизведение. Воспроизведение начинается с 8-го кадра PTS. Вам нужно будет мучительно проанализировать байты рассматриваемого потока вручную, чтобы полностью убедиться, что это то, что происходит, но я подозреваю, что вы на самом деле воспроизводите все кадры.

person Kaleb    schedule 23.02.2016
comment
Playback begins with the 8th frame's PTS - означает ли это, что PTS первого вывода кадра обновляется PTS 8-го кадра? - person nmxprime; 24.02.2016
comment
В худшем случае вы не сможете воспроизвести первые 8 кадров, потому что недостаточно информации для создания полностью декодированного кадра. Эти PTS будут проигнорированы, а первая выводимая PTS будет связана с первым полностью декодированным кадром (это может быть любой из первых 9 кадров), который можно передать в аудиоплеер. Если вы введете в плеер частично декодированный кадр с его PTS, вы услышите мусор. После того, как вы получите первый полностью декодированный кадр, вы увидите каждую введенную вами PTS в качестве вывода. Кажется, это именно то, что происходит в журнале. - person Kaleb; 24.02.2016