1// Copyright (c) 2012 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 CONTENT_COMMON_GPU_MEDIA_RENDERING_HELPER_H_
6#define CONTENT_COMMON_GPU_MEDIA_RENDERING_HELPER_H_
7
8#include <map>
9#include <queue>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/cancelable_callback.h"
14#include "base/time/time.h"
15#include "base/timer/timer.h"
16#include "ui/gfx/geometry/rect.h"
17#include "ui/gfx/geometry/size.h"
18#include "ui/gl/gl_bindings.h"
19#include "ui/gl/gl_context.h"
20#include "ui/gl/gl_surface.h"
21
22namespace base {
23class MessageLoop;
24class WaitableEvent;
25}
26
27namespace content {
28
29class VideoFrameTexture : public base::RefCounted<VideoFrameTexture> {
30 public:
31  uint32 texture_id() const { return texture_id_; }
32  uint32 texture_target() const { return texture_target_; }
33
34  VideoFrameTexture(uint32 texture_target,
35                    uint32 texture_id,
36                    const base::Closure& no_longer_needed_cb);
37
38 private:
39  friend class base::RefCounted<VideoFrameTexture>;
40
41  uint32 texture_target_;
42  uint32 texture_id_;
43  base::Closure no_longer_needed_cb_;
44
45  ~VideoFrameTexture();
46};
47
48struct RenderingHelperParams {
49  RenderingHelperParams();
50  ~RenderingHelperParams();
51
52  // The rendering FPS.
53  int rendering_fps;
54
55  // The desired size of each window. We play each stream in its own window
56  // on the screen.
57  std::vector<gfx::Size> window_sizes;
58
59  // The members below are only used for the thumbnail mode where all frames
60  // are rendered in sequence onto one FBO for comparison/verification purposes.
61
62  // Whether the frames are rendered as scaled thumbnails within a
63  // larger FBO that is in turn rendered to the window.
64  bool render_as_thumbnails;
65  // The size of the FBO containing all visible thumbnails.
66  gfx::Size thumbnails_page_size;
67  // The size of each thumbnail within the FBO.
68  gfx::Size thumbnail_size;
69};
70
71// Creates and draws textures used by the video decoder.
72// This class is not thread safe and thus all the methods of this class
73// (except for ctor/dtor) ensure they're being run on a single thread.
74class RenderingHelper {
75 public:
76
77  RenderingHelper();
78  ~RenderingHelper();
79
80  static bool InitializeOneOff();
81
82  // Create the render context and windows by the specified dimensions.
83  void Initialize(const RenderingHelperParams& params,
84                  base::WaitableEvent* done);
85
86  // Undo the effects of Initialize() and signal |*done|.
87  void UnInitialize(base::WaitableEvent* done);
88
89  // Return a newly-created GLES2 texture id of the specified size, and
90  // signal |*done|.
91  void CreateTexture(uint32 texture_target,
92                     uint32* texture_id,
93                     const gfx::Size& size,
94                     base::WaitableEvent* done);
95
96  // Render thumbnail in the |texture_id| to the FBO buffer using target
97  // |texture_target|.
98  void RenderThumbnail(uint32 texture_target, uint32 texture_id);
99
100  // Queues the |video_frame| for rendering.
101  void QueueVideoFrame(size_t window_id,
102                       scoped_refptr<VideoFrameTexture> video_frame);
103
104  // Flushes the pending frames. Notify the rendering_helper there won't be
105  // more video frames.
106  void Flush(size_t window_id);
107
108  // Delete |texture_id|.
109  void DeleteTexture(uint32 texture_id);
110
111  // Get the platform specific handle to the OpenGL display.
112  void* GetGLDisplay();
113
114  // Get the platform specific handle to the OpenGL context.
115  void* GetGLContext();
116
117  // Get rendered thumbnails as RGB.
118  // Sets alpha_solid to true if the alpha channel is entirely 0xff.
119  void GetThumbnailsAsRGB(std::vector<unsigned char>* rgb,
120                          bool* alpha_solid,
121                          base::WaitableEvent* done);
122
123 private:
124  struct RenderedVideo {
125    // The rect on the screen where the video will be rendered.
126    gfx::Rect render_area;
127
128    // True if the last (and the only one) frame in pending_frames has
129    // been rendered. We keep the last remaining frame in pending_frames even
130    // after it has been rendered, so that we have something to display if the
131    // client is falling behind on providing us with new frames during
132    // timer-driven playback.
133    bool last_frame_rendered;
134
135    // True if there won't be any new video frames comming.
136    bool is_flushing;
137
138    // The number of frames need to be dropped to catch up the rendering.
139    int frames_to_drop;
140
141    // The video frames pending for rendering.
142    std::queue<scoped_refptr<VideoFrameTexture> > pending_frames;
143
144    RenderedVideo();
145    ~RenderedVideo();
146  };
147
148  void Clear();
149
150  void RenderContent();
151
152  void LayoutRenderingAreas(const std::vector<gfx::Size>& window_sizes);
153
154  // Render |texture_id| to the current view port of the screen using target
155  // |texture_target|.
156  void RenderTexture(uint32 texture_target, uint32 texture_id);
157
158  base::MessageLoop* message_loop_;
159
160  scoped_refptr<gfx::GLContext> gl_context_;
161  scoped_refptr<gfx::GLSurface> gl_surface_;
162
163  gfx::AcceleratedWidget window_;
164
165  gfx::Size screen_size_;
166
167  std::vector<RenderedVideo> videos_;
168
169  bool render_as_thumbnails_;
170  int frame_count_;
171  GLuint thumbnails_fbo_id_;
172  GLuint thumbnails_texture_id_;
173  gfx::Size thumbnails_fbo_size_;
174  gfx::Size thumbnail_size_;
175  GLuint program_;
176  base::TimeDelta frame_duration_;
177  base::TimeTicks scheduled_render_time_;
178  base::CancelableClosure render_task_;
179
180  DISALLOW_COPY_AND_ASSIGN(RenderingHelper);
181};
182
183}  // namespace content
184
185#endif  // CONTENT_COMMON_GPU_MEDIA_RENDERING_HELPER_H_
186