blob: 9e928efbf1f1cf7b776fd331694d0f8eb1d6f800 [file] [log] [blame]
/*
* Copyright 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/api/videotrackrenderers.h"
#include "webrtc/media/engine/webrtcvideoframe.h"
namespace webrtc {
VideoTrackRenderers::VideoTrackRenderers() : enabled_(true) {
}
VideoTrackRenderers::~VideoTrackRenderers() {
}
void VideoTrackRenderers::AddOrUpdateSink(
VideoSinkInterface<cricket::VideoFrame>* sink,
const rtc::VideoSinkWants& wants) {
// TODO(nisse): Currently ignores wants. We should somehow use
// VideoBroadcaster, but we need to sort out its threading issues
// first.
rtc::CritScope cs(&critical_section_);
if (std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end())
sinks_.push_back(sink);
}
void VideoTrackRenderers::RemoveSink(
VideoSinkInterface<cricket::VideoFrame>* sink) {
rtc::CritScope cs(&critical_section_);
sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink), sinks_.end());
}
void VideoTrackRenderers::SetEnabled(bool enable) {
rtc::CritScope cs(&critical_section_);
enabled_ = enable;
}
bool VideoTrackRenderers::RenderFrame(const cricket::VideoFrame* frame) {
{
rtc::CritScope cs(&critical_section_);
if (enabled_) {
RenderFrameToSinks(*frame);
return true;
}
}
// Generate the black frame outside of the critical section. Note
// that this may result in unexpected frame order, in the unlikely
// case that RenderFrame is called from multiple threads without
// proper serialization, and the track is switched from disabled to
// enabled in the middle of the first call.
cricket::WebRtcVideoFrame black(new rtc::RefCountedObject<I420Buffer>(
static_cast<int>(frame->GetWidth()),
static_cast<int>(frame->GetHeight())),
frame->GetTimeStamp(),
frame->GetVideoRotation());
black.SetToBlack();
{
rtc::CritScope cs(&critical_section_);
// Check enabled_ flag again, since the track might have been
// enabled while we generated the black frame. I think the
// enabled-ness ought to be applied at the track output, and hence
// an enabled track shouldn't send any blacked out frames.
RenderFrameToSinks(enabled_ ? *frame : black);
return true;
}
}
// Called with critical_section_ already locked
void VideoTrackRenderers::RenderFrameToSinks(const cricket::VideoFrame& frame) {
for (auto sink : sinks_) {
sink->OnFrame(frame);
}
}
} // namespace webrtc