diff --git a/browser_patches/firefox/BUILD_NUMBER b/browser_patches/firefox/BUILD_NUMBER index 52fbedfa71..a1a6c96a89 100644 --- a/browser_patches/firefox/BUILD_NUMBER +++ b/browser_patches/firefox/BUILD_NUMBER @@ -1,2 +1,2 @@ -1194 -Changed: joel.einbinder@gmail.com Fri 16 Oct 2020 01:52:53 AM PDT +1195 +Changed: yurys@chromium.org Tue Oct 20 13:36:31 PDT 2020 diff --git a/browser_patches/firefox/juggler/screencast/ScreencastEncoder.cpp b/browser_patches/firefox/juggler/screencast/ScreencastEncoder.cpp index e281857211..b2457e058a 100644 --- a/browser_patches/firefox/juggler/screencast/ScreencastEncoder.cpp +++ b/browser_patches/firefox/juggler/screencast/ScreencastEncoder.cpp @@ -43,6 +43,10 @@ namespace mozilla { namespace { + +// Number of timebase unints per one frame. +constexpr int timeScale = 1000; + // Defines the dimension of a macro block. This is used to compute the active // map for the encoder. const int kMacroBlockSize = 16; @@ -111,8 +115,8 @@ public: , m_margin(margin) { } - void setDuration(int duration) { m_duration = duration; } - int duration() const { return m_duration; } + void setDuration(TimeDuration duration) { m_duration = duration; } + TimeDuration duration() const { return m_duration; } void convertToVpxImage(vpx_image_t* image) { @@ -171,7 +175,7 @@ private: rtc::scoped_refptr m_frameBuffer; Maybe m_scale; gfx::IntMargin m_margin; - int m_duration = 0; + TimeDuration m_duration; }; @@ -202,7 +206,14 @@ public: m_encoderQueue->Dispatch(NS_NewRunnableFunction("VPXCodec::encodeFrameAsync", [this, frame = std::move(frame)] { memset(m_imageBuffer.get(), 128, m_imageBufferSize); frame->convertToVpxImage(m_image.get()); - encodeFrame(m_image.get(), frame->duration()); + + double frameCount = frame->duration().ToSeconds() * fps; + // For long duration repeat frame at 1 fps to ensure last frame duration is short enough. + // TODO: figure out why simply passing duration doesn't work well. + for (;frameCount > 1.5; frameCount -= 1) { + encodeFrame(m_image.get(), timeScale); + } + encodeFrame(m_image.get(), std::max(1, frameCount * timeScale)); })); } @@ -276,8 +287,6 @@ ScreencastEncoder::~ScreencastEncoder() { } -static constexpr int fps = 24; - RefPtr ScreencastEncoder::create(nsCString& errorString, const nsCString& filePath, int width, int height, Maybe scale, const gfx::IntMargin& margin) { vpx_codec_iface_t* codec_interface = vpx_codec_vp8_cx(); @@ -302,7 +311,7 @@ RefPtr ScreencastEncoder::create(nsCString& errorString, cons cfg.g_w = width; cfg.g_h = height; cfg.g_timebase.num = 1; - cfg.g_timebase.den = fps; + cfg.g_timebase.den = fps * timeScale; cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT; vpx_codec_ctx_t codec; @@ -330,9 +339,7 @@ void ScreencastEncoder::flushLastFrame() if (!m_lastFrame) return; - TimeDuration seconds = now - m_lastFrameTimestamp; - int duration = 1 + seconds.ToSeconds() * fps; // Duration in timebase units - m_lastFrame->setDuration(duration); + m_lastFrame->setDuration(now - m_lastFrameTimestamp); m_vpxCodec->encodeFrameAsync(std::move(m_lastFrame)); } m_lastFrameTimestamp = now; diff --git a/browser_patches/firefox/juggler/screencast/ScreencastEncoder.h b/browser_patches/firefox/juggler/screencast/ScreencastEncoder.h index afdd1b284d..b6827800bc 100644 --- a/browser_patches/firefox/juggler/screencast/ScreencastEncoder.h +++ b/browser_patches/firefox/juggler/screencast/ScreencastEncoder.h @@ -21,6 +21,7 @@ namespace mozilla { class ScreencastEncoder { NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ScreencastEncoder) public: + static constexpr int fps = 25; static RefPtr create(nsCString& errorString, const nsCString& filePath, int width, int height, Maybe scale, const gfx::IntMargin& margin); diff --git a/browser_patches/firefox/juggler/screencast/nsScreencastService.cpp b/browser_patches/firefox/juggler/screencast/nsScreencastService.cpp index c4923eba35..7cd810e08d 100644 --- a/browser_patches/firefox/juggler/screencast/nsScreencastService.cpp +++ b/browser_patches/firefox/juggler/screencast/nsScreencastService.cpp @@ -92,7 +92,7 @@ class nsScreencastService::Session : public rtc::VideoSinkInterfaceStartCapture(capability); if (error) {