Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Side by Side Diff: content/renderer/media/android/stream_texture_wrapper_impl.cc

Issue 2136103010: Add StreamTextureWrapper/StreamTextureWrapperImpl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Renamed to StreamTextureWrapper, handled destruction Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 #include "content/renderer/media/android/stream_texture_wrapper_impl.h"
6
7 #include "base/callback.h"
8 #include "cc/layers/video_frame_provider.h"
9 #include "gpu/GLES2/gl2extchromium.h"
10 #include "gpu/command_buffer/client/gles2_interface.h"
11 #include "media/base/bind_to_current_loop.h"
12
13 using gpu::gles2::GLES2Interface;
14
15 static const uint32_t kGLTextureExternalOES = 0x8D65;
DaleCurtis 2016/07/21 22:14:22 What is this?
tguilbert 2016/07/21 23:06:42 I copied it as it was from WMPA. However, it seems
16
17 namespace {
18 // File-static function is to allow it to run even after this class is deleted.
19 static void OnReleaseTexture(
DaleCurtis 2016/07/21 22:14:22 No static necessary when anonymous namespace is us
tguilbert 2016/07/21 23:06:42 Done. However, liberato@ had asked me to add it in
20 const scoped_refptr<content::StreamTextureFactory>& factories,
21 uint32_t texture_id,
22 const gpu::SyncToken& sync_token) {
23 GLES2Interface* gl = factories->ContextGL();
24 gl->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
25 gl->DeleteTextures(1, &texture_id);
26 // Flush to ensure that the stream texture gets deleted in a timely fashion.
27 gl->ShallowFlushCHROMIUM();
28 }
29 }
30
31 namespace content {
32
33 StreamTextureWrapperImpl::StreamTextureWrapperImpl(
34 scoped_refptr<StreamTextureFactory> factory,
35 const scoped_refptr<base::SingleThreadTaskRunner>& main_task_runner)
36 : texture_id_(0),
37 stream_id_(0),
38 client_(NULL),
DaleCurtis 2016/07/21 22:14:22 nullptr, possibly prefer in header initialization.
tguilbert 2016/07/21 23:06:42 Done.
39 factory_(factory),
40 main_task_runner_(main_task_runner),
41 weak_factory_(this) {}
42
43 StreamTextureWrapperImpl::~StreamTextureWrapperImpl() {
44 DCHECK(main_task_runner_->BelongsToCurrentThread());
45
46 if (stream_id_) {
47 GLES2Interface* gl = factory_->ContextGL();
48 gl->DeleteTextures(1, &texture_id_);
49 // Flush to ensure that the stream texture gets deleted in a timely fashion.
50 gl->ShallowFlushCHROMIUM();
51 texture_id_ = 0;
DaleCurtis 2016/07/21 22:14:22 Any point?
tguilbert 2016/07/21 23:06:42 Not so much, you are right.
52 texture_mailbox_ = gpu::Mailbox();
53 stream_id_ = 0;
54 }
55
56 SetCurrentFrameInternal(NULL);
DaleCurtis 2016/07/21 22:14:22 nullptr.
tguilbert 2016/07/21 23:06:42 Done.
57 }
58
59 scoped_refptr<media::VideoFrame> StreamTextureWrapperImpl::GetCurrentFrame() {
60 base::AutoLock auto_lock(current_frame_lock_);
61 return current_frame_;
62 }
63
64 void StreamTextureWrapperImpl::ReallocateVideoFrame(
65 const gfx::Size& natural_size) {
66 DVLOG(2) << __FUNCTION__;
67 DCHECK(main_task_runner_->BelongsToCurrentThread());
68
69 GLES2Interface* gl = factory_->ContextGL();
70 GLuint texture_target = kGLTextureExternalOES;
71 GLuint texture_id_ref = gl->CreateAndConsumeTextureCHROMIUM(
72 texture_target, texture_mailbox_.name);
73 const GLuint64 fence_sync = gl->InsertFenceSyncCHROMIUM();
74 gl->Flush();
75
76 gpu::SyncToken texture_mailbox_sync_token;
77 gl->GenUnverifiedSyncTokenCHROMIUM(fence_sync,
78 texture_mailbox_sync_token.GetData());
79 if (texture_mailbox_sync_token.namespace_id() ==
80 gpu::CommandBufferNamespace::IN_PROCESS) {
81 // TODO(boliu): Remove this once Android WebView switches to IPC-based
82 // command buffer for video.
83 GLbyte* sync_tokens[] = {texture_mailbox_sync_token.GetData()};
84 gl->VerifySyncTokensCHROMIUM(sync_tokens, arraysize(sync_tokens));
85 }
86
87 gpu::MailboxHolder holders[media::VideoFrame::kMaxPlanes] = {
88 gpu::MailboxHolder(texture_mailbox_, texture_mailbox_sync_token,
89 texture_target)};
90
91 scoped_refptr<media::VideoFrame> new_frame =
92 media::VideoFrame::WrapNativeTextures(
93 media::PIXEL_FORMAT_ARGB, holders,
94 media::BindToCurrentLoop(
95 base::Bind(&OnReleaseTexture, factory_, texture_id_ref)),
96 natural_size, gfx::Rect(natural_size), natural_size,
97 base::TimeDelta());
98
99 // TODO(tguilbert): Create and pipe the enable_texture_copy_ flag for Webview
100 // scenarios. See crbug.com/628066.
101 //
102 // if (new_frame.get()) {
103 // new_frame->metadata()->SetBoolean(
104 // media::VideoFrameMetadata::COPY_REQUIRED, enable_texture_copy_);
105 // }
106
107 SetCurrentFrameInternal(new_frame);
108 }
109
110 void StreamTextureWrapperImpl::SetCurrentFrameInternal(
111 const scoped_refptr<media::VideoFrame>& video_frame) {
112 base::AutoLock auto_lock(current_frame_lock_);
113 current_frame_ = video_frame;
114 }
115
116 void StreamTextureWrapperImpl::UpdateTextureSize(const gfx::Size& new_size) {
117 DVLOG(2) << __FUNCTION__;
118
119 if (natural_size_ == new_size)
DaleCurtis 2016/07/21 22:14:22 Can't do this if on the wrong thread.
tguilbert 2016/07/21 23:06:42 You are right!
120 return;
121
122 if (!main_task_runner_->BelongsToCurrentThread()) {
123 main_task_runner_->PostTask(
124 FROM_HERE, base::Bind(&StreamTextureWrapperImpl::UpdateTextureSize,
125 weak_factory_.GetWeakPtr(), new_size));
126 return;
127 }
128
129 natural_size_ = new_size;
130
131 ReallocateVideoFrame(new_size);
132 factory_->SetStreamTextureSize(stream_id_, new_size);
133 }
134
135 void StreamTextureWrapperImpl::Initialize(
136 cc::VideoFrameProvider::Client* client,
137 const gfx::Size& natural_size,
138 const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner,
139 const base::Closure& init_cb) {
140 DVLOG(2) << __FUNCTION__;
141
142 compositor_task_runner_ = compositor_task_runner;
143 natural_size_ = natural_size;
144 client_ = client;
145
146 main_task_runner_->PostTask(
147 FROM_HERE, base::Bind(&StreamTextureWrapperImpl::InitializeInternal,
148 weak_factory_.GetWeakPtr(), init_cb));
149 }
150
151 void StreamTextureWrapperImpl::InitializeInternal(
DaleCurtis 2016/07/21 22:14:22 Maybe InitializeOnMainThread?
tguilbert 2016/07/21 23:06:42 Done.
152 const base::Closure& init_cb) {
153 DCHECK(main_task_runner_->BelongsToCurrentThread());
154 DVLOG(2) << __FUNCTION__;
155
156 stream_texture_proxy_.reset(factory_->CreateProxy());
157
158 stream_id_ = factory_->CreateStreamTexture(kGLTextureExternalOES,
159 &texture_id_, &texture_mailbox_);
160 ReallocateVideoFrame(natural_size_);
161
162 stream_texture_proxy_->BindToLoop(stream_id_, client_,
163 compositor_task_runner_);
164
165 // TODO(tguilbert): Register the surface properly. See crbug.com/627658.
166
167 // |init_cb| should be bound to the media thread, and continue its execution
168 // there.
169 init_cb.Run();
170 }
171
172 void StreamTextureWrapperImpl::Destroy() {
173 // Note: StreamTextureProxy will release its reference to |client_|
174 // immediately (and stop calling back DidReceiveFrame()), and then destroy
175 // itself on |compositor_task_runner_|.
176 stream_texture_proxy_.reset();
177 main_task_runner_->DeleteSoon(FROM_HERE, this);
178 }
179
180 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698