15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates an output stream based on the ALSA PCM interface. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// On device write failure, the stream will move itself to an invalid state. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// No more data will be pulled from the data source, or written to the device. 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// All calls to public API functions will either no-op themselves, or return an 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// error if possible. Specifically, If the stream is in an error state, Open() 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will return false, and Start() will call OnError() immediately on the 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provided callback. 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If the stream is successfully opened, Close() must be called. After Close 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// has been called, the object should be regarded as deleted and not touched. 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AlsaPcmOutputStream is a single threaded class that should only be used from 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the audio thread. When modifying the code in this class, please read the 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// threading assumptions at the top of the implementation. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_ 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_ 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <alsa/asoundlib.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h" 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/audio_io.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/audio/audio_parameters.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace base { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MessageLoop; 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AlsaWrapper; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioManagerLinux; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChannelMixer; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SeekableBuffer; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MEDIA_EXPORT AlsaPcmOutputStream : public AudioOutputStream { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // String for the generic "default" ALSA device that has the highest 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // compatibility and chance of working. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kDefaultDevice[]; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pass this to the AlsaPcmOutputStream if you want to attempt auto-selection 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of the audio device. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kAutoSelectDevice[]; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Prefix for device names to enable ALSA library resampling. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char kPlugPrefix[]; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The minimum latency that is accepted by the device. 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const uint32 kMinLatencyMicros; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a PCM Output stream for the ALSA device identified by 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |device_name|. The AlsaPcmOutputStream uses |wrapper| to communicate with 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the alsa libraries, allowing for dependency injection during testing. All 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requesting of data, and writing to the alsa device will be done on 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |message_loop|. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If unsure of what to use for |device_name|, use |kAutoSelectDevice|. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AlsaPcmOutputStream(const std::string& device_name, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AudioParameters& params, 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AlsaWrapper* wrapper, 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioManagerLinux* manager); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AlsaPcmOutputStream(); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Implementation of AudioOutputStream. 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Open() OVERRIDE; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Close() OVERRIDE; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Start(AudioSourceCallback* callback) OVERRIDE; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Stop() OVERRIDE; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetVolume(double volume) OVERRIDE; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void GetVolume(double* volume) OVERRIDE; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class AlsaPcmOutputStreamTest; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoSelectDevice_DeviceSelect); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutoSelectDevice_FallbackDevices); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, AutoSelectDevice_HintFail); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, BufferPacket); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, BufferPacket_Negative); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, BufferPacket_StopStream); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, BufferPacket_Underrun); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, BufferPacket_FullBuffer); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, ConstructedState); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, LatencyFloor); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, OpenClose); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, PcmOpenFailed); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, PcmSetParamsFailed); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, ScheduleNextWrite); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleNextWrite_StopStream); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, StartStop); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, WritePacket_FinishedPacket); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, WritePacket_NormalPacket); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, WritePacket_StopStream); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(AlsaPcmOutputStreamTest, WritePacket_WriteFails); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flags indicating the state of the stream. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) enum InternalState { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kInError = 0, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kCreated, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kIsOpened, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kIsPlaying, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kIsStopped, 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kIsClosed 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend std::ostream& operator<<(std::ostream& os, InternalState); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Functions to get another packet from the data source and write it into the 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ALSA device. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BufferPacket(bool* source_exhausted); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WritePacket(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteTask(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ScheduleNextWrite(bool source_exhausted); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Utility functions for talking with the ALSA API. 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static base::TimeDelta FramesToTimeDelta(int frames, double sample_rate); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string FindDeviceForChannels(uint32 channels); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snd_pcm_sframes_t GetAvailableFrames(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snd_pcm_sframes_t GetCurrentDelay(); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempts to find the best matching linux audio device for the given number 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of channels. This function will set |device_name_| and |channel_mixer_|. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snd_pcm_t* AutoSelectDevice(uint32 latency); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Functions to safeguard state transitions. All changes to the object state 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should go through these functions. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CanTransitionTo(InternalState to); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InternalState TransitionTo(InternalState to); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InternalState state(); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true when we're on the audio thread or if the audio thread's 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message loop is NULL (which will happen during shutdown). 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsOnAudioThread() const; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // API for Proxying calls to the AudioSourceCallback provided during 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start(). 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(ajwong): This is necessary because the ownership semantics for the 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |source_callback_| object are incorrect in AudioRenderHost. The callback 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is passed into the output stream, but ownership is not transfered which 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // requires a synchronization on access of the |source_callback_| to avoid 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // using a deleted callback. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int RunDataCallback(AudioBus* audio_bus, AudioBuffersState buffers_state); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunErrorCallback(int code); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // release ownership of the currently registered callback. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_source_callback(AudioSourceCallback* callback); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Configuration constants from the constructor. Referenceable by all threads 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // since they are constants. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string requested_device_name_; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const snd_pcm_format_t pcm_format_; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32 channels_; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ChannelLayout channel_layout_; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32 sample_rate_; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32 bytes_per_sample_; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint32 bytes_per_frame_; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Device configuration data. Populated after OpenTask() completes. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string device_name_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 packet_size_; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta latency_; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 bytes_per_output_frame_; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 alsa_buffer_frames_; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Flag indicating the code should stop reading from the data source or 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // writing to the ALSA device. This is set because the device has entered 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an unrecoverable error state, or the ClosedTask() has executed. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool stop_stream_; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wrapper class to invoke all the ALSA functions. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AlsaWrapper* wrapper_; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Audio manager that created us. Used to report that we've been closed. 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioManagerLinux* manager_; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Message loop to use for polling. The object is owned by the AudioManager. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We hold a reference to the audio thread message loop since 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // AudioManagerBase::ShutDown() can invalidate the message loop pointer 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before the stream gets deleted. 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop* message_loop_; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handle to the actual PCM playback device. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) snd_pcm_t* playback_handle_; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<media::SeekableBuffer> buffer_; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 frames_per_packet_; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allows us to run tasks on the AlsaPcmOutputStream instance which are 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bound by its lifetime. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WeakPtrFactory<AlsaPcmOutputStream> weak_factory_; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InternalState state_; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float volume_; // Volume level from 0.0 to 1.0. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioSourceCallback* source_callback_; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Container for retrieving data from AudioSourceCallback::OnMoreData(). 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioBus> audio_bus_; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Channel mixer and temporary bus for the final mixed channel data. 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ChannelMixer> channel_mixer_; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioBus> mixed_audio_bus_; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AlsaPcmOutputStream); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MEDIA_EXPORT std::ostream& operator<<(std::ostream& os, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AlsaPcmOutputStream::InternalState); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; // namespace media 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_ 229