1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef REMOTING_CLIENT_SOFTWARE_VIDEO_RENDERER_H_ 6#define REMOTING_CLIENT_SOFTWARE_VIDEO_RENDERER_H_ 7 8#include "base/memory/ref_counted.h" 9#include "base/memory/scoped_ptr.h" 10#include "remoting/client/chromoting_stats.h" 11#include "remoting/client/frame_consumer_proxy.h" 12#include "remoting/client/frame_producer.h" 13#include "remoting/client/video_renderer.h" 14#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" 15 16namespace base { 17class SingleThreadTaskRunner; 18} // namespace base 19 20namespace remoting { 21 22class ChromotingStats; 23 24// Implementation of VideoRenderer interface that decodes frame on CPU (on a 25// decode thread) and then passes decoded frames to a FrameConsumer. 26// FrameProducer methods can be called on any thread. All other methods must be 27// called on the main thread. Owned must ensure that this class outlives 28// FrameConsumer (which calls FrameProducer interface). 29class SoftwareVideoRenderer : public VideoRenderer, 30 public FrameProducer, 31 public base::NonThreadSafe { 32 public: 33 // Creates an update decoder on |main_task_runner_| and |decode_task_runner_|, 34 // outputting to |consumer|. The |main_task_runner_| is responsible for 35 // receiving and queueing packets. The |decode_task_runner_| is responsible 36 // for decoding the video packets. 37 // TODO(wez): Replace the ref-counted proxy with an owned FrameConsumer. 38 SoftwareVideoRenderer( 39 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, 40 scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner, 41 scoped_refptr<FrameConsumerProxy> consumer); 42 virtual ~SoftwareVideoRenderer(); 43 44 // VideoRenderer implementation. 45 virtual void Initialize(const protocol::SessionConfig& config) OVERRIDE; 46 virtual ChromotingStats* GetStats() OVERRIDE; 47 virtual void ProcessVideoPacket(scoped_ptr<VideoPacket> packet, 48 const base::Closure& done) OVERRIDE; 49 50 // FrameProducer implementation. These methods may be called before we are 51 // Initialize()d, or we know the source screen size. These methods may be 52 // called on any thread. 53 // 54 // TODO(sergeyu): On Android a separate display thread is used for drawing. 55 // FrameConsumer calls FrameProducer on that thread. Can we avoid having a 56 // separate display thread? E.g. can we do everything on the decode thread? 57 virtual void DrawBuffer(webrtc::DesktopFrame* buffer) OVERRIDE; 58 virtual void InvalidateRegion(const webrtc::DesktopRegion& region) OVERRIDE; 59 virtual void RequestReturnBuffers(const base::Closure& done) OVERRIDE; 60 virtual void SetOutputSizeAndClip( 61 const webrtc::DesktopSize& view_size, 62 const webrtc::DesktopRect& clip_area) OVERRIDE; 63 64 private: 65 class Core; 66 67 // Callback method when a VideoPacket is processed. |decode_start| contains 68 // the timestamp when the packet will start to be processed. 69 void OnPacketDone(base::Time decode_start, const base::Closure& done); 70 71 scoped_refptr<base::SingleThreadTaskRunner> decode_task_runner_; 72 scoped_ptr<Core> core_; 73 74 ChromotingStats stats_; 75 76 // Keep track of the most recent sequence number bounced back from the host. 77 int64 latest_sequence_number_; 78 79 base::WeakPtrFactory<SoftwareVideoRenderer> weak_factory_; 80 81 DISALLOW_COPY_AND_ASSIGN(SoftwareVideoRenderer); 82}; 83 84} // namespace remoting 85 86#endif // REMOTING_CLIENT_SOFTWARE_VIDEO_RENDERER_H_ 87