Use rtc::scoped_refptr for WebRtcVideoCapturer.

Un-breaks peerconnection_client which would instantly use-after-free on
an allocated VCM because it wasn't building a scoped_refptr so all
references to the VCM were dropped.

BUG=webrtc:5229
TBR=tommi@webrtc.org
TEST=Run peerconnection_client locally, verify that there's no crash.

Review URL: https://codereview.webrtc.org/1817953005 .

Cr-Commit-Position: refs/heads/master@{#12088}
This commit is contained in:
Peter Boström 2016-03-22 17:17:39 +01:00
parent 2943f015b6
commit 09c3a1e291
4 changed files with 21 additions and 26 deletions

View File

@ -21,11 +21,13 @@
// WebRtcVideoCapturer.
class FakeWebRtcVcmFactory : public cricket::WebRtcVcmFactoryInterface {
public:
virtual webrtc::VideoCaptureModule* Create(int module_id,
const char* device_id) {
virtual rtc::scoped_refptr<webrtc::VideoCaptureModule> Create(
int module_id,
const char* device_id) {
if (!device_info.GetDeviceById(device_id)) return NULL;
FakeWebRtcVideoCaptureModule* module =
new FakeWebRtcVideoCaptureModule(this, module_id);
rtc::scoped_refptr<FakeWebRtcVideoCaptureModule> module(
new rtc::RefCountedObject<FakeWebRtcVideoCaptureModule>(this,
module_id));
modules.push_back(module);
return module;
}
@ -38,7 +40,7 @@ class FakeWebRtcVcmFactory : public cricket::WebRtcVcmFactoryInterface {
std::remove(modules.begin(), modules.end(), module);
}
FakeWebRtcDeviceInfo device_info;
std::vector<FakeWebRtcVideoCaptureModule*> modules;
std::vector<rtc::scoped_refptr<FakeWebRtcVideoCaptureModule>> modules;
};
FakeWebRtcVideoCaptureModule::~FakeWebRtcVideoCaptureModule() {

View File

@ -28,6 +28,7 @@ class FakeWebRtcVideoCaptureModule : public webrtc::VideoCaptureModule {
running_(false),
delay_(0) {
}
~FakeWebRtcVideoCaptureModule();
int64_t TimeUntilNextProcess() override { return 0; }
void Process() override {}
void RegisterCaptureDataCallback(
@ -83,11 +84,6 @@ class FakeWebRtcVideoCaptureModule : public webrtc::VideoCaptureModule {
const webrtc::VideoCodec& codec) override {
return NULL; // not implemented
}
int32_t AddRef() const override { return 0; }
int32_t Release() const override {
delete this;
return 0;
}
void SendFrame(int w, int h) {
if (!running_) return;
@ -104,9 +100,6 @@ class FakeWebRtcVideoCaptureModule : public webrtc::VideoCaptureModule {
}
private:
// Ref-counted, use Release() instead.
~FakeWebRtcVideoCaptureModule();
FakeWebRtcVcmFactory* factory_;
int id_;
webrtc::VideoCaptureDataCallback* callback_;

View File

@ -52,7 +52,9 @@ static kVideoFourCCEntry kSupportedFourCCs[] = {
class WebRtcVcmFactory : public WebRtcVcmFactoryInterface {
public:
virtual webrtc::VideoCaptureModule* Create(int id, const char* device) {
virtual rtc::scoped_refptr<webrtc::VideoCaptureModule> Create(
int id,
const char* device) {
return webrtc::VideoCaptureFactory::Create(id, device);
}
virtual webrtc::VideoCaptureModule::DeviceInfo* CreateDeviceInfo(int id) {
@ -128,11 +130,7 @@ WebRtcVideoCapturer::WebRtcVideoCapturer(WebRtcVcmFactoryInterface* factory)
set_frame_factory(new WebRtcVideoFrameFactory());
}
WebRtcVideoCapturer::~WebRtcVideoCapturer() {
if (module_) {
module_->Release();
}
}
WebRtcVideoCapturer::~WebRtcVideoCapturer() {}
bool WebRtcVideoCapturer::Init(const Device& device) {
RTC_DCHECK(!start_thread_);
@ -198,14 +196,14 @@ bool WebRtcVideoCapturer::Init(const Device& device) {
}
// It is safe to change member attributes now.
module_->AddRef();
SetId(device.id);
SetSupportedFormats(supported);
return true;
}
bool WebRtcVideoCapturer::Init(webrtc::VideoCaptureModule* module) {
bool WebRtcVideoCapturer::Init(
const rtc::scoped_refptr<webrtc::VideoCaptureModule>& module) {
RTC_DCHECK(!start_thread_);
if (module_) {
LOG(LS_ERROR) << "The capturer is already initialized";
@ -216,7 +214,7 @@ bool WebRtcVideoCapturer::Init(webrtc::VideoCaptureModule* module) {
return false;
}
// TODO(juberti): Set id and formats.
(module_ = module)->AddRef();
module_ = module;
return true;
}

View File

@ -17,6 +17,7 @@
#include "webrtc/base/asyncinvoker.h"
#include "webrtc/base/messagehandler.h"
#include "webrtc/base/scoped_ref_ptr.h"
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
#include "webrtc/media/base/device.h"
#include "webrtc/media/base/videocapturer.h"
@ -30,8 +31,9 @@ namespace cricket {
class WebRtcVcmFactoryInterface {
public:
virtual ~WebRtcVcmFactoryInterface() {}
virtual webrtc::VideoCaptureModule* Create(
int id, const char* device) = 0;
virtual rtc::scoped_refptr<webrtc::VideoCaptureModule> Create(
int id,
const char* device) = 0;
virtual webrtc::VideoCaptureModule::DeviceInfo* CreateDeviceInfo(int id) = 0;
virtual void DestroyDeviceInfo(
webrtc::VideoCaptureModule::DeviceInfo* info) = 0;
@ -46,7 +48,7 @@ class WebRtcVideoCapturer : public VideoCapturer,
virtual ~WebRtcVideoCapturer();
bool Init(const Device& device);
bool Init(webrtc::VideoCaptureModule* module);
bool Init(const rtc::scoped_refptr<webrtc::VideoCaptureModule>& module);
// Override virtual methods of the parent class VideoCapturer.
bool GetBestCaptureFormat(const VideoFormat& desired,
@ -77,7 +79,7 @@ class WebRtcVideoCapturer : public VideoCapturer,
void SignalFrameCapturedOnStartThread(const webrtc::VideoFrame& frame);
std::unique_ptr<WebRtcVcmFactoryInterface> factory_;
webrtc::VideoCaptureModule* module_;
rtc::scoped_refptr<webrtc::VideoCaptureModule> module_;
int captured_frames_;
std::vector<uint8_t> capture_buffer_;
rtc::Thread* start_thread_; // Set in Start(), unset in Stop();