Bug 1392837 - Support multichannel audio input on gUM. r?padenot
MozReview-Commit-ID: FKCIAo4a8jy
--- a/dom/media/GraphDriver.cpp
+++ b/dom/media/GraphDriver.cpp
@@ -667,17 +667,17 @@ AudioCallbackDriver::Init()
input.channels = mInputChannels;
input.layout = CUBEB_LAYOUT_UNDEFINED;
#ifdef MOZ_WEBRTC
if (mGraphImpl->mInputWanted) {
StaticMutexAutoLock lock(AudioInputCubeb::Mutex());
uint32_t userChannels = 0;
AudioInputCubeb::GetUserChannelCount(mGraphImpl->mInputDeviceID, userChannels);
- input.channels = mInputChannels = userChannels;
+ input.channels = mInputChannels = std::min<uint32_t>(8, userChannels);
}
#endif
cubeb_stream* stream = nullptr;
CubebUtils::AudioDeviceID input_id = nullptr, output_id = nullptr;
// We have to translate the deviceID values to cubeb devid's since those can be
// freed whenever enumerate is called.
{
--- a/dom/media/webrtc/MediaEngineWebRTC.h
+++ b/dom/media/webrtc/MediaEngineWebRTC.h
@@ -640,16 +640,18 @@ private:
nsTArray<int16_t> mInputBuffer;
// mSkipProcessing is true if none of the processing passes are enabled,
// because of prefs or constraints. This allows simply copying the audio into
// the MSG, skipping resampling and the whole webrtc.org code.
bool mSkipProcessing;
// To only update microphone when needed, we keep track of previous settings.
MediaEnginePrefs mLastPrefs;
+
+ AlignedShortBuffer mInputDownmixBuffer;
};
class MediaEngineWebRTC : public MediaEngine
{
typedef MediaEngine Super;
public:
explicit MediaEngineWebRTC(MediaEnginePrefs& aPrefs);
--- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -201,16 +201,17 @@ MediaEngineWebRTCMicrophoneSource::Media
, mTrackID(TRACK_NONE)
, mStarted(false)
, mSampleFrequency(MediaEngine::DEFAULT_SAMPLE_RATE)
, mTotalFrames(0)
, mLastLogFrames(0)
, mPlayoutDelay(0)
, mNullTransport(nullptr)
, mSkipProcessing(false)
+ , mInputDownmixBuffer(MAX_SAMPLING_FREQ * MAX_CHANNELS / 100)
{
MOZ_ASSERT(aVoiceEnginePtr);
MOZ_ASSERT(aAudioInput);
mDeviceName.Assign(NS_ConvertUTF8toUTF16(name));
mDeviceUUID.Assign(uuid);
mListener = new mozilla::WebRTCAudioDataListener(this);
mSettings->mEchoCancellation.Construct(0);
mSettings->mAutoGainControl.Construct(0);
@@ -618,17 +619,26 @@ MediaEngineWebRTCMicrophoneSource::Packe
uint32_t samplesPerPacket = mPacketizer->PacketSize() *
mPacketizer->Channels();
if (mInputBuffer.Length() < samplesPerPacket) {
mInputBuffer.SetLength(samplesPerPacket);
}
int16_t* packet = mInputBuffer.Elements();
mPacketizer->Output(packet);
- mVoERender->ExternalRecordingInsertData(packet, samplesPerPacket, aRate, 0);
+ if (aChannels > MAX_CHANNELS) {
+ AudioConverter converter(AudioConfig(aChannels, 0, AudioConfig::FORMAT_S16),
+ AudioConfig(MAX_CHANNELS, 0, AudioConfig::FORMAT_S16));
+ converter.Process(mInputDownmixBuffer, packet, mPacketizer->PacketSize());
+ mVoERender->ExternalRecordingInsertData(mInputDownmixBuffer.Data(),
+ mPacketizer->PacketSize() * MAX_CHANNELS,
+ aRate, 0);
+ } else {
+ mVoERender->ExternalRecordingInsertData(packet, samplesPerPacket, aRate, 0);
+ }
}
}
template<typename T>
void
MediaEngineWebRTCMicrophoneSource::InsertInGraph(const T* aBuffer,
size_t aFrames,
uint32_t aChannels)
@@ -656,18 +666,18 @@ MediaEngineWebRTCMicrophoneSource::Inser
TimeStamp insertTime;
// Make sure we include the stream and the track.
// The 0:1 is a flag to note when we've done the final insert for a given input block.
LogTime(AsyncLatencyLogger::AudioTrackInsertion,
LATENCY_STREAM_ID(mSources[i].get(), mTrackID),
(i+1 < len) ? 0 : 1, insertTime);
// Bug 971528 - Support stereo capture in gUM
- MOZ_ASSERT(aChannels == 1 || aChannels == 2,
- "GraphDriver only supports mono and stereo audio for now");
+ MOZ_ASSERT(aChannels >= 1 && aChannels <= 8,
+ "Support up to 8 channels");
nsAutoPtr<AudioSegment> segment(new AudioSegment());
RefPtr<SharedBuffer> buffer =
SharedBuffer::Create(aFrames * aChannels * sizeof(T));
AutoTArray<const T*, 8> channels;
if (aChannels == 1) {
PodCopy(static_cast<T*>(buffer->Data()), aBuffer, aFrames);
channels.AppendElement(static_cast<T*>(buffer->Data()));
@@ -843,17 +853,18 @@ MediaEngineWebRTCMicrophoneSource::Alloc
// Set "codec" to PCM, 32kHz on device's channels
ScopedCustomReleasePtr<webrtc::VoECodec> ptrVoECodec(webrtc::VoECodec::GetInterface(mVoiceEngine));
if (ptrVoECodec) {
webrtc::CodecInst codec;
strcpy(codec.plname, ENCODING);
codec.channels = CHANNELS;
uint32_t maxChannels = 0;
if (mAudioInput->GetMaxAvailableChannels(maxChannels) == 0) {
- codec.channels = maxChannels;
+ MOZ_ASSERT(maxChannels);
+ codec.channels = std::min<uint32_t>(maxChannels, MAX_CHANNELS);
}
MOZ_ASSERT(mSampleFrequency == 16000 || mSampleFrequency == 32000);
codec.rate = SAMPLE_RATE(mSampleFrequency);
codec.plfreq = mSampleFrequency;
codec.pacsize = SAMPLE_LENGTH(mSampleFrequency);
codec.pltype = 0; // Default payload type
if (!ptrVoECodec->SetSendCodec(mChannel, codec)) {