Bug 1608505 - Cap the audio output channel count to something the device can handle. r=achronop

Differential Revision: https://phabricator.services.mozilla.com/D60549

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Paul Adenot 2020-01-24 11:23:37 +00:00
Родитель 53ec6e72dc
Коммит f47d3d7072
2 изменённых файлов: 49 добавлений и 2 удалений

Просмотреть файл

@ -880,6 +880,11 @@ void MediaTrackGraphImpl::DeviceChangedImpl() {
}
}
void MediaTrackGraphImpl::SetMaxOutputChannelCount(uint32_t aMaxChannelCount) {
MOZ_ASSERT(OnGraphThread());
mMaxOutputChannelCount = aMaxChannelCount;
}
void MediaTrackGraphImpl::DeviceChanged() {
// This is safe to be called from any thread: this message comes from an
// underlying platform API, and we don't have much guarantees. If it is not
@ -917,6 +922,34 @@ void MediaTrackGraphImpl::DeviceChanged() {
MOZ_ASSERT(NS_IsMainThread());
mAudioOutputLatency = 0.0;
// Dispatch to the bg thread to do the (potentially expensive) query of the
// maximum channel count, and then dispatch back to the main thread, then to
// the graph, with the new info.
RefPtr<MediaTrackGraphImpl> self = this;
NS_DispatchBackgroundTask(NS_NewRunnableFunction(
"MaxChannelCountUpdateOnBgThread", [self{std::move(self)}]() {
uint32_t maxChannelCount = CubebUtils::MaxNumberOfChannels();
self->Dispatch(NS_NewRunnableFunction(
"MaxChannelCountUpdateToMainThread",
[self{self}, maxChannelCount]() {
class MessageToGraph : public ControlMessage {
public:
explicit MessageToGraph(MediaTrackGraph* aGraph,
uint32_t aMaxChannelCount)
: ControlMessage(nullptr),
mGraphImpl(static_cast<MediaTrackGraphImpl*>(aGraph)),
mMaxChannelCount(aMaxChannelCount) {}
void Run() override {
mGraphImpl->SetMaxOutputChannelCount(mMaxChannelCount);
}
MediaTrackGraphImpl* mGraphImpl;
uint32_t mMaxChannelCount;
};
self->AppendMessage(
MakeUnique<MessageToGraph>(self, maxChannelCount));
}));
}));
AppendMessage(MakeUnique<Message>(this));
}
@ -2933,7 +2966,8 @@ MediaTrackGraphImpl::MediaTrackGraphImpl(GraphDriverType aDriverRequested,
#endif
,
mMainThreadGraphTime(0, "MediaTrackGraphImpl::mMainThreadGraphTime"),
mAudioOutputLatency(0.0) {
mAudioOutputLatency(0.0),
mMaxOutputChannelCount(std::min(8u, CubebUtils::MaxNumberOfChannels())) {
if (aRunTypeRequested == SINGLE_THREAD && !mGraphRunner) {
// Failed to create thread. Jump to the last phase of the lifecycle.
mLifecycleState = LIFECYCLE_WAITING_FOR_TRACK_DESTRUCTION;
@ -3546,7 +3580,8 @@ auto MediaTrackGraph::ApplyAudioContextOperation(
uint32_t MediaTrackGraphImpl::AudioOutputChannelCount() const {
MOZ_ASSERT(OnGraphThread());
// The audio output channel count for a graph is the maximum of the output
// channel count of all the tracks that are in mAudioOutputs.
// channel count of all the tracks that are in mAudioOutputs, or the max audio
// output channel count the machine can do, whichever is smaller.
uint32_t channelCount = 0;
for (auto& tkv : mAudioOutputs) {
MediaTrack* t = tkv.mTrack;
@ -3560,6 +3595,7 @@ uint32_t MediaTrackGraphImpl::AudioOutputChannelCount() const {
std::max<uint32_t>(channelCount, segment->MaxChannelCount());
}
}
channelCount = std::min(channelCount, mMaxOutputChannelCount);
if (channelCount) {
return channelCount;
} else {

Просмотреть файл

@ -485,7 +485,10 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
mTrackOrderDirty = true;
}
// Get the current maximum channel count. Graph thread only.
uint32_t AudioOutputChannelCount() const;
// Set a new maximum channel count. Graph thread only.
void SetMaxOutputChannelCount(uint32_t aMaxChannelCount);
double AudioOutputLatency();
@ -997,6 +1000,14 @@ class MediaTrackGraphImpl : public MediaTrackGraph,
* whenever the audio device running this MediaTrackGraph changes.
*/
double mAudioOutputLatency;
/**
* The max audio output channel count the default audio output device
* supports. This is cached here because it can be expensive to query. The
* cache is invalidated when the device is changed. This is initialized in the
* ctor, and the read/write only on the graph thread.
*/
uint32_t mMaxOutputChannelCount;
};
} // namespace mozilla