From b479869ddcfe2ce0ab64ddc867e14cbac1b32095 Mon Sep 17 00:00:00 2001 From: Yury Semikhatsky Date: Thu, 28 Jul 2022 13:39:34 -0700 Subject: [PATCH] browser(firefox): do not leak vpx codec (#16034) --- browser_patches/firefox-beta/BUILD_NUMBER | 4 +-- .../juggler/screencast/ScreencastEncoder.cpp | 34 +++++++++++++------ .../juggler/screencast/ScreencastEncoder.h | 2 +- browser_patches/firefox/BUILD_NUMBER | 4 +-- .../juggler/screencast/ScreencastEncoder.cpp | 34 +++++++++++++------ .../juggler/screencast/ScreencastEncoder.h | 2 +- 6 files changed, 52 insertions(+), 28 deletions(-) diff --git a/browser_patches/firefox-beta/BUILD_NUMBER b/browser_patches/firefox-beta/BUILD_NUMBER index 98f85a02dd..1e802310ff 100644 --- a/browser_patches/firefox-beta/BUILD_NUMBER +++ b/browser_patches/firefox-beta/BUILD_NUMBER @@ -1,2 +1,2 @@ -1336 -Changed: lushnikov@chromium.org Tue Jul 26 17:42:25 MSK 2022 +1337 +Changed: yurys@chromium.org Thu Jul 28 13:35:27 PDT 2022 diff --git a/browser_patches/firefox-beta/juggler/screencast/ScreencastEncoder.cpp b/browser_patches/firefox-beta/juggler/screencast/ScreencastEncoder.cpp index a217cf9559..582813e35b 100644 --- a/browser_patches/firefox-beta/juggler/screencast/ScreencastEncoder.cpp +++ b/browser_patches/firefox-beta/juggler/screencast/ScreencastEncoder.cpp @@ -45,6 +45,18 @@ namespace mozilla { namespace { +struct VpxCodecDeleter { + void operator()(vpx_codec_ctx_t* codec) { + if (codec) { + vpx_codec_err_t ret = vpx_codec_destroy(codec); + if (ret != VPX_CODEC_OK) + fprintf(stderr, "Failed to destroy codec: %s\n", vpx_codec_error(codec)); + } + } +}; + +using ScopedVpxCodec = std::unique_ptr; + // Number of timebase unints per one frame. constexpr int timeScale = 1000; @@ -183,8 +195,8 @@ private: class ScreencastEncoder::VPXCodec { public: - VPXCodec(vpx_codec_ctx_t codec, vpx_codec_enc_cfg_t cfg, FILE* file) - : m_codec(codec) + VPXCodec(ScopedVpxCodec codec, vpx_codec_enc_cfg_t cfg, FILE* file) + : m_codec(std::move(codec)) , m_cfg(cfg) , m_file(file) , m_writer(new WebMFileWriter(file, &m_cfg)) @@ -233,14 +245,14 @@ private: vpx_codec_iter_t iter = nullptr; const vpx_codec_cx_pkt_t *pkt = nullptr; int flags = 0; - const vpx_codec_err_t res = vpx_codec_encode(&m_codec, img, m_pts, duration, flags, VPX_DL_REALTIME); + const vpx_codec_err_t res = vpx_codec_encode(m_codec.get(), img, m_pts, duration, flags, VPX_DL_REALTIME); if (res != VPX_CODEC_OK) { - fprintf(stderr, "Failed to encode frame: %s\n", vpx_codec_error(&m_codec)); + fprintf(stderr, "Failed to encode frame: %s\n", vpx_codec_error(m_codec.get())); return false; } bool gotPkts = false; - while ((pkt = vpx_codec_get_cx_data(&m_codec, &iter)) != nullptr) { + while ((pkt = vpx_codec_get_cx_data(m_codec.get(), &iter)) != nullptr) { gotPkts = true; if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { @@ -266,7 +278,7 @@ private: } RefPtr m_encoderQueue; - vpx_codec_ctx_t m_codec; + ScopedVpxCodec m_codec; vpx_codec_enc_cfg_t m_cfg; FILE* m_file { nullptr }; std::unique_ptr m_writer; @@ -277,7 +289,7 @@ private: std::unique_ptr m_image; }; -ScreencastEncoder::ScreencastEncoder(std::unique_ptr&& vpxCodec, const gfx::IntMargin& margin) +ScreencastEncoder::ScreencastEncoder(std::unique_ptr vpxCodec, const gfx::IntMargin& margin) : m_vpxCodec(std::move(vpxCodec)) , m_margin(margin) { @@ -314,9 +326,9 @@ RefPtr ScreencastEncoder::create(nsCString& errorString, cons cfg.g_timebase.den = fps * timeScale; cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT; - vpx_codec_ctx_t codec; - if (vpx_codec_enc_init(&codec, codec_interface, &cfg, 0)) { - errorString.AppendPrintf("Failed to initialize encoder: %s", vpx_codec_error(&codec)); + ScopedVpxCodec codec(new vpx_codec_ctx_t); + if (vpx_codec_enc_init(codec.get(), codec_interface, &cfg, 0)) { + errorString.AppendPrintf("Failed to initialize encoder: %s", vpx_codec_error(codec.get())); return nullptr; } @@ -326,7 +338,7 @@ RefPtr ScreencastEncoder::create(nsCString& errorString, cons return nullptr; } - std::unique_ptr vpxCodec(new VPXCodec(codec, cfg, file)); + std::unique_ptr vpxCodec(new VPXCodec(std::move(codec), cfg, file)); // fprintf(stderr, "ScreencastEncoder initialized with: %s\n", vpx_codec_iface_name(codec_interface)); return new ScreencastEncoder(std::move(vpxCodec), margin); } diff --git a/browser_patches/firefox-beta/juggler/screencast/ScreencastEncoder.h b/browser_patches/firefox-beta/juggler/screencast/ScreencastEncoder.h index bfc9b69e76..07b99f2fdc 100644 --- a/browser_patches/firefox-beta/juggler/screencast/ScreencastEncoder.h +++ b/browser_patches/firefox-beta/juggler/screencast/ScreencastEncoder.h @@ -26,7 +26,7 @@ public: static RefPtr create(nsCString& errorString, const nsCString& filePath, int width, int height, const gfx::IntMargin& margin); class VPXCodec; - ScreencastEncoder(std::unique_ptr&&, const gfx::IntMargin& margin); + ScreencastEncoder(std::unique_ptr, const gfx::IntMargin& margin); void encodeFrame(const webrtc::VideoFrame& videoFrame); diff --git a/browser_patches/firefox/BUILD_NUMBER b/browser_patches/firefox/BUILD_NUMBER index 98f85a02dd..0550830b0d 100644 --- a/browser_patches/firefox/BUILD_NUMBER +++ b/browser_patches/firefox/BUILD_NUMBER @@ -1,2 +1,2 @@ -1336 -Changed: lushnikov@chromium.org Tue Jul 26 17:42:25 MSK 2022 +1337 +Changed: yurys@chromium.org Thu Jul 28 13:34:25 PDT 2022 diff --git a/browser_patches/firefox/juggler/screencast/ScreencastEncoder.cpp b/browser_patches/firefox/juggler/screencast/ScreencastEncoder.cpp index a217cf9559..582813e35b 100644 --- a/browser_patches/firefox/juggler/screencast/ScreencastEncoder.cpp +++ b/browser_patches/firefox/juggler/screencast/ScreencastEncoder.cpp @@ -45,6 +45,18 @@ namespace mozilla { namespace { +struct VpxCodecDeleter { + void operator()(vpx_codec_ctx_t* codec) { + if (codec) { + vpx_codec_err_t ret = vpx_codec_destroy(codec); + if (ret != VPX_CODEC_OK) + fprintf(stderr, "Failed to destroy codec: %s\n", vpx_codec_error(codec)); + } + } +}; + +using ScopedVpxCodec = std::unique_ptr; + // Number of timebase unints per one frame. constexpr int timeScale = 1000; @@ -183,8 +195,8 @@ private: class ScreencastEncoder::VPXCodec { public: - VPXCodec(vpx_codec_ctx_t codec, vpx_codec_enc_cfg_t cfg, FILE* file) - : m_codec(codec) + VPXCodec(ScopedVpxCodec codec, vpx_codec_enc_cfg_t cfg, FILE* file) + : m_codec(std::move(codec)) , m_cfg(cfg) , m_file(file) , m_writer(new WebMFileWriter(file, &m_cfg)) @@ -233,14 +245,14 @@ private: vpx_codec_iter_t iter = nullptr; const vpx_codec_cx_pkt_t *pkt = nullptr; int flags = 0; - const vpx_codec_err_t res = vpx_codec_encode(&m_codec, img, m_pts, duration, flags, VPX_DL_REALTIME); + const vpx_codec_err_t res = vpx_codec_encode(m_codec.get(), img, m_pts, duration, flags, VPX_DL_REALTIME); if (res != VPX_CODEC_OK) { - fprintf(stderr, "Failed to encode frame: %s\n", vpx_codec_error(&m_codec)); + fprintf(stderr, "Failed to encode frame: %s\n", vpx_codec_error(m_codec.get())); return false; } bool gotPkts = false; - while ((pkt = vpx_codec_get_cx_data(&m_codec, &iter)) != nullptr) { + while ((pkt = vpx_codec_get_cx_data(m_codec.get(), &iter)) != nullptr) { gotPkts = true; if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) { @@ -266,7 +278,7 @@ private: } RefPtr m_encoderQueue; - vpx_codec_ctx_t m_codec; + ScopedVpxCodec m_codec; vpx_codec_enc_cfg_t m_cfg; FILE* m_file { nullptr }; std::unique_ptr m_writer; @@ -277,7 +289,7 @@ private: std::unique_ptr m_image; }; -ScreencastEncoder::ScreencastEncoder(std::unique_ptr&& vpxCodec, const gfx::IntMargin& margin) +ScreencastEncoder::ScreencastEncoder(std::unique_ptr vpxCodec, const gfx::IntMargin& margin) : m_vpxCodec(std::move(vpxCodec)) , m_margin(margin) { @@ -314,9 +326,9 @@ RefPtr ScreencastEncoder::create(nsCString& errorString, cons cfg.g_timebase.den = fps * timeScale; cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT; - vpx_codec_ctx_t codec; - if (vpx_codec_enc_init(&codec, codec_interface, &cfg, 0)) { - errorString.AppendPrintf("Failed to initialize encoder: %s", vpx_codec_error(&codec)); + ScopedVpxCodec codec(new vpx_codec_ctx_t); + if (vpx_codec_enc_init(codec.get(), codec_interface, &cfg, 0)) { + errorString.AppendPrintf("Failed to initialize encoder: %s", vpx_codec_error(codec.get())); return nullptr; } @@ -326,7 +338,7 @@ RefPtr ScreencastEncoder::create(nsCString& errorString, cons return nullptr; } - std::unique_ptr vpxCodec(new VPXCodec(codec, cfg, file)); + std::unique_ptr vpxCodec(new VPXCodec(std::move(codec), cfg, file)); // fprintf(stderr, "ScreencastEncoder initialized with: %s\n", vpx_codec_iface_name(codec_interface)); return new ScreencastEncoder(std::move(vpxCodec), margin); } diff --git a/browser_patches/firefox/juggler/screencast/ScreencastEncoder.h b/browser_patches/firefox/juggler/screencast/ScreencastEncoder.h index bfc9b69e76..07b99f2fdc 100644 --- a/browser_patches/firefox/juggler/screencast/ScreencastEncoder.h +++ b/browser_patches/firefox/juggler/screencast/ScreencastEncoder.h @@ -26,7 +26,7 @@ public: static RefPtr create(nsCString& errorString, const nsCString& filePath, int width, int height, const gfx::IntMargin& margin); class VPXCodec; - ScreencastEncoder(std::unique_ptr&&, const gfx::IntMargin& margin); + ScreencastEncoder(std::unique_ptr, const gfx::IntMargin& margin); void encodeFrame(const webrtc::VideoFrame& videoFrame);