Updated to 83.0, Updated PipeWire patches from mozbz#1672944
This commit is contained in:
parent
be686cde3c
commit
d6756537dd
2
.gitignore
vendored
2
.gitignore
vendored
@ -430,3 +430,5 @@ firefox-3.6.4.source.tar.bz2
|
||||
/firefox-langpacks-82.0.2-20201029.tar.xz
|
||||
/firefox-82.0.3.source.tar.xz
|
||||
/firefox-langpacks-82.0.3-20201109.tar.xz
|
||||
/firefox-83.0.source.tar.xz
|
||||
/firefox-langpacks-83.0-20201112.tar.xz
|
||||
|
@ -1,526 +0,0 @@
|
||||
diff -up firefox-79.0/config/system-headers.mozbuild.firefox-pipewire-0-2 firefox-79.0/config/system-headers.mozbuild
|
||||
--- firefox-79.0/config/system-headers.mozbuild.firefox-pipewire-0-2 2020-07-21 00:49:36.000000000 +0200
|
||||
+++ firefox-79.0/config/system-headers.mozbuild 2020-07-29 11:03:51.455284187 +0200
|
||||
@@ -314,6 +314,7 @@ system_headers = [
|
||||
'Gestalt.h',
|
||||
'getopt.h',
|
||||
'gio/gio.h',
|
||||
+ 'gio/gunixfdlist.h',
|
||||
'glibconfig.h',
|
||||
'glib.h',
|
||||
'glib-object.h',
|
||||
@@ -607,6 +608,7 @@ system_headers = [
|
||||
'Pgenerr.h',
|
||||
'PGenErr.h',
|
||||
'Ph.h',
|
||||
+ 'pipewire/pipewire.h',
|
||||
'pixman.h',
|
||||
'pk11func.h',
|
||||
'pk11pqg.h',
|
||||
diff -up firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build.firefox-pipewire-0-2 firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build
|
||||
--- firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build.firefox-pipewire-0-2 2020-07-29 11:03:51.455284187 +0200
|
||||
+++ firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build 2020-07-29 11:04:40.898017241 +0200
|
||||
@@ -231,6 +231,27 @@ if CONFIG["OS_TARGET"] == "OpenBSD":
|
||||
"/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc"
|
||||
]
|
||||
|
||||
+# PipeWire specific files
|
||||
+if CONFIG["OS_TARGET"] == "Linux":
|
||||
+
|
||||
+ DEFINES["WEBRTC_USE_PIPEWIRE"] = "1"
|
||||
+
|
||||
+ OS_LIBS += [
|
||||
+ "rt",
|
||||
+ "pipewire-0.2",
|
||||
+ "glib-2.0",
|
||||
+ "gio-2.0",
|
||||
+ "gobject-2.0"
|
||||
+ ]
|
||||
+
|
||||
+ CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
+
|
||||
+ UNIFIED_SOURCES += [
|
||||
+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc",
|
||||
+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc",
|
||||
+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc"
|
||||
+ ]
|
||||
+
|
||||
if CONFIG["OS_TARGET"] == "WINNT":
|
||||
|
||||
DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True
|
||||
diff -up firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h.firefox-pipewire-0-2 firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h
|
||||
--- firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h.firefox-pipewire-0-2 2020-07-20 22:54:16.000000000 +0200
|
||||
+++ firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h 2020-07-29 11:03:51.456284181 +0200
|
||||
@@ -141,7 +141,7 @@ class DesktopCaptureOptions {
|
||||
bool disable_effects_ = true;
|
||||
bool detect_updated_region_ = false;
|
||||
#if defined(WEBRTC_USE_PIPEWIRE)
|
||||
- bool allow_pipewire_ = false;
|
||||
+ bool allow_pipewire_ = true;
|
||||
#endif
|
||||
};
|
||||
|
||||
diff -up firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc.firefox-pipewire-0-2 firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
|
||||
--- firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc.firefox-pipewire-0-2 2020-07-20 22:54:27.000000000 +0200
|
||||
+++ firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc 2020-07-29 11:03:51.618283306 +0200
|
||||
@@ -18,6 +18,11 @@
|
||||
#include <spa/param/video/raw-utils.h>
|
||||
#include <spa/support/type-map.h>
|
||||
|
||||
+#include <linux/dma-buf.h>
|
||||
+#include <sys/mman.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <sys/syscall.h>
|
||||
+
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
@@ -36,6 +41,27 @@ const char kSessionInterfaceName[] = "or
|
||||
const char kRequestInterfaceName[] = "org.freedesktop.portal.Request";
|
||||
const char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast";
|
||||
|
||||
+
|
||||
+// static
|
||||
+void BaseCapturerPipeWire::SyncDmaBuf(int fd, uint64_t start_or_end) {
|
||||
+ struct dma_buf_sync sync = { 0 };
|
||||
+
|
||||
+ sync.flags = start_or_end | DMA_BUF_SYNC_READ;
|
||||
+
|
||||
+ while(true) {
|
||||
+ int ret;
|
||||
+ ret = ioctl (fd, DMA_BUF_IOCTL_SYNC, &sync);
|
||||
+ if (ret == -1 && errno == EINTR) {
|
||||
+ continue;
|
||||
+ } else if (ret == -1) {
|
||||
+ RTC_LOG(LS_ERROR) << "Failed to synchronize DMA buffer: " << g_strerror(errno);
|
||||
+ break;
|
||||
+ } else {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
// static
|
||||
void BaseCapturerPipeWire::OnStateChanged(void* data,
|
||||
pw_remote_state old_state,
|
||||
@@ -108,11 +134,13 @@ void BaseCapturerPipeWire::OnStreamForma
|
||||
auto stride = SPA_ROUND_UP_N(width * kBytesPerPixel, 4);
|
||||
auto size = height * stride;
|
||||
|
||||
+ that->desktop_size_ = DesktopSize(width, height);
|
||||
+
|
||||
uint8_t buffer[1024] = {};
|
||||
auto builder = spa_pod_builder{buffer, sizeof(buffer)};
|
||||
|
||||
// Setup buffers and meta header for new format.
|
||||
- const struct spa_pod* params[2];
|
||||
+ const struct spa_pod* params[3];
|
||||
params[0] = reinterpret_cast<spa_pod*>(spa_pod_builder_object(
|
||||
&builder,
|
||||
// id to enumerate buffer requirements
|
||||
@@ -141,8 +169,14 @@ void BaseCapturerPipeWire::OnStreamForma
|
||||
// Size: size of the metadata, specified as integer (i)
|
||||
":", that->pw_core_type_->param_meta.size, "i",
|
||||
sizeof(struct spa_meta_header)));
|
||||
-
|
||||
- pw_stream_finish_format(that->pw_stream_, /*res=*/0, params, /*n_params=*/2);
|
||||
+ params[2] = reinterpret_cast<spa_pod*>(
|
||||
+ spa_pod_builder_object(&builder, that->pw_core_type_->param.idMeta,
|
||||
+ that->pw_core_type_->param_meta.Meta, ":",
|
||||
+ that->pw_core_type_->param_meta.type, "I",
|
||||
+ that->pw_core_type_->meta.VideoCrop, ":",
|
||||
+ that->pw_core_type_->param_meta.size, "i",
|
||||
+ sizeof(struct spa_meta_video_crop)));
|
||||
+ pw_stream_finish_format(that->pw_stream_, /*res=*/0, params, /*n_params=*/3);
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -150,15 +184,25 @@ void BaseCapturerPipeWire::OnStreamProce
|
||||
BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
|
||||
RTC_DCHECK(that);
|
||||
|
||||
- pw_buffer* buf = nullptr;
|
||||
+ struct pw_buffer *next_buffer;
|
||||
+ struct pw_buffer *buffer = nullptr;
|
||||
|
||||
- if (!(buf = pw_stream_dequeue_buffer(that->pw_stream_))) {
|
||||
+ next_buffer = pw_stream_dequeue_buffer(that->pw_stream_);
|
||||
+ while (next_buffer) {
|
||||
+ buffer = next_buffer;
|
||||
+ next_buffer = pw_stream_dequeue_buffer(that->pw_stream_);
|
||||
+
|
||||
+ if (next_buffer)
|
||||
+ pw_stream_queue_buffer (that->pw_stream_, buffer);
|
||||
+ }
|
||||
+
|
||||
+ if (!buffer) {
|
||||
return;
|
||||
}
|
||||
|
||||
- that->HandleBuffer(buf);
|
||||
+ that->HandleBuffer(buffer);
|
||||
|
||||
- pw_stream_queue_buffer(that->pw_stream_, buf);
|
||||
+ pw_stream_queue_buffer(that->pw_stream_, buffer);
|
||||
}
|
||||
|
||||
BaseCapturerPipeWire::BaseCapturerPipeWire(CaptureSourceType source_type)
|
||||
@@ -197,10 +241,6 @@ BaseCapturerPipeWire::~BaseCapturerPipeW
|
||||
pw_loop_destroy(pw_loop_);
|
||||
}
|
||||
|
||||
- if (current_frame_) {
|
||||
- free(current_frame_);
|
||||
- }
|
||||
-
|
||||
if (start_request_signal_id_) {
|
||||
g_dbus_connection_signal_unsubscribe(connection_, start_request_signal_id_);
|
||||
}
|
||||
@@ -290,12 +330,7 @@ void BaseCapturerPipeWire::InitPipeWireT
|
||||
|
||||
void BaseCapturerPipeWire::CreateReceivingStream() {
|
||||
spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1};
|
||||
- spa_rectangle pwScreenBounds =
|
||||
- spa_rectangle{static_cast<uint32_t>(desktop_size_.width()),
|
||||
- static_cast<uint32_t>(desktop_size_.height())};
|
||||
-
|
||||
- spa_fraction pwFrameRateMin = spa_fraction{0, 1};
|
||||
- spa_fraction pwFrameRateMax = spa_fraction{60, 1};
|
||||
+ spa_rectangle pwMaxScreenBounds = spa_rectangle{INT32_MAX, INT32_MAX};
|
||||
|
||||
pw_properties* reuseProps = pw_properties_new("pipewire.client.reuse", "1",
|
||||
/*end of varargs*/ nullptr);
|
||||
@@ -313,27 +348,19 @@ void BaseCapturerPipeWire::CreateReceivi
|
||||
// then allowed formats are enumerated (e) and the format is undecided (u)
|
||||
// to allow negotiation
|
||||
":", pw_type_->format_video.format, "Ieu", pw_type_->video_format.BGRx,
|
||||
- SPA_POD_PROP_ENUM(2, pw_type_->video_format.RGBx,
|
||||
- pw_type_->video_format.BGRx),
|
||||
+ SPA_POD_PROP_ENUM(
|
||||
+ 4, pw_type_->video_format.RGBx, pw_type_->video_format.BGRx,
|
||||
+ pw_type_->video_format.RGBA, pw_type_->video_format.BGRA),
|
||||
// Video size: specified as rectangle (R), preferred size is specified as
|
||||
// first parameter, then allowed size is defined as range (r) from min and
|
||||
// max values and the format is undecided (u) to allow negotiation
|
||||
- ":", pw_type_->format_video.size, "Rru", &pwScreenBounds, 2,
|
||||
- &pwMinScreenBounds, &pwScreenBounds,
|
||||
- // Frame rate: specified as fraction (F) and set to minimum frame rate
|
||||
- // value
|
||||
- ":", pw_type_->format_video.framerate, "F", &pwFrameRateMin,
|
||||
- // Max frame rate: specified as fraction (F), preferred frame rate is set
|
||||
- // to maximum value, then allowed frame rate is defined as range (r) from
|
||||
- // min and max values and it is undecided (u) to allow negotiation
|
||||
- ":", pw_type_->format_video.max_framerate, "Fru", &pwFrameRateMax, 2,
|
||||
- &pwFrameRateMin, &pwFrameRateMax));
|
||||
+ ":", pw_type_->format_video.size, "Rru", &pwMinScreenBounds,
|
||||
+ SPA_POD_PROP_MIN_MAX(&pwMinScreenBounds, &pwMaxScreenBounds)));
|
||||
|
||||
pw_stream_add_listener(pw_stream_, &spa_stream_listener_, &pw_stream_events_,
|
||||
this);
|
||||
pw_stream_flags flags = static_cast<pw_stream_flags>(
|
||||
- PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE |
|
||||
- PW_STREAM_FLAG_MAP_BUFFERS);
|
||||
+ PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE);
|
||||
if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, /*port_path=*/nullptr,
|
||||
flags, params,
|
||||
/*n_params=*/1) != 0) {
|
||||
@@ -344,15 +371,81 @@ void BaseCapturerPipeWire::CreateReceivi
|
||||
}
|
||||
|
||||
void BaseCapturerPipeWire::HandleBuffer(pw_buffer* buffer) {
|
||||
+ struct spa_meta_video_crop* video_crop;
|
||||
spa_buffer* spaBuffer = buffer->buffer;
|
||||
- void* src = nullptr;
|
||||
+ uint8_t *map = nullptr;
|
||||
+ uint8_t* src = nullptr;
|
||||
+ uint8_t* dst = nullptr;
|
||||
+
|
||||
+ if (spaBuffer->datas[0].chunk->size == 0) {
|
||||
+ map = nullptr;
|
||||
+ src = nullptr;
|
||||
+ } else if (spaBuffer->datas[0].type == pw_core_type_->data.MemFd) {
|
||||
+ map = static_cast<uint8_t*>(mmap(
|
||||
+ nullptr, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
|
||||
+ PROT_READ, MAP_PRIVATE, spaBuffer->datas[0].fd, 0));
|
||||
+ src = SPA_MEMBER(map, spaBuffer->datas[0].mapoffset, uint8_t);
|
||||
+ } else if (spaBuffer->datas[0].type == pw_core_type_->data.DmaBuf) {
|
||||
+ int fd;
|
||||
+ fd = spaBuffer->datas[0].fd;
|
||||
+
|
||||
+ map = static_cast<uint8_t*>(mmap(
|
||||
+ nullptr, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
|
||||
+ PROT_READ, MAP_PRIVATE, fd, 0));
|
||||
+ SyncDmaBuf(fd, DMA_BUF_SYNC_START);
|
||||
+
|
||||
+ src = SPA_MEMBER(map, spaBuffer->datas[0].mapoffset, uint8_t);
|
||||
+ } else if (spaBuffer->datas[0].type == pw_core_type_->data.MemPtr) {
|
||||
+ map = nullptr;
|
||||
+ src = static_cast<uint8_t*>(spaBuffer->datas[0].data);
|
||||
+ } else {
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- if (!(src = spaBuffer->datas[0].data)) {
|
||||
+ if (!src) {
|
||||
return;
|
||||
}
|
||||
|
||||
- uint32_t maxSize = spaBuffer->datas[0].maxsize;
|
||||
- int32_t srcStride = spaBuffer->datas[0].chunk->stride;
|
||||
+ DesktopSize prev_crop_size = DesktopSize(0, 0);
|
||||
+ if (video_crop_size_initialized_) {
|
||||
+ prev_crop_size = video_crop_size_;
|
||||
+ }
|
||||
+
|
||||
+ if ((video_crop = static_cast<struct spa_meta_video_crop*>(
|
||||
+ spa_buffer_find_meta(spaBuffer, pw_core_type_->meta.VideoCrop)))) {
|
||||
+ RTC_DCHECK(video_crop->width <= desktop_size_.width() &&
|
||||
+ video_crop->height <= desktop_size_.height());
|
||||
+ if ((video_crop->width != desktop_size_.width() ||
|
||||
+ video_crop->height != desktop_size_.height()) && video_crop->width && video_crop->height) {
|
||||
+ video_crop_size_ = DesktopSize(video_crop->width, video_crop->height);
|
||||
+ video_crop_size_initialized_ = true;
|
||||
+ } else {
|
||||
+ video_crop_size_initialized_ = false;
|
||||
+ }
|
||||
+ } else {
|
||||
+ video_crop_size_initialized_ = false;
|
||||
+ }
|
||||
+
|
||||
+ size_t frame_size;
|
||||
+ if (video_crop_size_initialized_) {
|
||||
+ frame_size =
|
||||
+ video_crop_size_.width() * video_crop_size_.height() * kBytesPerPixel;
|
||||
+ } else {
|
||||
+ frame_size =
|
||||
+ desktop_size_.width() * desktop_size_.height() * kBytesPerPixel;
|
||||
+ }
|
||||
+
|
||||
+ if (!current_frame_ ||
|
||||
+ (video_crop_size_initialized_ && !video_crop_size_.equals(prev_crop_size))) {
|
||||
+ current_frame_ = std::make_unique<uint8_t[]>(frame_size);
|
||||
+ }
|
||||
+ RTC_DCHECK(current_frame_ != nullptr);
|
||||
+
|
||||
+ const int32_t dstStride = video_crop_size_initialized_
|
||||
+ ? video_crop_size_.width() * kBytesPerPixel
|
||||
+ : desktop_size_.width() * kBytesPerPixel;
|
||||
+ const int32_t srcStride = spaBuffer->datas[0].chunk->stride;
|
||||
+
|
||||
if (srcStride != (desktop_size_.width() * kBytesPerPixel)) {
|
||||
RTC_LOG(LS_ERROR) << "Got buffer with stride different from screen stride: "
|
||||
<< srcStride
|
||||
@@ -361,21 +454,39 @@ void BaseCapturerPipeWire::HandleBuffer(
|
||||
return;
|
||||
}
|
||||
|
||||
- if (!current_frame_) {
|
||||
- current_frame_ = static_cast<uint8_t*>(malloc(maxSize));
|
||||
+ dst = current_frame_.get();
|
||||
+
|
||||
+ // Adjust source content based on crop video position
|
||||
+ if (video_crop_size_initialized_ &&
|
||||
+ (video_crop->y + video_crop_size_.height() <= desktop_size_.height())) {
|
||||
+ for (int i = 0; i < video_crop->y; ++i) {
|
||||
+ src += srcStride;
|
||||
+ }
|
||||
+ }
|
||||
+ const int xOffset =
|
||||
+ video_crop_size_initialized_ && (video_crop->x + video_crop_size_.width() <=
|
||||
+ desktop_size_.width())
|
||||
+ ? video_crop->x * kBytesPerPixel
|
||||
+ : 0;
|
||||
+ const int height = video_crop_size_initialized_ ? video_crop_size_.height() : desktop_size_.height();
|
||||
+ for (int i = 0; i < height; ++i) {
|
||||
+ // Adjust source content based on crop video position if needed
|
||||
+ src += xOffset;
|
||||
+ std::memcpy(dst, src, dstStride);
|
||||
+ // If both sides decided to go with the RGBx format we need to convert it to
|
||||
+ // BGRx to match color format expected by WebRTC.
|
||||
+ if (spa_video_format_->format == pw_type_->video_format.RGBx) {
|
||||
+ ConvertRGBxToBGRx(dst, dstStride);
|
||||
+ }
|
||||
+ src += srcStride - xOffset;
|
||||
+ dst += dstStride;
|
||||
}
|
||||
- RTC_DCHECK(current_frame_ != nullptr);
|
||||
|
||||
- // If both sides decided to go with the RGBx format we need to convert it to
|
||||
- // BGRx to match color format expected by WebRTC.
|
||||
- if (spa_video_format_->format == pw_type_->video_format.RGBx) {
|
||||
- uint8_t* tempFrame = static_cast<uint8_t*>(malloc(maxSize));
|
||||
- std::memcpy(tempFrame, src, maxSize);
|
||||
- ConvertRGBxToBGRx(tempFrame, maxSize);
|
||||
- std::memcpy(current_frame_, tempFrame, maxSize);
|
||||
- free(tempFrame);
|
||||
- } else {
|
||||
- std::memcpy(current_frame_, src, maxSize);
|
||||
+ if (map) {
|
||||
+ if (spaBuffer->datas[0].type == pw_core_type_->data.DmaBuf) {
|
||||
+ SyncDmaBuf(spaBuffer->datas[0].fd, DMA_BUF_SYNC_END);
|
||||
+ }
|
||||
+ munmap(map, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -725,10 +836,6 @@ void BaseCapturerPipeWire::OnStartReques
|
||||
g_variant_get(variant, "(u@a{sv})", &stream_id, &options);
|
||||
RTC_DCHECK(options != nullptr);
|
||||
|
||||
- g_variant_lookup(options, "size", "(ii)", &width, &height);
|
||||
-
|
||||
- that->desktop_size_.set(width, height);
|
||||
-
|
||||
g_variant_unref(options);
|
||||
g_variant_unref(variant);
|
||||
}
|
||||
@@ -813,10 +920,15 @@ void BaseCapturerPipeWire::CaptureFrame(
|
||||
return;
|
||||
}
|
||||
|
||||
- std::unique_ptr<DesktopFrame> result(new BasicDesktopFrame(desktop_size_));
|
||||
+ DesktopSize frame_size = desktop_size_;
|
||||
+ if (video_crop_size_initialized_) {
|
||||
+ frame_size = video_crop_size_;
|
||||
+ }
|
||||
+
|
||||
+ std::unique_ptr<DesktopFrame> result(new BasicDesktopFrame(frame_size));
|
||||
result->CopyPixelsFrom(
|
||||
- current_frame_, (desktop_size_.width() * kBytesPerPixel),
|
||||
- DesktopRect::MakeWH(desktop_size_.width(), desktop_size_.height()));
|
||||
+ current_frame_.get(), (frame_size.width() * kBytesPerPixel),
|
||||
+ DesktopRect::MakeWH(frame_size.width(), frame_size.height()));
|
||||
if (!result) {
|
||||
callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
|
||||
return;
|
||||
@@ -837,4 +949,22 @@ bool BaseCapturerPipeWire::SelectSource(
|
||||
return true;
|
||||
}
|
||||
|
||||
+// static
|
||||
+std::unique_ptr<DesktopCapturer>
|
||||
+BaseCapturerPipeWire::CreateRawScreenCapturer(
|
||||
+ const DesktopCaptureOptions& options) {
|
||||
+ std::unique_ptr<BaseCapturerPipeWire> capturer =
|
||||
+ std::make_unique<BaseCapturerPipeWire>(BaseCapturerPipeWire::CaptureSourceType::kAny);
|
||||
+ return std::move(capturer);}
|
||||
+
|
||||
+// static
|
||||
+std::unique_ptr<DesktopCapturer>
|
||||
+BaseCapturerPipeWire::CreateRawWindowCapturer(
|
||||
+ const DesktopCaptureOptions& options) {
|
||||
+
|
||||
+ std::unique_ptr<BaseCapturerPipeWire> capturer =
|
||||
+ std::make_unique<BaseCapturerPipeWire>(BaseCapturerPipeWire::CaptureSourceType::kAny);
|
||||
+ return std::move(capturer);
|
||||
+}
|
||||
+
|
||||
} // namespace webrtc
|
||||
diff -up firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h.firefox-pipewire-0-2 firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
|
||||
--- firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h.firefox-pipewire-0-2 2020-07-20 22:54:40.000000000 +0200
|
||||
+++ firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h 2020-07-29 11:03:51.619283301 +0200
|
||||
@@ -32,7 +32,11 @@ class PipeWireType {
|
||||
|
||||
class BaseCapturerPipeWire : public DesktopCapturer {
|
||||
public:
|
||||
- enum CaptureSourceType { Screen = 1, Window };
|
||||
+ enum CaptureSourceType : uint32_t {
|
||||
+ kScreen = 0b01,
|
||||
+ kWindow = 0b10,
|
||||
+ kAny = 0b11
|
||||
+ };
|
||||
|
||||
explicit BaseCapturerPipeWire(CaptureSourceType source_type);
|
||||
~BaseCapturerPipeWire() override;
|
||||
@@ -43,6 +47,12 @@ class BaseCapturerPipeWire : public Desk
|
||||
bool GetSourceList(SourceList* sources) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
|
||||
+ static std::unique_ptr<DesktopCapturer> CreateRawScreenCapturer(
|
||||
+ const DesktopCaptureOptions& options);
|
||||
+
|
||||
+ static std::unique_ptr<DesktopCapturer> CreateRawWindowCapturer(
|
||||
+ const DesktopCaptureOptions& options);
|
||||
+
|
||||
private:
|
||||
// PipeWire types -->
|
||||
pw_core* pw_core_ = nullptr;
|
||||
@@ -64,7 +74,7 @@ class BaseCapturerPipeWire : public Desk
|
||||
gint32 pw_fd_ = -1;
|
||||
|
||||
CaptureSourceType capture_source_type_ =
|
||||
- BaseCapturerPipeWire::CaptureSourceType::Screen;
|
||||
+ BaseCapturerPipeWire::CaptureSourceType::kAny;
|
||||
|
||||
// <-- end of PipeWire types
|
||||
|
||||
@@ -78,10 +88,12 @@ class BaseCapturerPipeWire : public Desk
|
||||
guint sources_request_signal_id_ = 0;
|
||||
guint start_request_signal_id_ = 0;
|
||||
|
||||
+ bool video_crop_size_initialized_ = false;
|
||||
+ DesktopSize video_crop_size_;;
|
||||
DesktopSize desktop_size_ = {};
|
||||
DesktopCaptureOptions options_ = {};
|
||||
|
||||
- uint8_t* current_frame_ = nullptr;
|
||||
+ std::unique_ptr<uint8_t[]> current_frame_;
|
||||
Callback* callback_ = nullptr;
|
||||
|
||||
bool portal_init_failed_ = false;
|
||||
@@ -95,6 +107,7 @@ class BaseCapturerPipeWire : public Desk
|
||||
|
||||
void ConvertRGBxToBGRx(uint8_t* frame, uint32_t size);
|
||||
|
||||
+ static void SyncDmaBuf(int fd, uint64_t start_or_end);
|
||||
static void OnStateChanged(void* data,
|
||||
pw_remote_state old_state,
|
||||
pw_remote_state state,
|
||||
diff -up firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc.firefox-pipewire-0-2 firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc
|
||||
--- firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc.firefox-pipewire-0-2 2020-07-20 22:53:57.000000000 +0200
|
||||
+++ firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc 2020-07-29 11:03:51.619283301 +0200
|
||||
@@ -15,7 +15,7 @@
|
||||
namespace webrtc {
|
||||
|
||||
ScreenCapturerPipeWire::ScreenCapturerPipeWire()
|
||||
- : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Screen) {}
|
||||
+ : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::kScreen) {}
|
||||
ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {}
|
||||
|
||||
// static
|
||||
diff -up firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc.firefox-pipewire-0-2 firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc
|
||||
--- firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc.firefox-pipewire-0-2 2020-07-20 22:54:18.000000000 +0200
|
||||
+++ firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc 2020-07-29 11:03:51.619283301 +0200
|
||||
@@ -15,7 +15,7 @@
|
||||
namespace webrtc {
|
||||
|
||||
WindowCapturerPipeWire::WindowCapturerPipeWire()
|
||||
- : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::Window) {}
|
||||
+ : BaseCapturerPipeWire(BaseCapturerPipeWire::CaptureSourceType::kWindow) {}
|
||||
WindowCapturerPipeWire::~WindowCapturerPipeWire() {}
|
||||
|
||||
// static
|
||||
diff -up firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc.firefox-pipewire-0-2 firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc
|
||||
--- firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc.firefox-pipewire-0-2 2020-07-20 22:54:40.000000000 +0200
|
||||
+++ firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc 2020-07-29 11:03:51.620283296 +0200
|
||||
@@ -26,7 +26,7 @@ std::unique_ptr<DesktopCapturer> Desktop
|
||||
const DesktopCaptureOptions& options) {
|
||||
#if defined(WEBRTC_USE_PIPEWIRE)
|
||||
if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) {
|
||||
- return ScreenCapturerPipeWire::CreateRawScreenCapturer(options);
|
||||
+ return BaseCapturerPipeWire::CreateRawScreenCapturer(options);
|
||||
}
|
||||
#endif // defined(WEBRTC_USE_PIPEWIRE)
|
||||
|
||||
diff -up firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc.firefox-pipewire-0-2 firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc
|
||||
--- firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc.firefox-pipewire-0-2 2020-07-20 22:53:32.000000000 +0200
|
||||
+++ firefox-79.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc 2020-07-29 11:03:51.620283296 +0200
|
||||
@@ -26,7 +26,7 @@ std::unique_ptr<DesktopCapturer> Desktop
|
||||
const DesktopCaptureOptions& options) {
|
||||
#if defined(WEBRTC_USE_PIPEWIRE)
|
||||
if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) {
|
||||
- return WindowCapturerPipeWire::CreateRawWindowCapturer(options);
|
||||
+ return BaseCapturerPipeWire::CreateRawWindowCapturer(options);
|
||||
}
|
||||
#endif // defined(WEBRTC_USE_PIPEWIRE)
|
||||
|
48
firefox.spec
48
firefox.spec
@ -121,13 +121,13 @@ ExcludeArch: s390x
|
||||
|
||||
Summary: Mozilla Firefox Web browser
|
||||
Name: firefox
|
||||
Version: 82.0.3
|
||||
Release: 2%{?pre_tag}%{?dist}
|
||||
Version: 83.0
|
||||
Release: 1%{?pre_tag}%{?dist}
|
||||
URL: https://www.mozilla.org/firefox/
|
||||
License: MPLv1.1 or GPLv2+ or LGPLv2+
|
||||
Source0: https://archive.mozilla.org/pub/firefox/releases/%{version}%{?pre_version}/source/firefox-%{version}%{?pre_version}.source.tar.xz
|
||||
%if %{with langpacks}
|
||||
Source1: firefox-langpacks-%{version}%{?pre_version}-20201109.tar.xz
|
||||
Source1: firefox-langpacks-%{version}%{?pre_version}-20201112.tar.xz
|
||||
%endif
|
||||
Source2: cbindgen-vendor.tar.xz
|
||||
Source10: firefox-mozconfig
|
||||
@ -166,7 +166,6 @@ Patch49: build-arm-libaom.patch
|
||||
Patch53: firefox-gcc-build.patch
|
||||
# This should be fixed in Firefox 83
|
||||
Patch54: mozilla-1669639.patch
|
||||
Patch55: mozilla-1669442.patch
|
||||
|
||||
# Fedora specific patches
|
||||
Patch215: firefox-enable-addons.patch
|
||||
@ -180,23 +179,22 @@ Patch228: disable-openh264-download.patch
|
||||
|
||||
# Upstream patches
|
||||
Patch402: mozilla-1196777.patch
|
||||
Patch406: mozilla-1665329.patch
|
||||
Patch407: mozilla-1667096.patch
|
||||
Patch408: mozilla-1663844.patch
|
||||
Patch409: mozilla-1640567.patch
|
||||
Patch410: mozilla-1661192.patch
|
||||
Patch412: mozilla-1634404.patch
|
||||
Patch413: mozilla-1669495.patch
|
||||
Patch414: mozilla-1656727.patch
|
||||
Patch415: mozilla-1670333.patch
|
||||
Patch416: mozilla-1673202.patch
|
||||
Patch417: mozilla-1673313.patch
|
||||
Patch418: mozilla-1556931-s390x-hidden-syms.patch
|
||||
Patch419: mozilla-1885133.patch
|
||||
|
||||
# Wayland specific upstream patches
|
||||
Patch574: firefox-pipewire-0-2.patch
|
||||
Patch575: firefox-pipewire-0-3.patch
|
||||
# Upstream patches from mozbz#1672944
|
||||
Patch450: pw1.patch
|
||||
Patch451: pw2.patch
|
||||
Patch452: pw3.patch
|
||||
Patch453: pw4.patch
|
||||
Patch454: pw5.patch
|
||||
Patch455: pw6.patch
|
||||
Patch456: pw7.patch
|
||||
|
||||
#VA-API patches
|
||||
Patch584: firefox-disable-ffvpx-with-vapi.patch
|
||||
@ -380,7 +378,6 @@ This package contains results of tests executed during build.
|
||||
%patch49 -p1 -b .build-arm-libaom
|
||||
%patch53 -p1 -b .firefox-gcc-build
|
||||
%patch54 -p1 -b .1669639
|
||||
%patch55 -p1 -b .1669442
|
||||
|
||||
# Fedora patches
|
||||
%patch215 -p1 -b .addons
|
||||
@ -395,14 +392,8 @@ This package contains results of tests executed during build.
|
||||
%patch228 -p1 -b .disable-openh264-download
|
||||
|
||||
%patch402 -p1 -b .1196777
|
||||
%patch406 -p1 -b .1665329
|
||||
%patch407 -p1 -b .1667096
|
||||
%patch408 -p1 -b .1663844
|
||||
%patch409 -p1 -b .1640567
|
||||
%patch410 -p1 -b .1661192
|
||||
%patch412 -p1 -b .1634404
|
||||
%patch413 -p1 -b .1669495
|
||||
%patch414 -p1 -b .1656727
|
||||
%patch415 -p1 -b .1670333
|
||||
%if 0%{?fedora} > 33 || 0%{?eln}
|
||||
%patch416 -p1 -b .1673202
|
||||
@ -411,12 +402,13 @@ This package contains results of tests executed during build.
|
||||
%patch418 -p1 -b .1556931-s390x-hidden-syms
|
||||
%patch419 -p1 -b .1885133
|
||||
|
||||
# Wayland specific upstream patches
|
||||
%if 0%{?fedora} > 31 || 0%{?eln}
|
||||
%patch575 -p1 -b .firefox-pipewire-0-3
|
||||
%else
|
||||
%patch574 -p1 -b .firefox-pipewire-0-2
|
||||
%endif
|
||||
%patch450 -p1 -b .pw1
|
||||
%patch451 -p1 -b .pw2
|
||||
%patch452 -p1 -b .pw3
|
||||
%patch453 -p1 -b .pw4
|
||||
%patch454 -p1 -b .pw5
|
||||
%patch455 -p1 -b .pw6
|
||||
%patch456 -p1 -b .pw7
|
||||
|
||||
# VA-API fixes
|
||||
%patch584 -p1 -b .firefox-disable-ffvpx-with-vapi
|
||||
@ -986,6 +978,10 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || :
|
||||
#---------------------------------------------------------------------
|
||||
|
||||
%changelog
|
||||
* Thu Nov 12 2020 Martin Stransky <stransky@redhat.com> - 83.0-1
|
||||
- Updated to 83.0
|
||||
- Updated PipeWire patches from mozbz#1672944
|
||||
|
||||
* Tue Nov 10 2020 Martin Stransky <stransky@redhat.com> - 82.0.3-2
|
||||
- Added fix for mozbz#1885133
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
|
||||
--- a/widget/gtk/nsWindow.cpp
|
||||
+++ b/widget/gtk/nsWindow.cpp
|
||||
@@ -1593,7 +1593,14 @@
|
||||
// Get anchor rectangle
|
||||
LayoutDeviceIntRect anchorRect(0, 0, 0, 0);
|
||||
nsMenuPopupFrame* popupFrame = GetMenuPopupFrame(GetFrame());
|
||||
- int32_t p2a = AppUnitsPerCSSPixel() / gfxPlatformGtk::GetFontScaleFactor();
|
||||
+
|
||||
+ int32_t p2a;
|
||||
+ double devPixelsPerCSSPixel = StaticPrefs::layout_css_devPixelsPerPx();
|
||||
+ if (devPixelsPerCSSPixel > 0.0) {
|
||||
+ p2a = AppUnitsPerCSSPixel() / devPixelsPerCSSPixel * GdkScaleFactor();
|
||||
+ } else {
|
||||
+ p2a = AppUnitsPerCSSPixel() / gfxPlatformGtk::GetFontScaleFactor();
|
||||
+ }
|
||||
if (popupFrame) {
|
||||
#ifdef MOZ_WAYLAND
|
||||
anchorRect = LayoutDeviceIntRect::FromAppUnitsToOutside(
|
||||
|
@ -1,18 +0,0 @@
|
||||
diff --git a/layout/xul/nsMenuPopupFrame.cpp b/layout/xul/nsMenuPopupFrame.cpp
|
||||
--- a/layout/xul/nsMenuPopupFrame.cpp
|
||||
+++ b/layout/xul/nsMenuPopupFrame.cpp
|
||||
@@ -1422,11 +1422,9 @@
|
||||
!GDK_IS_X11_DISPLAY(gdk_display_get_default())) {
|
||||
screenPoint = nsPoint(anchorRect.x, anchorRect.y);
|
||||
mAnchorRect = anchorRect;
|
||||
- } else
|
||||
+ }
|
||||
#endif
|
||||
- {
|
||||
- screenPoint = AdjustPositionForAnchorAlign(anchorRect, hFlip, vFlip);
|
||||
- }
|
||||
+ screenPoint = AdjustPositionForAnchorAlign(anchorRect, hFlip, vFlip);
|
||||
} else {
|
||||
// with no anchor, the popup is positioned relative to the root frame
|
||||
anchorRect = rootScreenRect;
|
||||
|
@ -1,213 +0,0 @@
|
||||
diff -up firefox-82.0/widget/gtk/WindowSurfaceWayland.cpp.1656727 firefox-82.0/widget/gtk/WindowSurfaceWayland.cpp
|
||||
--- firefox-82.0/widget/gtk/WindowSurfaceWayland.cpp.1656727 2020-10-15 16:16:53.522050159 +0200
|
||||
+++ firefox-82.0/widget/gtk/WindowSurfaceWayland.cpp 2020-10-15 16:18:24.956289348 +0200
|
||||
@@ -158,7 +158,6 @@ We allocate shared memory (shm) by mmap(
|
||||
between us and wayland compositor. We draw our graphics data to the shm and
|
||||
handle to wayland compositor by WindowBackBuffer/WindowSurfaceWayland
|
||||
(wl_buffer/wl_surface).
|
||||
-
|
||||
*/
|
||||
|
||||
#define EVENT_LOOP_DELAY (1000 / 240)
|
||||
@@ -166,6 +165,44 @@ handle to wayland compositor by WindowBa
|
||||
#define BUFFER_BPP 4
|
||||
gfx::SurfaceFormat WindowBackBuffer::mFormat = gfx::SurfaceFormat::B8G8R8A8;
|
||||
|
||||
+static mozilla::Mutex* gDelayedCommitLock = nullptr;
|
||||
+static GList* gDelayedCommits = nullptr;
|
||||
+
|
||||
+static void DelayedCommitsEnsureMutext() {
|
||||
+ if (!gDelayedCommitLock) {
|
||||
+ gDelayedCommitLock = new mozilla::Mutex("DelayedCommit lock");
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static bool DelayedCommitsCheckAndRemoveSurface(
|
||||
+ WindowSurfaceWayland* aSurface) {
|
||||
+ MutexAutoLock lock(*gDelayedCommitLock);
|
||||
+ GList* foundCommit = g_list_find(gDelayedCommits, aSurface);
|
||||
+ if (foundCommit) {
|
||||
+ gDelayedCommits = g_list_delete_link(gDelayedCommits, foundCommit);
|
||||
+ }
|
||||
+ return foundCommit != nullptr;
|
||||
+}
|
||||
+
|
||||
+static bool DelayedCommitsCheckAndAddSurface(WindowSurfaceWayland* aSurface) {
|
||||
+ MutexAutoLock lock(*gDelayedCommitLock);
|
||||
+ GList* foundCommit = g_list_find(gDelayedCommits, aSurface);
|
||||
+ if (!foundCommit) {
|
||||
+ gDelayedCommits = g_list_prepend(gDelayedCommits, aSurface);
|
||||
+ }
|
||||
+ return foundCommit == nullptr;
|
||||
+}
|
||||
+
|
||||
+// When a new window is created we may not have a valid wl_surface
|
||||
+// for drawing (Gtk haven't created it yet). All commits are queued
|
||||
+// and CommitWaylandBuffer() is called by timer when wl_surface is ready
|
||||
+// for drawing.
|
||||
+static void WaylandBufferDelayCommitHandler(WindowSurfaceWayland* aSurface) {
|
||||
+ if (DelayedCommitsCheckAndRemoveSurface(aSurface)) {
|
||||
+ aSurface->CommitWaylandBuffer();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
RefPtr<nsWaylandDisplay> WindowBackBuffer::GetWaylandDisplay() {
|
||||
return mWindowSurfaceWayland->GetWaylandDisplay();
|
||||
}
|
||||
@@ -399,7 +436,6 @@ WindowSurfaceWayland::WindowSurfaceWayla
|
||||
mWaylandFullscreenDamage(false),
|
||||
mFrameCallback(nullptr),
|
||||
mLastCommittedSurface(nullptr),
|
||||
- mDelayedCommitHandle(nullptr),
|
||||
mLastCommitTime(0),
|
||||
mDrawToWaylandBufferDirectly(true),
|
||||
mCanSwitchWaylandBuffer(true),
|
||||
@@ -411,6 +447,7 @@ WindowSurfaceWayland::WindowSurfaceWayla
|
||||
for (int i = 0; i < BACK_BUFFER_NUM; i++) {
|
||||
mShmBackupBuffer[i] = nullptr;
|
||||
}
|
||||
+ DelayedCommitsEnsureMutext();
|
||||
}
|
||||
|
||||
WindowSurfaceWayland::~WindowSurfaceWayland() {
|
||||
@@ -418,12 +455,9 @@ WindowSurfaceWayland::~WindowSurfaceWayl
|
||||
NS_WARNING("Deleted WindowSurfaceWayland with a pending commit!");
|
||||
}
|
||||
|
||||
- if (mDelayedCommitHandle) {
|
||||
- // Delete reference to this to prevent WaylandBufferDelayCommitHandler()
|
||||
- // operate on released this. mDelayedCommitHandle itself will
|
||||
- // be released at WaylandBufferDelayCommitHandler().
|
||||
- *mDelayedCommitHandle = nullptr;
|
||||
- }
|
||||
+ // Delete reference to this to prevent WaylandBufferDelayCommitHandler()
|
||||
+ // operate on released this.
|
||||
+ DelayedCommitsCheckAndRemoveSurface(this);
|
||||
|
||||
if (mFrameCallback) {
|
||||
wl_callback_destroy(mFrameCallback);
|
||||
@@ -864,23 +898,11 @@ bool WindowSurfaceWayland::CommitImageCa
|
||||
return true;
|
||||
}
|
||||
|
||||
-static void WaylandBufferDelayCommitHandler(WindowSurfaceWayland** aSurface) {
|
||||
- if (*aSurface) {
|
||||
- (*aSurface)->DelayedCommitHandler();
|
||||
- } else {
|
||||
- // Referenced WindowSurfaceWayland is already deleted.
|
||||
- // Do nothing but just release the mDelayedCommitHandle allocated at
|
||||
- // WindowSurfaceWayland::CommitWaylandBuffer().
|
||||
- free(aSurface);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
void WindowSurfaceWayland::CommitWaylandBuffer() {
|
||||
LOGWAYLAND(("WindowSurfaceWayland::CommitWaylandBuffer [%p]\n", (void*)this));
|
||||
LOGWAYLAND(
|
||||
(" mDrawToWaylandBufferDirectly = %d\n", mDrawToWaylandBufferDirectly));
|
||||
LOGWAYLAND((" mCanSwitchWaylandBuffer = %d\n", mCanSwitchWaylandBuffer));
|
||||
- LOGWAYLAND((" mDelayedCommitHandle = %p\n", mDelayedCommitHandle));
|
||||
LOGWAYLAND((" mFrameCallback = %p\n", mFrameCallback));
|
||||
LOGWAYLAND((" mLastCommittedSurface = %p\n", mLastCommittedSurface));
|
||||
LOGWAYLAND((" mBufferPendingCommit = %d\n", mBufferPendingCommit));
|
||||
@@ -916,16 +938,10 @@ void WindowSurfaceWayland::CommitWayland
|
||||
MOZ_ASSERT(!mFrameCallback || waylandSurface != mLastCommittedSurface,
|
||||
"Missing wayland surface at frame callback!");
|
||||
|
||||
- // Do nothing if there's already mDelayedCommitHandle pending.
|
||||
- if (!mDelayedCommitHandle) {
|
||||
- mDelayedCommitHandle = static_cast<WindowSurfaceWayland**>(
|
||||
- moz_xmalloc(sizeof(*mDelayedCommitHandle)));
|
||||
- *mDelayedCommitHandle = this;
|
||||
-
|
||||
+ if (DelayedCommitsCheckAndAddSurface(this)) {
|
||||
MessageLoop::current()->PostDelayedTask(
|
||||
NewRunnableFunction("WaylandBackBufferCommit",
|
||||
- &WaylandBufferDelayCommitHandler,
|
||||
- mDelayedCommitHandle),
|
||||
+ &WaylandBufferDelayCommitHandler, this),
|
||||
EVENT_LOOP_DELAY);
|
||||
}
|
||||
return;
|
||||
@@ -1037,25 +1053,6 @@ void WindowSurfaceWayland::FrameCallback
|
||||
|
||||
CommitWaylandBuffer();
|
||||
}
|
||||
-
|
||||
-void WindowSurfaceWayland::DelayedCommitHandler() {
|
||||
- MOZ_ASSERT(mIsMainThread == NS_IsMainThread());
|
||||
- MOZ_ASSERT(mDelayedCommitHandle != nullptr, "Missing mDelayedCommitHandle!");
|
||||
-
|
||||
- LOGWAYLAND(
|
||||
- ("WindowSurfaceWayland::DelayedCommitHandler [%p]\n", (void*)this));
|
||||
-
|
||||
- if (!mDelayedCommitHandle) {
|
||||
- LOGWAYLAND((" We're missing mDelayedCommitHandle!\n"));
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- *mDelayedCommitHandle = nullptr;
|
||||
- free(mDelayedCommitHandle);
|
||||
- mDelayedCommitHandle = nullptr;
|
||||
-
|
||||
- CommitWaylandBuffer();
|
||||
-}
|
||||
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
diff -up firefox-82.0/widget/gtk/WindowSurfaceWayland.h.1656727 firefox-82.0/widget/gtk/WindowSurfaceWayland.h
|
||||
--- firefox-82.0/widget/gtk/WindowSurfaceWayland.h.1656727 2020-10-14 19:20:27.000000000 +0200
|
||||
+++ firefox-82.0/widget/gtk/WindowSurfaceWayland.h 2020-10-15 16:16:53.528050175 +0200
|
||||
@@ -161,7 +161,7 @@ class WindowSurfaceWayland : public Wind
|
||||
// If we fail (wayland compositor is busy,
|
||||
// wl_surface is not created yet) we queue the painting
|
||||
// and we send it to wayland compositor in FrameCallbackHandler()/
|
||||
- // DelayedCommitHandler/CommitWaylandBuffer().
|
||||
+ // CommitWaylandBuffer().
|
||||
already_AddRefed<gfx::DrawTarget> Lock(
|
||||
const LayoutDeviceIntRegion& aRegion) override;
|
||||
void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final;
|
||||
@@ -171,12 +171,6 @@ class WindowSurfaceWayland : public Wind
|
||||
// queued commits.
|
||||
void FrameCallbackHandler();
|
||||
|
||||
- // When a new window is created we may not have a valid wl_surface
|
||||
- // for drawing (Gtk haven't created it yet). All commits are queued
|
||||
- // and DelayedCommitHandler() is called by timer when wl_surface is ready
|
||||
- // for drawing.
|
||||
- void DelayedCommitHandler();
|
||||
-
|
||||
// Try to commit all queued drawings to Wayland compositor. This is usually
|
||||
// called from other routines but can be used to explicitly flush
|
||||
// all drawings as we do when wl_buffer is released
|
||||
@@ -249,17 +243,14 @@ class WindowSurfaceWayland : public Wind
|
||||
wl_callback* mFrameCallback;
|
||||
wl_surface* mLastCommittedSurface;
|
||||
|
||||
- // Registered reference to pending DelayedCommitHandler() call.
|
||||
- WindowSurfaceWayland** mDelayedCommitHandle;
|
||||
-
|
||||
// Cached drawings. If we can't get WaylandBuffer (wl_buffer) at
|
||||
// WindowSurfaceWayland::Lock() we direct gecko rendering to
|
||||
// mImageSurface.
|
||||
// If we can't get WaylandBuffer at WindowSurfaceWayland::Commit()
|
||||
// time, mImageSurface is moved to mDelayedImageCommits which
|
||||
// holds all cached drawings.
|
||||
- // mDelayedImageCommits can be drawn by FrameCallbackHandler(),
|
||||
- // DelayedCommitHandler() or when WaylandBuffer is detached.
|
||||
+ // mDelayedImageCommits can be drawn by FrameCallbackHandler()
|
||||
+ // or when WaylandBuffer is detached.
|
||||
RefPtr<gfxImageSurface> mImageSurface;
|
||||
AutoTArray<WindowImageSurface, 30> mDelayedImageCommits;
|
||||
|
||||
@@ -282,8 +273,8 @@ class WindowSurfaceWayland : public Wind
|
||||
// We can't send WaylandBuffer (wl_buffer) to compositor when gecko
|
||||
// is rendering into it (i.e. between WindowSurfaceWayland::Lock() /
|
||||
// WindowSurfaceWayland::Commit()).
|
||||
- // Thus we use mBufferCommitAllowed to disable commit by callbacks
|
||||
- // (FrameCallbackHandler(), DelayedCommitHandler())
|
||||
+ // Thus we use mBufferCommitAllowed to disable commit by
|
||||
+ // CommitWaylandBuffer().
|
||||
bool mBufferCommitAllowed;
|
||||
|
||||
// We need to clear WaylandBuffer when entire transparent window is repainted.
|
@ -1,25 +0,0 @@
|
||||
diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp
|
||||
--- a/widget/gtk/nsWindow.cpp
|
||||
+++ b/widget/gtk/nsWindow.cpp
|
||||
@@ -1600,9 +1600,11 @@
|
||||
#endif
|
||||
}
|
||||
|
||||
+ bool hasAnchorRect = true;
|
||||
if (anchorRect.width == 0) {
|
||||
LOG((" No anchor rect given, use aPosition for anchor"));
|
||||
anchorRect.SetRect(aPosition->x, aPosition->y, 1, 1);
|
||||
+ hasAnchorRect = false;
|
||||
}
|
||||
LOG((" anchor x %d y %d width %d height %d (absolute coords)\n",
|
||||
anchorRect.x, anchorRect.y, anchorRect.width, anchorRect.height));
|
||||
@@ -1704,7 +1706,7 @@
|
||||
nsPoint cursorOffset(0, 0);
|
||||
#ifdef MOZ_WAYLAND
|
||||
// Offset is already computed to the tooltips
|
||||
- if (popupFrame && mPopupType != ePopupTypeTooltip) {
|
||||
+ if (hasAnchorRect && popupFrame && mPopupType != ePopupTypeTooltip) {
|
||||
nsMargin margin(0, 0, 0, 0);
|
||||
popupFrame->StyleMargin()->GetMargin(margin);
|
||||
switch (popupFrame->GetPopupAlignment()) {
|
||||
|
@ -1,16 +0,0 @@
|
||||
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
|
||||
--- a/modules/libpref/init/StaticPrefList.yaml
|
||||
+++ b/modules/libpref/init/StaticPrefList.yaml
|
||||
@@ -7565,11 +7565,7 @@
|
||||
# acceleration for decoding.
|
||||
- name: media.navigator.mediadatadecoder_vpx_enabled
|
||||
type: RelaxedAtomicBool
|
||||
- #if defined(NIGHTLY_BUILD)
|
||||
value: true
|
||||
- #else
|
||||
- value: false
|
||||
- #endif
|
||||
mirror: always
|
||||
|
||||
# Use MediaDataDecoder API for H264 in WebRTC. This includes hardware
|
||||
|
@ -1,13 +0,0 @@
|
||||
diff --git a/config/recurse.mk b/config/recurse.mk
|
||||
--- a/config/recurse.mk
|
||||
+++ b/config/recurse.mk
|
||||
@@ -206,7 +206,7 @@
|
||||
# Interdependencies that moz.build world don't know about yet for compilation.
|
||||
# Note some others are hardcoded or "guessed" in recursivemake.py and emitter.py
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk)
|
||||
-toolkit/library/target: widget/gtk/mozgtk/gtk3/target
|
||||
+toolkit/library/build/target: widget/gtk/mozgtk/gtk3/target
|
||||
endif
|
||||
|
||||
ifndef MOZ_FOLD_LIBS
|
||||
|
@ -1,130 +0,0 @@
|
||||
diff -up firefox-82.0/layout/xul/nsMenuPopupFrame.cpp.1669495 firefox-82.0/layout/xul/nsMenuPopupFrame.cpp
|
||||
--- firefox-82.0/layout/xul/nsMenuPopupFrame.cpp.1669495 2020-10-15 16:13:12.304471453 +0200
|
||||
+++ firefox-82.0/layout/xul/nsMenuPopupFrame.cpp 2020-10-15 16:13:12.308471463 +0200
|
||||
@@ -533,6 +533,26 @@ void nsMenuPopupFrame::LayoutPopup(nsBox
|
||||
}
|
||||
prefSize = XULBoundsCheck(minSize, prefSize, maxSize);
|
||||
|
||||
+#ifdef MOZ_WAYLAND
|
||||
+ static bool inWayland = gdk_display_get_default() &&
|
||||
+ !GDK_IS_X11_DISPLAY(gdk_display_get_default());
|
||||
+#else
|
||||
+ static bool inWayland = false;
|
||||
+#endif
|
||||
+ if (inWayland) {
|
||||
+ // If prefSize it is not a whole number in css pixels we need round it up
|
||||
+ // to avoid reflow of the tooltips/popups and putting the text on two lines
|
||||
+ // (usually happens with 200% scale factor and font scale factor <> 1)
|
||||
+ // because GTK thrown away the decimals.
|
||||
+ int32_t appPerCSS = AppUnitsPerCSSPixel();
|
||||
+ if (prefSize.width % appPerCSS > 0) {
|
||||
+ prefSize.width += appPerCSS;
|
||||
+ }
|
||||
+ if (prefSize.height % appPerCSS > 0) {
|
||||
+ prefSize.height += appPerCSS;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
bool sizeChanged = (mPrefSize != prefSize);
|
||||
// if the size changed then set the bounds to be the preferred size
|
||||
if (sizeChanged) {
|
||||
diff -up firefox-82.0/widget/gtk/nsWindow.cpp.1669495 firefox-82.0/widget/gtk/nsWindow.cpp
|
||||
--- firefox-82.0/widget/gtk/nsWindow.cpp.1669495 2020-10-15 16:13:12.307471461 +0200
|
||||
+++ firefox-82.0/widget/gtk/nsWindow.cpp 2020-10-15 16:15:49.243882006 +0200
|
||||
@@ -1092,11 +1092,13 @@ void nsWindow::Show(bool aState) {
|
||||
|
||||
void nsWindow::ResizeInt(int aX, int aY, int aWidth, int aHeight, bool aMove,
|
||||
bool aRepaint) {
|
||||
- LOG(("nsWindow::ResizeInt [%p] %d %d -> %d %d repaint %d\n", (void*)this, aX,
|
||||
- aY, aWidth, aHeight, aRepaint));
|
||||
+ LOG(("nsWindow::ResizeInt [%p] x:%d y:%d -> w:%d h:%d repaint %d aMove %d\n",
|
||||
+ (void*)this, aX, aY, aWidth, aHeight, aRepaint, aMove));
|
||||
|
||||
ConstrainSize(&aWidth, &aHeight);
|
||||
|
||||
+ LOG((" ConstrainSize: w:%d h;%d\n", aWidth, aHeight));
|
||||
+
|
||||
// If we used to have insane bounds, we may have skipped actually positioning
|
||||
// the widget in NativeMoveResizeWaylandPopup, in which case we need to
|
||||
// actually position it now as well.
|
||||
@@ -1141,8 +1143,7 @@ void nsWindow::ResizeInt(int aX, int aY,
|
||||
}
|
||||
|
||||
void nsWindow::Resize(double aWidth, double aHeight, bool aRepaint) {
|
||||
- LOG(("nsWindow::Resize [%p] %d %d\n", (void*)this, (int)aWidth,
|
||||
- (int)aHeight));
|
||||
+ LOG(("nsWindow::Resize [%p] %f %f\n", (void*)this, aWidth, aHeight));
|
||||
|
||||
double scale =
|
||||
BoundsUseDesktopPixels() ? GetDesktopToDeviceScale().scale : 1.0;
|
||||
@@ -1154,8 +1155,8 @@ void nsWindow::Resize(double aWidth, dou
|
||||
|
||||
void nsWindow::Resize(double aX, double aY, double aWidth, double aHeight,
|
||||
bool aRepaint) {
|
||||
- LOG(("nsWindow::Resize [%p] %d %d repaint %d\n", (void*)this, (int)aWidth,
|
||||
- (int)aHeight, aRepaint));
|
||||
+ LOG(("nsWindow::Resize [%p] %f %f repaint %d\n", (void*)this, aWidth, aHeight,
|
||||
+ aRepaint));
|
||||
|
||||
double scale =
|
||||
BoundsUseDesktopPixels() ? GetDesktopToDeviceScale().scale : 1.0;
|
||||
@@ -1478,14 +1479,15 @@ void nsWindow::NativeMoveResizeWaylandPo
|
||||
|
||||
newBounds.x = GdkCoordToDevicePixels(newBounds.x);
|
||||
newBounds.y = GdkCoordToDevicePixels(newBounds.y);
|
||||
- LOG((" new mBounds x=%d y=%d width=%d height=%d\n", newBounds.x,
|
||||
- newBounds.y, newBounds.width, newBounds.height));
|
||||
|
||||
double scale =
|
||||
BoundsUseDesktopPixels() ? GetDesktopToDeviceScale().scale : 1.0;
|
||||
int32_t newWidth = NSToIntRound(scale * newBounds.width);
|
||||
int32_t newHeight = NSToIntRound(scale * newBounds.height);
|
||||
|
||||
+ LOG((" new mBounds x=%d y=%d width=%d height=%d\n", newBounds.x,
|
||||
+ newBounds.y, newWidth, newHeight));
|
||||
+
|
||||
bool needsPositionUpdate =
|
||||
(newBounds.x != mBounds.x || newBounds.y != mBounds.y);
|
||||
bool needsSizeUpdate =
|
||||
@@ -1493,6 +1495,7 @@ void nsWindow::NativeMoveResizeWaylandPo
|
||||
// Update view
|
||||
|
||||
if (needsSizeUpdate) {
|
||||
+ LOG((" needSizeUpdate\n"));
|
||||
int32_t p2a = AppUnitsPerCSSPixel() / gfxPlatformGtk::GetFontScaleFactor();
|
||||
mPreferredPopupRect = nsRect(NSIntPixelsToAppUnits(newBounds.x, p2a),
|
||||
NSIntPixelsToAppUnits(newBounds.y, p2a),
|
||||
@@ -1511,6 +1514,7 @@ void nsWindow::NativeMoveResizeWaylandPo
|
||||
}
|
||||
|
||||
if (needsPositionUpdate) {
|
||||
+ LOG((" needPositionUpdate\n"));
|
||||
// The newBounds are in coordinates relative to the parent window/popup.
|
||||
// The NotifyWindowMoved requires the coordinates relative to the toplevel.
|
||||
// We use the gdk_window_get_origin to get correct coordinates.
|
||||
@@ -4245,6 +4249,8 @@ nsresult nsWindow::Create(nsIWidget* aPa
|
||||
|
||||
// save our bounds
|
||||
mBounds = aRect;
|
||||
+ LOG((" mBounds: x:%d y:%d w:%d h:%d\n", mBounds.x, mBounds.y, mBounds.width,
|
||||
+ mBounds.height));
|
||||
|
||||
mPreferredPopupRectFlushed = false;
|
||||
|
||||
@@ -5083,13 +5089,16 @@ void nsWindow::NativeShow(bool aAction)
|
||||
}
|
||||
}
|
||||
|
||||
+ LOG((" calling gtk_widget_show(mShell)\n"));
|
||||
gtk_widget_show(mShell);
|
||||
if (!mIsX11Display) {
|
||||
WaylandStartVsync();
|
||||
}
|
||||
} else if (mContainer) {
|
||||
+ LOG((" calling gtk_widget_show(mContainer)\n"));
|
||||
gtk_widget_show(GTK_WIDGET(mContainer));
|
||||
} else if (mGdkWindow) {
|
||||
+ LOG((" calling gdk_window_show_unraised\n"));
|
||||
gdk_window_show_unraised(mGdkWindow);
|
||||
}
|
||||
} else {
|
78
pw1.patch
Normal file
78
pw1.patch
Normal file
@ -0,0 +1,78 @@
|
||||
|
||||
# HG changeset patch
|
||||
# User stransky <stransky@redhat.com>
|
||||
# Date 1604562416 0
|
||||
# Node ID 1c126b520042591194e88618ae11a6adc1da9a08
|
||||
# Parent 6e2e4f0e4a95b0cae777dda9369a9e9bf49a51b1
|
||||
Bug 1672987 Use PipeWire when Wayland display is actually used, r=dminor
|
||||
|
||||
Right now PipeWire is enabled when Wayland session is used regardless of an active Gtk backend (X11/Wayland).
|
||||
Let's use PipeWire only when Wayland Gtk backend is used and disable it for X11 one to avoid possible regressions.
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D94588
|
||||
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capturer.cc b/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capturer.cc
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capturer.cc
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capturer.cc
|
||||
@@ -8,16 +8,21 @@
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "modules/desktop_capture/desktop_capturer.h"
|
||||
|
||||
#include "modules/desktop_capture/desktop_capture_options.h"
|
||||
#include "modules/desktop_capture/desktop_capturer_differ_wrapper.h"
|
||||
|
||||
+#if defined(WEBRTC_USE_PIPEWIRE) || defined(USE_X11)
|
||||
+#include <gtk/gtk.h>
|
||||
+#include <gtk/gtkx.h>
|
||||
+#endif
|
||||
+
|
||||
namespace webrtc {
|
||||
|
||||
DesktopCapturer::~DesktopCapturer() = default;
|
||||
|
||||
void DesktopCapturer::SetSharedMemoryFactory(
|
||||
std::unique_ptr<SharedMemoryFactory> shared_memory_factory) {}
|
||||
|
||||
void DesktopCapturer::SetExcludedWindow(WindowId window) {}
|
||||
@@ -67,21 +72,37 @@ std::unique_ptr<DesktopCapturer> Desktop
|
||||
if (capturer && options.detect_updated_region()) {
|
||||
capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer)));
|
||||
}
|
||||
|
||||
return capturer;
|
||||
}
|
||||
|
||||
#if defined(WEBRTC_USE_PIPEWIRE) || defined(USE_X11)
|
||||
-bool DesktopCapturer::IsRunningUnderWayland() {
|
||||
+// Return true if Firefox is actually running with Wayland backend.
|
||||
+static bool IsWaylandDisplayUsed() {
|
||||
+ const auto display = gdk_display_get_default();
|
||||
+ if (display == nullptr) {
|
||||
+ // We're running in headless mode.
|
||||
+ return false;
|
||||
+ }
|
||||
+ return !GDK_IS_X11_DISPLAY(display);
|
||||
+}
|
||||
+
|
||||
+// Return true if Firefox is actually running on Wayland enabled session.
|
||||
+// It means some screensharing capabilities may be limited.
|
||||
+static bool IsWaylandSessionUsed() {
|
||||
const char* xdg_session_type = getenv("XDG_SESSION_TYPE");
|
||||
if (!xdg_session_type || strncmp(xdg_session_type, "wayland", 7) != 0)
|
||||
return false;
|
||||
|
||||
if (!(getenv("WAYLAND_DISPLAY")))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
+
|
||||
+bool DesktopCapturer::IsRunningUnderWayland() {
|
||||
+ return IsWaylandSessionUsed() ? IsWaylandDisplayUsed() : false;
|
||||
+}
|
||||
#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(USE_X11)
|
||||
|
||||
} // namespace webrtc
|
||||
|
@ -1,100 +1,47 @@
|
||||
diff -up firefox-81.0/config/system-headers.mozbuild.firefox-pipewire-0-3 firefox-81.0/config/system-headers.mozbuild
|
||||
--- firefox-81.0/config/system-headers.mozbuild.firefox-pipewire-0-3 2020-09-15 03:48:26.000000000 +0200
|
||||
+++ firefox-81.0/config/system-headers.mozbuild 2020-09-15 14:40:00.721481417 +0200
|
||||
@@ -314,6 +314,7 @@ system_headers = [
|
||||
'Gestalt.h',
|
||||
'getopt.h',
|
||||
'gio/gio.h',
|
||||
+ 'gio/gunixfdlist.h',
|
||||
'glibconfig.h',
|
||||
'glib.h',
|
||||
'glib-object.h',
|
||||
@@ -607,6 +608,7 @@ system_headers = [
|
||||
'Pgenerr.h',
|
||||
'PGenErr.h',
|
||||
'Ph.h',
|
||||
+ 'pipewire/pipewire.h',
|
||||
'pixman.h',
|
||||
'pk11func.h',
|
||||
'pk11pqg.h',
|
||||
diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn.firefox-pipewire-0-3 firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn
|
||||
--- firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn.firefox-pipewire-0-3 2020-09-15 03:48:32.000000000 +0200
|
||||
+++ firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/BUILD.gn 2020-09-15 14:40:00.721481417 +0200
|
||||
@@ -158,7 +158,7 @@ if (rtc_include_tests) {
|
||||
if (is_linux) {
|
||||
if (rtc_use_pipewire) {
|
||||
pkg_config("pipewire") {
|
||||
- packages = [ "libpipewire-0.2" ]
|
||||
+ packages = [ "libpipewire-0.3" ]
|
||||
|
||||
# HG changeset patch
|
||||
# User stransky <stransky@redhat.com>
|
||||
# Date 1604560111 0
|
||||
# Node ID 998e6d0b24e4a560e5664aaef87307e9c069ad87
|
||||
# Parent 1c126b520042591194e88618ae11a6adc1da9a08
|
||||
Bug 1672947 Update PipeWire WebRTC code to PipeWire 0.3, r=ng
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D94589
|
||||
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc b/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
|
||||
@@ -10,18 +10,20 @@
|
||||
|
||||
defines = [ "WEBRTC_USE_PIPEWIRE" ]
|
||||
}
|
||||
diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build.firefox-pipewire-0-3 firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build
|
||||
--- firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build.firefox-pipewire-0-3 2020-09-15 14:40:00.722481420 +0200
|
||||
+++ firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build 2020-09-15 14:48:47.454733146 +0200
|
||||
@@ -193,6 +193,28 @@ if CONFIG["OS_TARGET"] == "Linux":
|
||||
"/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc"
|
||||
]
|
||||
#include "modules/desktop_capture/linux/base_capturer_pipewire.h"
|
||||
|
||||
+# PipeWire specific files
|
||||
+if CONFIG["OS_TARGET"] == "Linux":
|
||||
+ DEFINES["WEBRTC_USE_PIPEWIRE"] = "1"
|
||||
+
|
||||
+ OS_LIBS += [
|
||||
+ "rt",
|
||||
+ "pipewire-0.3",
|
||||
+ "glib-2.0",
|
||||
+ "gio-2.0",
|
||||
+ "gobject-2.0"
|
||||
+ ]
|
||||
+
|
||||
+ CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
+ CXXFLAGS += [ "-I/usr/include/pipewire-0.3" ]
|
||||
+ CXXFLAGS += [ "-I/usr/include/spa-0.2" ]
|
||||
+
|
||||
+ UNIFIED_SOURCES += [
|
||||
+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc",
|
||||
+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc",
|
||||
+ "/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc"
|
||||
+ ]
|
||||
+
|
||||
if CONFIG["OS_TARGET"] == "NetBSD":
|
||||
|
||||
DEFINES["USE_X11"] = "1"
|
||||
diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h.firefox-pipewire-0-3 firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h
|
||||
--- firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h.firefox-pipewire-0-3 2020-09-15 03:48:32.000000000 +0200
|
||||
+++ firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/desktop_capture_options.h 2020-09-15 14:40:00.722481420 +0200
|
||||
@@ -141,7 +141,7 @@ class DesktopCaptureOptions {
|
||||
bool disable_effects_ = true;
|
||||
bool detect_updated_region_ = false;
|
||||
#if defined(WEBRTC_USE_PIPEWIRE)
|
||||
- bool allow_pipewire_ = false;
|
||||
+ bool allow_pipewire_ = true;
|
||||
#endif
|
||||
};
|
||||
|
||||
diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc.firefox-pipewire-0-3 firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
|
||||
--- firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc.firefox-pipewire-0-3 2020-09-15 03:48:32.000000000 +0200
|
||||
+++ firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc 2020-09-15 14:40:00.722481420 +0200
|
||||
@@ -15,8 +15,11 @@
|
||||
#include <gio/gunixfdlist.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <spa/param/format-utils.h>
|
||||
#include <spa/param/props.h>
|
||||
-#include <spa/param/video/raw-utils.h>
|
||||
-#include <spa/support/type-map.h>
|
||||
+
|
||||
+#include <linux/dma-buf.h>
|
||||
+#include <sys/mman.h>
|
||||
+#include <sys/ioctl.h>
|
||||
+#include <sys/syscall.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
@@ -36,32 +39,37 @@ const char kSessionInterfaceName[] = "or
|
||||
|
||||
#include "modules/desktop_capture/desktop_capture_options.h"
|
||||
#include "modules/desktop_capture/desktop_capturer.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "rtc_base/logging.h"
|
||||
@@ -32,180 +34,166 @@ const char kDesktopBusName[] = "org.free
|
||||
const char kDesktopObjectPath[] = "/org/freedesktop/portal/desktop";
|
||||
const char kDesktopRequestObjectPath[] =
|
||||
"/org/freedesktop/portal/desktop/request";
|
||||
const char kSessionInterfaceName[] = "org.freedesktop.portal.Session";
|
||||
const char kRequestInterfaceName[] = "org.freedesktop.portal.Request";
|
||||
const char kScreenCastInterfaceName[] = "org.freedesktop.portal.ScreenCast";
|
||||
|
||||
+
|
||||
// static
|
||||
-void BaseCapturerPipeWire::OnStateChanged(void* data,
|
||||
- pw_remote_state old_state,
|
||||
@ -102,19 +49,21 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
- const char* error_message) {
|
||||
- BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
|
||||
- RTC_DCHECK(that);
|
||||
+void BaseCapturerPipeWire::SyncDmaBuf(int fd, uint64_t start_or_end) {
|
||||
+ struct dma_buf_sync sync = { 0 };
|
||||
+struct dma_buf_sync {
|
||||
+ uint64_t flags;
|
||||
+};
|
||||
+#define DMA_BUF_SYNC_READ (1 << 0)
|
||||
+#define DMA_BUF_SYNC_START (0 << 2)
|
||||
+#define DMA_BUF_SYNC_END (1 << 2)
|
||||
+#define DMA_BUF_BASE 'b'
|
||||
+#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
|
||||
|
||||
- switch (state) {
|
||||
- case PW_REMOTE_STATE_ERROR:
|
||||
- RTC_LOG(LS_ERROR) << "PipeWire remote state error: " << error_message;
|
||||
- break;
|
||||
- case PW_REMOTE_STATE_CONNECTED:
|
||||
- RTC_LOG(LS_INFO) << "PipeWire remote state: connected.";
|
||||
- that->CreateReceivingStream();
|
||||
- break;
|
||||
- case PW_REMOTE_STATE_CONNECTING:
|
||||
- RTC_LOG(LS_INFO) << "PipeWire remote state: connecting.";
|
||||
+static void SyncDmaBuf(int fd, uint64_t start_or_end) {
|
||||
+ struct dma_buf_sync sync = { 0 };
|
||||
+
|
||||
+ sync.flags = start_or_end | DMA_BUF_SYNC_READ;
|
||||
+
|
||||
+ while(true) {
|
||||
@ -125,10 +74,17 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
+ } else if (ret == -1) {
|
||||
+ RTC_LOG(LS_ERROR) << "Failed to synchronize DMA buffer: " << g_strerror(errno);
|
||||
break;
|
||||
- case PW_REMOTE_STATE_UNCONNECTED:
|
||||
- RTC_LOG(LS_INFO) << "PipeWire remote state: unconnected.";
|
||||
- case PW_REMOTE_STATE_CONNECTED:
|
||||
- RTC_LOG(LS_INFO) << "PipeWire remote state: connected.";
|
||||
- that->CreateReceivingStream();
|
||||
+ } else {
|
||||
break;
|
||||
- case PW_REMOTE_STATE_CONNECTING:
|
||||
- RTC_LOG(LS_INFO) << "PipeWire remote state: connecting.";
|
||||
- break;
|
||||
- case PW_REMOTE_STATE_UNCONNECTED:
|
||||
- RTC_LOG(LS_INFO) << "PipeWire remote state: unconnected.";
|
||||
- break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
@ -146,20 +102,24 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
void BaseCapturerPipeWire::OnStreamStateChanged(void* data,
|
||||
pw_stream_state old_state,
|
||||
pw_stream_state state,
|
||||
@@ -73,76 +81,54 @@ void BaseCapturerPipeWire::OnStreamState
|
||||
const char* error_message) {
|
||||
BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
|
||||
RTC_DCHECK(that);
|
||||
|
||||
switch (state) {
|
||||
case PW_STREAM_STATE_ERROR:
|
||||
RTC_LOG(LS_ERROR) << "PipeWire stream state error: " << error_message;
|
||||
break;
|
||||
- case PW_STREAM_STATE_CONFIGURE:
|
||||
- pw_stream_set_active(that->pw_stream_, true);
|
||||
- break;
|
||||
- case PW_STREAM_STATE_UNCONNECTED:
|
||||
- case PW_STREAM_STATE_CONNECTING:
|
||||
+ case PW_STREAM_STATE_PAUSED:
|
||||
+ case PW_STREAM_STATE_STREAMING:
|
||||
case PW_STREAM_STATE_UNCONNECTED:
|
||||
case PW_STREAM_STATE_CONNECTING:
|
||||
- case PW_STREAM_STATE_READY:
|
||||
case PW_STREAM_STATE_PAUSED:
|
||||
case PW_STREAM_STATE_STREAMING:
|
||||
+ case PW_STREAM_STATE_UNCONNECTED:
|
||||
+ case PW_STREAM_STATE_CONNECTING:
|
||||
- case PW_STREAM_STATE_PAUSED:
|
||||
- case PW_STREAM_STATE_STREAMING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -249,24 +209,25 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -150,15 +136,25 @@ void BaseCapturerPipeWire::OnStreamProce
|
||||
void BaseCapturerPipeWire::OnStreamProcess(void* data) {
|
||||
BaseCapturerPipeWire* that = static_cast<BaseCapturerPipeWire*>(data);
|
||||
RTC_DCHECK(that);
|
||||
|
||||
- pw_buffer* buf = nullptr;
|
||||
+ struct pw_buffer *next_buffer;
|
||||
+ struct pw_buffer *buffer = nullptr;
|
||||
+
|
||||
|
||||
- if (!(buf = pw_stream_dequeue_buffer(that->pw_stream_))) {
|
||||
+ next_buffer = pw_stream_dequeue_buffer(that->pw_stream_);
|
||||
+ while (next_buffer) {
|
||||
+ buffer = next_buffer;
|
||||
+ next_buffer = pw_stream_dequeue_buffer(that->pw_stream_);
|
||||
+
|
||||
+ if (next_buffer)
|
||||
+ if (next_buffer) {
|
||||
+ pw_stream_queue_buffer (that->pw_stream_, buffer);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- if (!(buf = pw_stream_dequeue_buffer(that->pw_stream_))) {
|
||||
+
|
||||
+ if (!buffer) {
|
||||
return;
|
||||
}
|
||||
@ -279,7 +240,10 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
}
|
||||
|
||||
BaseCapturerPipeWire::BaseCapturerPipeWire(CaptureSourceType source_type)
|
||||
@@ -169,38 +165,22 @@ BaseCapturerPipeWire::~BaseCapturerPipeW
|
||||
: capture_source_type_(source_type) {}
|
||||
|
||||
BaseCapturerPipeWire::~BaseCapturerPipeWire() {
|
||||
if (pw_main_loop_) {
|
||||
pw_thread_loop_stop(pw_main_loop_);
|
||||
}
|
||||
|
||||
@ -322,16 +286,22 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
if (start_request_signal_id_) {
|
||||
g_dbus_connection_signal_unsubscribe(connection_, start_request_signal_id_);
|
||||
}
|
||||
@@ -250,27 +230,35 @@ void BaseCapturerPipeWire::InitPortal()
|
||||
if (sources_request_signal_id_) {
|
||||
g_dbus_connection_signal_unsubscribe(connection_,
|
||||
sources_request_signal_id_);
|
||||
}
|
||||
if (session_request_signal_id_) {
|
||||
@@ -245,143 +233,210 @@ void BaseCapturerPipeWire::InitPortal()
|
||||
kDesktopBusName, kDesktopObjectPath, kScreenCastInterfaceName,
|
||||
/*cancellable=*/nullptr,
|
||||
reinterpret_cast<GAsyncReadyCallback>(OnProxyRequested), this);
|
||||
}
|
||||
|
||||
void BaseCapturerPipeWire::InitPipeWire() {
|
||||
pw_init(/*argc=*/nullptr, /*argc=*/nullptr);
|
||||
|
||||
- pw_loop_ = pw_loop_new(/*properties=*/nullptr);
|
||||
- pw_main_loop_ = pw_thread_loop_new(pw_loop_, "pipewire-main-loop");
|
||||
-
|
||||
- pw_core_ = pw_core_new(pw_loop_, /*properties=*/nullptr);
|
||||
- pw_core_type_ = pw_core_get_type(pw_core_);
|
||||
- pw_remote_ = pw_remote_new(pw_core_, nullptr, /*user_data_size=*/0);
|
||||
+ pw_main_loop_ = pw_thread_loop_new("pipewire-main-loop", nullptr);
|
||||
+ pw_context_ = pw_context_new(pw_thread_loop_get_loop(pw_main_loop_), nullptr, 0);
|
||||
+ if (!pw_context_) {
|
||||
@ -339,6 +309,10 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- pw_core_ = pw_core_new(pw_loop_, /*properties=*/nullptr);
|
||||
- pw_core_type_ = pw_core_get_type(pw_core_);
|
||||
- pw_remote_ = pw_remote_new(pw_core_, nullptr, /*user_data_size=*/0);
|
||||
-
|
||||
- InitPipeWireTypes();
|
||||
+ pw_core_ = pw_context_connect(pw_context_, nullptr, 0);
|
||||
+ if (!pw_core_) {
|
||||
@ -371,30 +345,30 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
|
||||
if (pw_thread_loop_start(pw_main_loop_) < 0) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to start main PipeWire loop";
|
||||
@@ -278,81 +266,132 @@ void BaseCapturerPipeWire::InitPipeWire(
|
||||
portal_init_failed_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
-void BaseCapturerPipeWire::InitPipeWireTypes() {
|
||||
- spa_type_map* map = pw_core_type_->map;
|
||||
- pw_type_ = new PipeWireType();
|
||||
+pw_stream* BaseCapturerPipeWire::CreateReceivingStream() {
|
||||
+ spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1};
|
||||
+ spa_rectangle pwMaxScreenBounds = spa_rectangle{INT32_MAX, INT32_MAX};
|
||||
|
||||
-
|
||||
- spa_type_media_type_map(map, &pw_type_->media_type);
|
||||
- spa_type_media_subtype_map(map, &pw_type_->media_subtype);
|
||||
- spa_type_format_video_map(map, &pw_type_->format_video);
|
||||
- spa_type_video_format_map(map, &pw_type_->video_format);
|
||||
-}
|
||||
+ auto stream = pw_stream_new(pw_core_, "webrtc-pipewire-stream", nullptr);
|
||||
+pw_stream* BaseCapturerPipeWire::CreateReceivingStream() {
|
||||
+ spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1};
|
||||
+ spa_rectangle pwMaxScreenBounds = spa_rectangle{UINT32_MAX, UINT32_MAX};
|
||||
|
||||
-void BaseCapturerPipeWire::CreateReceivingStream() {
|
||||
- spa_rectangle pwMinScreenBounds = spa_rectangle{1, 1};
|
||||
- spa_rectangle pwScreenBounds =
|
||||
- spa_rectangle{static_cast<uint32_t>(desktop_size_.width()),
|
||||
- static_cast<uint32_t>(desktop_size_.height())};
|
||||
-
|
||||
+ auto stream = pw_stream_new(pw_core_, "webrtc-pipewire-stream", nullptr);
|
||||
|
||||
- spa_fraction pwFrameRateMin = spa_fraction{0, 1};
|
||||
- spa_fraction pwFrameRateMax = spa_fraction{60, 1};
|
||||
-
|
||||
@ -435,7 +409,15 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
- &pwFrameRateMin, &pwFrameRateMax));
|
||||
+ const spa_pod* params[2];
|
||||
+ spa_pod_builder builder = SPA_POD_BUILDER_INIT(buffer, sizeof (buffer));
|
||||
+
|
||||
|
||||
- pw_stream_add_listener(pw_stream_, &spa_stream_listener_, &pw_stream_events_,
|
||||
- this);
|
||||
- pw_stream_flags flags = static_cast<pw_stream_flags>(
|
||||
- PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE |
|
||||
- PW_STREAM_FLAG_MAP_BUFFERS);
|
||||
- if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, /*port_path=*/nullptr,
|
||||
- flags, params,
|
||||
- /*n_params=*/1) != 0) {
|
||||
+ params[0] = reinterpret_cast<spa_pod *>(spa_pod_builder_add_object(&builder,
|
||||
+ SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||
+ SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
|
||||
@ -447,156 +429,121 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
+ &pwMaxScreenBounds),
|
||||
+ 0));
|
||||
+ pw_stream_add_listener(stream, &spa_stream_listener_, &pw_stream_events_, this);
|
||||
|
||||
- pw_stream_add_listener(pw_stream_, &spa_stream_listener_, &pw_stream_events_,
|
||||
- this);
|
||||
pw_stream_flags flags = static_cast<pw_stream_flags>(
|
||||
- PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE |
|
||||
- PW_STREAM_FLAG_MAP_BUFFERS);
|
||||
- if (pw_stream_connect(pw_stream_, PW_DIRECTION_INPUT, /*port_path=*/nullptr,
|
||||
- flags, params,
|
||||
- /*n_params=*/1) != 0) {
|
||||
+ PW_STREAM_FLAG_AUTOCONNECT | PW_STREAM_FLAG_INACTIVE);
|
||||
+
|
||||
+ if (pw_stream_connect(stream, PW_DIRECTION_INPUT, pw_stream_node_id_, PW_STREAM_FLAG_AUTOCONNECT, params, 1) != 0) {
|
||||
+ if (pw_stream_connect(stream, PW_DIRECTION_INPUT, pw_stream_node_id_,
|
||||
+ PW_STREAM_FLAG_AUTOCONNECT, params, 1) != 0) {
|
||||
RTC_LOG(LS_ERROR) << "Could not connect receiving stream.";
|
||||
portal_init_failed_ = true;
|
||||
- return;
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ return stream;
|
||||
+}
|
||||
+
|
||||
+static void SpaBufferUnmap(unsigned char *map, int map_size, bool IsDMABuf, int fd) {
|
||||
+ if (map) {
|
||||
+ if (IsDMABuf) {
|
||||
+ SyncDmaBuf(fd, DMA_BUF_SYNC_END);
|
||||
+ }
|
||||
+ munmap(map, map_size);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseCapturerPipeWire::HandleBuffer(pw_buffer* buffer) {
|
||||
+ struct spa_meta_region* video_crop;
|
||||
spa_buffer* spaBuffer = buffer->buffer;
|
||||
- void* src = nullptr;
|
||||
+ uint8_t *map = nullptr;
|
||||
+ uint8_t* src = nullptr;
|
||||
+ uint8_t* dst = nullptr;
|
||||
+
|
||||
+ if (spaBuffer->datas[0].chunk->size == 0) {
|
||||
+ map = nullptr;
|
||||
+ src = nullptr;
|
||||
+ } else if (spaBuffer->datas[0].type == SPA_DATA_MemFd) {
|
||||
+ map = static_cast<uint8_t*>(mmap(
|
||||
+ nullptr, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
|
||||
+ PROT_READ, MAP_PRIVATE, spaBuffer->datas[0].fd, 0));
|
||||
+
|
||||
+ if (map == MAP_FAILED) {
|
||||
+ RTC_LOG(LS_ERROR) << "Failed to mmap the memory: " << std::strerror(errno);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ src = SPA_MEMBER(map, spaBuffer->datas[0].mapoffset, uint8_t);
|
||||
+ } else if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf) {
|
||||
+ int fd;
|
||||
+ fd = spaBuffer->datas[0].fd;
|
||||
+
|
||||
+ map = static_cast<uint8_t*>(mmap(
|
||||
+ nullptr, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
|
||||
+ PROT_READ, MAP_PRIVATE, fd, 0));
|
||||
+
|
||||
+ if (map == MAP_FAILED) {
|
||||
+ RTC_LOG(LS_ERROR) << "Failed to mmap the memory: " << std::strerror(errno);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- if (!(src = spaBuffer->datas[0].data)) {
|
||||
+ SyncDmaBuf(fd, DMA_BUF_SYNC_START);
|
||||
+
|
||||
+ src = SPA_MEMBER(map, spaBuffer->datas[0].mapoffset, uint8_t);
|
||||
+ } else if (spaBuffer->datas[0].type == SPA_DATA_MemPtr) {
|
||||
+ map = nullptr;
|
||||
+ src = static_cast<uint8_t*>(spaBuffer->datas[0].data);
|
||||
+ } else {
|
||||
+ if (spaBuffer->datas[0].chunk->size == 0) {
|
||||
+ RTC_LOG(LS_ERROR) << "Failed to get video stream: Zero size.";
|
||||
return;
|
||||
}
|
||||
|
||||
- uint32_t maxSize = spaBuffer->datas[0].maxsize;
|
||||
- int32_t srcStride = spaBuffer->datas[0].chunk->stride;
|
||||
- if (srcStride != (desktop_size_.width() * kBytesPerPixel)) {
|
||||
- RTC_LOG(LS_ERROR) << "Got buffer with stride different from screen stride: "
|
||||
- << srcStride
|
||||
- << " != " << (desktop_size_.width() * kBytesPerPixel);
|
||||
- portal_init_failed_ = true;
|
||||
+ switch (spaBuffer->datas[0].type) {
|
||||
+ case SPA_DATA_MemFd:
|
||||
+ case SPA_DATA_DmaBuf:
|
||||
+ map = static_cast<uint8_t*>(mmap(
|
||||
+ nullptr, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
|
||||
+ PROT_READ, MAP_PRIVATE, spaBuffer->datas[0].fd, 0));
|
||||
+ if (map == MAP_FAILED) {
|
||||
+ RTC_LOG(LS_ERROR) << "Failed to mmap memory: " << std::strerror(errno);
|
||||
+ return;
|
||||
+ }
|
||||
+ if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf) {
|
||||
+ SyncDmaBuf(spaBuffer->datas[0].fd, DMA_BUF_SYNC_START);
|
||||
+ }
|
||||
+ src = SPA_MEMBER(map, spaBuffer->datas[0].mapoffset, uint8_t);
|
||||
+ break;
|
||||
+ case SPA_DATA_MemPtr:
|
||||
+ map = nullptr;
|
||||
+ src = static_cast<uint8_t*>(spaBuffer->datas[0].data);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (!src) {
|
||||
+ RTC_LOG(LS_ERROR) << "Failed to get video stream: Wrong data after mmap()";
|
||||
+ SpaBufferUnmap(map,
|
||||
+ spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
|
||||
+ spaBuffer->datas[0].type == SPA_DATA_DmaBuf, spaBuffer->datas[0].fd);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ DesktopSize prev_crop_size = DesktopSize(0, 0);
|
||||
+ if (video_crop_size_initialized_) {
|
||||
+ prev_crop_size = video_crop_size_;
|
||||
+ }
|
||||
+ struct spa_meta_region* video_metadata =
|
||||
+ static_cast<struct spa_meta_region*>(
|
||||
+ spa_buffer_find_meta_data(spaBuffer, SPA_META_VideoCrop, sizeof(*video_metadata)));
|
||||
+
|
||||
+ if ((video_crop = static_cast<struct spa_meta_region*>(
|
||||
+ spa_buffer_find_meta_data(spaBuffer, SPA_META_VideoCrop, sizeof(*video_crop))))) {
|
||||
+ RTC_DCHECK(video_crop->region.size.width <= desktop_size_.width() &&
|
||||
+ video_crop->region.size.height <= desktop_size_.height());
|
||||
+ if ((video_crop->region.size.width != desktop_size_.width() ||
|
||||
+ video_crop->region.size.height != desktop_size_.height()) && video_crop->region.size.width && video_crop->region.size.height) {
|
||||
+ video_crop_size_ = DesktopSize(video_crop->region.size.width, video_crop->region.size.height);
|
||||
+ video_crop_size_initialized_ = true;
|
||||
+ } else {
|
||||
+ video_crop_size_initialized_ = false;
|
||||
+ }
|
||||
+ } else {
|
||||
+ video_crop_size_initialized_ = false;
|
||||
+ }
|
||||
+
|
||||
+ size_t frame_size;
|
||||
+ if (video_crop_size_initialized_) {
|
||||
+ frame_size =
|
||||
+ video_crop_size_.width() * video_crop_size_.height() * kBytesPerPixel;
|
||||
+ } else {
|
||||
+ frame_size =
|
||||
+ desktop_size_.width() * desktop_size_.height() * kBytesPerPixel;
|
||||
+ }
|
||||
+
|
||||
+ if (!current_frame_ ||
|
||||
+ (video_crop_size_initialized_ && !video_crop_size_.equals(prev_crop_size))) {
|
||||
+ current_frame_ = std::make_unique<uint8_t[]>(frame_size);
|
||||
+ }
|
||||
+ RTC_DCHECK(current_frame_ != nullptr);
|
||||
+
|
||||
+ const int32_t dstStride = video_crop_size_initialized_
|
||||
+ ? video_crop_size_.width() * kBytesPerPixel
|
||||
+ : desktop_size_.width() * kBytesPerPixel;
|
||||
+ const int32_t srcStride = spaBuffer->datas[0].chunk->stride;
|
||||
+
|
||||
if (srcStride != (desktop_size_.width() * kBytesPerPixel)) {
|
||||
RTC_LOG(LS_ERROR) << "Got buffer with stride different from screen stride: "
|
||||
<< srcStride
|
||||
@@ -361,21 +400,40 @@ void BaseCapturerPipeWire::HandleBuffer(
|
||||
+ // Video size from metada is bigger than an actual video stream size.
|
||||
+ // The metadata are wrong or we should up-scale te video...in both cases
|
||||
+ // just quit now.
|
||||
+ if (video_metadata &&
|
||||
+ (video_metadata->region.size.width > (uint32_t)desktop_size_.width() ||
|
||||
+ video_metadata->region.size.height > (uint32_t)desktop_size_.height())) {
|
||||
+ RTC_LOG(LS_ERROR) << "Stream metadata sizes are wrong!";
|
||||
+ SpaBufferUnmap(map,
|
||||
+ spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
|
||||
+ spaBuffer->datas[0].type == SPA_DATA_DmaBuf, spaBuffer->datas[0].fd);
|
||||
return;
|
||||
}
|
||||
|
||||
- if (!current_frame_) {
|
||||
- current_frame_ = static_cast<uint8_t*>(malloc(maxSize));
|
||||
+ dst = current_frame_.get();
|
||||
+ // Use video metada when video size from metadata is set and smaller than
|
||||
+ // video stream size, so we need to adjust it.
|
||||
+ video_metadata_use_ = (video_metadata &&
|
||||
+ video_metadata->region.size.width != 0 &&
|
||||
+ video_metadata->region.size.height != 0 &&
|
||||
+ (video_metadata->region.size.width < (uint32_t)desktop_size_.width() ||
|
||||
+ video_metadata->region.size.height < (uint32_t)desktop_size_.height()));
|
||||
+
|
||||
+ // Adjust source content based on crop video position
|
||||
+ if (video_crop_size_initialized_ &&
|
||||
+ (video_crop->region.position.y + video_crop_size_.height() <= desktop_size_.height())) {
|
||||
+ for (int i = 0; i < video_crop->region.position.y; ++i) {
|
||||
+ src += srcStride;
|
||||
+ }
|
||||
+ }
|
||||
+ const int xOffset =
|
||||
+ video_crop_size_initialized_ && (video_crop->region.position.x + video_crop_size_.width() <=
|
||||
+ desktop_size_.width())
|
||||
+ ? video_crop->region.position.x * kBytesPerPixel
|
||||
+ : 0;
|
||||
+ const int height = video_crop_size_initialized_ ? video_crop_size_.height() : desktop_size_.height();
|
||||
+ for (int i = 0; i < height; ++i) {
|
||||
+ // Adjust source content based on crop video position if needed
|
||||
+ src += xOffset;
|
||||
+ std::memcpy(dst, src, dstStride);
|
||||
+ // If both sides decided to go with the RGBx format we need to convert it to
|
||||
+ // BGRx to match color format expected by WebRTC.
|
||||
+ if (spa_video_format_.format == SPA_VIDEO_FORMAT_RGBx ||
|
||||
+ spa_video_format_.format == SPA_VIDEO_FORMAT_RGBA) {
|
||||
+ ConvertRGBxToBGRx(dst, dstStride);
|
||||
+ }
|
||||
+ src += srcStride - xOffset;
|
||||
+ dst += dstStride;
|
||||
+ DesktopSize video_size_prev = video_size_;
|
||||
+ if (video_metadata_use_) {
|
||||
+ video_size_ = DesktopSize(video_metadata->region.size.width,
|
||||
+ video_metadata->region.size.height);
|
||||
+ } else {
|
||||
+ video_size_ = desktop_size_;
|
||||
}
|
||||
- RTC_DCHECK(current_frame_ != nullptr);
|
||||
+
|
||||
+ if (!current_frame_ ||
|
||||
+ (video_metadata_use_ && !video_size_.equals(video_size_prev))) {
|
||||
+ current_frame_ =
|
||||
+ std::make_unique<uint8_t[]>
|
||||
+ (video_size_.width() * video_size_.height() * kBytesPerPixel);
|
||||
+ }
|
||||
+
|
||||
+ const int32_t dstStride = video_size_.width() * kBytesPerPixel;
|
||||
+ const int32_t srcStride = spaBuffer->datas[0].chunk->stride;
|
||||
|
||||
- // If both sides decided to go with the RGBx format we need to convert it to
|
||||
- // BGRx to match color format expected by WebRTC.
|
||||
@ -608,15 +555,56 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
- free(tempFrame);
|
||||
- } else {
|
||||
- std::memcpy(current_frame_, src, maxSize);
|
||||
+ if (map) {
|
||||
+ if (spaBuffer->datas[0].type == SPA_DATA_DmaBuf) {
|
||||
+ SyncDmaBuf(spaBuffer->datas[0].fd, DMA_BUF_SYNC_END);
|
||||
+ }
|
||||
+ munmap(map, spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset);
|
||||
+ // Adjust source content based on metadata video position
|
||||
+ if (video_metadata_use_ &&
|
||||
+ (video_metadata->region.position.y + video_size_.height() <= desktop_size_.height())) {
|
||||
+ src += srcStride * video_metadata->region.position.y;
|
||||
}
|
||||
+ const int xOffset =
|
||||
+ video_metadata_use_ &&
|
||||
+ (video_metadata->region.position.x + video_size_.width() <= desktop_size_.width())
|
||||
+ ? video_metadata->region.position.x * kBytesPerPixel
|
||||
+ : 0;
|
||||
+
|
||||
+ uint8_t* dst = current_frame_.get();
|
||||
+ for (int i = 0; i < video_size_.height(); ++i) {
|
||||
+ // Adjust source content based on crop video position if needed
|
||||
+ src += xOffset;
|
||||
+ std::memcpy(dst, src, dstStride);
|
||||
+ // If both sides decided to go with the RGBx format we need to convert it to
|
||||
+ // BGRx to match color format expected by WebRTC.
|
||||
+ if (spa_video_format_.format == SPA_VIDEO_FORMAT_RGBx ||
|
||||
+ spa_video_format_.format == SPA_VIDEO_FORMAT_RGBA) {
|
||||
+ ConvertRGBxToBGRx(dst, dstStride);
|
||||
+ }
|
||||
+ src += srcStride - xOffset;
|
||||
+ dst += dstStride;
|
||||
+ }
|
||||
+
|
||||
+ SpaBufferUnmap(map,
|
||||
+ spaBuffer->datas[0].maxsize + spaBuffer->datas[0].mapoffset,
|
||||
+ spaBuffer->datas[0].type == SPA_DATA_DmaBuf, spaBuffer->datas[0].fd);
|
||||
}
|
||||
|
||||
@@ -725,10 +783,7 @@ void BaseCapturerPipeWire::OnStartReques
|
||||
void BaseCapturerPipeWire::ConvertRGBxToBGRx(uint8_t* frame, uint32_t size) {
|
||||
// Change color format for KDE KWin which uses RGBx and not BGRx
|
||||
for (uint32_t i = 0; i < size; i += 4) {
|
||||
uint8_t tempR = frame[i];
|
||||
uint8_t tempB = frame[i + 2];
|
||||
frame[i] = tempB;
|
||||
@@ -713,27 +768,22 @@ void BaseCapturerPipeWire::OnStartReques
|
||||
// Array of PipeWire streams. See
|
||||
// https://github.com/flatpak/xdg-desktop-portal/blob/master/data/org.freedesktop.portal.ScreenCast.xml
|
||||
// documentation for <method name="Start">.
|
||||
if (g_variant_lookup(response_data, "streams", "a(ua{sv})", &iter)) {
|
||||
GVariant* variant;
|
||||
|
||||
while (g_variant_iter_next(iter, "@(ua{sv})", &variant)) {
|
||||
guint32 stream_id;
|
||||
- gint32 width;
|
||||
- gint32 height;
|
||||
GVariant* options;
|
||||
|
||||
g_variant_get(variant, "(u@a{sv})", &stream_id, &options);
|
||||
RTC_DCHECK(options != nullptr);
|
||||
|
||||
@ -628,16 +616,26 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
g_variant_unref(options);
|
||||
g_variant_unref(variant);
|
||||
}
|
||||
@@ -813,10 +868,15 @@ void BaseCapturerPipeWire::CaptureFrame(
|
||||
}
|
||||
g_variant_iter_free(iter);
|
||||
g_variant_unref(response_data);
|
||||
|
||||
that->OpenPipeWireRemote();
|
||||
@@ -808,20 +858,25 @@ void BaseCapturerPipeWire::CaptureFrame(
|
||||
return;
|
||||
}
|
||||
|
||||
if (!current_frame_) {
|
||||
callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
- std::unique_ptr<DesktopFrame> result(new BasicDesktopFrame(desktop_size_));
|
||||
+ DesktopSize frame_size = desktop_size_;
|
||||
+ if (video_crop_size_initialized_) {
|
||||
+ frame_size = video_crop_size_;
|
||||
+ if (video_metadata_use_) {
|
||||
+ frame_size = video_size_;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ std::unique_ptr<DesktopFrame> result(new BasicDesktopFrame(frame_size));
|
||||
result->CopyPixelsFrom(
|
||||
- current_frame_, (desktop_size_.width() * kBytesPerPixel),
|
||||
@ -647,7 +645,17 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
if (!result) {
|
||||
callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
|
||||
return;
|
||||
@@ -837,4 +897,22 @@ bool BaseCapturerPipeWire::SelectSource(
|
||||
}
|
||||
callback_->OnCaptureResult(Result::SUCCESS, std::move(result));
|
||||
}
|
||||
|
||||
bool BaseCapturerPipeWire::GetSourceList(SourceList* sources) {
|
||||
@@ -832,9 +887,27 @@ bool BaseCapturerPipeWire::GetSourceList
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseCapturerPipeWire::SelectSource(SourceId id) {
|
||||
// Screen selection is handled by the xdg-desktop-portal.
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -670,10 +678,15 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
+}
|
||||
+
|
||||
} // namespace webrtc
|
||||
diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h.firefox-pipewire-0-3 firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
|
||||
--- firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h.firefox-pipewire-0-3 2020-09-15 03:48:32.000000000 +0200
|
||||
+++ firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h 2020-09-15 14:40:00.722481420 +0200
|
||||
@@ -22,17 +22,13 @@
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h b/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.h
|
||||
@@ -17,99 +17,102 @@
|
||||
#include <spa/param/video/format-utils.h>
|
||||
|
||||
#include "modules/desktop_capture/desktop_capture_options.h"
|
||||
#include "modules/desktop_capture/desktop_capturer.h"
|
||||
#include "rtc_base/constructormagic.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -696,7 +709,10 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
|
||||
explicit BaseCapturerPipeWire(CaptureSourceType source_type);
|
||||
~BaseCapturerPipeWire() override;
|
||||
@@ -43,28 +39,32 @@ class BaseCapturerPipeWire : public Desk
|
||||
|
||||
// DesktopCapturer interface.
|
||||
void Start(Callback* delegate) override;
|
||||
void CaptureFrame() override;
|
||||
bool GetSourceList(SourceList* sources) override;
|
||||
bool SelectSource(SourceId id) override;
|
||||
|
||||
@ -737,12 +753,18 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
|
||||
// <-- end of PipeWire types
|
||||
|
||||
@@ -78,33 +78,37 @@ class BaseCapturerPipeWire : public Desk
|
||||
GDBusConnection* connection_ = nullptr;
|
||||
GDBusProxy* proxy_ = nullptr;
|
||||
gchar* portal_handle_ = nullptr;
|
||||
gchar* session_handle_ = nullptr;
|
||||
gchar* sources_handle_ = nullptr;
|
||||
gchar* start_handle_ = nullptr;
|
||||
guint session_request_signal_id_ = 0;
|
||||
guint sources_request_signal_id_ = 0;
|
||||
guint start_request_signal_id_ = 0;
|
||||
|
||||
+ bool video_crop_size_initialized_ = false;
|
||||
+ DesktopSize video_crop_size_;;
|
||||
+ bool video_metadata_use_ = false;
|
||||
+ DesktopSize video_size_;
|
||||
DesktopSize desktop_size_ = {};
|
||||
DesktopCaptureOptions options_ = {};
|
||||
|
||||
@ -766,7 +788,6 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
- pw_remote_state old_state,
|
||||
- pw_remote_state state,
|
||||
- const char* error);
|
||||
+ static void SyncDmaBuf(int fd, uint64_t start_or_end);
|
||||
+ static void OnCoreError(void *data,
|
||||
+ uint32_t id,
|
||||
+ int seq,
|
||||
@ -784,10 +805,20 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/ba
|
||||
static void OnStreamProcess(void* data);
|
||||
static void OnNewBuffer(void* data, uint32_t id);
|
||||
|
||||
diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc.firefox-pipewire-0-3 firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc
|
||||
--- firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc.firefox-pipewire-0-3 2020-09-15 03:48:32.000000000 +0200
|
||||
+++ firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc 2020-09-15 14:40:00.722481420 +0200
|
||||
@@ -15,7 +15,7 @@
|
||||
guint SetupRequestResponseSignal(const gchar* object_path,
|
||||
GDBusSignalCallback callback);
|
||||
|
||||
static void OnProxyRequested(GObject* object,
|
||||
GAsyncResult* result,
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc b/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc
|
||||
@@ -10,17 +10,17 @@
|
||||
|
||||
#include "modules/desktop_capture/linux/screen_capturer_pipewire.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
ScreenCapturerPipeWire::ScreenCapturerPipeWire()
|
||||
@ -796,10 +827,20 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/sc
|
||||
ScreenCapturerPipeWire::~ScreenCapturerPipeWire() {}
|
||||
|
||||
// static
|
||||
diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc.firefox-pipewire-0-3 firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc
|
||||
--- firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc.firefox-pipewire-0-3 2020-09-15 03:48:32.000000000 +0200
|
||||
+++ firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc 2020-09-15 14:40:00.722481420 +0200
|
||||
@@ -15,7 +15,7 @@
|
||||
std::unique_ptr<DesktopCapturer>
|
||||
ScreenCapturerPipeWire::CreateRawScreenCapturer(
|
||||
const DesktopCaptureOptions& options) {
|
||||
return std::make_unique<ScreenCapturerPipeWire>();
|
||||
}
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc b/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc
|
||||
@@ -10,17 +10,17 @@
|
||||
|
||||
#include "modules/desktop_capture/linux/window_capturer_pipewire.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
WindowCapturerPipeWire::WindowCapturerPipeWire()
|
||||
@ -808,10 +849,20 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/linux/wi
|
||||
WindowCapturerPipeWire::~WindowCapturerPipeWire() {}
|
||||
|
||||
// static
|
||||
diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc.firefox-pipewire-0-3 firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc
|
||||
--- firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc.firefox-pipewire-0-3 2020-09-15 03:48:32.000000000 +0200
|
||||
+++ firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_capturer_linux.cc 2020-09-15 14:40:00.722481420 +0200
|
||||
@@ -26,7 +26,7 @@ std::unique_ptr<DesktopCapturer> Desktop
|
||||
std::unique_ptr<DesktopCapturer>
|
||||
WindowCapturerPipeWire::CreateRawWindowCapturer(
|
||||
const DesktopCaptureOptions& options) {
|
||||
return std::make_unique<WindowCapturerPipeWire>();
|
||||
}
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/screen_capturer_linux.cc b/third_party/libwebrtc/webrtc/modules/desktop_capture/screen_capturer_linux.cc
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/screen_capturer_linux.cc
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/screen_capturer_linux.cc
|
||||
@@ -21,17 +21,17 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// static
|
||||
std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawScreenCapturer(
|
||||
const DesktopCaptureOptions& options) {
|
||||
#if defined(WEBRTC_USE_PIPEWIRE)
|
||||
if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) {
|
||||
@ -820,10 +871,20 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/screen_c
|
||||
}
|
||||
#endif // defined(WEBRTC_USE_PIPEWIRE)
|
||||
|
||||
diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc.firefox-pipewire-0-3 firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc
|
||||
--- firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc.firefox-pipewire-0-3 2020-09-15 03:48:32.000000000 +0200
|
||||
+++ firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_capturer_linux.cc 2020-09-15 14:40:00.722481420 +0200
|
||||
@@ -26,7 +26,7 @@ std::unique_ptr<DesktopCapturer> Desktop
|
||||
#if defined(USE_X11)
|
||||
return ScreenCapturerX11::CreateRawScreenCapturer(options);
|
||||
#endif // defined(USE_X11)
|
||||
|
||||
return nullptr;
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/window_capturer_linux.cc b/third_party/libwebrtc/webrtc/modules/desktop_capture/window_capturer_linux.cc
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/window_capturer_linux.cc
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/window_capturer_linux.cc
|
||||
@@ -21,17 +21,17 @@
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
// static
|
||||
std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
|
||||
const DesktopCaptureOptions& options) {
|
||||
#if defined(WEBRTC_USE_PIPEWIRE)
|
||||
if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) {
|
||||
@ -832,3 +893,9 @@ diff -up firefox-81.0/media/webrtc/trunk/webrtc/modules/desktop_capture/window_c
|
||||
}
|
||||
#endif // defined(WEBRTC_USE_PIPEWIRE)
|
||||
|
||||
#if defined(USE_X11)
|
||||
return WindowCapturerX11::CreateRawWindowCapturer(options);
|
||||
#endif // defined(USE_X11)
|
||||
|
||||
return nullptr;
|
||||
|
183
pw3.patch
Normal file
183
pw3.patch
Normal file
@ -0,0 +1,183 @@
|
||||
|
||||
# HG changeset patch
|
||||
# User stransky <stransky@redhat.com>
|
||||
# Date 1604562423 0
|
||||
# Node ID d1a244822d7811575f5bb3cd024f8f324275aec2
|
||||
# Parent 998e6d0b24e4a560e5664aaef87307e9c069ad87
|
||||
Bug 1672989 Build PipeWire as a part of default builds, r=dminor
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D94590
|
||||
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/BUILD.gn b/third_party/libwebrtc/webrtc/modules/desktop_capture/BUILD.gn
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/BUILD.gn
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/BUILD.gn
|
||||
@@ -152,22 +152,17 @@ if (rtc_include_tests) {
|
||||
"../../rtc_base:rtc_base_approved",
|
||||
"../../test:test_support",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (is_linux) {
|
||||
if (rtc_use_pipewire) {
|
||||
- pkg_config("pipewire") {
|
||||
- packages = [ "libpipewire-0.2" ]
|
||||
-
|
||||
- defines = [ "WEBRTC_USE_PIPEWIRE" ]
|
||||
- }
|
||||
-
|
||||
+ defines = [ "WEBRTC_USE_PIPEWIRE" ]
|
||||
pkg_config("gio") {
|
||||
packages = [
|
||||
"gio-2.0",
|
||||
"gio-unix-2.0",
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -326,16 +321,17 @@ rtc_static_library("desktop_capture_gene
|
||||
} else {
|
||||
sources += [
|
||||
"fake_desktop_capturer.cc",
|
||||
"fake_desktop_capturer.h",
|
||||
]
|
||||
}
|
||||
|
||||
if (use_x11 || rtc_use_pipewire) {
|
||||
+ include_dirs = [ "/third_party/libwebrtc/third_party/pipewire" ]
|
||||
sources += [
|
||||
"mouse_cursor_monitor_linux.cc",
|
||||
"screen_capturer_linux.cc",
|
||||
"window_capturer_linux.cc",
|
||||
]
|
||||
}
|
||||
|
||||
if (use_x11) {
|
||||
@@ -367,16 +363,17 @@ rtc_static_library("desktop_capture_gene
|
||||
"linux/desktop_device_info_x11.h",
|
||||
"linux/shared_x_util.cc",
|
||||
"linux/shared_x_util.h",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
if (rtc_use_pipewire) {
|
||||
+ include_dirs = [ "/third_party/libwebrtc/third_party/pipewire" ]
|
||||
sources += [
|
||||
"linux/base_capturer_pipewire.cc",
|
||||
"linux/base_capturer_pipewire.h",
|
||||
"linux/screen_capturer_pipewire.cc",
|
||||
"linux/screen_capturer_pipewire.h",
|
||||
"linux/window_capturer_pipewire.cc",
|
||||
"linux/window_capturer_pipewire.h",
|
||||
]
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build b/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_generic_gn/moz.build
|
||||
@@ -20,17 +20,18 @@ DEFINES["WEBRTC_RESTRICT_LOGGING"] = Tru
|
||||
FINAL_LIBRARY = "webrtc"
|
||||
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
"!/ipc/ipdl/_ipdlheaders",
|
||||
"/ipc/chromium/src",
|
||||
"/ipc/glue",
|
||||
"/media/libyuv/libyuv/include/",
|
||||
- "/third_party/libwebrtc/webrtc/"
|
||||
+ "/third_party/libwebrtc/webrtc/",
|
||||
+ "/third_party/pipewire"
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/blank_detector_desktop_capturer_wrapper.cc",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/capture_result_desktop_capturer_wrapper.cc",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/cropped_desktop_frame.cc",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/cropping_window_capturer.cc",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc",
|
||||
@@ -156,16 +157,17 @@ if CONFIG["OS_TARGET"] == "FreeBSD":
|
||||
|
||||
if CONFIG["OS_TARGET"] == "Linux":
|
||||
|
||||
DEFINES["USE_NSS_CERTS"] = "1"
|
||||
DEFINES["USE_X11"] = "1"
|
||||
DEFINES["WEBRTC_LINUX"] = True
|
||||
DEFINES["WEBRTC_POSIX"] = True
|
||||
DEFINES["_FILE_OFFSET_BITS"] = "64"
|
||||
+ DEFINES["WEBRTC_USE_PIPEWIRE"] = "1"
|
||||
|
||||
OS_LIBS += [
|
||||
"rt",
|
||||
"X11",
|
||||
"X11-xcb",
|
||||
"xcb",
|
||||
"Xcomposite",
|
||||
"Xcursor",
|
||||
@@ -188,16 +190,24 @@ if CONFIG["OS_TARGET"] == "Linux":
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/x_atom_cache.cc",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/x_error_trap.cc",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/x_server_pixel_buffer.cc",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/mouse_cursor_monitor_linux.cc",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/screen_capturer_linux.cc",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/window_capturer_linux.cc"
|
||||
]
|
||||
|
||||
+ CXXFLAGS += CONFIG['TK_CFLAGS']
|
||||
+
|
||||
+ UNIFIED_SOURCES += [
|
||||
+ "/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc",
|
||||
+ "/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/screen_capturer_pipewire.cc",
|
||||
+ "/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/window_capturer_pipewire.cc"
|
||||
+ ]
|
||||
+
|
||||
if CONFIG["OS_TARGET"] == "NetBSD":
|
||||
|
||||
DEFINES["USE_X11"] = "1"
|
||||
DEFINES["WEBRTC_BSD"] = True
|
||||
DEFINES["WEBRTC_POSIX"] = True
|
||||
DEFINES["_FILE_OFFSET_BITS"] = "64"
|
||||
|
||||
OS_LIBS += [
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_options.h b/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_options.h
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_options.h
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_options.h
|
||||
@@ -136,15 +136,15 @@ class DesktopCaptureOptions {
|
||||
#if defined(USE_X11)
|
||||
bool use_update_notifications_ = false;
|
||||
#else
|
||||
bool use_update_notifications_ = true;
|
||||
#endif
|
||||
bool disable_effects_ = true;
|
||||
bool detect_updated_region_ = false;
|
||||
#if defined(WEBRTC_USE_PIPEWIRE)
|
||||
- bool allow_pipewire_ = false;
|
||||
+ bool allow_pipewire_ = true;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
#endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURE_OPTIONS_H_
|
||||
diff --git a/third_party/libwebrtc/webrtc/moz.build b/third_party/libwebrtc/webrtc/moz.build
|
||||
--- a/third_party/libwebrtc/webrtc/moz.build
|
||||
+++ b/third_party/libwebrtc/webrtc/moz.build
|
||||
@@ -181,16 +181,19 @@ if CONFIG["OS_TARGET"] == "Linux":
|
||||
|
||||
DIRS += [
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_generic_gn",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_gn",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/primitives_gn",
|
||||
"/third_party/libwebrtc/webrtc/modules/video_capture/video_capture_internal_impl_gn",
|
||||
"/third_party/libwebrtc/webrtc/system_wrappers/cpu_features_linux_gn"
|
||||
]
|
||||
+ DIRS += [
|
||||
+ "/third_party/pipewire/libpipewire"
|
||||
+ ]
|
||||
|
||||
if CONFIG["OS_TARGET"] == "NetBSD":
|
||||
|
||||
DIRS += [
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_generic_gn",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capture_gn",
|
||||
"/third_party/libwebrtc/webrtc/modules/desktop_capture/primitives_gn",
|
||||
"/third_party/libwebrtc/webrtc/modules/video_capture/video_capture_internal_impl_gn"
|
||||
|
53
pw5.patch
Normal file
53
pw5.patch
Normal file
@ -0,0 +1,53 @@
|
||||
|
||||
# HG changeset patch
|
||||
# User stransky <stransky@redhat.com>
|
||||
# Date 1605025841 0
|
||||
# Node ID e04be7688dfb4fbbe8dee73e366df8bc9a5da580
|
||||
# Parent 41d3c1292480de14d05b34aa0cf2d56015994878
|
||||
Bug 1675767 [Linux] Use PipeWire on Wayland desktop, r=dminor
|
||||
|
||||
Differential Revision: https://phabricator.services.mozilla.com/D96587
|
||||
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capturer.cc b/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capturer.cc
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capturer.cc
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/desktop_capturer.cc
|
||||
@@ -72,37 +72,21 @@ std::unique_ptr<DesktopCapturer> Desktop
|
||||
if (capturer && options.detect_updated_region()) {
|
||||
capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer)));
|
||||
}
|
||||
|
||||
return capturer;
|
||||
}
|
||||
|
||||
#if defined(WEBRTC_USE_PIPEWIRE) || defined(USE_X11)
|
||||
-// Return true if Firefox is actually running with Wayland backend.
|
||||
-static bool IsWaylandDisplayUsed() {
|
||||
- const auto display = gdk_display_get_default();
|
||||
- if (display == nullptr) {
|
||||
- // We're running in headless mode.
|
||||
- return false;
|
||||
- }
|
||||
- return !GDK_IS_X11_DISPLAY(display);
|
||||
-}
|
||||
-
|
||||
-// Return true if Firefox is actually running on Wayland enabled session.
|
||||
-// It means some screensharing capabilities may be limited.
|
||||
-static bool IsWaylandSessionUsed() {
|
||||
+bool DesktopCapturer::IsRunningUnderWayland() {
|
||||
const char* xdg_session_type = getenv("XDG_SESSION_TYPE");
|
||||
if (!xdg_session_type || strncmp(xdg_session_type, "wayland", 7) != 0)
|
||||
return false;
|
||||
|
||||
if (!(getenv("WAYLAND_DISPLAY")))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
-
|
||||
-bool DesktopCapturer::IsRunningUnderWayland() {
|
||||
- return IsWaylandSessionUsed() ? IsWaylandDisplayUsed() : false;
|
||||
-}
|
||||
#endif // defined(WEBRTC_USE_PIPEWIRE) || defined(USE_X11)
|
||||
|
||||
} // namespace webrtc
|
||||
|
75
pw6.patch
Normal file
75
pw6.patch
Normal file
@ -0,0 +1,75 @@
|
||||
diff --git a/browser/actors/WebRTCParent.jsm b/browser/actors/WebRTCParent.jsm
|
||||
--- a/browser/actors/WebRTCParent.jsm
|
||||
+++ b/browser/actors/WebRTCParent.jsm
|
||||
@@ -45,6 +45,9 @@
|
||||
"nsIOSPermissionRequest"
|
||||
);
|
||||
|
||||
+const PIPEWIRE_PORTAL_NAME = "####_PIPEWIRE_PORTAL_####";
|
||||
+const PIPEWIRE_ID = 0xaffffff;
|
||||
+
|
||||
class WebRTCParent extends JSWindowActorParent {
|
||||
didDestroy() {
|
||||
webrtcUI.forgetStreamsFromBrowserContext(this.browsingContext);
|
||||
@@ -774,6 +777,23 @@
|
||||
}
|
||||
} else {
|
||||
name = device.name;
|
||||
+ // When we share content by PipeWire add only one item to the device
|
||||
+ // list. When it's selected PipeWire portal dialog is opened and
|
||||
+ // user confirms actual window/screen sharing there.
|
||||
+ // Don't mark it as scary as there's an extra confirmation step by
|
||||
+ // PipeWire portal dialog.
|
||||
+ if (name == PIPEWIRE_PORTAL_NAME && device.id == PIPEWIRE_ID) {
|
||||
+ let sawcStringId = "getUserMedia.sharePipeWirePortal.label";
|
||||
+ let item = addDeviceToList(
|
||||
+ menupopup,
|
||||
+ stringBundle.getString(sawcStringId),
|
||||
+ i,
|
||||
+ type
|
||||
+ );
|
||||
+ item.deviceId = device.id;
|
||||
+ item.mediaSource = type;
|
||||
+ break;
|
||||
+ }
|
||||
if (type == "application") {
|
||||
// The application names returned by the platform are of the form:
|
||||
// <window count>\x1e<application name>
|
||||
diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties
|
||||
--- a/browser/locales/en-US/chrome/browser/browser.properties
|
||||
+++ b/browser/locales/en-US/chrome/browser/browser.properties
|
||||
@@ -767,6 +767,7 @@
|
||||
getUserMedia.selectWindowOrScreen.accesskey=W
|
||||
getUserMedia.pickWindowOrScreen.label = Select Window or Screen
|
||||
getUserMedia.shareEntireScreen.label = Entire screen
|
||||
+getUserMedia.sharePipeWirePortal.label = Use operating system settings
|
||||
# LOCALIZATION NOTE (getUserMedia.shareMonitor.label):
|
||||
# %S is screen number (digits 1, 2, etc)
|
||||
# Example: Screen 1, Screen 2,..
|
||||
diff --git a/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc b/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
|
||||
--- a/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
|
||||
+++ b/third_party/libwebrtc/webrtc/modules/desktop_capture/linux/base_capturer_pipewire.cc
|
||||
@@ -898,17 +898,17 @@
|
||||
callback_->OnCaptureResult(Result::SUCCESS, std::move(result));
|
||||
}
|
||||
|
||||
+#define PIPEWIRE_ID 0xaffffff
|
||||
+#define PIPEWIRE_NAME "####_PIPEWIRE_PORTAL_####"
|
||||
+
|
||||
bool BaseCapturerPipeWire::GetSourceList(SourceList* sources) {
|
||||
- RTC_DCHECK(sources->size() == 0);
|
||||
- // List of available screens is already presented by the xdg-desktop-portal.
|
||||
- // But we have to add an empty source as the code expects it.
|
||||
- sources->push_back({0});
|
||||
+ sources->push_back({PIPEWIRE_ID, 0, PIPEWIRE_NAME});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseCapturerPipeWire::SelectSource(SourceId id) {
|
||||
// Screen selection is handled by the xdg-desktop-portal.
|
||||
- return true;
|
||||
+ return id == PIPEWIRE_ID;
|
||||
}
|
||||
|
||||
// static
|
||||
|
95
pw7.patch
Normal file
95
pw7.patch
Normal file
@ -0,0 +1,95 @@
|
||||
diff --git a/browser/actors/WebRTCParent.jsm b/browser/actors/WebRTCParent.jsm
|
||||
--- a/browser/actors/WebRTCParent.jsm
|
||||
+++ b/browser/actors/WebRTCParent.jsm
|
||||
@@ -756,6 +756,8 @@
|
||||
);
|
||||
menupopup.appendChild(doc.createXULElement("menuseparator"));
|
||||
|
||||
+ let isPipeWire = false;
|
||||
+
|
||||
// Build the list of 'devices'.
|
||||
let monitorIndex = 1;
|
||||
for (let i = 0; i < devices.length; ++i) {
|
||||
@@ -783,6 +785,7 @@
|
||||
// Don't mark it as scary as there's an extra confirmation step by
|
||||
// PipeWire portal dialog.
|
||||
if (name == PIPEWIRE_PORTAL_NAME && device.id == PIPEWIRE_ID) {
|
||||
+ isPipeWire = true;
|
||||
let sawcStringId = "getUserMedia.sharePipeWirePortal.label";
|
||||
let item = addDeviceToList(
|
||||
menupopup,
|
||||
@@ -908,39 +911,41 @@
|
||||
perms.EXPIRE_SESSION
|
||||
);
|
||||
|
||||
- video.deviceId = deviceId;
|
||||
- let constraints = {
|
||||
- video: { mediaSource: type, deviceId: { exact: deviceId } },
|
||||
- };
|
||||
- chromeWin.navigator.mediaDevices.getUserMedia(constraints).then(
|
||||
- stream => {
|
||||
- if (video.deviceId != deviceId) {
|
||||
- // The user has selected a different device or closed the panel
|
||||
- // before getUserMedia finished.
|
||||
- stream.getTracks().forEach(t => t.stop());
|
||||
- return;
|
||||
+ if (!isPipeWire) {
|
||||
+ video.deviceId = deviceId;
|
||||
+ let constraints = {
|
||||
+ video: { mediaSource: type, deviceId: { exact: deviceId } },
|
||||
+ };
|
||||
+ chromeWin.navigator.mediaDevices.getUserMedia(constraints).then(
|
||||
+ stream => {
|
||||
+ if (video.deviceId != deviceId) {
|
||||
+ // The user has selected a different device or closed the panel
|
||||
+ // before getUserMedia finished.
|
||||
+ stream.getTracks().forEach(t => t.stop());
|
||||
+ return;
|
||||
+ }
|
||||
+ video.srcObject = stream;
|
||||
+ video.stream = stream;
|
||||
+ doc.getElementById("webRTC-preview").hidden = false;
|
||||
+ video.onloadedmetadata = function(e) {
|
||||
+ video.play();
|
||||
+ };
|
||||
+ },
|
||||
+ err => {
|
||||
+ if (
|
||||
+ err.name == "OverconstrainedError" &&
|
||||
+ err.constraint == "deviceId"
|
||||
+ ) {
|
||||
+ // Window has disappeared since enumeration, which can happen.
|
||||
+ // No preview for you.
|
||||
+ return;
|
||||
+ }
|
||||
+ Cu.reportError(
|
||||
+ `error in preview: ${err.message} ${err.constraint}`
|
||||
+ );
|
||||
}
|
||||
- video.srcObject = stream;
|
||||
- video.stream = stream;
|
||||
- doc.getElementById("webRTC-preview").hidden = false;
|
||||
- video.onloadedmetadata = function(e) {
|
||||
- video.play();
|
||||
- };
|
||||
- },
|
||||
- err => {
|
||||
- if (
|
||||
- err.name == "OverconstrainedError" &&
|
||||
- err.constraint == "deviceId"
|
||||
- ) {
|
||||
- // Window has disappeared since enumeration, which can happen.
|
||||
- // No preview for you.
|
||||
- return;
|
||||
- }
|
||||
- Cu.reportError(
|
||||
- `error in preview: ${err.message} ${err.constraint}`
|
||||
- );
|
||||
- }
|
||||
- );
|
||||
+ );
|
||||
+ }
|
||||
};
|
||||
menupopup.addEventListener("command", menupopup._commandEventListener);
|
||||
}
|
||||
|
4
sources
4
sources
@ -1,3 +1,3 @@
|
||||
SHA512 (cbindgen-vendor.tar.xz) = f0425020e2d43a3d28b03f82bdb9719728112a2c94b1d595da384d0674ca21d0940a6f729a690434d670e598fbc6bb5193c89da0a4633a734c70dd786222e711
|
||||
SHA512 (firefox-82.0.3.source.tar.xz) = b12c35cd1aa223e481be8b79ddb6aa7949531f9dc519bb1caa492ea32c7cbf495c1dd7382692a3428c75955f911f3b8905906e77d246d9f4a0ba12bcd3155d24
|
||||
SHA512 (firefox-langpacks-82.0.3-20201109.tar.xz) = fb7a352761e860a0d754161e97c46ef7d34b30d404121042fd495d36c715c318c250eec406e26214f2816b8975772389a54d6cbeb9d98676017f9f1455139c59
|
||||
SHA512 (firefox-83.0.source.tar.xz) = 2d0cbc1b778bec6981586ea18e9558356e58678bda05efda0f4ea32f85942bfca35bfa00a28ca7be83a9ade679184394209abb53c38df3ef912d14d000df8fc8
|
||||
SHA512 (firefox-langpacks-83.0-20201112.tar.xz) = 7c8999bcdfcd1b23a7593233fec39ea617fd591ff887226feb87c5b3557749745cf6f2aa411a75a6f674423cd511effd8266e8fe76122b21536a4133325dee5c
|
||||
|
Loading…
Reference in New Issue
Block a user