15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CONTENT_COMMON_GPU_MEDIA_RENDERING_HELPER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CONTENT_COMMON_GPU_MEDIA_RENDERING_HELPER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
84e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <map>
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include <queue>
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector>
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/cancelable_callback.h"
14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/time/time.h"
15f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/timer/timer.h"
16f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/gfx/geometry/rect.h"
17f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/gfx/geometry/size.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "ui/gl/gl_bindings.h"
195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gl/gl_context.h"
205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/gl/gl_surface.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class MessageLoop;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WaitableEvent;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)class VideoFrameTexture : public base::RefCounted<VideoFrameTexture> {
3003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) public:
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint32 texture_id() const { return texture_id_; }
3203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint32 texture_target() const { return texture_target_; }
3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  VideoFrameTexture(uint32 texture_target,
3503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                    uint32 texture_id,
3603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                    const base::Closure& no_longer_needed_cb);
3703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
3803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) private:
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  friend class base::RefCounted<VideoFrameTexture>;
4003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint32 texture_target_;
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  uint32 texture_id_;
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  base::Closure no_longer_needed_cb_;
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ~VideoFrameTexture();
4603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
4703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)struct RenderingHelperParams {
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  RenderingHelperParams();
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ~RenderingHelperParams();
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The rendering FPS.
5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  int rendering_fps;
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The desired size of each window. We play each stream in its own window
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // on the screen.
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<gfx::Size> window_sizes;
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The members below are only used for the thumbnail mode where all frames
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // are rendered in sequence onto one FBO for comparison/verification purposes.
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Whether the frames are rendered as scaled thumbnails within a
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // larger FBO that is in turn rendered to the window.
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  bool render_as_thumbnails;
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The size of the FBO containing all visible thumbnails.
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  gfx::Size thumbnails_page_size;
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // The size of each thumbnail within the FBO.
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  gfx::Size thumbnail_size;
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)};
70a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates and draws textures used by the video decoder.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class is not thread safe and thus all the methods of this class
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (except for ctor/dtor) ensure they're being run on a single thread.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RenderingHelper {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  RenderingHelper();
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ~RenderingHelper();
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static bool InitializeOneOff();
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create the render context and windows by the specified dimensions.
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void Initialize(const RenderingHelperParams& params,
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                  base::WaitableEvent* done);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Undo the effects of Initialize() and signal |*done|.
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void UnInitialize(base::WaitableEvent* done);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Return a newly-created GLES2 texture id of the specified size, and
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // signal |*done|.
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void CreateTexture(uint32 texture_target,
924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     uint32* texture_id,
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                     const gfx::Size& size,
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                     base::WaitableEvent* done);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Render thumbnail in the |texture_id| to the FBO buffer using target
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // |texture_target|.
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void RenderThumbnail(uint32 texture_target, uint32 texture_id);
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Queues the |video_frame| for rendering.
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void QueueVideoFrame(size_t window_id,
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                       scoped_refptr<VideoFrameTexture> video_frame);
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Flushes the pending frames. Notify the rendering_helper there won't be
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // more video frames.
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void Flush(size_t window_id);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Delete |texture_id|.
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void DeleteTexture(uint32 texture_id);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the platform specific handle to the OpenGL display.
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void* GetGLDisplay();
113a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
114e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Get the platform specific handle to the OpenGL context.
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void* GetGLContext();
116e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
117a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Get rendered thumbnails as RGB.
118a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // Sets alpha_solid to true if the alpha channel is entirely 0xff.
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void GetThumbnailsAsRGB(std::vector<unsigned char>* rgb,
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          bool* alpha_solid,
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          base::WaitableEvent* done);
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
12403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  struct RenderedVideo {
12503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // The rect on the screen where the video will be rendered.
12603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    gfx::Rect render_area;
12703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
12803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // True if the last (and the only one) frame in pending_frames has
12903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // been rendered. We keep the last remaining frame in pending_frames even
13003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // after it has been rendered, so that we have something to display if the
13103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // client is falling behind on providing us with new frames during
13203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // timer-driven playback.
13303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    bool last_frame_rendered;
13403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // True if there won't be any new video frames comming.
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool is_flushing;
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // The number of frames need to be dropped to catch up the rendering.
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int frames_to_drop;
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // The video frames pending for rendering.
14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    std::queue<scoped_refptr<VideoFrameTexture> > pending_frames;
14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    RenderedVideo();
14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    ~RenderedVideo();
14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  };
14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void Clear();
1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void RenderContent();
151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void LayoutRenderingAreas(const std::vector<gfx::Size>& window_sizes);
15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Render |texture_id| to the current view port of the screen using target
15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // |texture_target|.
15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  void RenderTexture(uint32 texture_target, uint32 texture_id);
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::MessageLoop* message_loop_;
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<gfx::GLContext> gl_context_;
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<gfx::GLSurface> gl_surface_;
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  gfx::AcceleratedWidget window_;
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  gfx::Size screen_size_;
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::vector<RenderedVideo> videos_;
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  bool render_as_thumbnails_;
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int frame_count_;
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GLuint thumbnails_fbo_id_;
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GLuint thumbnails_texture_id_;
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Size thumbnails_fbo_size_;
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::Size thumbnail_size_;
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GLuint program_;
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::TimeDelta frame_duration_;
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::TimeTicks scheduled_render_time_;
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  base::CancelableClosure render_task_;
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RenderingHelper);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CONTENT_COMMON_GPU_MEDIA_RENDERING_HELPER_H_
186