blob: 9b451205e5b93a51ee1adc24e5c00eb38e5358b5 [file] [log] [blame]
/*
* Copyright (C) 2011 Ericsson AB. All rights reserved.
* Copyright (C) 2012 Google Inc. All rights reserved.
* Copyright (C) 2013-2017 Apple Inc. All rights reserved.
* Copyright (C) 2013 Nokia Corporation and/or its subsidiary(-ies).
*
* 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.
* 3. Neither the name of Ericsson nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
* OWNER 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 "CaptureDevice.h"
#include "Image.h"
#include "MediaConstraints.h"
#include "MediaSample.h"
#include "PlatformLayer.h"
#include "RealtimeMediaSourceCapabilities.h"
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/Vector.h>
#include <wtf/WeakPtr.h>
#include <wtf/text/WTFString.h>
namespace WTF {
class MediaTime;
}
namespace WebCore {
class AudioStreamDescription;
class FloatRect;
class GraphicsContext;
class MediaStreamPrivate;
class OrientationNotifier;
class PlatformAudioData;
class RealtimeMediaSourceSettings;
struct CaptureSourceOrError;
class WEBCORE_EXPORT RealtimeMediaSource : public ThreadSafeRefCounted<RealtimeMediaSource> {
public:
class Observer {
public:
virtual ~Observer() = default;
// Source state changes.
virtual void sourceStarted() { }
virtual void sourceStopped() { }
virtual void sourceMutedChanged() { }
virtual void sourceSettingsChanged() { }
// Observer state queries.
virtual bool preventSourceFromStopping() { return false; }
// Called on the main thread.
virtual void videoSampleAvailable(MediaSample&) { }
// May be called on a background thread.
virtual void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t /*numberOfFrames*/) { }
};
class SingleSourceFactory {
public:
void setActiveSource(RealtimeMediaSource& source)
{
if (m_activeSource == &source)
return;
if (m_activeSource && m_activeSource->isProducingData())
m_activeSource->setMuted(true);
m_activeSource = &source;
}
void unsetActiveSource(RealtimeMediaSource& source)
{
if (m_activeSource == &source)
m_activeSource = nullptr;
}
RealtimeMediaSource* activeSource() { return m_activeSource; }
private:
RealtimeMediaSource* m_activeSource { nullptr };
};
class AudioCaptureFactory
#if PLATFORM(IOS)
: public RealtimeMediaSource::SingleSourceFactory
#endif
{
public:
virtual ~AudioCaptureFactory() = default;
virtual CaptureSourceOrError createAudioCaptureSource(const CaptureDevice&, const MediaConstraints*) = 0;
protected:
AudioCaptureFactory() = default;
};
class VideoCaptureFactory
#if PLATFORM(IOS)
: public RealtimeMediaSource::SingleSourceFactory
#endif
{
public:
virtual ~VideoCaptureFactory() = default;
virtual CaptureSourceOrError createVideoCaptureSource(const CaptureDevice&, const MediaConstraints*) = 0;
virtual void setVideoCapturePageState(bool, bool) { }
protected:
VideoCaptureFactory() = default;
};
virtual ~RealtimeMediaSource() = default;
const String& id() const { return m_id; }
const String& persistentID() const { return m_persistentID; }
virtual void setPersistentID(String&& persistentID) { m_persistentID = WTFMove(persistentID); }
enum class Type { None, Audio, Video };
Type type() const { return m_type; }
bool isProducingData() const { return m_isProducingData; }
void start();
void stop();
void requestStop(Observer* callingObserver = nullptr);
bool muted() const { return m_muted; }
void setMuted(bool);
bool captureDidFail() const { return m_captureDidFailed; }
virtual bool interrupted() const { return m_interrupted; }
virtual void setInterrupted(bool, bool);
const String& name() const { return m_name; }
void setName(const String& name) { m_name = name; }
unsigned fitnessScore() const { return m_fitnessScore; }
WEBCORE_EXPORT void addObserver(Observer&);
WEBCORE_EXPORT void removeObserver(Observer&);
void setWidth(int);
void setHeight(int);
const IntSize& size() const { return m_size; }
virtual bool applySize(const IntSize&) { return false; }
double frameRate() const { return m_frameRate; }
void setFrameRate(double);
virtual bool applyFrameRate(double) { return false; }
double aspectRatio() const { return m_aspectRatio; }
void setAspectRatio(double);
virtual bool applyAspectRatio(double) { return false; }
RealtimeMediaSourceSettings::VideoFacingMode facingMode() const { return m_facingMode; }
void setFacingMode(RealtimeMediaSourceSettings::VideoFacingMode);
virtual bool applyFacingMode(RealtimeMediaSourceSettings::VideoFacingMode) { return false; }
double volume() const { return m_volume; }
void setVolume(double);
virtual bool applyVolume(double) { return false; }
int sampleRate() const { return m_sampleRate; }
void setSampleRate(int);
virtual bool applySampleRate(int) { return false; }
int sampleSize() const { return m_sampleSize; }
void setSampleSize(int);
virtual bool applySampleSize(int) { return false; }
bool echoCancellation() const { return m_echoCancellation; }
void setEchoCancellation(bool);
virtual bool applyEchoCancellation(bool) { return false; }
virtual const RealtimeMediaSourceCapabilities& capabilities() const = 0;
virtual const RealtimeMediaSourceSettings& settings() const = 0;
using SuccessHandler = WTF::Function<void()>;
using FailureHandler = WTF::Function<void(const String& badConstraint, const String& errorString)>;
virtual void applyConstraints(const MediaConstraints&, SuccessHandler&&, FailureHandler&&);
std::optional<std::pair<String, String>> applyConstraints(const MediaConstraints&);
bool supportsConstraints(const MediaConstraints&, String&);
bool supportsConstraint(const MediaConstraint&) const;
virtual void settingsDidChange();
virtual bool isIsolated() const { return false; }
virtual bool isCaptureSource() const { return false; }
virtual void monitorOrientation(OrientationNotifier&) { }
void captureFailed();
// Testing only
virtual void delaySamples(Seconds) { };
protected:
RealtimeMediaSource(const String& id, Type, const String& name);
void scheduleDeferredTask(WTF::Function<void()>&&);
virtual void beginConfiguration() { }
virtual void commitConfiguration() { }
enum class SelectType { ForApplyConstraints, ForSupportsConstraints };
bool selectSettings(const MediaConstraints&, FlattenedConstraint&, String&, SelectType);
double fitnessDistance(const MediaConstraint&);
void applyConstraint(const MediaConstraint&);
void applyConstraints(const FlattenedConstraint&);
bool supportsSizeAndFrameRate(std::optional<IntConstraint> width, std::optional<IntConstraint> height, std::optional<DoubleConstraint>, String&, double& fitnessDistance);
virtual bool supportsSizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>);
virtual void applySizeAndFrameRate(std::optional<int> width, std::optional<int> height, std::optional<double>);
void notifyMutedObservers() const;
void notifyMutedChange(bool muted);
void initializeVolume(double volume) { m_volume = volume; }
void initializeSampleRate(int sampleRate) { m_sampleRate = sampleRate; }
void initializeEchoCancellation(bool echoCancellation) { m_echoCancellation = echoCancellation; }
void videoSampleAvailable(MediaSample&);
void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t);
WeakPtr<RealtimeMediaSource> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(*this); }
private:
virtual void startProducingData() { }
virtual void stopProducingData() { }
bool m_muted { false };
WeakPtrFactory<RealtimeMediaSource> m_weakPtrFactory;
String m_id;
String m_persistentID;
Type m_type;
String m_name;
Vector<std::reference_wrapper<Observer>> m_observers;
IntSize m_size;
double m_frameRate { 30 };
double m_aspectRatio { 0 };
double m_volume { 1 };
double m_sampleRate { 0 };
double m_sampleSize { 0 };
double m_fitnessScore { std::numeric_limits<double>::infinity() };
RealtimeMediaSourceSettings::VideoFacingMode m_facingMode { RealtimeMediaSourceSettings::User};
bool m_echoCancellation { false };
bool m_pendingSettingsDidChangeNotification { false };
bool m_isProducingData { false };
bool m_interrupted { false };
bool m_captureDidFailed { false };
};
struct CaptureSourceOrError {
CaptureSourceOrError() = default;
CaptureSourceOrError(Ref<RealtimeMediaSource>&& source) : captureSource(WTFMove(source)) { }
CaptureSourceOrError(String&& message) : errorMessage(WTFMove(message)) { }
operator bool() const { return !!captureSource; }
Ref<RealtimeMediaSource> source() { return captureSource.releaseNonNull(); }
RefPtr<RealtimeMediaSource> captureSource;
String errorMessage;
};
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM)