| Index: webrtc/media/base/capturerenderadapter.cc
|
| diff --git a/webrtc/media/base/capturerenderadapter.cc b/webrtc/media/base/capturerenderadapter.cc
|
| index 4eb738b0dbe601f76e514d495af393f5cb4eca3e..f8d28f792f675be05595a533bbc08725b3f16f31 100644
|
| --- a/webrtc/media/base/capturerenderadapter.cc
|
| +++ b/webrtc/media/base/capturerenderadapter.cc
|
| @@ -8,4 +8,76 @@
|
| * be found in the AUTHORS file in the root of the source tree.
|
| */
|
|
|
| -// TODO(perkj): Remove this dummy file once Chrome is not depending on it.
|
| +#include "webrtc/media/base/capturerenderadapter.h"
|
| +
|
| +#include "webrtc/base/logging.h"
|
| +#include "webrtc/media/base/videocapturer.h"
|
| +#include "webrtc/media/base/videorenderer.h"
|
| +
|
| +namespace cricket {
|
| +
|
| +CaptureRenderAdapter::CaptureRenderAdapter(VideoCapturer* video_capturer)
|
| + : video_capturer_(video_capturer) {
|
| +}
|
| +
|
| +CaptureRenderAdapter::~CaptureRenderAdapter() {
|
| + // Since the signal we're connecting to is multi-threaded,
|
| + // disconnect_all() will block until all calls are serviced, meaning any
|
| + // outstanding calls to OnVideoFrame will be done when this is done, and no
|
| + // more calls will be serviced by this.
|
| + // We do this explicitly instead of just letting the has_slots<> destructor
|
| + // take care of it because we need to do this *before* sinks_ is
|
| + // cleared by the destructor; otherwise we could mess with it while
|
| + // OnVideoFrame is running.
|
| + // We *don't* take capture_crit_ here since it could deadlock with the lock
|
| + // taken by the video frame signal.
|
| + disconnect_all();
|
| +}
|
| +
|
| +CaptureRenderAdapter* CaptureRenderAdapter::Create(
|
| + VideoCapturer* video_capturer) {
|
| + if (!video_capturer) {
|
| + return NULL;
|
| + }
|
| + CaptureRenderAdapter* return_value = new CaptureRenderAdapter(video_capturer);
|
| + return_value->Init(); // Can't fail.
|
| + return return_value;
|
| +}
|
| +
|
| +void CaptureRenderAdapter::AddSink(rtc::VideoSinkInterface<VideoFrame>* sink) {
|
| + RTC_DCHECK(sink);
|
| +
|
| + rtc::CritScope cs(&capture_crit_);
|
| + // This implements set semantics, the same renderer can only be
|
| + // added once.
|
| + // TODO(nisse): Is this really needed?
|
| + if (std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end())
|
| + sinks_.push_back(sink);
|
| +}
|
| +
|
| +void CaptureRenderAdapter::RemoveSink(
|
| + rtc::VideoSinkInterface<VideoFrame>* sink) {
|
| + RTC_DCHECK(sink);
|
| +
|
| + rtc::CritScope cs(&capture_crit_);
|
| + sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink), sinks_.end());
|
| +}
|
| +
|
| +void CaptureRenderAdapter::Init() {
|
| + video_capturer_->SignalVideoFrame.connect(
|
| + this,
|
| + &CaptureRenderAdapter::OnVideoFrame);
|
| +}
|
| +
|
| +void CaptureRenderAdapter::OnVideoFrame(VideoCapturer* capturer,
|
| + const VideoFrame* video_frame) {
|
| + rtc::CritScope cs(&capture_crit_);
|
| + if (sinks_.empty()) {
|
| + return;
|
| + }
|
| +
|
| + for (auto* sink : sinks_)
|
| + sink->OnFrame(*video_frame);
|
| +}
|
| +
|
| +} // namespace cricket
|
|
|