Index: content/renderer/media/android/stream_texture_wrapper_impl.h |
diff --git a/content/renderer/media/android/stream_texture_wrapper_impl.h b/content/renderer/media/android/stream_texture_wrapper_impl.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..48fc6cfec416712e1714b4d25db313fb05eaf0d2 |
--- /dev/null |
+++ b/content/renderer/media/android/stream_texture_wrapper_impl.h |
@@ -0,0 +1,106 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef _CONTENT_RENDERER_MEDIA_ANDROID_STREAM_TEXTURE_WRAPPER_IMPL_H_ |
+#define _CONTENT_RENDERER_MEDIA_ANDROID_STREAM_TEXTURE_WRAPPER_IMPL_H_ |
+ |
+#include <memory> |
+ |
+#include "content/renderer/media/android/stream_texture_factory.h" |
+#include "gpu/command_buffer/common/mailbox.h" |
+#include "media/base/android/stream_texture_wrapper.h" |
+#include "media/base/video_frame.h" |
+ |
+namespace content { |
+ |
+// Concrete implementation of SurfaceTextureFrameProvider, backed by a |
+// StreamTexture living in the GPU process. |
+// |
+// A SurfaceTexture is an Android primitive, joining an Android Surface (the |
+// producer side, used by MediaPlayer for example) with a GL Texture (the |
+// consumer side, used by our compositor). Its documentation can be found here: |
+// https://developer.android.com/reference/android/graphics/SurfaceTexture.html |
+// |
+// The StreamTexture is an abstraction allowing Chrome to wrap a SurfaceTexture |
+// living in the GPU process. It allows VideoFrames to be created from the |
+// SurfaceTexture's texture, in the Renderer process. |
+// |
+// The general idea behind our use of StreamTexture is as follows: |
+// - We create a client GL texture in the Renderer process. |
+// - We request the creation of a StreamTexture via the StreamTextureFactory, |
+// passing the client texture ID. The call is sent to the GPU process via the |
+// CommandBuffer. The "platform" GL texture reference associated with the client |
+// texture ID is looked up in the TextureManager. A StreamTexture is then |
+// created, wrapping a SurfaceTexture created from the texture reference. The |
+// SurfaceTexture's OnFrameAvailable() callback is tied to StreamTexture's |
+// OnFrameAvailable(), which fires an IPC accross the GPU channel. |
+// - We create a StreamTextureProxy in the Renderer process which listens for |
+// the IPC fired by the StreamTexture's OnFrameAvailable() callback. |
+// - We bind the StreamTextureProxy's lifetime to the |compositor_task_runner_|. |
+// - We wrap the client texture into a VideoFrame. |
+// - When the SurfaceTexture's OnFrameAvailable() callback is fired (and routed |
+// to the StreamTextureProxy living on the compositor thread), we notify |
+// |client_| that a new frame is available, via the DidReceiveFrame() callback. |
+// |
+// N.B: Technically, we only create one VideoFrame, but pretend it is a new one |
+// and ask the compositor to re-paint it whenever the underlying texture's data |
+// has changed. |
+// |
+// TODO(tguilbert): Register the underlying SurfaceTexture for retrieval in the |
+// browser process. See crbug.com/627658. |
+// |
+class StreamTextureWrapperImpl : public media::StreamTextureWrapper { |
+ public: |
+ StreamTextureWrapperImpl( |
+ scoped_refptr<StreamTextureFactory> factory, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner); |
+ virtual ~StreamTextureWrapperImpl(); |
+ |
+ // StreamTextureWrapper implementation. |
+ void Initialize( |
+ cc::VideoFrameProvider::Client* client, |
+ const gfx::Size& natural_size, |
+ const scoped_refptr<base::SingleThreadTaskRunner>& media_task_runner, |
+ const base::Closure& init_cb) override; |
+ void UpdateTextureSize(const gfx::Size& natural_size) override; |
+ scoped_refptr<media::VideoFrame> GetCurrentFrame() override; |
+ |
+ private: |
+ void InitializeInternal(const base::Closure& init_cb); |
+ |
+ void ReallocateVideoFrame(const gfx::Size& natural_size); |
+ |
+ void SetCurrentFrameInternal(scoped_refptr<media::VideoFrame>& video_frame); |
+ |
+ // GL texture ID allocated to the video. |
+ unsigned int texture_id_; |
+ |
+ // GL texture mailbox for |texture_id_| to provide in the VideoFrame, and sync |
+ // point for when the mailbox was produced. |
+ gpu::Mailbox texture_mailbox_; |
+ |
+ // Stream texture ID allocated to the video. |
+ unsigned int stream_id_; |
+ |
+ // Object for calling back the compositor thread to repaint the video when a |
+ // frame available. It should be bound to the compositor thread. |
+ ScopedStreamTextureProxy stream_texture_proxy_; |
+ |
+ cc::VideoFrameProvider::Client* client_; |
+ |
+ // Size of the allocated underlying texture. |
+ gfx::Size natural_size_; |
+ |
+ scoped_refptr<StreamTextureFactory> factory_; |
+ |
+ base::Lock current_frame_lock_; |
+ scoped_refptr<media::VideoFrame> current_frame_; |
+ |
+ scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
+ scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; |
+}; |
+ |
+} // namespace media |
+ |
+#endif // _CONTENT_RENDERER_MEDIA_ANDROID_STREAM_TEXTURE_WRAPPER_IMPL_H_ |