blob: 9bdafd61b56e5837537136a589368b866313d89f [file] [log] [blame]
/*
* Copyright (C) 2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "SharedRingBufferStorage.h"
#if USE(MEDIATOOLBOX)
#include <WebCore/CARingBuffer.h>
namespace WebKit {
ReadOnlySharedRingBufferStorage::ReadOnlySharedRingBufferStorage(const SharedMemory::Handle& handle)
: m_storage(SharedMemory::map(handle, SharedMemory::Protection::ReadOnly))
{
}
void* ReadOnlySharedRingBufferStorage::data()
{
return m_storage ? static_cast<Byte*>(m_storage->data()) + sizeof(FrameBounds) : nullptr;
}
auto ReadOnlySharedRingBufferStorage::sharedFrameBounds() const -> const FrameBounds*
{
return m_storage ? reinterpret_cast<const FrameBounds*>(m_storage->data()) : nullptr;
}
auto ReadOnlySharedRingBufferStorage::sharedFrameBounds() -> FrameBounds*
{
return m_storage ? reinterpret_cast<FrameBounds*>(m_storage->data()) : nullptr;
}
void ReadOnlySharedRingBufferStorage::getCurrentFrameBounds(uint64_t& startFrame, uint64_t& endFrame)
{
startFrame = m_startFrame;
endFrame = m_endFrame;
}
void ReadOnlySharedRingBufferStorage::flush()
{
m_startFrame = m_endFrame = 0;
}
void ReadOnlySharedRingBufferStorage::updateFrameBounds()
{
auto* sharedBounds = sharedFrameBounds();
if (!sharedBounds) {
m_startFrame = m_endFrame = 0;
return;
}
unsigned boundsBufferIndex = sharedBounds->boundsBufferIndex.load(std::memory_order_acquire);
if (UNLIKELY(boundsBufferIndex >= boundsBufferSize)) {
m_startFrame = m_endFrame = 0;
return;
}
auto pair = sharedBounds->boundsBuffer[boundsBufferIndex];
m_startFrame = pair.first;
m_endFrame = pair.second;
}
size_t ReadOnlySharedRingBufferStorage::size() const
{
if (!m_storage || m_storage->size() < sizeof(FrameBounds))
return 0;
return m_storage->size() - sizeof(FrameBounds);
}
bool ReadOnlySharedRingBufferStorage::allocate(size_t byteCount, const CAAudioStreamDescription& format, size_t frameCount)
{
ASSERT_NOT_REACHED();
return false;
}
void SharedRingBufferStorage::setStorage(RefPtr<SharedMemory>&& storage, const CAAudioStreamDescription& format, size_t frameCount)
{
m_storage = WTFMove(storage);
if (m_storageChangedHandler)
m_storageChangedHandler(m_storage.get(), format, frameCount);
}
bool SharedRingBufferStorage::allocate(size_t byteCount, const CAAudioStreamDescription& format, size_t frameCount)
{
auto sharedMemory = SharedMemory::allocate(byteCount + sizeof(FrameBounds));
if (!sharedMemory)
return false;
new (NotNull, sharedMemory->data()) FrameBounds;
setStorage(WTFMove(sharedMemory), format, frameCount);
return true;
}
void SharedRingBufferStorage::deallocate()
{
setStorage(nullptr, { }, 0);
}
void SharedRingBufferStorage::setCurrentFrameBounds(uint64_t startFrame, uint64_t endFrame)
{
m_startFrame = startFrame;
m_endFrame = endFrame;
auto* sharedBounds = sharedFrameBounds();
if (!sharedBounds)
return;
unsigned indexToWrite = (sharedBounds->boundsBufferIndex.load(std::memory_order_acquire) + 1) % boundsBufferSize;
sharedBounds->boundsBuffer[indexToWrite] = std::make_pair(startFrame, endFrame);
sharedBounds->boundsBufferIndex.store(indexToWrite, std::memory_order_release);
}
} // namespace WebKit
#endif