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