Jak zainicjować MediaFormat, aby skonfigurować MediaCodec do dekodowania surowych danych AAC?

Mam dziwny problem z odtwarzaczem StreamPlayer i potrzebuję wszelkiej pomocy.

Głównym celem, jaki muszę osiągnąć, jest StreamPlayer, który jest w stanie odtwarzać strumienie transportowe MPEG-2 z możliwie najmniejszym opóźnieniem. W tym celu stosuję następujące podejście:

Strumień jest analizowany przez parser TS oparty na Javie. Zaimplementowałem TSExtractor, który jest podobny do MediaExtractora i który działa dobrze. Mogę odbierać wszystkie próbki mediów dla wybranej ścieżki w taki sam sposób, w jaki jest to możliwe przy użyciu MediaExtractor

extractor.readSampleData(...);
extractor.advance();

Aby zdekodować dane AAC, chcę utworzyć i skonfigurować instancję MediaCodec. Korzystając z klasy MediaExtractor, zwykle robi się to przez

MediaFormat mediaFormat = extractor.getTrackFormat(i);
decoder = MediaCodec.createDecoderByType(mediaFormat.getString(MediaFormat.KEY_MIME));
decoder.configure(mediaFormat, null, null, 0);

Ponieważ muszę zainicjować MediaFormat w metodzie TSExtractor.getTrackFormat (ścieżka int), której używam

MediaFormat mf = MediaFormat.createAudioFormat ("audio/mp4a-latm", getSampleRate(), getChannelCount());

a ponieważ wszystkie moje próbki AAC zawierają ADTS, robię to

mediaFormat.setInteger(MediaFormat.KEY_IS_ADTS, 1); 

Po przeczytaniuto W końcu dodam ramkę ESDS przy użyciu klucza „csd-0”

mediaFormat.setByteBuffer("csd-0", ByteBuffer.allocate(2).put(new byte[]{(byte) 0x11, (byte)0x90}));

gdzie wartości 0x11 i 0x90 są wyodrębniane z ADTS.

Kiedy teraz chcę zdekodować AAC, próbkuje posty dekodera

AAC decoder returned error 4097, substituting silence

do dziennika.

Aby sprawdzić, czy mój TSExtractor poprawnie wyodrębnia próbki, nagrałem ten sam strumień, używając VLC, przesyłając go ponownie do pliku mp4 bez transkodowania, tak aby surowy strumień pozostał niezmieniony. Teraz mogę zainicjować MediaExtractor za pomocą nagranego pliku mp4 i porównać próbki utworzone przez mój TSExtractor i MediaExtractor. Używając szlaku i błędu, znalazłem bardzo dziwne zachowanie:

Kiedy konfiguruję MediaCodec przy użyciu mediaFormat utworzonego przez MediaExtractor, MediaCodec dekoduje próbki AAC zwrócone przez mój TSExtractor bez żadnych problemów. Porównywanie MediaFormat, który w zasadzie otacza HashMap, stworzony przez mój TSExtractor i ten stworzony przez MediaExtractor, daje te różnice:

Stworzony przez MediaExtractor:

mediaFormat: {max-input-size = 1212, durationUs = 77428875, is-adts = 1, liczba kanałów = 2, mime = audio / mp4a-latm, csd-0 = java.nio.ByteArrayBuffer [pozycja = 0, limit = 2, pojemność = 2], częstotliwość próbkowania = 48000}

Stworzony przez TSExtractor:

mediaFormat: {is-adts = 1, liczba kanałów = 2, mime = audio / mp4a-latm, csd-0 = java.nio.ByteArrayBuffer [pozycja = 2, limit = 2, pojemność = 2], częstotliwość próbkowania = 48000}

Nawet gdy przyjmuję MediaFormat stworzony przez TSExtractor, aby był podobny do tego stworzonego przez MediaExtractor, dekoder daje ten sam błąd, używając stworzonego przez siebie i dekoduje bez żadnych problemów używając drugiego.

Każda pomoc byłaby naprawdę pomocna.

questionAnswers(4)

yourAnswerToTheQuestion