browser(firefox): do not leak vpx codec (#16034)

This commit is contained in:
Yury Semikhatsky 2022-07-28 13:39:34 -07:00 committed by GitHub
parent dcbcb93c26
commit b479869ddc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 52 additions and 28 deletions

View File

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

View File

@ -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<vpx_codec_ctx_t, VpxCodecDeleter>;
// 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<nsIThread> 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<WebMFileWriter> m_writer;
@ -277,7 +289,7 @@ private:
std::unique_ptr<vpx_image_t> m_image;
};
ScreencastEncoder::ScreencastEncoder(std::unique_ptr<VPXCodec>&& vpxCodec, const gfx::IntMargin& margin)
ScreencastEncoder::ScreencastEncoder(std::unique_ptr<VPXCodec> vpxCodec, const gfx::IntMargin& margin)
: m_vpxCodec(std::move(vpxCodec))
, m_margin(margin)
{
@ -314,9 +326,9 @@ RefPtr<ScreencastEncoder> 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> ScreencastEncoder::create(nsCString& errorString, cons
return nullptr;
}
std::unique_ptr<VPXCodec> vpxCodec(new VPXCodec(codec, cfg, file));
std::unique_ptr<VPXCodec> 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);
}

View File

@ -26,7 +26,7 @@ public:
static RefPtr<ScreencastEncoder> create(nsCString& errorString, const nsCString& filePath, int width, int height, const gfx::IntMargin& margin);
class VPXCodec;
ScreencastEncoder(std::unique_ptr<VPXCodec>&&, const gfx::IntMargin& margin);
ScreencastEncoder(std::unique_ptr<VPXCodec>, const gfx::IntMargin& margin);
void encodeFrame(const webrtc::VideoFrame& videoFrame);

View File

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

View File

@ -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<vpx_codec_ctx_t, VpxCodecDeleter>;
// 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<nsIThread> 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<WebMFileWriter> m_writer;
@ -277,7 +289,7 @@ private:
std::unique_ptr<vpx_image_t> m_image;
};
ScreencastEncoder::ScreencastEncoder(std::unique_ptr<VPXCodec>&& vpxCodec, const gfx::IntMargin& margin)
ScreencastEncoder::ScreencastEncoder(std::unique_ptr<VPXCodec> vpxCodec, const gfx::IntMargin& margin)
: m_vpxCodec(std::move(vpxCodec))
, m_margin(margin)
{
@ -314,9 +326,9 @@ RefPtr<ScreencastEncoder> 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> ScreencastEncoder::create(nsCString& errorString, cons
return nullptr;
}
std::unique_ptr<VPXCodec> vpxCodec(new VPXCodec(codec, cfg, file));
std::unique_ptr<VPXCodec> 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);
}

View File

@ -26,7 +26,7 @@ public:
static RefPtr<ScreencastEncoder> create(nsCString& errorString, const nsCString& filePath, int width, int height, const gfx::IntMargin& margin);
class VPXCodec;
ScreencastEncoder(std::unique_ptr<VPXCodec>&&, const gfx::IntMargin& margin);
ScreencastEncoder(std::unique_ptr<VPXCodec>, const gfx::IntMargin& margin);
void encodeFrame(const webrtc::VideoFrame& videoFrame);