Commit f73e1ca0 authored by perkj@chromium.org's avatar perkj@chromium.org

Deliver video frames on libjingle worker thread to WebRtcVideoCapturerAdapter.

This change so that WebRtcVideoCapturerAdapter receives video frames on libjingle worker thread instead of the IO-thread.

BUG= 371711, 350111

Review URL: https://codereview.chromium.org/282523003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270048 0039d316-1c4b-4281-b951-d872f2087c98
parent 18e80f7b
......@@ -601,6 +601,12 @@ void MediaStreamDependencyFactory::AddNativeAudioTrackToBlinkTrack(
is_local_track));
}
scoped_refptr<base::MessageLoopProxy>
MediaStreamDependencyFactory::GetWebRtcWorkerThread() const {
DCHECK(CalledOnValidThread());
return chrome_worker_thread_.message_loop_proxy();
}
bool MediaStreamDependencyFactory::OnControlMessageReceived(
const IPC::Message& message) {
bool handled = true;
......
......@@ -131,6 +131,8 @@ class CONTENT_EXPORT MediaStreamDependencyFactory
const blink::WebMediaStreamTrack& webkit_track,
bool is_local_track);
scoped_refptr<base::MessageLoopProxy> GetWebRtcWorkerThread() const;
protected:
// Asks the PeerConnection factory to create a Local Audio Source.
virtual scoped_refptr<webrtc::AudioSourceInterface>
......
......@@ -17,6 +17,7 @@ WebRtcVideoCapturerAdapter::WebRtcVideoCapturerAdapter(bool is_screencast)
running_(false),
buffer_(NULL),
buffer_size_(0) {
thread_checker_.DetachFromThread();
}
WebRtcVideoCapturerAdapter::~WebRtcVideoCapturerAdapter() {
......@@ -26,6 +27,7 @@ WebRtcVideoCapturerAdapter::~WebRtcVideoCapturerAdapter() {
cricket::CaptureState WebRtcVideoCapturerAdapter::Start(
const cricket::VideoFormat& capture_format) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!running_);
DVLOG(3) << " WebRtcVideoCapturerAdapter::Start w = " << capture_format.width
<< " h = " << capture_format.height;
......@@ -35,6 +37,7 @@ cricket::CaptureState WebRtcVideoCapturerAdapter::Start(
}
void WebRtcVideoCapturerAdapter::Stop() {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(3) << " WebRtcVideoCapturerAdapter::Stop ";
DCHECK(running_);
running_ = false;
......@@ -43,11 +46,13 @@ void WebRtcVideoCapturerAdapter::Stop() {
}
bool WebRtcVideoCapturerAdapter::IsRunning() {
DCHECK(thread_checker_.CalledOnValidThread());
return running_;
}
bool WebRtcVideoCapturerAdapter::GetPreferredFourccs(
std::vector<uint32>* fourccs) {
DCHECK(thread_checker_.CalledOnValidThread());
if (!fourccs)
return false;
fourccs->push_back(cricket::FOURCC_I420);
......@@ -61,6 +66,7 @@ bool WebRtcVideoCapturerAdapter::IsScreencast() const {
bool WebRtcVideoCapturerAdapter::GetBestCaptureFormat(
const cricket::VideoFormat& desired,
cricket::VideoFormat* best_format) {
DCHECK(thread_checker_.CalledOnValidThread());
DVLOG(3) << " GetBestCaptureFormat:: "
<< " w = " << desired.width
<< " h = " << desired.height;
......@@ -77,6 +83,7 @@ bool WebRtcVideoCapturerAdapter::GetBestCaptureFormat(
void WebRtcVideoCapturerAdapter::OnFrameCaptured(
const scoped_refptr<media::VideoFrame>& frame) {
DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(media::VideoFrame::I420 == frame->format() ||
media::VideoFrame::YV12 == frame->format());
if (first_frame_timestamp_ == media::kNoTimestamp())
......@@ -120,6 +127,7 @@ void WebRtcVideoCapturerAdapter::OnFrameCaptured(
void WebRtcVideoCapturerAdapter::UpdateI420Buffer(
const scoped_refptr<media::VideoFrame>& src) {
DCHECK(thread_checker_.CalledOnValidThread());
const int src_width = src->coded_size().width();
const int src_height = src->coded_size().height();
const int dst_width = src->visible_rect().width();
......
......@@ -8,6 +8,8 @@
#include <vector>
#include "base/compiler_specific.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/threading/thread_checker.h"
#include "content/common/content_export.h"
#include "media/base/video_frame.h"
#include "media/video/capture/video_capture_types.h"
......@@ -19,12 +21,18 @@ namespace content {
// used for VideoCapturing in libJingle and especially in PeerConnections.
// The class is created and destroyed on the main render thread.
// PeerConnection access cricket::VideoCapturer from a libJingle worker thread.
// An instance of WebRtcVideoCapturerAdapter is owned by an instance of
// webrtc::VideoSourceInterface in libJingle. The implementation of
// webrtc::VideoSourceInterface guarantees that this object is not deleted
// while it is still used in libJingle.
class CONTENT_EXPORT WebRtcVideoCapturerAdapter
: NON_EXPORTED_BASE(public cricket::VideoCapturer) {
public:
explicit WebRtcVideoCapturerAdapter(bool is_screencast);
virtual ~WebRtcVideoCapturerAdapter();
// OnFrameCaptured delivers video frames to libjingle. It must be called on
// libjingles worker thread.
// This method is virtual for testing purposes.
virtual void OnFrameCaptured(const scoped_refptr<media::VideoFrame>& frame);
......@@ -42,7 +50,9 @@ class CONTENT_EXPORT WebRtcVideoCapturerAdapter
void UpdateI420Buffer(const scoped_refptr<media::VideoFrame>& src);
private:
// |thread_checker_| is bound to the libjingle worker thread.
base::ThreadChecker thread_checker_;
const bool is_screencast_;
bool running_;
base::TimeDelta first_frame_timestamp_;
......
......@@ -18,17 +18,25 @@ bool ConstraintKeyExists(const blink::WebMediaConstraints& constraints,
constraints.getOptionalConstraintValue(name, value_str);
}
// Used to make sure |source| is released on the main render thread.
void ReleaseWebRtcSourceOnMainRenderThread(
webrtc::VideoSourceInterface* source) {
source->Release();
}
} // anonymouse namespace
namespace content {
// Simple help class used for receiving video frames on the IO-thread from
// a MediaStreamVideoTrack and forward the frames to a
// WebRtcVideoCapturerAdapter that implements a video capturer for libjingle.
// WebRtcVideoCapturerAdapter on libjingle's worker thread.
// WebRtcVideoCapturerAdapter implements a video capturer for libjingle.
class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter
: public base::RefCountedThreadSafe<WebRtcVideoSourceAdapter> {
public:
WebRtcVideoSourceAdapter(
const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread,
const scoped_refptr<webrtc::VideoSourceInterface>& source,
WebRtcVideoCapturerAdapter* capture_adapter);
......@@ -36,31 +44,66 @@ class WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter
const media::VideoCaptureFormat& format);
private:
void OnVideoFrameOnWorkerThread(const scoped_refptr<media::VideoFrame>& frame,
const media::VideoCaptureFormat& format);
friend class base::RefCountedThreadSafe<WebRtcVideoSourceAdapter>;
virtual ~WebRtcVideoSourceAdapter();
scoped_refptr<base::MessageLoopProxy> render_thread_message_loop_;
// Used to DCHECK that frames are called on the IO-thread.
base::ThreadChecker io_thread_checker_;
// Used for posting frames to libjingle's worker thread. Accessed on the
// IO-thread.
scoped_refptr<base::MessageLoopProxy> libjingle_worker_thread_;
scoped_refptr<webrtc::VideoSourceInterface> video_source_;
// |capture_adapter_| is owned by |video_source_|
WebRtcVideoCapturerAdapter* capture_adapter_;
};
WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::WebRtcVideoSourceAdapter(
const scoped_refptr<base::MessageLoopProxy>& libjingle_worker_thread,
const scoped_refptr<webrtc::VideoSourceInterface>& source,
WebRtcVideoCapturerAdapter* capture_adapter)
: video_source_(source),
: render_thread_message_loop_(base::MessageLoopProxy::current()),
libjingle_worker_thread_(libjingle_worker_thread),
video_source_(source),
capture_adapter_(capture_adapter) {
io_thread_checker_.DetachFromThread();
}
WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::~WebRtcVideoSourceAdapter() {
// Since frames are posted to the worker thread, this object might be deleted
// on that thread. However, since |video_source_| was created on the render
// thread, it should be released on the render thread.
if (!render_thread_message_loop_->BelongsToCurrentThread()) {
webrtc::VideoSourceInterface* source = video_source_.get();
source->AddRef();
video_source_ = NULL;
render_thread_message_loop_->PostTask(
FROM_HERE,
base::Bind(&ReleaseWebRtcSourceOnMainRenderThread,
base::Unretained(source)));
}
}
void WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnIO(
const scoped_refptr<media::VideoFrame>& frame,
const media::VideoCaptureFormat& format) {
DCHECK(io_thread_checker_.CalledOnValidThread());
libjingle_worker_thread_->PostTask(
FROM_HERE,
base::Bind(&WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread,
this, frame, format));
}
void
WebRtcVideoTrackAdapter::WebRtcVideoSourceAdapter::OnVideoFrameOnWorkerThread(
const scoped_refptr<media::VideoFrame>& frame,
const media::VideoCaptureFormat& format) {
DCHECK(libjingle_worker_thread_->BelongsToCurrentThread());
capture_adapter_->OnFrameCaptured(frame);
}
......@@ -86,8 +129,10 @@ WebRtcVideoTrackAdapter::WebRtcVideoTrackAdapter(
video_track_->set_enabled(web_track_.isEnabled());
source_adapter_ = new WebRtcVideoSourceAdapter(video_source,
capture_adapter);
source_adapter_ = new WebRtcVideoSourceAdapter(
factory->GetWebRtcWorkerThread(),
video_source,
capture_adapter);
AddToVideoTrack(
this,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment