This CL makes the playout delay value thread safe.
With the patch, _sndCardPlayDelay is calculated in the DoRenderThread instead of capture thread, an capture thread only gets the _sndCardPlayDelay value. And _sndCardPlayDelay and _sndCardRecDelay are only changed to be Atomic32 to make them to be accessed by multiple threads. Test=None Bug=256 Review URL: https://webrtc-codereview.appspot.com/394001 git-svn-id: http://webrtc.googlecode.com/svn/trunk@1653 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
9c84b0dc9f
commit
3dbed8597e
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Use of this source code is governed by a BSD-style license
|
* Use of this source code is governed by a BSD-style license
|
||||||
* that can be found in the LICENSE file in the root of the source
|
* that can be found in the LICENSE file in the root of the source
|
||||||
@ -2991,7 +2991,10 @@ WebRtc_Word32 AudioDeviceWindowsCore::StopRecording()
|
|||||||
|
|
||||||
_UnLock();
|
_UnLock();
|
||||||
|
|
||||||
return err;
|
// Reset the recording delay value.
|
||||||
|
_sndCardRecDelay = 0;
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -3166,6 +3169,9 @@ WebRtc_Word32 AudioDeviceWindowsCore::StopPlayout()
|
|||||||
}
|
}
|
||||||
} // critScoped
|
} // critScoped
|
||||||
|
|
||||||
|
// Reset the playout delay value.
|
||||||
|
_sndCardPlayDelay = 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3175,8 +3181,7 @@ WebRtc_Word32 AudioDeviceWindowsCore::StopPlayout()
|
|||||||
|
|
||||||
WebRtc_Word32 AudioDeviceWindowsCore::PlayoutDelay(WebRtc_UWord16& delayMS) const
|
WebRtc_Word32 AudioDeviceWindowsCore::PlayoutDelay(WebRtc_UWord16& delayMS) const
|
||||||
{
|
{
|
||||||
CriticalSectionScoped lock(_critSect);
|
delayMS = static_cast<WebRtc_UWord16>(_sndCardPlayDelay.Value());
|
||||||
delayMS = (WebRtc_UWord16)_sndCardPlayDelay;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3186,8 +3191,7 @@ WebRtc_Word32 AudioDeviceWindowsCore::PlayoutDelay(WebRtc_UWord16& delayMS) cons
|
|||||||
|
|
||||||
WebRtc_Word32 AudioDeviceWindowsCore::RecordingDelay(WebRtc_UWord16& delayMS) const
|
WebRtc_Word32 AudioDeviceWindowsCore::RecordingDelay(WebRtc_UWord16& delayMS) const
|
||||||
{
|
{
|
||||||
CriticalSectionScoped lock(_critSect);
|
delayMS = static_cast<WebRtc_UWord16>(_sndCardRecDelay.Value());
|
||||||
delayMS = (WebRtc_UWord16)_sndCardRecDelay;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3226,19 +3230,21 @@ WebRtc_Word32 AudioDeviceWindowsCore::SetPlayoutBuffer(const AudioDeviceModule::
|
|||||||
|
|
||||||
WebRtc_Word32 AudioDeviceWindowsCore::PlayoutBuffer(AudioDeviceModule::BufferType& type, WebRtc_UWord16& sizeMS) const
|
WebRtc_Word32 AudioDeviceWindowsCore::PlayoutBuffer(AudioDeviceModule::BufferType& type, WebRtc_UWord16& sizeMS) const
|
||||||
{
|
{
|
||||||
|
{
|
||||||
CriticalSectionScoped lock(_critSect);
|
CriticalSectionScoped lock(_critSect);
|
||||||
|
|
||||||
type = _playBufType;
|
type = _playBufType;
|
||||||
|
}
|
||||||
|
|
||||||
if (type == AudioDeviceModule::kFixedBufferSize)
|
if (type == AudioDeviceModule::kFixedBufferSize)
|
||||||
{
|
{
|
||||||
sizeMS = _playBufDelayFixed;
|
CriticalSectionScoped lock(_critSect);
|
||||||
}
|
sizeMS = _playBufDelayFixed;
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
// Use same value as for PlayoutDelay
|
{
|
||||||
sizeMS = (WebRtc_UWord16)_sndCardPlayDelay;
|
// Use same value as for PlayoutDelay
|
||||||
}
|
sizeMS = static_cast<WebRtc_UWord16>(_sndCardPlayDelay.Value());
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3527,9 +3533,12 @@ DWORD AudioDeviceWindowsCore::DoRenderThread()
|
|||||||
// Derive inital rendering delay.
|
// Derive inital rendering delay.
|
||||||
// Example: 10*(960/480) + 15 = 20 + 15 = 35ms
|
// Example: 10*(960/480) + 15 = 20 + 15 = 35ms
|
||||||
//
|
//
|
||||||
_sndCardPlayDelay = 10 * (bufferLength / _playBlockSize) + (int)((latency + devPeriod) / 10000);
|
int playout_delay = 10 * (bufferLength / _playBlockSize) +
|
||||||
|
(int)((latency + devPeriod) / 10000);
|
||||||
|
_sndCardPlayDelay = playout_delay;
|
||||||
_writtenSamples = 0;
|
_writtenSamples = 0;
|
||||||
WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "[REND] initial delay : %u", _sndCardPlayDelay);
|
WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id,
|
||||||
|
"[REND] initial delay : %u", playout_delay);
|
||||||
|
|
||||||
double endpointBufferSizeMS = 10.0 * ((double)bufferLength / (double)_devicePlayBlockSize);
|
double endpointBufferSizeMS = 10.0 * ((double)bufferLength / (double)_devicePlayBlockSize);
|
||||||
WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "[REND] endpointBufferSizeMS : %3.2f", endpointBufferSizeMS);
|
WEBRTC_TRACE(kTraceInfo, kTraceAudioDevice, _id, "[REND] endpointBufferSizeMS : %3.2f", endpointBufferSizeMS);
|
||||||
@ -3545,8 +3554,14 @@ DWORD AudioDeviceWindowsCore::DoRenderThread()
|
|||||||
|
|
||||||
_writtenSamples += bufferLength;
|
_writtenSamples += bufferLength;
|
||||||
|
|
||||||
|
IAudioClock* clock = NULL;
|
||||||
|
hr = _ptrClientOut->GetService(__uuidof(IAudioClock), (void**)&clock);
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
WEBRTC_TRACE(kTraceWarning, kTraceAudioDevice, _id,
|
||||||
|
"failed to get IAudioClock interface from the IAudioClient");
|
||||||
|
}
|
||||||
|
|
||||||
// Start up the rendering audio stream.
|
// Start up the rendering audio stream.
|
||||||
//
|
|
||||||
hr = _ptrClientOut->Start();
|
hr = _ptrClientOut->Start();
|
||||||
EXIT_ON_ERROR(hr);
|
EXIT_ON_ERROR(hr);
|
||||||
|
|
||||||
@ -3655,6 +3670,17 @@ DWORD AudioDeviceWindowsCore::DoRenderThread()
|
|||||||
_writtenSamples += _playBlockSize;
|
_writtenSamples += _playBlockSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check the current delay on the playout side.
|
||||||
|
if (clock) {
|
||||||
|
UINT64 pos = 0;
|
||||||
|
UINT64 freq = 1;
|
||||||
|
clock->GetPosition(&pos, NULL);
|
||||||
|
clock->GetFrequency(&freq);
|
||||||
|
playout_delay = ROUND((double(_writtenSamples) /
|
||||||
|
_devicePlaySampleRate - double(pos) / freq) * 1000.0);
|
||||||
|
_sndCardPlayDelay = playout_delay;
|
||||||
|
}
|
||||||
|
|
||||||
_UnLock();
|
_UnLock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3665,6 +3691,8 @@ DWORD AudioDeviceWindowsCore::DoRenderThread()
|
|||||||
hr = _ptrClientOut->Stop();
|
hr = _ptrClientOut->Stop();
|
||||||
|
|
||||||
Exit:
|
Exit:
|
||||||
|
SAFE_RELEASE(clock);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
_UnLock();
|
_UnLock();
|
||||||
@ -4070,28 +4098,15 @@ DWORD AudioDeviceWindowsCore::DoCaptureThread()
|
|||||||
|
|
||||||
QueryPerformanceCounter(&t1);
|
QueryPerformanceCounter(&t1);
|
||||||
|
|
||||||
// Check the current delay on the recording side
|
// Get the current recording and playout delay.
|
||||||
//
|
WebRtc_UWord32 sndCardRecDelay = (WebRtc_UWord32)
|
||||||
_sndCardRecDelay = (WebRtc_UWord32)((((UINT64)t1.QuadPart * _perfCounterFactor) - recTime) / 10000) + (10*syncBufIndex) / _recBlockSize - 10;
|
(((((UINT64)t1.QuadPart * _perfCounterFactor) - recTime)
|
||||||
|
/ 10000) + (10*syncBufIndex) / _recBlockSize - 10);
|
||||||
|
WebRtc_UWord32 sndCardPlayDelay =
|
||||||
|
static_cast<WebRtc_UWord32>(_sndCardPlayDelay.Value());
|
||||||
|
|
||||||
// Check the current delay on the playout side
|
_sndCardRecDelay = sndCardRecDelay;
|
||||||
//
|
|
||||||
if (_ptrClientOut)
|
|
||||||
{
|
|
||||||
IAudioClock* clock = NULL;
|
|
||||||
UINT64 pos = 0;
|
|
||||||
UINT64 freq = 1;
|
|
||||||
hr = _ptrClientOut->GetService(__uuidof(IAudioClock), (void**)&clock);
|
|
||||||
EXIT_ON_ERROR(hr);
|
|
||||||
clock->GetPosition(&pos, NULL);
|
|
||||||
clock->GetFrequency(&freq);
|
|
||||||
_sndCardPlayDelay = ROUND((double(_writtenSamples) / _devicePlaySampleRate - double(pos) / freq) * 1000.0);
|
|
||||||
SAFE_RELEASE(clock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the captured data to the registered consumer
|
|
||||||
//
|
|
||||||
WebRtc_UWord32 sndCardRecDelay = _sndCardRecDelay; // avoid modifying the "correct" delay
|
|
||||||
while (syncBufIndex >= _recBlockSize)
|
while (syncBufIndex >= _recBlockSize)
|
||||||
{
|
{
|
||||||
if (_ptrAudioBuffer)
|
if (_ptrAudioBuffer)
|
||||||
@ -4099,10 +4114,13 @@ DWORD AudioDeviceWindowsCore::DoCaptureThread()
|
|||||||
_ptrAudioBuffer->SetRecordedBuffer((const WebRtc_Word8*)syncBuffer, _recBlockSize);
|
_ptrAudioBuffer->SetRecordedBuffer((const WebRtc_Word8*)syncBuffer, _recBlockSize);
|
||||||
|
|
||||||
_driftAccumulator += _sampleDriftAt48kHz;
|
_driftAccumulator += _sampleDriftAt48kHz;
|
||||||
const WebRtc_Word32 clockDrift = static_cast<WebRtc_Word32>(_driftAccumulator);
|
const WebRtc_Word32 clockDrift =
|
||||||
|
static_cast<WebRtc_Word32>(_driftAccumulator);
|
||||||
_driftAccumulator -= clockDrift;
|
_driftAccumulator -= clockDrift;
|
||||||
|
|
||||||
_ptrAudioBuffer->SetVQEData(_sndCardPlayDelay, sndCardRecDelay, clockDrift);
|
_ptrAudioBuffer->SetVQEData(sndCardPlayDelay,
|
||||||
|
sndCardRecDelay,
|
||||||
|
clockDrift);
|
||||||
|
|
||||||
QueryPerformanceCounter(&t1); // measure time: START
|
QueryPerformanceCounter(&t1); // measure time: START
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
|
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Use of this source code is governed by a BSD-style license
|
* Use of this source code is governed by a BSD-style license
|
||||||
* that can be found in the LICENSE file in the root of the source
|
* that can be found in the LICENSE file in the root of the source
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#include <mediaobj.h> // IMediaObject
|
#include <mediaobj.h> // IMediaObject
|
||||||
#include <Mmdeviceapi.h> // MMDevice
|
#include <Mmdeviceapi.h> // MMDevice
|
||||||
|
|
||||||
|
#include "atomic32_wrapper.h"
|
||||||
#include "critical_section_wrapper.h"
|
#include "critical_section_wrapper.h"
|
||||||
#include "scoped_refptr.h"
|
#include "scoped_refptr.h"
|
||||||
|
|
||||||
@ -319,7 +320,7 @@ private: // WASAPI
|
|||||||
WebRtc_UWord32 _playBlockSize;
|
WebRtc_UWord32 _playBlockSize;
|
||||||
WebRtc_UWord32 _devicePlayBlockSize;
|
WebRtc_UWord32 _devicePlayBlockSize;
|
||||||
WebRtc_UWord32 _playChannels;
|
WebRtc_UWord32 _playChannels;
|
||||||
WebRtc_UWord32 _sndCardPlayDelay;
|
Atomic32Wrapper _sndCardPlayDelay;
|
||||||
UINT64 _writtenSamples;
|
UINT64 _writtenSamples;
|
||||||
LONGLONG _playAcc;
|
LONGLONG _playAcc;
|
||||||
|
|
||||||
@ -328,7 +329,7 @@ private: // WASAPI
|
|||||||
WebRtc_UWord32 _recBlockSize;
|
WebRtc_UWord32 _recBlockSize;
|
||||||
WebRtc_UWord32 _recChannels;
|
WebRtc_UWord32 _recChannels;
|
||||||
UINT64 _readSamples;
|
UINT64 _readSamples;
|
||||||
WebRtc_UWord32 _sndCardRecDelay;
|
Atomic32Wrapper _sndCardRecDelay;
|
||||||
|
|
||||||
float _sampleDriftAt48kHz;
|
float _sampleDriftAt48kHz;
|
||||||
float _driftAccumulator;
|
float _driftAccumulator;
|
||||||
|
Loading…
Reference in New Issue
Block a user