Декодирование MP3 на Android

Мы реализуем программу для телефонов на базе Android, которая играет аудио, переданное потоком из Интернета. Вот приблизительно, что мы делаем:

  1. Загрузите пользовательский зашифрованный формат.
  2. Дешифруйте для получения блоков регулярных данных MP3.
  3. Декодируйте данные MP3 к необработанным данным PCM в буфере памяти.
  4. Передайте необработанные данные PCM по каналу к AudioTrack

Нашими целевыми устройствами до сих пор является Droid и Nexus One. Все работает отлично на Nexus One, но декодирование MP3 является слишком медленным на Droid. Воспроизведение звука начинает пропускать, если мы подвергаем Droid загрузке. Нам не разрешают декодировать данные MP3 к SD-карте, но я знаю, что это не наша проблема так или иначе.

Мы не записали наш собственный декодер MP3, но используемый MPADEC (http://sourceforge.net/projects/mpadec/). Это свободно и было легко интегрироваться с нашей программой. Мы компилируем его с NDK.

После исчерпывающего анализа с различными профильными инструментами мы убеждены, что именно этот декодер отстает.

Вот опции, о которых мы думаем:

  1. Найдите другой декодер MP3, который мы можем скомпилировать с NDK Android. Этот декодер MP3 должен был бы быть или оптимизирован, чтобы работать на мобильных устройствах ARM или возможно использовать математику только для целого числа или некоторую другую оптимизацию для увеличения производительности.

  2. Так как встроенный сервис Android MediaPlayer возьмет URL, мы смогли реализовывать крошечный сервер HTTP в нашей программе и служить MediaPlayer с дешифрованным MP3s. Тем путем мы можем использовать в своих интересах встроенный декодер MP3.

  3. Получите доступ к встроенному декодеру MP3 через NDK. Я не знаю, возможно ли это.

У кого-либо есть какие-либо предложения на том, что мы можем сделать для ускорения нашего декодирования MP3?

- Ограбьте Sz

29
задан Rob Szumlakowski 22 March 2010 в 17:48
поделиться

3 ответа

Я не пробовал это, но считаю, что вы можете дать медиаплееру дескриптор файла:

public void setDataSource (FileDescriptor fd, long offset, long length)

Может быть, вы могли бы записать расшифрованный mp3 в файл и воспроизвести его с помощью файлового дескриптора. Это может даже работать для потоковой передачи, если вы заранее знаете длину файла. Если это сработает, это будет намного проще, чем создание локального веб-сервера.

0
ответ дан 28 November 2019 в 02:11
поделиться

Правильный способ сделать это - создать собственную прошивку и выполнить расшифровку как часть собственного кодека OpenCORE. Это, конечно, ограничит вас устройствами, на которые вы можете установить эту прошивку.

Имейте в виду, что все остальное носит несколько умозрительный характер. Мне действительно нужно сделать что-то похожее на то, что вы описываете, но у меня нет времени, чтобы решить эту проблему в течение пары месяцев. Итак, я опишу это так, как я подхожу к проблеме.

Одно из решений описано в ответе twk. Вам не обязательно использовать SD-карту, но вам, вероятно, необходимо иметь доступный для чтения временный файл в локальном хранилище файлов вашего приложения ( getFilesDir () ). Загрузите первый фрагмент, расшифруйте его, запишите его как полный доступный для чтения файл MP3 (но с достаточно неясным каталогом / путем) и передайте его MediaPlayer через setDataSource () . Во время воспроизведения вы загружаете / расшифровываете и настраиваете второй экземпляр MediaPlayer , который начинает воспроизведение, как только заканчивается первый, для максимально плавного перехода. Затем вы сбрасываете первый MediaPlayer и повторно используете его со своим третьим блоком, балансируя между ними.

Соответствующее решение можно найти в комментарии jleedev. Это почти то же самое, за исключением того, что вы предоставляете FileDescriptor через ContentProvider . Здесь есть возможность использовать сокет, который может позволить вам избежать временного файла.Однако ContentProvider сам по себе должен быть общедоступным, поэтому временный файл с неясным каталогом может быть более приватным.

Если вас беспокоит тот факт, что эти вещи могут быть прочитаны другими процессами, пожалуйста, поймите, что сам MediaPlayer (или, скорее, подсистема OpenCORE) находится в другом процессе. Кроме того, предлагаемый вами HTTP-сервер также доступен для чтения на устройстве. Таким образом, защита посредством неизвестности - ваш единственный жизнеспособный вариант, если вы собираетесь позволить MediaPlayer выполнять декодирование.

Насколько мне известно, NDK не предоставляет доступ к OpenCORE, хотя я признаюсь, что у меня ограниченный опыт работы с NDK, поэтому я могу ошибаться. Конечно, существуют и другие декодеры MP3 ( ffmpeg / mplayer и т. Д.), Хотя неясно, насколько легко их можно преобразовать в библиотеку NDK.

Итак, все сводится к тому, от кого вы пытаетесь защищаться. Если вы пытаетесь защититься от пользователя, вам, вероятно, придется как-то его расшифровать самостоятельно.

2
ответ дан 28 November 2019 в 02:11
поделиться

MAD библиотека декодеров только для целочисленных арифметических операций, которая, кажется, пользуется большим успехом.

(Разве декодирование данных на SD-карту не замедлит вас?)

1
ответ дан 28 November 2019 в 02:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: