| /* |
| * Copyright (C) 2018 Metrological Group B.V. |
| * Copyright (C) 2020 Igalia S.L. |
| * Author: Thibault Saunier <tsaunier@igalia.com> |
| * Author: Alejandro G. Castro <alex@igalia.com> |
| * Copyright (C) 2021 Apple Inc. All rights reserved. |
| * |
| * 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(GSTREAMER) |
| #include "MockRealtimeVideoSourceGStreamer.h" |
| |
| #include "MediaSampleGStreamer.h" |
| #include "MockRealtimeMediaSourceCenter.h" |
| #include "PixelBuffer.h" |
| |
| namespace WebCore { |
| |
| CaptureSourceOrError MockRealtimeVideoSource::create(String&& deviceID, String&& name, String&& hashSalt, const MediaConstraints* constraints) |
| { |
| #ifndef NDEBUG |
| auto device = MockRealtimeMediaSourceCenter::mockDeviceWithPersistentID(deviceID); |
| ASSERT(device); |
| if (!device) |
| return { "No mock camera device"_s }; |
| #endif |
| |
| auto source = adoptRef(*new MockRealtimeVideoSourceGStreamer(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt))); |
| if (constraints) { |
| if (auto error = source->applyConstraints(*constraints)) |
| return WTFMove(error.value().badConstraint); |
| } |
| |
| return CaptureSourceOrError(RealtimeVideoSource::create(WTFMove(source))); |
| } |
| |
| CaptureSourceOrError MockDisplayCaptureSourceGStreamer::create(const CaptureDevice& device, const MediaConstraints* constraints) |
| { |
| auto mockSource = adoptRef(*new MockRealtimeVideoSourceGStreamer(String { device.persistentId() }, String { device.label() }, { })); |
| |
| if (constraints) { |
| if (auto error = mockSource->applyConstraints(*constraints)) |
| return WTFMove(error.value().badConstraint); |
| } |
| |
| auto source = adoptRef(*new MockDisplayCaptureSourceGStreamer(WTFMove(mockSource), device.type())); |
| return CaptureSourceOrError(WTFMove(source)); |
| } |
| |
| MockDisplayCaptureSourceGStreamer::MockDisplayCaptureSourceGStreamer(Ref<MockRealtimeVideoSourceGStreamer>&& source, CaptureDevice::DeviceType type) |
| : RealtimeMediaSource(Type::Video, source->name().isolatedCopy()) |
| , m_source(WTFMove(source)) |
| , m_type(type) |
| { |
| m_source->addVideoSampleObserver(*this); |
| } |
| |
| MockDisplayCaptureSourceGStreamer::~MockDisplayCaptureSourceGStreamer() |
| { |
| m_source->removeVideoSampleObserver(*this); |
| } |
| |
| void MockDisplayCaptureSourceGStreamer::stopProducingData() |
| { |
| m_source->removeVideoSampleObserver(*this); |
| m_source->stop(); |
| } |
| |
| void MockDisplayCaptureSourceGStreamer::requestToEnd(Observer& callingObserver) |
| { |
| m_source->removeVideoSampleObserver(*this); |
| m_source->requestToEnd(callingObserver); |
| } |
| |
| void MockDisplayCaptureSourceGStreamer::videoSampleAvailable(MediaSample& sample) |
| { |
| RealtimeMediaSource::videoSampleAvailable(sample); |
| } |
| |
| const RealtimeMediaSourceCapabilities& MockDisplayCaptureSourceGStreamer::capabilities() |
| { |
| if (!m_capabilities) { |
| RealtimeMediaSourceCapabilities capabilities(settings().supportedConstraints()); |
| |
| // FIXME: what should these be? |
| // Currently mimicking the values for SCREEN-1 in MockRealtimeMediaSourceCenter.cpp::defaultDevices() |
| capabilities.setWidth(CapabilityValueOrRange(1, 1920)); |
| capabilities.setHeight(CapabilityValueOrRange(1, 1080)); |
| capabilities.setFrameRate(CapabilityValueOrRange(.01, 30.0)); |
| |
| m_capabilities = WTFMove(capabilities); |
| } |
| return m_capabilities.value(); |
| } |
| |
| const RealtimeMediaSourceSettings& MockDisplayCaptureSourceGStreamer::settings() |
| { |
| if (!m_currentSettings) { |
| RealtimeMediaSourceSettings settings; |
| settings.setFrameRate(frameRate()); |
| |
| m_source->ensureIntrinsicSizeMaintainsAspectRatio(); |
| auto size = m_source->size(); |
| settings.setWidth(size.width()); |
| settings.setHeight(size.height()); |
| |
| settings.setLogicalSurface(false); |
| |
| RealtimeMediaSourceSupportedConstraints supportedConstraints; |
| supportedConstraints.setSupportsFrameRate(true); |
| supportedConstraints.setSupportsWidth(true); |
| supportedConstraints.setSupportsHeight(true); |
| supportedConstraints.setSupportsDisplaySurface(true); |
| supportedConstraints.setSupportsLogicalSurface(true); |
| |
| settings.setSupportedConstraints(supportedConstraints); |
| |
| m_currentSettings = WTFMove(settings); |
| } |
| return m_currentSettings.value(); |
| } |
| |
| MockRealtimeVideoSourceGStreamer::MockRealtimeVideoSourceGStreamer(String&& deviceID, String&& name, String&& hashSalt) |
| : MockRealtimeVideoSource(WTFMove(deviceID), WTFMove(name), WTFMove(hashSalt)) |
| { |
| ensureGStreamerInitialized(); |
| } |
| |
| void MockRealtimeVideoSourceGStreamer::updateSampleBuffer() |
| { |
| auto imageBuffer = this->imageBuffer(); |
| if (!imageBuffer) |
| return; |
| |
| auto pixelBuffer = imageBuffer->getPixelBuffer({ AlphaPremultiplication::Premultiplied, PixelFormat::BGRA8, DestinationColorSpace::SRGB() }, { { }, imageBuffer->logicalSize() }); |
| if (!pixelBuffer) |
| return; |
| |
| auto sample = MediaSampleGStreamer::createImageSample(WTFMove(*pixelBuffer), size(), frameRate()); |
| sample->offsetTimestampsBy(MediaTime::createWithDouble((elapsedTime() + 100_ms).seconds())); |
| dispatchMediaSampleToObservers(sample.get()); |
| } |
| |
| } // namespace WebCore |
| |
| #endif // ENABLE(MEDIA_STREAM) && USE(GSTREAMER) |