blob: aa568c2f4611f7c6b913dcdf0d8335445442d3ee [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. ``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
* 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.
*/
#pragma once
#if ENABLE(MEDIA_STREAM)
#include "AudioSampleBufferList.h"
#include <CoreAudio/CoreAudioTypes.h>
#include <wtf/LoggerHelper.h>
#include <wtf/MediaTime.h>
#include <wtf/RefPtr.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/text/WTFString.h>
typedef const struct opaqueCMFormatDescription *CMFormatDescriptionRef;
typedef struct opaqueCMSampleBuffer *CMSampleBufferRef;
namespace WebCore {
class CAAudioStreamDescription;
class CARingBuffer;
class MediaStreamTrackPrivate;
class AudioSampleDataSource : public ThreadSafeRefCounted<AudioSampleDataSource, WTF::DestructionThread::MainRunLoop>
#if !RELEASE_LOG_DISABLED
, private LoggerHelper
#endif
{
public:
static Ref<AudioSampleDataSource> create(size_t, MediaStreamTrackPrivate&);
~AudioSampleDataSource();
OSStatus setInputFormat(const CAAudioStreamDescription&);
OSStatus setOutputFormat(const CAAudioStreamDescription&);
void pushSamples(const MediaTime&, const PlatformAudioData&, size_t);
void pushSamples(const AudioStreamBasicDescription&, CMSampleBufferRef);
enum PullMode { Copy, Mix };
bool pullSamples(AudioSampleBufferList&, size_t, uint64_t, double, PullMode);
bool pullSamples(AudioBufferList&, size_t, uint64_t, double, PullMode);
bool pullAvalaibleSamplesAsChunks(AudioBufferList&, size_t frameCount, uint64_t timeStamp, Function<void()>&&);
void setPaused(bool);
void setVolume(float volume) { m_volume = volume; }
float volume() const { return m_volume; }
void setMuted(bool muted) { m_muted = muted; }
bool muted() const { return m_muted; }
#if !RELEASE_LOG_DISABLED
const Logger& logger() const final { return m_logger; }
const void* logIdentifier() const final { return m_logIdentifier; }
void setLogger(Ref<const Logger>&&, const void*);
#endif
private:
AudioSampleDataSource(size_t, MediaStreamTrackPrivate&);
OSStatus setupConverter();
bool pullSamplesInternal(AudioBufferList&, size_t&, uint64_t, double, PullMode);
void pushSamplesInternal(const AudioBufferList&, const MediaTime&, size_t frameCount);
std::unique_ptr<CAAudioStreamDescription> m_inputDescription;
std::unique_ptr<CAAudioStreamDescription> m_outputDescription;
MediaTime hostTime() const;
#if !RELEASE_LOG_DISABLED
const char* logClassName() const final { return "AudioSampleDataSource"; }
WTFLogChannel& logChannel() const final;
#endif
uint64_t m_lastPushedSampleCount { 0 };
MediaTime m_expectedNextPushedSampleTime { MediaTime::invalidTime() };
MediaTime m_inputSampleOffset;
int64_t m_outputSampleOffset { 0 };
AudioConverterRef m_converter;
RefPtr<AudioSampleBufferList> m_scratchBuffer;
std::unique_ptr<CARingBuffer> m_ringBuffer;
size_t m_maximumSampleCount { 0 };
float m_volume { 1.0 };
bool m_muted { false };
bool m_paused { true };
bool m_transitioningFromPaused { true };
#if !RELEASE_LOG_DISABLED
Ref<const Logger> m_logger;
const void* m_logIdentifier;
#endif
};
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)