Updated to 83.0, Updated PipeWire patches from mozbz#1672944

This commit is contained in:
Martin Stransky 2020-11-12 14:33:57 +01:00
parent be686cde3c
commit d6756537dd
18 changed files with 19775 additions and 1259 deletions

2
.gitignore vendored
View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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(

View File

@ -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;

View File

@ -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.

View File

@ -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()) {

View File

@ -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

View File

@ -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

View File

@ -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
View 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

View File

@ -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
View 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"

18928
pw4.patch Normal file

File diff suppressed because it is too large Load Diff

53
pw5.patch Normal file
View 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
View 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
View 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);
}

View File

@ -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