⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 293664 in webkit


Ignore:
Timestamp:
May 2, 2022, 9:15:55 AM (4 years ago)
Author:
youenn@apple.com
Message:

VPIO requires the same sample rate for microphone and speaker formats
​https://bugs.webkit.org/show_bug.cgi?id=239956

Reviewed by Eric Carlson.

VPIO requires the speaker sample rate and microphone sample rate to be the same.
This is not guaranteed to be true : getUserMedia/applyConstraints may set the microphone sample rate to different values.
If audio rendering already started at capture start time, we use the audio rendering sample rate.
This is not strictly compliant, given required constraints but they are not widely used.
Applications that want to make sure to use a specific sample rate would need to pause audio rendering when starting to capture.
We reset exposed settings when starting to capture to expose the actual sample rate to JavaScript through MediaStreamTrack.getSettings().

Manually tested.

  • platform/mediastream/mac/BaseAudioSharedUnit.h:
  • platform/mediastream/mac/CoreAudioCaptureSource.cpp:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r293661 r293664  
     12022-05-02  Youenn Fablet  <youenn@apple.com>
     2
     3        VPIO requires the same sample rate for microphone and speaker formats
     4        https://bugs.webkit.org/show_bug.cgi?id=239956
     5
     6        Reviewed by Eric Carlson.
     7
     8        VPIO requires the speaker sample rate and microphone sample rate to be the same.
     9        This is not guaranteed to be true : getUserMedia/applyConstraints may set the microphone sample rate to different values.
     10        If audio rendering already started at capture start time, we use the audio rendering sample rate.
     11        This is not strictly compliant, given required constraints but they are not widely used.
     12        Applications that want to make sure to use a specific sample rate would need to pause audio rendering when starting to capture.
     13        We reset exposed settings when starting to capture to expose the actual sample rate to JavaScript through MediaStreamTrack.getSettings().
     14
     15        Manually tested.
     16
     17        * platform/mediastream/mac/BaseAudioSharedUnit.h:
     18        * platform/mediastream/mac/CoreAudioCaptureSource.cpp:
     19
    1202022-05-01  Philippe Normand  <philn@igalia.com>
    221
  • trunk/Source/WebCore/platform/mediastream/mac/BaseAudioSharedUnit.h

    r288620 r293664  
    7878
    7979    virtual CapabilityValueOrRange sampleRateCapacities() const = 0;
     80    virtual int actualSampleRate() const { return sampleRate(); }
    8081
    8182    void devicesChanged(const Vector<CaptureDevice>&);
  • trunk/Source/WebCore/platform/mediastream/mac/CoreAudioCaptureSource.cpp

    r293563 r293664  
    102102    void isProducingMicrophoneSamplesChanged() final;
    103103    void validateOutputDevice(uint32_t deviceID) final;
    104 
    105     OSStatus configureSpeakerProc();
    106     OSStatus configureMicrophoneProc();
     104    int actualSampleRate() const final;
     105
     106    OSStatus configureSpeakerProc(int sampleRate);
     107    OSStatus configureMicrophoneProc(int sampleRate);
    107108    OSStatus defaultOutputDevice(uint32_t*);
    108109    OSStatus defaultInputDevice(uint32_t*);
    … …  
    150151
    151152    bool m_isReconfiguring { false };
    152     Lock m_speakerSamplesProducerLock;
     153    mutable Lock m_speakerSamplesProducerLock;
    153154    CoreAudioSpeakerSamplesProducer* m_speakerSamplesProducer WTF_GUARDED_BY_LOCK(m_speakerSamplesProducerLock) { nullptr };
    154155};
    … …  
    259260#endif
    260261
    261     err = configureMicrophoneProc();
     262    // FIXME: Add support for different speaker/microphone sample rates.
     263    int actualSampleRate = this->actualSampleRate();
     264    err = configureMicrophoneProc(actualSampleRate);
    262265    if (err)
    263266        return err;
    264267
    265     err = configureSpeakerProc();
     268    err = configureSpeakerProc(actualSampleRate);
    266269    if (err)
    267270        return err;
    … …  
    286289}
    287290
    288 OSStatus CoreAudioSharedUnit::configureMicrophoneProc()
    289 {
     291int CoreAudioSharedUnit::actualSampleRate() const
     292{
     293    Locker locker { m_speakerSamplesProducerLock };
     294    return m_speakerSamplesProducer ? m_speakerSamplesProducer->format().streamDescription().mSampleRate : sampleRate();
     295}
     296
     297OSStatus CoreAudioSharedUnit::configureMicrophoneProc(int sampleRate)
     298{
     299    ASSERT(isMainThread());
     300
    290301    if (!isProducingMicrophoneSamples())
    291302        return noErr;
    … …  
    307318    }
    308319
    309     microphoneProcFormat.mSampleRate = sampleRate();
     320    microphoneProcFormat.mSampleRate = sampleRate;
    310321    err = PAL::AudioUnitSetProperty(m_ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, inputBus, &microphoneProcFormat, size);
    311322    if (err) {
    … …  
    320331}
    321332
    322 OSStatus CoreAudioSharedUnit::configureSpeakerProc()
    323 {
     333OSStatus CoreAudioSharedUnit::configureSpeakerProc(int sampleRate)
     334{
     335    ASSERT(isMainThread());
     336
    324337    AURenderCallbackStruct callback = { speakerCallback, this };
    325338    auto err = PAL::AudioUnitSetProperty(m_ioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, outputBus, &callback, sizeof(callback));
    … …  
    333346    {
    334347        Locker locker { m_speakerSamplesProducerLock };
    335         if (m_speakerSamplesProducer)
     348        if (m_speakerSamplesProducer) {
     349            ASSERT(speakerProcFormat.mSampleRate == sampleRate);
    336350            speakerProcFormat = m_speakerSamplesProducer->format().streamDescription();
    337         else {
     351        } else {
    338352            err = PAL::AudioUnitGetProperty(m_ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, outputBus, &speakerProcFormat, &size);
    339353            if (err) {
    … …  
    341355                return err;
    342356            }
    343             speakerProcFormat.mSampleRate = sampleRate();
    344357        }
    345358    }
     359    speakerProcFormat.mSampleRate = sampleRate;
    346360
    347361    err = PAL::AudioUnitSetProperty(m_ioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, outputBus, &speakerProcFormat, size);
    … …  
    494508OSStatus CoreAudioSharedUnit::startInternal()
    495509{
     510    ASSERT(isMainThread());
     511
    496512    setIsProducingMicrophoneSamples(true);
    497513
    … …  
    574590void CoreAudioSharedUnit::stopInternal()
    575591{
     592    ASSERT(isMainThread());
     593
    576594    m_verifyCapturingTimer.stop();
    577595
    … …  
    633651void CoreAudioSharedUnit::registerSpeakerSamplesProducer(CoreAudioSpeakerSamplesProducer& producer)
    634652{
     653    ASSERT(isMainThread());
     654
    635655    setIsRenderingAudio(true);
    636656
    … …  
    650670void CoreAudioSharedUnit::unregisterSpeakerSamplesProducer(CoreAudioSpeakerSamplesProducer& producer)
    651671{
     672    ASSERT(isMainThread());
     673
    652674    {
    653675        Locker locker { m_speakerSamplesProducerLock };
    … …  
    820842    initializeToStartProducingData();
    821843    unit().startProducingData();
     844    m_currentSettings = { };
    822845}
    823846
    … …  
    846869        RealtimeMediaSourceSettings settings;
    847870        settings.setVolume(volume());
    848         settings.setSampleRate(sampleRate());
     871        settings.setSampleRate(unit().actualSampleRate());
    849872        settings.setDeviceId(hashedId());
    850873        settings.setLabel(name());
Note: See TracChangeset for help on using the changeset viewer.