Update V8 to version 4.7.42.
[chromium-blink-merge.git] / media / blink / video_frame_compositor.h
blob8cadedbbb321f222237652dd40592d619acb1223
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.
5 #ifndef MEDIA_BLINK_VIDEO_FRAME_COMPOSITOR_H_
6 #define MEDIA_BLINK_VIDEO_FRAME_COMPOSITOR_H_
8 #include "base/callback.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/synchronization/lock.h"
12 #include "base/time/tick_clock.h"
13 #include "base/timer/timer.h"
14 #include "cc/layers/video_frame_provider.h"
15 #include "media/base/media_export.h"
16 #include "media/base/video_renderer_sink.h"
17 #include "ui/gfx/geometry/size.h"
19 namespace media {
20 class VideoFrame;
22 // VideoFrameCompositor acts as a bridge between the media and cc layers for
23 // rendering video frames. I.e. a media::VideoRenderer will talk to this class
24 // from the media side, while a cc::VideoFrameProvider::Client will talk to it
25 // from the cc side.
27 // This class is responsible for requesting new frames from a video renderer in
28 // response to requests from the VFP::Client. Since the VFP::Client may stop
29 // issuing requests in response to visibility changes it is also responsible for
30 // ensuring the "freshness" of the current frame for programmatic frame
31 // requests; e.g., Canvas.drawImage() requests
33 // This class is also responsible for detecting frames dropped by the compositor
34 // after rendering and signaling that information to a RenderCallback. It
35 // detects frames not dropped by verifying each GetCurrentFrame() is followed
36 // by a PutCurrentFrame() before the next UpdateCurrentFrame() call.
38 // VideoRenderSink::RenderCallback implementations must call Start() and Stop()
39 // once new frames are expected or are no longer expected to be ready; this data
40 // is relayed to the compositor to avoid extraneous callbacks.
42 // VideoFrameCompositor is also responsible for pumping UpdateCurrentFrame()
43 // callbacks in the background when |client_| has decided to suspend them.
45 // VideoFrameCompositor must live on the same thread as the compositor, though
46 // it may be constructed on any thread.
47 class MEDIA_EXPORT VideoFrameCompositor
48 : public VideoRendererSink,
49 NON_EXPORTED_BASE(public cc::VideoFrameProvider) {
50 public:
51 // |compositor_task_runner| is the task runner on which this class will live,
52 // though it may be constructed on any thread.
54 // |natural_size_changed_cb| is run with the new natural size of the video
55 // frame whenever a change in natural size is detected. It is not called the
56 // first time UpdateCurrentFrame() is called. Run on the same thread as the
57 // caller of UpdateCurrentFrame().
59 // |opacity_changed_cb| is run when a change in opacity is detected. It *is*
60 // called the first time UpdateCurrentFrame() is called. Run on the same
61 // thread as the caller of UpdateCurrentFrame().
63 // TODO(dalecurtis): Investigate the inconsistency between the callbacks with
64 // respect to why we don't call |natural_size_changed_cb| on the first frame.
65 // I suspect it was for historical reasons that no longer make sense.
66 VideoFrameCompositor(
67 const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner,
68 const base::Callback<void(gfx::Size)>& natural_size_changed_cb,
69 const base::Callback<void(bool)>& opacity_changed_cb);
71 // Destruction must happen on the compositor thread; Stop() must have been
72 // called before destruction starts.
73 ~VideoFrameCompositor() override;
75 // cc::VideoFrameProvider implementation. These methods must be called on the
76 // |compositor_task_runner_|.
77 void SetVideoFrameProviderClient(
78 cc::VideoFrameProvider::Client* client) override;
79 bool UpdateCurrentFrame(base::TimeTicks deadline_min,
80 base::TimeTicks deadline_max) override;
81 bool HasCurrentFrame() override;
82 scoped_refptr<VideoFrame> GetCurrentFrame() override;
83 void PutCurrentFrame() override;
85 // VideoRendererSink implementation. These methods must be called from the
86 // same thread (typically the media thread).
87 void Start(RenderCallback* callback) override;
88 void Stop() override;
89 void PaintFrameUsingOldRenderingPath(
90 const scoped_refptr<VideoFrame>& frame) override;
92 // Returns |current_frame_| if |client_| is set. If no |client_| is set,
93 // |is_background_rendering_| is true, and |callback_| is set, it requests a
94 // new frame from |callback_|, using the elapsed time between calls to this
95 // function as the render interval; defaulting to 16.6ms if no prior calls
96 // have been made. A cap of 250Hz (4ms) is in place to prevent clients from
97 // accidentally (or intentionally) spamming the rendering pipeline.
99 // This method is primarily to facilitate canvas and WebGL based applications
100 // where the <video> tag is invisible (possibly not even in the DOM) and thus
101 // does not receive a |client_|. In this case, frame acquisition is driven by
102 // the frequency of canvas or WebGL paints requested via JavaScript.
103 scoped_refptr<VideoFrame> GetCurrentFrameAndUpdateIfStale();
105 void set_tick_clock_for_testing(scoped_ptr<base::TickClock> tick_clock) {
106 tick_clock_ = tick_clock.Pass();
109 void clear_current_frame_for_testing() { current_frame_ = nullptr; }
111 // Enables or disables background rendering. If |enabled|, |timeout| is the
112 // amount of time to wait after the last Render() call before starting the
113 // background rendering mode. Note, this can not disable the background
114 // rendering call issues when a sink is started.
115 void set_background_rendering_for_testing(bool enabled) {
116 background_rendering_enabled_ = enabled;
119 private:
120 // Called on the compositor thread in response to Start() or Stop() calls;
121 // must be used to change |rendering_| state.
122 void OnRendererStateUpdate(bool new_state);
124 // Handles setting of |current_frame_| and fires |natural_size_changed_cb_|
125 // and |opacity_changed_cb_| when the frame properties changes.
126 bool ProcessNewFrame(const scoped_refptr<VideoFrame>& frame);
128 // Called by |background_rendering_timer_| when enough time elapses where we
129 // haven't seen a Render() call.
130 void BackgroundRender();
132 // If |callback_| is available, calls Render() with the provided properties.
133 // Updates |is_background_rendering_|, |last_interval_|, and resets
134 // |background_rendering_timer_|. Ensures that natural size and opacity
135 // changes are correctly fired. Returns true if there's a new frame available
136 // via GetCurrentFrame().
137 bool CallRender(base::TimeTicks deadline_min,
138 base::TimeTicks deadline_max,
139 bool background_rendering);
141 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
142 scoped_ptr<base::TickClock> tick_clock_;
144 // These callbacks are executed on the compositor thread.
145 const base::Callback<void(gfx::Size)> natural_size_changed_cb_;
146 const base::Callback<void(bool)> opacity_changed_cb_;
148 // Allows tests to disable the background rendering task.
149 bool background_rendering_enabled_;
151 // Manages UpdateCurrentFrame() callbacks if |client_| has stopped sending
152 // them for various reasons. Runs on |compositor_task_runner_| and is reset
153 // after each successful UpdateCurrentFrame() call.
154 base::Timer background_rendering_timer_;
156 // These values are only set and read on the compositor thread.
157 cc::VideoFrameProvider::Client* client_;
158 scoped_refptr<VideoFrame> current_frame_;
159 bool rendering_;
160 bool rendered_last_frame_;
161 bool is_background_rendering_;
162 bool new_background_frame_;
163 base::TimeDelta last_interval_;
164 base::TimeTicks last_background_render_;
166 // These values are updated and read from the media and compositor threads.
167 base::Lock lock_;
168 VideoRendererSink::RenderCallback* callback_;
170 DISALLOW_COPY_AND_ASSIGN(VideoFrameCompositor);
173 } // namespace media
175 #endif // MEDIA_BLINK_VIDEO_FRAME_COMPOSITOR_H_