RealtimeMediaSource.h [plain text]
#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;
virtual void sourceStarted() { }
virtual void sourceStopped() { }
virtual void sourceMutedChanged() { }
virtual void sourceSettingsChanged() { }
virtual bool preventSourceFromStopping() { return false; }
virtual void videoSampleAvailable(MediaSample&) { }
virtual void audioSamplesAvailable(const MediaTime&, const PlatformAudioData&, const AudioStreamDescription&, size_t ) { }
};
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&);
virtual bool supportsConstraints(const MediaConstraints&, String&);
virtual 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();
virtual void delaySamples(float) { };
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);
virtual double fitnessDistance(const MediaConstraint&);
virtual 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 applyConstraint(const MediaConstraint&);
virtual void applyConstraints(const FlattenedConstraint&);
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;
};
}
#endif // ENABLE(MEDIA_STREAM)