Какой поток использовать для декодирования звука?

При работе с воспроизведением аудио я привык к следующему шаблону:

  • один дисковый (или сетевой) поток, который считывает данные с диска (или сети) и заполняет кольцевой буфер
  • один аудиопоток, который считывает данные из кольцевого буфера, возможно, выполняет DSP и записывает в аудиооборудование (pull или push API)

Это работает нормально, и нет проблем при работе, скажем, с файлом WAV.

Теперь, если исходные данные закодированы в сжатом формате, таком как Vorbis или MP3, декодирование занимает некоторое время.

И кажется, что декодирование в дисковом/сетевом потоке выполняется довольно часто.

Но разве это не неправильный дизайн? Когда доступ к диску или сети блокируется, некоторое время ЦП доступно для декодирования, но тратится впустую, если декодирование происходит в том же потоке.

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

Итак, разве декодирование не должно выполняться в аудиопотоке?

В моем контексте я бы предпочел не добавлять выделенный поток декодирования. Это для мобильных платформ, а SMP сейчас встречается довольно редко. Но, пожалуйста, скажите, действительно ли для вас имеет смысл отдельная ветка декодирования.


person olivierg    schedule 09.05.2011    source источник


Ответы (2)


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

В идеале вы должны использовать три потока. Один для чтения сети, один для декодирования и один для воспроизведения. В нашем приложении, которое занимается захватом аудио/видео, записью и потоковой передачей, у нас есть восемь потоков на поток (недавно увеличилось с шести потоков, так как мы недавно добавили новые функции). Каждому потоку намного проще иметь свою собственную функциональность, а затем он может соответствующим образом измерять свою производительность по сравнению с производительностью своих входящих/исходящих буферов. Это также приносит пользу профилированию и оптимизации.

person Samuel Neff    schedule 09.05.2011
comment
Вы правы, в случае двух потоков декодирование должно выполняться в сетевом потоке. После написания я понял, что, поскольку декодирование звука основано на пакетах, оно может блокироваться на долгое время каждые N аудиоциклов, и это вызовет xrun. Тем не менее, выделенный поток декодирования становится для меня все более и более привлекательным, особенно для сетевых потоков (или медленных дисков/хранилищ). - person olivierg; 10.05.2011

Если ваше устройство имеет один ЦП, все потоки используют его совместно. Обмен потоками ОС обычно очень эффективен (вы не потеряете значимой мощности ЦП для обмена). Поэтому вам следует создать больше потоков, если это упростит вашу логику.

В вашем случае есть трубопровод. Различные потоки для каждого этапа конвейера — хороший шаблон. Альтернатива, как вы заметили, включает в себя сложную логику, синхронизацию, события, прерывания или что-то еще. Иногда хороших альтернатив нет вообще.

Следовательно, мое предложение - создать специальную ветку для декодирования звука.

Если у вас будет более одного ЦП, вы даже повысите эффективность, используя один поток для каждого шага конвейера.

person Lior Kogan    schedule 09.05.2011
comment
Я много раз читал, что слишком много потоков может быть тяжелым. Поэтому я обычно дважды думаю, прежде чем добавлять новую тему, и даже больше, когда работаю на мобильной платформе. Я не уверен, что упрощение логики обязательно является веской причиной для добавления потока в конвейер. Но в этом контексте выделенный поток декодирования, кажется, имеет смысл. - person olivierg; 10.05.2011
comment
Я думаю, что 100 потоков могут быть проблемой (хотя я без проблем использовал 300 потоков под Windows). Однако другие механизмы/стратегии синхронизации также имеют свою цену. Эта стоимость может быть выше или ниже, но обычно эффект невелик. Если потоки конвейера реализованы правильно, большую часть времени они просто будут спать и ждать событий. - person Lior Kogan; 10.05.2011