browser(firefox): exclude browser controls from screencast (#2855)
This commit is contained in:
parent
39144dd5b2
commit
9640dbf2a6
|
|
@ -1,2 +1,2 @@
|
||||||
1123
|
1124
|
||||||
Changed: yurys@chromium.org Mon Jul 6 11:13:23 PDT 2020
|
Changed: yurys@chromium.org Mon Jul 6 17:16:56 PDT 2020
|
||||||
|
|
|
||||||
|
|
@ -294,7 +294,9 @@ class PageHandler {
|
||||||
|
|
||||||
const screencast = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);
|
const screencast = Cc['@mozilla.org/juggler/screencast;1'].getService(Ci.nsIScreencastService);
|
||||||
const docShell = this._pageTarget._gBrowser.ownerGlobal.docShell;
|
const docShell = this._pageTarget._gBrowser.ownerGlobal.docShell;
|
||||||
this._videoSessionId = screencast.startVideoRecording(docShell, file, width, height, scale || 0);
|
// Exclude address bar and navigation control from the video.
|
||||||
|
const rect = this._pageTarget.linkedBrowser().getBoundingClientRect();
|
||||||
|
this._videoSessionId = screencast.startVideoRecording(docShell, file, width, height, scale || 0, rect.top);
|
||||||
}
|
}
|
||||||
|
|
||||||
stopVideoRecording() {
|
stopVideoRecording() {
|
||||||
|
|
|
||||||
|
|
@ -158,9 +158,10 @@ void ivf_write_frame_header(FILE *outfile, int64_t pts, size_t frame_size) {
|
||||||
|
|
||||||
class ScreencastEncoder::VPXFrame {
|
class ScreencastEncoder::VPXFrame {
|
||||||
public:
|
public:
|
||||||
VPXFrame(rtc::scoped_refptr<webrtc::VideoFrameBuffer>&& buffer, Maybe<double> scale)
|
VPXFrame(rtc::scoped_refptr<webrtc::VideoFrameBuffer>&& buffer, Maybe<double> scale, int offsetTop)
|
||||||
: m_frameBuffer(std::move(buffer))
|
: m_frameBuffer(std::move(buffer))
|
||||||
, m_scale(scale)
|
, m_scale(scale)
|
||||||
|
, m_offsetTop(offsetTop)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void setDuration(int duration) { m_duration = duration; }
|
void setDuration(int duration) { m_duration = duration; }
|
||||||
|
|
@ -189,15 +190,15 @@ public:
|
||||||
src_width *= image->w / dst_width;
|
src_width *= image->w / dst_width;
|
||||||
dst_width = image->w;
|
dst_width = image->w;
|
||||||
}
|
}
|
||||||
int src_height = src->height();
|
int src_height = src->height() - m_offsetTop;
|
||||||
double dst_height = src_height * m_scale.value();
|
double dst_height = src_height * m_scale.value();
|
||||||
if (dst_height > image->h) {
|
if (dst_height > image->h) {
|
||||||
src_height *= image->h / dst_height;
|
src_height *= image->h / dst_height;
|
||||||
dst_height = image->h;
|
dst_height = image->h;
|
||||||
}
|
}
|
||||||
libyuv::I420Scale(src->DataY(), src->StrideY(),
|
libyuv::I420Scale(src->DataY() + m_offsetTop * src->StrideY(), src->StrideY(),
|
||||||
src->DataU(), src->StrideU(),
|
src->DataU() + (m_offsetTop + 1) / 2 * src->StrideU(), src->StrideU(),
|
||||||
src->DataV(), src->StrideV(),
|
src->DataV() + (m_offsetTop + 1) / 2 * src->StrideV(), src->StrideV(),
|
||||||
src_width, src_height,
|
src_width, src_height,
|
||||||
y_data, y_stride,
|
y_data, y_stride,
|
||||||
u_data, uv_stride,
|
u_data, uv_stride,
|
||||||
|
|
@ -206,10 +207,11 @@ public:
|
||||||
libyuv::kFilterBilinear);
|
libyuv::kFilterBilinear);
|
||||||
} else {
|
} else {
|
||||||
int width = std::min<int>(image->w, src->width());
|
int width = std::min<int>(image->w, src->width());
|
||||||
int height = std::min<int>(image->h, src->height());
|
int height = std::min<int>(image->h, src->height() - m_offsetTop);
|
||||||
libyuv::I420Copy(src->DataY(), src->StrideY(),
|
|
||||||
src->DataU(), src->StrideU(),
|
libyuv::I420Copy(src->DataY() + m_offsetTop * src->StrideY(), src->StrideY(),
|
||||||
src->DataV(), src->StrideV(),
|
src->DataU() + (m_offsetTop + 1) / 2 * src->StrideU(), src->StrideU(),
|
||||||
|
src->DataV() + (m_offsetTop + 1) / 2 * src->StrideV(), src->StrideV(),
|
||||||
y_data, y_stride,
|
y_data, y_stride,
|
||||||
u_data, uv_stride,
|
u_data, uv_stride,
|
||||||
v_data, uv_stride,
|
v_data, uv_stride,
|
||||||
|
|
@ -220,6 +222,7 @@ public:
|
||||||
private:
|
private:
|
||||||
rtc::scoped_refptr<webrtc::VideoFrameBuffer> m_frameBuffer;
|
rtc::scoped_refptr<webrtc::VideoFrameBuffer> m_frameBuffer;
|
||||||
Maybe<double> m_scale;
|
Maybe<double> m_scale;
|
||||||
|
int m_offsetTop = 0;
|
||||||
int m_duration = 0;
|
int m_duration = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -325,11 +328,10 @@ private:
|
||||||
std::unique_ptr<vpx_image_t> m_image;
|
std::unique_ptr<vpx_image_t> m_image;
|
||||||
};
|
};
|
||||||
|
|
||||||
ScreencastEncoder::ScreencastEncoder(std::unique_ptr<VPXCodec>&& vpxCodec, int width, int height, Maybe<double> scale)
|
ScreencastEncoder::ScreencastEncoder(std::unique_ptr<VPXCodec>&& vpxCodec, Maybe<double> scale, int offsetTop)
|
||||||
: m_vpxCodec(std::move(vpxCodec))
|
: m_vpxCodec(std::move(vpxCodec))
|
||||||
, m_width(width)
|
|
||||||
, m_height(height)
|
|
||||||
, m_scale(scale)
|
, m_scale(scale)
|
||||||
|
, m_offsetTop(offsetTop)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -338,10 +340,9 @@ ScreencastEncoder::~ScreencastEncoder()
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr uint32_t vp8fourcc = 0x30385056;
|
static constexpr uint32_t vp8fourcc = 0x30385056;
|
||||||
static constexpr uint32_t vp9fourcc = 0x30395056;
|
static constexpr int fps = 24;
|
||||||
static constexpr int fps = 30;
|
|
||||||
|
|
||||||
RefPtr<ScreencastEncoder> ScreencastEncoder::create(nsCString& errorString, const nsCString& filePath, int width, int height, Maybe<double> scale)
|
RefPtr<ScreencastEncoder> ScreencastEncoder::create(nsCString& errorString, const nsCString& filePath, int width, int height, Maybe<double> scale, int offsetTop)
|
||||||
{
|
{
|
||||||
const uint32_t fourcc = vp8fourcc;
|
const uint32_t fourcc = vp8fourcc;
|
||||||
vpx_codec_iface_t* codec_interface = vpx_codec_vp8_cx();
|
vpx_codec_iface_t* codec_interface = vpx_codec_vp8_cx();
|
||||||
|
|
@ -383,7 +384,7 @@ RefPtr<ScreencastEncoder> ScreencastEncoder::create(nsCString& errorString, cons
|
||||||
|
|
||||||
std::unique_ptr<VPXCodec> vpxCodec(new VPXCodec(fourcc, codec, cfg, file));
|
std::unique_ptr<VPXCodec> vpxCodec(new VPXCodec(fourcc, codec, cfg, file));
|
||||||
fprintf(stderr, "ScreencastEncoder initialized with: %s\n", vpx_codec_iface_name(codec_interface));
|
fprintf(stderr, "ScreencastEncoder initialized with: %s\n", vpx_codec_iface_name(codec_interface));
|
||||||
return new ScreencastEncoder(std::move(vpxCodec), width, height, scale);
|
return new ScreencastEncoder(std::move(vpxCodec), scale, offsetTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreencastEncoder::flushLastFrame()
|
void ScreencastEncoder::flushLastFrame()
|
||||||
|
|
@ -407,7 +408,7 @@ void ScreencastEncoder::encodeFrame(const webrtc::VideoFrame& videoFrame)
|
||||||
fprintf(stderr, "ScreencastEncoder::encodeFrame\n");
|
fprintf(stderr, "ScreencastEncoder::encodeFrame\n");
|
||||||
flushLastFrame();
|
flushLastFrame();
|
||||||
|
|
||||||
m_lastFrame = std::make_unique<VPXFrame>(videoFrame.video_frame_buffer(), m_scale);
|
m_lastFrame = std::make_unique<VPXFrame>(videoFrame.video_frame_buffer(), m_scale, m_offsetTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScreencastEncoder::finish(std::function<void()>&& callback)
|
void ScreencastEncoder::finish(std::function<void()>&& callback)
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,10 @@ class ScreencastEncoder {
|
||||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ScreencastEncoder)
|
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ScreencastEncoder)
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static RefPtr<ScreencastEncoder> create(nsCString& errorString, const nsCString& filePath, int width, int height, Maybe<double> scale);
|
static RefPtr<ScreencastEncoder> create(nsCString& errorString, const nsCString& filePath, int width, int height, Maybe<double> scale, int offsetTop);
|
||||||
|
|
||||||
class VPXCodec;
|
class VPXCodec;
|
||||||
ScreencastEncoder(std::unique_ptr<VPXCodec>&&, int width, int height, Maybe<double> scale);
|
ScreencastEncoder(std::unique_ptr<VPXCodec>&&, Maybe<double> scale, int offsetTop);
|
||||||
|
|
||||||
void encodeFrame(const webrtc::VideoFrame& videoFrame);
|
void encodeFrame(const webrtc::VideoFrame& videoFrame);
|
||||||
|
|
||||||
|
|
@ -36,9 +36,8 @@ private:
|
||||||
void flushLastFrame();
|
void flushLastFrame();
|
||||||
|
|
||||||
std::unique_ptr<VPXCodec> m_vpxCodec;
|
std::unique_ptr<VPXCodec> m_vpxCodec;
|
||||||
int m_width;
|
|
||||||
int m_height;
|
|
||||||
Maybe<double> m_scale;
|
Maybe<double> m_scale;
|
||||||
|
int m_offsetTop;
|
||||||
TimeStamp m_lastFrameTimestamp;
|
TimeStamp m_lastFrameTimestamp;
|
||||||
class VPXFrame;
|
class VPXFrame;
|
||||||
std::unique_ptr<VPXFrame> m_lastFrame;
|
std::unique_ptr<VPXFrame> m_lastFrame;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,6 @@ interface nsIDocShell;
|
||||||
[scriptable, uuid(d8c4d9e0-9462-445e-9e43-68d3872ad1de)]
|
[scriptable, uuid(d8c4d9e0-9462-445e-9e43-68d3872ad1de)]
|
||||||
interface nsIScreencastService : nsISupports
|
interface nsIScreencastService : nsISupports
|
||||||
{
|
{
|
||||||
long startVideoRecording(in nsIDocShell docShell, in ACString fileName, in uint32_t width, in uint32_t height, in double scale);
|
long startVideoRecording(in nsIDocShell docShell, in ACString fileName, in uint32_t width, in uint32_t height, in double scale, in int32_t offset_top);
|
||||||
void stopVideoRecording(in long sessionId);
|
void stopVideoRecording(in long sessionId);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,7 @@ StaticRefPtr<nsScreencastService> gScreencastService;
|
||||||
class nsScreencastService::Session : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
|
class nsScreencastService::Session : public rtc::VideoSinkInterface<webrtc::VideoFrame> {
|
||||||
public:
|
public:
|
||||||
Session(int sessionId, const nsCString& windowId, RefPtr<ScreencastEncoder>&& encoder)
|
Session(int sessionId, const nsCString& windowId, RefPtr<ScreencastEncoder>&& encoder)
|
||||||
: mSessionId(sessionId)
|
: mCaptureModule(webrtc::DesktopCaptureImpl::Create(
|
||||||
, mCaptureModule(webrtc::DesktopCaptureImpl::Create(
|
|
||||||
sessionId, windowId.get(), webrtc::CaptureDeviceType::Window))
|
sessionId, windowId.get(), webrtc::CaptureDeviceType::Window))
|
||||||
, mEncoder(std::move(encoder)) {
|
, mEncoder(std::move(encoder)) {
|
||||||
}
|
}
|
||||||
|
|
@ -71,7 +70,6 @@ class nsScreencastService::Session : public rtc::VideoSinkInterface<webrtc::Vide
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int mSessionId;
|
|
||||||
rtc::scoped_refptr<webrtc::VideoCaptureModule> mCaptureModule;
|
rtc::scoped_refptr<webrtc::VideoCaptureModule> mCaptureModule;
|
||||||
RefPtr<ScreencastEncoder> mEncoder;
|
RefPtr<ScreencastEncoder> mEncoder;
|
||||||
};
|
};
|
||||||
|
|
@ -93,7 +91,7 @@ nsScreencastService::nsScreencastService() = default;
|
||||||
nsScreencastService::~nsScreencastService() {
|
nsScreencastService::~nsScreencastService() {
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult nsScreencastService::StartVideoRecording(nsIDocShell* aDocShell, const nsACString& aFileName, uint32_t width, uint32_t height, double scale, int32_t* sessionId) {
|
nsresult nsScreencastService::StartVideoRecording(nsIDocShell* aDocShell, const nsACString& aFileName, uint32_t width, uint32_t height, double scale, int32_t offsetTop, int32_t* sessionId) {
|
||||||
MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Screencast service must be started on the Main thread.");
|
MOZ_RELEASE_ASSERT(NS_IsMainThread(), "Screencast service must be started on the Main thread.");
|
||||||
*sessionId = -1;
|
*sessionId = -1;
|
||||||
|
|
||||||
|
|
@ -124,7 +122,7 @@ nsresult nsScreencastService::StartVideoRecording(nsIDocShell* aDocShell, const
|
||||||
Maybe<double> maybeScale;
|
Maybe<double> maybeScale;
|
||||||
if (scale)
|
if (scale)
|
||||||
maybeScale = Some(scale);
|
maybeScale = Some(scale);
|
||||||
RefPtr<ScreencastEncoder> encoder = ScreencastEncoder::create(error, PromiseFlatCString(aFileName), width, height, maybeScale);
|
RefPtr<ScreencastEncoder> encoder = ScreencastEncoder::create(error, PromiseFlatCString(aFileName), width, height, maybeScale, offsetTop);
|
||||||
if (!encoder) {
|
if (!encoder) {
|
||||||
fprintf(stderr, "Failed to create ScreencastEncoder: %s\n", error.get());
|
fprintf(stderr, "Failed to create ScreencastEncoder: %s\n", error.get());
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue