[Mac] Support audioSourceProvider() in MediaPlayerPrivateAVFoundationObjC
authorjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Sep 2014 20:05:49 +0000 (20:05 +0000)
committerjer.noble@apple.com <jer.noble@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 Sep 2014 20:05:49 +0000 (20:05 +0000)
commite9f60b6bce5f32e32d1d602544a53507ca3845e6
tree570859e4fb31419264344706f26ffc457178f15c
parentc31711088b96e6fc6b865c8b57889e615bb59d5f
[Mac] Support audioSourceProvider() in MediaPlayerPrivateAVFoundationObjC
https://bugs.webkit.org/show_bug.cgi?id=135042

Reviewed by Eric Carlson.

Source/WebCore:

Add support for AudioSourceProvider in MediaPlayerPrivateAVFoundationObjC, thereby
supporting MediaElementAudioSourceNode.

Import the CARingBuffer from CoreAudio sample code, making the necessary modifications
for WebKit style and coding conventions. The threading assumptions for this class are
that there will be a single writer thread and a single reader thread.

* platform/audio/mac/CARingBuffer.cpp: Added.
(WebCore::CARingBuffer::create): Create a unique_ptr.
(WebCore::CARingBuffer::CARingBuffer): Simple constructor.
(WebCore::CARingBuffer::~CARingBuffer): Simple destructor.
(WebCore::CARingBuffer::allocate): Initialize the buffers and time bounds structures.
(WebCore::CARingBuffer::deallocate): Destroy same.
(WebCore::ZeroRange): Static utility method.
(WebCore::StoreABL): Ditto.
(WebCore::FetchABL): Ditto.
(WebCore::ZeroABL): Ditto.
(WebCore::CARingBuffer::store): Store the passed in buffer in the ring buffer, wrapping
    if necessary.
(WebCore::CARingBuffer::setTimeBounds): Set the new time bounds by incrementing the
    bounds index locally, filling in the new values, then atomically incrementing the
    reader-visible index.
(WebCore::CARingBuffer::getTimeBounds): Get the new time bounds by masking the time
    bounds index, and using it as an offset to the time bounds array. Protect against
    CPU starvation on the reading thread by checking the index against the stored
    index in the array entry. This check will fail if the writing thread has wrapped
    more than the size of the array.
(WebCore::CARingBuffer::clipTimeBounds): Clamp the passed values to the available bounds.
(WebCore::CARingBuffer::startFrame): Simple accessor.
(WebCore::CARingBuffer::endFrame): Ditto.
(WebCore::CARingBuffer::fetch): Read an audio buffer list from the ring buffer, possbily
    wrapping around to the start of the ring buffer.
* platform/audio/mac/CARingBuffer.h: Added.
(WebCore::CARingBuffer::numberOfChannels): Simple accessor.
(WebCore::CARingBuffer::frameOffset): Ditto.
(WebCore::CARingBuffer::TimeBounds::TimeBounds): Struct holding the start and end frame values.

Add an implementation of AudioSourceProvider, using AVAudioMix and MTAudioProcessingTap
to tap an AVPlayerItem's audio output and feed it to a MediaElementAudioSourceNode.

* platform/graphics/avfoundation/AudioSourceProviderAVFObjC.h: Added.
* platform/graphics/avfoundation/AudioSourceProviderAVFObjC.mm: Added.
(WebCore::AudioSourceProviderAVFObjC::create): Simple factory.
(WebCore::AudioSourceProviderAVFObjC::AudioSourceProviderAVFObjC): Simple constructor.
(WebCore::AudioSourceProviderAVFObjC::~AudioSourceProviderAVFObjC): Simple destructor.
(WebCore::AudioSourceProviderAVFObjC::provideInput): Push audio into the ring buffer.
(WebCore::AudioSourceProviderAVFObjC::setClient): Call destroyMix()/createMix() as appropriate.
(WebCore::AudioSourceProviderAVFObjC::setPlayerItem): Ditto.
(WebCore::AudioSourceProviderAVFObjC::destroyMix): Detach and destroy the AVAudioMix and tap.
(WebCore::AudioSourceProviderAVFObjC::createMix): Set up the AVAudioMix and tap and attach to
    the AVPlayerItem.
(WebCore::AudioSourceProviderAVFObjC::initCallback): Pass to class method.
(WebCore::AudioSourceProviderAVFObjC::finalizeCallback): Ditto.
(WebCore::AudioSourceProviderAVFObjC::prepareCallback): Ditto.
(WebCore::AudioSourceProviderAVFObjC::unprepareCallback): Ditto.
(WebCore::AudioSourceProviderAVFObjC::processCallback): Ditto.
(WebCore::AudioSourceProviderAVFObjC::init): Set up the storage pointer for the tap.
(WebCore::AudioSourceProviderAVFObjC::finalize): No-op.
(WebCore::operator==): Compare two AudioStreamBasicDescription objects.
(WebCore::operator!=): Ditto.
(WebCore::AudioSourceProviderAVFObjC::prepare): Create an AudioCoverter object if necessary,
    create the ring buffer, and notify the client of format changes.
(WebCore::AudioSourceProviderAVFObjC::unprepare): Destroy same.
(WebCore::AudioSourceProviderAVFObjC::process): Copy samples out of the ring buffer,
    format converting them if necessary. Mute original audio.

Create the AudioSourceProviderAVFObjC object and notify it when the current AVPlayerItem changes.

* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h:
* platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm:
(WebCore::MediaPlayerPrivateAVFoundationObjC::cancelLoad):
(WebCore::MediaPlayerPrivateAVFoundationObjC::createAVPlayerItem):
(WebCore::MediaPlayerPrivateAVFoundationObjC::audioSourceProvider):

Enable SOFT_LINK_MAY_FAIL on the Mac platform.

* platform/mac/SoftLinking.h:

Add new files to the project.

* WebCore.xcodeproj/project.pbxproj:

Source/WTF:

* wtf/Platform.h: Add WTF_USE_MEDIATOOLBOX.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@173628 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Source/WTF/ChangeLog
Source/WTF/wtf/Platform.h
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/platform/audio/mac/CARingBuffer.cpp [new file with mode: 0644]
Source/WebCore/platform/audio/mac/CARingBuffer.h [new file with mode: 0644]
Source/WebCore/platform/graphics/avfoundation/AudioSourceProviderAVFObjC.h [new file with mode: 0644]
Source/WebCore/platform/graphics/avfoundation/AudioSourceProviderAVFObjC.mm [new file with mode: 0644]
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.h
Source/WebCore/platform/graphics/avfoundation/objc/MediaPlayerPrivateAVFoundationObjC.mm
Source/WebCore/platform/mac/SoftLinking.h