Chromium Code Reviews| Index: remoting/protocol/webrtc_video_renderer_adapter.cc |
| diff --git a/remoting/protocol/webrtc_video_renderer_adapter.cc b/remoting/protocol/webrtc_video_renderer_adapter.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..785e9c7a3e214df35dfb531c3fbd68b1371e48b7 |
| --- /dev/null |
| +++ b/remoting/protocol/webrtc_video_renderer_adapter.cc |
| @@ -0,0 +1,75 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "remoting/protocol/webrtc_video_renderer_adapter.h" |
| + |
| +#include <utility> |
| + |
| +#include "base/bind.h" |
| +#include "base/callback.h" |
| +#include "base/location.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/single_thread_task_runner.h" |
| +#include "base/thread_task_runner_handle.h" |
| +#include "remoting/protocol/frame_consumer.h" |
| +#include "third_party/libjingle/source/talk/media/base/videoframe.h" |
| +#include "third_party/libyuv/include/libyuv/video_common.h" |
| +#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
| + |
| +namespace remoting { |
| +namespace protocol { |
| + |
| +WebrtcVideoRendererAdapter::WebrtcVideoRendererAdapter( |
| + scoped_refptr<webrtc::MediaStreamInterface> media_stream, |
| + FrameConsumer* frame_consumer) |
| + : media_stream_(std::move(media_stream)), |
| + frame_consumer_(frame_consumer), |
| + output_format_fourcc_(frame_consumer_->GetPixelFormat() == |
| + FrameConsumer::FORMAT_BGRA |
| + ? libyuv::FOURCC_ARGB |
| + : libyuv::FOURCC_ABGR), |
| + task_runner_(base::ThreadTaskRunnerHandle::Get()), |
| + weak_factory_(this) { |
| + webrtc::VideoTrackVector video_tracks = media_stream_->GetVideoTracks(); |
| + if (video_tracks.empty()) { |
| + LOG(ERROR) << "Received media stream with no video tracks."; |
| + return; |
| + } |
| + |
| + video_tracks[0]->AddRenderer(this); |
|
Jamie
2016/01/12 21:00:04
Also LOG(ERROR) if there's more than 1?
Sergey Ulanov
2016/01/12 22:13:45
Done.
|
| +} |
| + |
| +WebrtcVideoRendererAdapter::~WebrtcVideoRendererAdapter() { |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| +} |
| + |
| +void WebrtcVideoRendererAdapter::RenderFrame(const cricket::VideoFrame* frame) { |
| + // TODO(sergeyu): WebRTC calls RenderFrame on a separate thread it creates. |
| + // FrameConsumer normally expects to be called on the network thread, so we |
| + // cannot call FrameConsumer::AllocateFrame() here and instead |
| + // BasicDesktopFrame is created directly. This will not correctly with all |
| + // FrameConsumer implementations. Fix this somehow. |
|
Jamie
2016/01/12 21:00:04
It doesn't need to be this CL, but why not just bo
Sergey Ulanov
2016/01/12 22:13:45
Because we don't get ownership of the |frame| here
|
| + scoped_ptr<webrtc::DesktopFrame> rgb_frame(new webrtc::BasicDesktopFrame( |
| + webrtc::DesktopSize(frame->GetWidth(), frame->GetHeight()))); |
| + |
| + frame->ConvertToRgbBuffer( |
| + output_format_fourcc_, rgb_frame->data(), |
| + std::abs(rgb_frame->stride()) * rgb_frame->size().height(), |
| + rgb_frame->stride()); |
| + rgb_frame->mutable_updated_region()->AddRect( |
| + webrtc::DesktopRect::MakeSize(rgb_frame->size())); |
| + task_runner_->PostTask( |
| + FROM_HERE, |
| + base::Bind(&WebrtcVideoRendererAdapter::DrawFrame, |
| + weak_factory_.GetWeakPtr(), base::Passed(&rgb_frame))); |
| +} |
| + |
| +void WebrtcVideoRendererAdapter::DrawFrame( |
| + scoped_ptr<webrtc::DesktopFrame> frame) { |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| + frame_consumer_->DrawFrame(std::move(frame), base::Closure()); |
| +} |
| + |
| +} // namespace remoting |
| +} // namespace protocol |