blob: a48fcc8f6f642d66f9fcb89885badbebc2c0cf13 [file] [log] [blame]
/*
* Copyright (C) 2018 Metrological Group B.V.
* Author: Thibault Saunier <tsaunier@igalia.com>
* Author: Alejandro G. Castro <alex@igalia.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* aint with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "config.h"
#if ENABLE(MEDIA_STREAM) && USE(LIBWEBRTC) && USE(GSTREAMER)
#include "MockGStreamerVideoCaptureSource.h"
#include "MediaSampleGStreamer.h"
#include "MockRealtimeVideoSource.h"
#include <gst/app/gstappsrc.h>
namespace WebCore {
class WrappedMockRealtimeVideoSource : public MockRealtimeVideoSource {
public:
static Ref<WrappedMockRealtimeVideoSource> create(String&& deviceID, String&& name, String&& hashSalt)
{
return adoptRef(*new WrappedMockRealtimeVideoSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt)));
}
RealtimeMediaSource& asRealtimeMediaSource()
{
return *this;
}
void updateSampleBuffer()
{
auto imageBuffer = this->imageBuffer();
if (!imageBuffer)
return;
int fpsNumerator, fpsDenominator;
gst_util_double_to_fraction(frameRate(), &fpsNumerator, &fpsDenominator);
auto imageSize = imageBuffer->internalSize();
auto caps = adoptGRef(gst_caps_new_simple("video/x-raw",
"format", G_TYPE_STRING, "BGRA",
"width", G_TYPE_INT, imageSize.width(),
"height", G_TYPE_INT, imageSize.height(),
"framerate", GST_TYPE_FRACTION, fpsNumerator, fpsDenominator, nullptr));
auto data = imageBuffer->toBGRAData();
auto size = data.size();
auto buffer = adoptGRef(gst_buffer_new_wrapped(g_memdup(data.releaseBuffer().get(), size), size));
auto gstSample = adoptGRef(gst_sample_new(buffer.get(), caps.get(), nullptr, nullptr));
videoSampleAvailable(MediaSampleGStreamer::create(WTFMove(gstSample), FloatSize(), String()));
}
private:
WrappedMockRealtimeVideoSource(String&& deviceID, String&& name, String&& hashSalt)
: MockRealtimeVideoSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt))
{
}
};
CaptureSourceOrError MockRealtimeVideoSource::create(String&& deviceID,
String&& name, String&& hashSalt, const MediaConstraints* constraints)
{
auto source = adoptRef(*new MockGStreamerVideoCaptureSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt)));
if (constraints && source->applyConstraints(*constraints))
return { };
return CaptureSourceOrError(WTFMove(source));
}
void MockGStreamerVideoCaptureSource::startProducingData()
{
GStreamerVideoCaptureSource::startProducingData();
m_wrappedSource->start();
}
void MockGStreamerVideoCaptureSource::stopProducingData()
{
m_wrappedSource->stop();
GStreamerVideoCaptureSource::stopProducingData();
}
void MockGStreamerVideoCaptureSource::videoSampleAvailable(MediaSample& sample)
{
auto src = capturer()->source();
if (src) {
auto gstsample = static_cast<MediaSampleGStreamer*>(&sample)->platformSample().sample.gstSample;
gst_app_src_push_sample(GST_APP_SRC(src), gstsample);
}
}
MockGStreamerVideoCaptureSource::MockGStreamerVideoCaptureSource(String&& deviceID, String&& name, String&& hashSalt)
: GStreamerVideoCaptureSource(String { deviceID }, String { name }, String { hashSalt }, "appsrc")
, m_wrappedSource(WrappedMockRealtimeVideoSource::create(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt)))
{
m_wrappedSource->addObserver(*this);
}
MockGStreamerVideoCaptureSource::~MockGStreamerVideoCaptureSource()
{
m_wrappedSource->removeObserver(*this);
}
Optional<RealtimeMediaSource::ApplyConstraintsError> MockGStreamerVideoCaptureSource::applyConstraints(const MediaConstraints& constraints)
{
m_wrappedSource->applyConstraints(constraints);
return GStreamerVideoCaptureSource::applyConstraints(constraints);
}
void MockGStreamerVideoCaptureSource::applyConstraints(const MediaConstraints& constraints, ApplyConstraintsHandler&& completionHandler)
{
m_wrappedSource->applyConstraints(constraints, WTFMove(completionHandler));
}
const RealtimeMediaSourceSettings& MockGStreamerVideoCaptureSource::settings()
{
return m_wrappedSource->asRealtimeMediaSource().settings();
}
const RealtimeMediaSourceCapabilities& MockGStreamerVideoCaptureSource::capabilities()
{
m_capabilities = m_wrappedSource->asRealtimeMediaSource().capabilities();
m_currentSettings = m_wrappedSource->asRealtimeMediaSource().settings();
return m_capabilities.value();
}
void MockGStreamerVideoCaptureSource::captureFailed()
{
stop();
RealtimeMediaSource::captureFailed();
}
} // namespace WebCore
#endif // ENABLE(MEDIA_STREAM) && USE(LIBWEBRTC) && USE(GSTREAMER)