alsa_output.cc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. //
  5. // THREAD SAFETY
  6. //
  7. // AlsaPcmOutputStream object is *not* thread-safe and should only be used
  8. // from the audio thread. We DCHECK on this assumption whenever we can.
  9. //
  10. // SEMANTICS OF Close()
  11. //
  12. // Close() is responsible for cleaning up any resources that were acquired after
  13. // a successful Open(). Close() will nullify any scheduled outstanding runnable
  14. // methods.
  15. //
  16. //
  17. // SEMANTICS OF ERROR STATES
  18. //
  19. // The object has two distinct error states: |state_| == kInError
  20. // and |stop_stream_|. The |stop_stream_| variable is used to indicate
  21. // that the playback_handle should no longer be used either because of a
  22. // hardware/low-level event.
  23. //
  24. // When |state_| == kInError, all public API functions will fail with an error
  25. // (Start() will call the OnError() function on the callback immediately), or
  26. // no-op themselves with the exception of Close(). Even if an error state has
  27. // been entered, if Open() has previously returned successfully, Close() must be
  28. // called to cleanup the ALSA devices and release resources.
  29. //
  30. // When |stop_stream_| is set, no more commands will be made against the
  31. // ALSA device, and playback will effectively stop. From the client's point of
  32. // view, it will seem that the device has just clogged and stopped requesting
  33. // data.
  34. #include "media/audio/alsa/alsa_output.h"
  35. #include <stddef.h>
  36. #include <algorithm>
  37. #include <memory>
  38. #include <utility>
  39. #include "base/bind.h"
  40. #include "base/logging.h"
  41. #include "base/memory/free_deleter.h"
  42. #include "base/threading/thread_task_runner_handle.h"
  43. #include "base/time/default_tick_clock.h"
  44. #include "base/trace_event/trace_event.h"
  45. #include "media/audio/alsa/alsa_util.h"
  46. #include "media/audio/alsa/alsa_wrapper.h"
  47. #include "media/audio/alsa/audio_manager_alsa.h"
  48. #include "media/base/audio_timestamp_helper.h"
  49. #include "media/base/channel_mixer.h"
  50. #include "media/base/data_buffer.h"
  51. #include "media/base/seekable_buffer.h"
  52. namespace media {
  53. // Set to 0 during debugging if you want error messages due to underrun
  54. // events or other recoverable errors.
  55. #if defined(NDEBUG)
  56. static const int kPcmRecoverIsSilent = 1;
  57. #else
  58. static const int kPcmRecoverIsSilent = 0;
  59. #endif
  60. // The output channel layout if we set up downmixing for the kDefaultDevice
  61. // device.
  62. static const ChannelLayout kDefaultOutputChannelLayout = CHANNEL_LAYOUT_STEREO;
  63. // While the "default" device may support multi-channel audio, in Alsa, only
  64. // the device names surround40, surround41, surround50, etc, have a defined
  65. // channel mapping according to Lennart:
  66. //
  67. // http://0pointer.de/blog/projects/guide-to-sound-apis.html
  68. //
  69. // This function makes a best guess at the specific > 2 channel device name
  70. // based on the number of channels requested. nullptr is returned if no device
  71. // can be found to match the channel numbers. In this case, using
  72. // kDefaultDevice is probably the best bet.
  73. //
  74. // A five channel source is assumed to be surround50 instead of surround41
  75. // (which is also 5 channels).
  76. //
  77. // TODO(ajwong): The source data should have enough info to tell us if we want
  78. // surround41 versus surround51, etc., instead of needing us to guess based on
  79. // channel number. Fix API to pass that data down.
  80. static const char* GuessSpecificDeviceName(uint32_t channels) {
  81. switch (channels) {
  82. case 8:
  83. return "surround71";
  84. case 7:
  85. return "surround70";
  86. case 6:
  87. return "surround51";
  88. case 5:
  89. return "surround50";
  90. case 4:
  91. return "surround40";
  92. default:
  93. return nullptr;
  94. }
  95. }
  96. std::ostream& operator<<(std::ostream& os,
  97. AlsaPcmOutputStream::InternalState state) {
  98. switch (state) {
  99. case AlsaPcmOutputStream::kInError:
  100. os << "kInError";
  101. break;
  102. case AlsaPcmOutputStream::kCreated:
  103. os << "kCreated";
  104. break;
  105. case AlsaPcmOutputStream::kIsOpened:
  106. os << "kIsOpened";
  107. break;
  108. case AlsaPcmOutputStream::kIsPlaying:
  109. os << "kIsPlaying";
  110. break;
  111. case AlsaPcmOutputStream::kIsStopped:
  112. os << "kIsStopped";
  113. break;
  114. case AlsaPcmOutputStream::kIsClosed:
  115. os << "kIsClosed";
  116. break;
  117. }
  118. return os;
  119. }
  120. static const SampleFormat kSampleFormat = kSampleFormatS16;
  121. static const snd_pcm_format_t kAlsaSampleFormat = SND_PCM_FORMAT_S16;
  122. const char AlsaPcmOutputStream::kDefaultDevice[] = "default";
  123. const char AlsaPcmOutputStream::kAutoSelectDevice[] = "";
  124. const char AlsaPcmOutputStream::kPlugPrefix[] = "plug:";
  125. // We use 40ms as our minimum required latency. If it is needed, we may be able
  126. // to get it down to 20ms.
  127. const uint32_t AlsaPcmOutputStream::kMinLatencyMicros = 40 * 1000;
  128. AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name,
  129. const AudioParameters& params,
  130. AlsaWrapper* wrapper,
  131. AudioManagerBase* manager)
  132. : requested_device_name_(device_name),
  133. pcm_format_(kAlsaSampleFormat),
  134. channels_(params.channels()),
  135. channel_layout_(params.channel_layout()),
  136. sample_rate_(params.sample_rate()),
  137. bytes_per_sample_(SampleFormatToBytesPerChannel(kSampleFormat)),
  138. bytes_per_frame_(params.GetBytesPerFrame(kSampleFormat)),
  139. packet_size_(params.GetBytesPerBuffer(kSampleFormat)),
  140. latency_(std::max(
  141. base::Microseconds(kMinLatencyMicros),
  142. AudioTimestampHelper::FramesToTime(params.frames_per_buffer() * 2,
  143. sample_rate_))),
  144. bytes_per_output_frame_(bytes_per_frame_),
  145. alsa_buffer_frames_(0),
  146. stop_stream_(false),
  147. wrapper_(wrapper),
  148. manager_(manager),
  149. task_runner_(base::ThreadTaskRunnerHandle::Get()),
  150. playback_handle_(nullptr),
  151. frames_per_packet_(packet_size_ / bytes_per_frame_),
  152. state_(kCreated),
  153. volume_(1.0f),
  154. source_callback_(nullptr),
  155. audio_bus_(AudioBus::Create(params)),
  156. tick_clock_(base::DefaultTickClock::GetInstance()) {
  157. DCHECK(manager_->GetTaskRunner()->BelongsToCurrentThread());
  158. DCHECK_EQ(audio_bus_->frames() * bytes_per_frame_, packet_size_);
  159. // Sanity check input values.
  160. if (!params.IsValid()) {
  161. LOG(WARNING) << "Unsupported audio parameters.";
  162. TransitionTo(kInError);
  163. }
  164. }
  165. AlsaPcmOutputStream::~AlsaPcmOutputStream() {
  166. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  167. InternalState current_state = state();
  168. DCHECK(current_state == kCreated ||
  169. current_state == kIsClosed ||
  170. current_state == kInError);
  171. DCHECK(!playback_handle_);
  172. }
  173. bool AlsaPcmOutputStream::Open() {
  174. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  175. if (state() == kInError)
  176. return false;
  177. if (!CanTransitionTo(kIsOpened)) {
  178. NOTREACHED() << "Invalid state: " << state();
  179. return false;
  180. }
  181. // We do not need to check if the transition was successful because
  182. // CanTransitionTo() was checked above, and it is assumed that this
  183. // object's public API is only called on one thread so the state cannot
  184. // transition out from under us.
  185. TransitionTo(kIsOpened);
  186. // Try to open the device.
  187. if (requested_device_name_ == kAutoSelectDevice) {
  188. playback_handle_ = AutoSelectDevice(latency_.InMicroseconds());
  189. if (playback_handle_)
  190. DVLOG(1) << "Auto-selected device: " << device_name_;
  191. } else {
  192. device_name_ = requested_device_name_;
  193. playback_handle_ = alsa_util::OpenPlaybackDevice(
  194. wrapper_, device_name_.c_str(), channels_, sample_rate_,
  195. pcm_format_, latency_.InMicroseconds());
  196. }
  197. // Finish initializing the stream if the device was opened successfully.
  198. if (playback_handle_ == nullptr) {
  199. stop_stream_ = true;
  200. TransitionTo(kInError);
  201. return false;
  202. }
  203. bytes_per_output_frame_ =
  204. channel_mixer_ ? mixed_audio_bus_->channels() * bytes_per_sample_
  205. : bytes_per_frame_;
  206. uint32_t output_packet_size = frames_per_packet_ * bytes_per_output_frame_;
  207. buffer_ = std::make_unique<SeekableBuffer>(0, output_packet_size);
  208. // Get alsa buffer size.
  209. snd_pcm_uframes_t buffer_size;
  210. snd_pcm_uframes_t period_size;
  211. int error =
  212. wrapper_->PcmGetParams(playback_handle_, &buffer_size, &period_size);
  213. if (error < 0) {
  214. LOG(ERROR) << "Failed to get playback buffer size from ALSA: "
  215. << wrapper_->StrError(error);
  216. // Buffer size is at least twice of packet size.
  217. alsa_buffer_frames_ = frames_per_packet_ * 2;
  218. } else {
  219. alsa_buffer_frames_ = buffer_size;
  220. }
  221. return true;
  222. }
  223. void AlsaPcmOutputStream::Close() {
  224. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  225. if (state() != kIsClosed)
  226. TransitionTo(kIsClosed);
  227. // Shutdown the audio device.
  228. if (playback_handle_) {
  229. int res =
  230. alsa_util::CloseDevice(wrapper_, playback_handle_.ExtractAsDangling());
  231. if (res < 0) {
  232. LOG(WARNING) << "Unable to close audio device. Leaking handle.";
  233. }
  234. // Release the buffer.
  235. buffer_.reset();
  236. // Signal anything that might already be scheduled to stop.
  237. stop_stream_ = true; // Not necessary in production, but unit tests
  238. // uses the flag to verify that stream was closed.
  239. }
  240. weak_factory_.InvalidateWeakPtrs();
  241. // Signal to the manager that we're closed and can be removed.
  242. // Should be last call in the method as it deletes "this".
  243. manager_->ReleaseOutputStream(this);
  244. }
  245. void AlsaPcmOutputStream::Start(AudioSourceCallback* callback) {
  246. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  247. CHECK(callback);
  248. if (stop_stream_)
  249. return;
  250. // Only post the task if we can enter the playing state.
  251. if (TransitionTo(kIsPlaying) != kIsPlaying)
  252. return;
  253. // Before starting, the buffer might have audio from previous user of this
  254. // device.
  255. buffer_->Clear();
  256. // When starting again, drop all packets in the device and prepare it again
  257. // in case we are restarting from a pause state and need to flush old data.
  258. int error = wrapper_->PcmDrop(playback_handle_);
  259. if (error < 0 && error != -EAGAIN) {
  260. LOG(ERROR) << "Failure clearing playback device ("
  261. << wrapper_->PcmName(playback_handle_) << "): "
  262. << wrapper_->StrError(error);
  263. stop_stream_ = true;
  264. return;
  265. }
  266. error = wrapper_->PcmPrepare(playback_handle_);
  267. if (error < 0 && error != -EAGAIN) {
  268. LOG(ERROR) << "Failure preparing stream ("
  269. << wrapper_->PcmName(playback_handle_) << "): "
  270. << wrapper_->StrError(error);
  271. stop_stream_ = true;
  272. return;
  273. }
  274. // Ensure the first buffer is silence to avoid startup glitches.
  275. int buffer_size = GetAvailableFrames() * bytes_per_output_frame_;
  276. scoped_refptr<DataBuffer> silent_packet = new DataBuffer(buffer_size);
  277. silent_packet->set_data_size(buffer_size);
  278. memset(silent_packet->writable_data(), 0, silent_packet->data_size());
  279. buffer_->Append(silent_packet);
  280. WritePacket();
  281. // Start the callback chain.
  282. set_source_callback(callback);
  283. WriteTask();
  284. }
  285. void AlsaPcmOutputStream::Stop() {
  286. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  287. // Reset the callback, so that it is not called anymore.
  288. set_source_callback(nullptr);
  289. weak_factory_.InvalidateWeakPtrs();
  290. TransitionTo(kIsStopped);
  291. }
  292. // This stream is always used with sub second buffer sizes, where it's
  293. // sufficient to simply always flush upon Start().
  294. void AlsaPcmOutputStream::Flush() {}
  295. void AlsaPcmOutputStream::SetVolume(double volume) {
  296. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  297. volume_ = static_cast<float>(volume);
  298. }
  299. void AlsaPcmOutputStream::GetVolume(double* volume) {
  300. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  301. *volume = volume_;
  302. }
  303. void AlsaPcmOutputStream::SetTickClockForTesting(
  304. const base::TickClock* tick_clock) {
  305. DCHECK(tick_clock);
  306. tick_clock_ = tick_clock;
  307. }
  308. void AlsaPcmOutputStream::BufferPacket(bool* source_exhausted) {
  309. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  310. // If stopped, simulate a 0-length packet.
  311. if (stop_stream_) {
  312. buffer_->Clear();
  313. *source_exhausted = true;
  314. return;
  315. }
  316. *source_exhausted = false;
  317. // Request more data only when we run out of data in the buffer, because
  318. // WritePacket() consumes only the current chunk of data.
  319. if (!buffer_->forward_bytes()) {
  320. // Before making a request to source for data we need to determine the
  321. // delay for the requested data to be played.
  322. const base::TimeDelta delay =
  323. AudioTimestampHelper::FramesToTime(GetCurrentDelay(), sample_rate_);
  324. scoped_refptr<DataBuffer> packet = new DataBuffer(packet_size_);
  325. int frames_filled =
  326. RunDataCallback(delay, tick_clock_->NowTicks(), audio_bus_.get());
  327. size_t packet_size = frames_filled * bytes_per_frame_;
  328. DCHECK_LE(packet_size, packet_size_);
  329. // TODO(dalecurtis): Channel downmixing, upmixing, should be done in mixer;
  330. // volume adjust should use SSE optimized vector_fmul() prior to interleave.
  331. AudioBus* output_bus = audio_bus_.get();
  332. ChannelLayout output_channel_layout = channel_layout_;
  333. if (channel_mixer_) {
  334. output_bus = mixed_audio_bus_.get();
  335. channel_mixer_->Transform(audio_bus_.get(), output_bus);
  336. output_channel_layout = kDefaultOutputChannelLayout;
  337. // Adjust packet size for downmix.
  338. packet_size = packet_size / bytes_per_frame_ * bytes_per_output_frame_;
  339. }
  340. // Reorder channels for 5.0, 5.1, and 7.1 to match ALSA's channel order,
  341. // which has front center at channel index 4 and LFE at channel index 5.
  342. // See http://ffmpeg.org/pipermail/ffmpeg-cvslog/2011-June/038454.html.
  343. switch (output_channel_layout) {
  344. case CHANNEL_LAYOUT_5_0:
  345. case CHANNEL_LAYOUT_5_0_BACK:
  346. output_bus->SwapChannels(2, 3);
  347. output_bus->SwapChannels(3, 4);
  348. break;
  349. case CHANNEL_LAYOUT_5_1:
  350. case CHANNEL_LAYOUT_5_1_BACK:
  351. case CHANNEL_LAYOUT_7_1:
  352. output_bus->SwapChannels(2, 4);
  353. output_bus->SwapChannels(3, 5);
  354. break;
  355. default:
  356. break;
  357. }
  358. // Note: If this ever changes to output raw float the data must be clipped
  359. // and sanitized since it may come from an untrusted source such as NaCl.
  360. output_bus->Scale(volume_);
  361. output_bus->ToInterleaved<SignedInt16SampleTypeTraits>(
  362. frames_filled, reinterpret_cast<int16_t*>(packet->writable_data()));
  363. if (packet_size > 0) {
  364. packet->set_data_size(packet_size);
  365. // Add the packet to the buffer.
  366. buffer_->Append(packet);
  367. } else {
  368. *source_exhausted = true;
  369. }
  370. }
  371. }
  372. void AlsaPcmOutputStream::WritePacket() {
  373. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  374. // If the device is in error, just eat the bytes.
  375. if (stop_stream_) {
  376. buffer_->Clear();
  377. return;
  378. }
  379. if (state() != kIsPlaying)
  380. return;
  381. CHECK_EQ(buffer_->forward_bytes() % bytes_per_output_frame_, 0u);
  382. const uint8_t* buffer_data;
  383. int buffer_size;
  384. if (buffer_->GetCurrentChunk(&buffer_data, &buffer_size)) {
  385. snd_pcm_sframes_t frames = std::min(
  386. static_cast<snd_pcm_sframes_t>(buffer_size / bytes_per_output_frame_),
  387. GetAvailableFrames());
  388. if (!frames)
  389. return;
  390. snd_pcm_sframes_t frames_written =
  391. wrapper_->PcmWritei(playback_handle_, buffer_data, frames);
  392. if (frames_written < 0) {
  393. // Attempt once to immediately recover from EINTR,
  394. // EPIPE (overrun/underrun), ESTRPIPE (stream suspended). WritePacket
  395. // will eventually be called again, so eventual recovery will happen if
  396. // muliple retries are required.
  397. frames_written = wrapper_->PcmRecover(playback_handle_,
  398. frames_written,
  399. kPcmRecoverIsSilent);
  400. if (frames_written < 0) {
  401. if (frames_written != -EAGAIN) {
  402. LOG(ERROR) << "Failed to write to pcm device: "
  403. << wrapper_->StrError(frames_written);
  404. RunErrorCallback(frames_written);
  405. stop_stream_ = true;
  406. }
  407. }
  408. } else {
  409. DCHECK_EQ(frames_written, frames);
  410. // Seek forward in the buffer after we've written some data to ALSA.
  411. buffer_->Seek(frames_written * bytes_per_output_frame_);
  412. }
  413. } else {
  414. // If nothing left to write and playback hasn't started yet, start it now.
  415. // This ensures that shorter sounds will still play.
  416. if (playback_handle_ &&
  417. (wrapper_->PcmState(playback_handle_) == SND_PCM_STATE_PREPARED) &&
  418. GetCurrentDelay() > 0) {
  419. wrapper_->PcmStart(playback_handle_);
  420. }
  421. }
  422. }
  423. void AlsaPcmOutputStream::WriteTask() {
  424. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  425. if (stop_stream_)
  426. return;
  427. if (state() == kIsStopped)
  428. return;
  429. bool source_exhausted;
  430. BufferPacket(&source_exhausted);
  431. WritePacket();
  432. ScheduleNextWrite(source_exhausted);
  433. }
  434. void AlsaPcmOutputStream::ScheduleNextWrite(bool source_exhausted) {
  435. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  436. if (stop_stream_ || state() != kIsPlaying)
  437. return;
  438. const uint32_t kTargetFramesAvailable = alsa_buffer_frames_ / 2;
  439. uint32_t available_frames = GetAvailableFrames();
  440. base::TimeDelta next_fill_time;
  441. if (buffer_->forward_bytes() && available_frames) {
  442. // If we've got data available and ALSA has room, deliver it immediately.
  443. next_fill_time = base::TimeDelta();
  444. } else if (buffer_->forward_bytes()) {
  445. // If we've got data available and no room, poll until room is available.
  446. // Polling in this manner allows us to ensure a more consistent callback
  447. // schedule. In testing this yields a variance of +/- 5ms versus the non-
  448. // polling strategy which is around +/- 30ms and bimodal.
  449. next_fill_time = base::Milliseconds(5);
  450. } else if (available_frames < kTargetFramesAvailable) {
  451. // Schedule the next write for the moment when the available buffer of the
  452. // sound card hits |kTargetFramesAvailable|.
  453. next_fill_time = AudioTimestampHelper::FramesToTime(
  454. kTargetFramesAvailable - available_frames, sample_rate_);
  455. } else if (!source_exhausted) {
  456. // The sound card has |kTargetFramesAvailable| or more frames available.
  457. // Invoke the next write immediately to avoid underrun.
  458. next_fill_time = base::TimeDelta();
  459. } else {
  460. // The sound card has frames available, but our source is exhausted, so
  461. // avoid busy looping by delaying a bit.
  462. next_fill_time = base::Milliseconds(10);
  463. }
  464. task_runner_->PostDelayedTaskAt(
  465. base::subtle::PostDelayedTaskPassKey(), FROM_HERE,
  466. base::BindOnce(&AlsaPcmOutputStream::WriteTask,
  467. weak_factory_.GetWeakPtr()),
  468. next_fill_time.is_zero() ? base::TimeTicks()
  469. : base::TimeTicks::Now() + next_fill_time,
  470. base::subtle::DelayPolicy::kPrecise);
  471. }
  472. std::string AlsaPcmOutputStream::FindDeviceForChannels(uint32_t channels) {
  473. // Constants specified by the ALSA API for device hints.
  474. static const int kGetAllDevices = -1;
  475. static const char kPcmInterfaceName[] = "pcm";
  476. static const char kIoHintName[] = "IOID";
  477. static const char kNameHintName[] = "NAME";
  478. const char* wanted_device = GuessSpecificDeviceName(channels);
  479. if (!wanted_device)
  480. return std::string();
  481. std::string guessed_device;
  482. void** hints = nullptr;
  483. int error = wrapper_->DeviceNameHint(kGetAllDevices,
  484. kPcmInterfaceName,
  485. &hints);
  486. if (error == 0) {
  487. // NOTE: Do not early return from inside this if statement. The
  488. // hints above need to be freed.
  489. for (void** hint_iter = hints; *hint_iter != nullptr; hint_iter++) {
  490. // Only examine devices that are output capable.. Valid values are
  491. // "Input", "Output", and nullptr which means both input and output.
  492. std::unique_ptr<char, base::FreeDeleter> io(
  493. wrapper_->DeviceNameGetHint(*hint_iter, kIoHintName));
  494. if (io != nullptr && strcmp(io.get(), "Input") == 0)
  495. continue;
  496. // Attempt to select the closest device for number of channels.
  497. std::unique_ptr<char, base::FreeDeleter> name(
  498. wrapper_->DeviceNameGetHint(*hint_iter, kNameHintName));
  499. if (strncmp(wanted_device, name.get(), strlen(wanted_device)) == 0) {
  500. guessed_device = name.get();
  501. break;
  502. }
  503. }
  504. // Destroy the hint now that we're done with it.
  505. wrapper_->DeviceNameFreeHint(hints);
  506. hints = nullptr;
  507. } else {
  508. LOG(ERROR) << "Unable to get hints for devices: "
  509. << wrapper_->StrError(error);
  510. }
  511. return guessed_device;
  512. }
  513. snd_pcm_sframes_t AlsaPcmOutputStream::GetCurrentDelay() {
  514. snd_pcm_sframes_t delay = -1;
  515. // Don't query ALSA's delay if we have underrun since it'll be jammed at some
  516. // non-zero value and potentially even negative!
  517. //
  518. // Also, if we're in the prepared state, don't query because that seems to
  519. // cause an I/O error when we do query the delay.
  520. snd_pcm_state_t pcm_state = wrapper_->PcmState(playback_handle_);
  521. if (pcm_state != SND_PCM_STATE_XRUN &&
  522. pcm_state != SND_PCM_STATE_PREPARED) {
  523. int error = wrapper_->PcmDelay(playback_handle_, &delay);
  524. if (error < 0) {
  525. // Assume a delay of zero and attempt to recover the device.
  526. delay = -1;
  527. error = wrapper_->PcmRecover(playback_handle_,
  528. error,
  529. kPcmRecoverIsSilent);
  530. if (error < 0) {
  531. LOG(ERROR) << "Failed querying delay: " << wrapper_->StrError(error);
  532. }
  533. }
  534. }
  535. // snd_pcm_delay() sometimes returns crazy values. In this case return delay
  536. // of data we know currently is in ALSA's buffer. Note: When the underlying
  537. // driver is PulseAudio based, certain configuration settings (e.g., tsched=1)
  538. // will generate much larger delay values than |alsa_buffer_frames_|, so only
  539. // clip if delay is truly crazy (> 10x expected).
  540. if (delay < 0 ||
  541. static_cast<snd_pcm_uframes_t>(delay) > alsa_buffer_frames_ * 10) {
  542. delay = alsa_buffer_frames_ - GetAvailableFrames();
  543. }
  544. if (delay < 0) {
  545. delay = 0;
  546. }
  547. return delay;
  548. }
  549. snd_pcm_sframes_t AlsaPcmOutputStream::GetAvailableFrames() {
  550. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  551. if (stop_stream_)
  552. return 0;
  553. // Find the number of frames queued in the sound device.
  554. snd_pcm_sframes_t available_frames =
  555. wrapper_->PcmAvailUpdate(playback_handle_);
  556. if (available_frames < 0) {
  557. available_frames = wrapper_->PcmRecover(playback_handle_,
  558. available_frames,
  559. kPcmRecoverIsSilent);
  560. }
  561. if (available_frames < 0) {
  562. LOG(ERROR) << "Failed querying available frames. Assuming 0: "
  563. << wrapper_->StrError(available_frames);
  564. return 0;
  565. }
  566. if (static_cast<uint32_t>(available_frames) > alsa_buffer_frames_ * 2) {
  567. LOG(ERROR) << "ALSA returned " << available_frames << " of "
  568. << alsa_buffer_frames_ << " frames available.";
  569. return alsa_buffer_frames_;
  570. }
  571. return available_frames;
  572. }
  573. snd_pcm_t* AlsaPcmOutputStream::AutoSelectDevice(unsigned int latency) {
  574. // For auto-selection:
  575. // 1) Attempt to open a device that best matches the number of channels
  576. // requested.
  577. // 2) If that fails, attempt the "plug:" version of it in case ALSA can
  578. // remap and do some software conversion to make it work.
  579. // 3) If that fails, attempt the "plug:" version of the guessed name in
  580. // case ALSA can remap and do some software conversion to make it work.
  581. // 4) Fallback to kDefaultDevice.
  582. // 5) If that fails too, try the "plug:" version of kDefaultDevice.
  583. // 6) Give up.
  584. snd_pcm_t* handle = nullptr;
  585. device_name_ = FindDeviceForChannels(channels_);
  586. // Step 1.
  587. if (!device_name_.empty()) {
  588. if ((handle = alsa_util::OpenPlaybackDevice(
  589. wrapper_, device_name_.c_str(), channels_, sample_rate_,
  590. pcm_format_, latency)) != nullptr) {
  591. return handle;
  592. }
  593. // Step 2.
  594. device_name_ = kPlugPrefix + device_name_;
  595. if ((handle = alsa_util::OpenPlaybackDevice(
  596. wrapper_, device_name_.c_str(), channels_, sample_rate_,
  597. pcm_format_, latency)) != nullptr) {
  598. return handle;
  599. }
  600. // Step 3.
  601. device_name_ = GuessSpecificDeviceName(channels_);
  602. if (!device_name_.empty()) {
  603. device_name_ = kPlugPrefix + device_name_;
  604. if ((handle = alsa_util::OpenPlaybackDevice(
  605. wrapper_, device_name_.c_str(), channels_, sample_rate_,
  606. pcm_format_, latency)) != nullptr) {
  607. return handle;
  608. }
  609. }
  610. }
  611. // For the kDefaultDevice device, we can only reliably depend on 2-channel
  612. // output to have the correct ordering according to Lennart. For the channel
  613. // formats that we know how to downmix from (3 channel to 8 channel), setup
  614. // downmixing.
  615. uint32_t default_channels = channels_;
  616. if (default_channels > 2) {
  617. channel_mixer_ = std::make_unique<ChannelMixer>(
  618. channel_layout_, kDefaultOutputChannelLayout);
  619. default_channels = 2;
  620. mixed_audio_bus_ = AudioBus::Create(
  621. default_channels, audio_bus_->frames());
  622. }
  623. // Step 4.
  624. device_name_ = kDefaultDevice;
  625. if ((handle = alsa_util::OpenPlaybackDevice(
  626. wrapper_, device_name_.c_str(), default_channels, sample_rate_,
  627. pcm_format_, latency)) != nullptr) {
  628. return handle;
  629. }
  630. // Step 5.
  631. device_name_ = kPlugPrefix + device_name_;
  632. if ((handle = alsa_util::OpenPlaybackDevice(
  633. wrapper_, device_name_.c_str(), default_channels, sample_rate_,
  634. pcm_format_, latency)) != nullptr) {
  635. return handle;
  636. }
  637. // Unable to open any device.
  638. device_name_.clear();
  639. return nullptr;
  640. }
  641. bool AlsaPcmOutputStream::CanTransitionTo(InternalState to) {
  642. switch (state_) {
  643. case kCreated:
  644. return to == kIsOpened || to == kIsClosed || to == kInError;
  645. case kIsOpened:
  646. return to == kIsPlaying || to == kIsStopped ||
  647. to == kIsClosed || to == kInError;
  648. case kIsPlaying:
  649. return to == kIsPlaying || to == kIsStopped ||
  650. to == kIsClosed || to == kInError;
  651. case kIsStopped:
  652. return to == kIsPlaying || to == kIsStopped ||
  653. to == kIsClosed || to == kInError;
  654. case kInError:
  655. return to == kIsClosed || to == kInError;
  656. case kIsClosed:
  657. default:
  658. return false;
  659. }
  660. }
  661. AlsaPcmOutputStream::InternalState
  662. AlsaPcmOutputStream::TransitionTo(InternalState to) {
  663. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  664. if (!CanTransitionTo(to)) {
  665. NOTREACHED() << "Cannot transition from: " << state_ << " to: " << to;
  666. state_ = kInError;
  667. } else {
  668. state_ = to;
  669. }
  670. return state_;
  671. }
  672. AlsaPcmOutputStream::InternalState AlsaPcmOutputStream::state() {
  673. return state_;
  674. }
  675. int AlsaPcmOutputStream::RunDataCallback(base::TimeDelta delay,
  676. base::TimeTicks delay_timestamp,
  677. AudioBus* audio_bus) {
  678. TRACE_EVENT0("audio", "AlsaPcmOutputStream::RunDataCallback");
  679. if (source_callback_)
  680. return source_callback_->OnMoreData(delay, delay_timestamp, 0, audio_bus);
  681. return 0;
  682. }
  683. void AlsaPcmOutputStream::RunErrorCallback(int code) {
  684. // TODO(dalecurtis): Consider sending a translated |code| value.
  685. if (source_callback_)
  686. source_callback_->OnError(AudioSourceCallback::ErrorType::kUnknown);
  687. }
  688. // Changes the AudioSourceCallback to proxy calls to. Pass in nullptr to
  689. // release ownership of the currently registered callback.
  690. void AlsaPcmOutputStream::set_source_callback(AudioSourceCallback* callback) {
  691. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  692. source_callback_ = callback;
  693. }
  694. } // namespace media