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

Side by Side Diff: content/renderer/media/renderer_gpu_video_decoder_factories.cc

Issue 11016006: Support reading pixels from HW-decoded video textures into canvas/webgl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 2 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/renderer_gpu_video_decoder_factories.h" 5 #include "content/renderer/media/renderer_gpu_video_decoder_factories.h"
6 6
7 #include <GLES2/gl2.h> 7 #include <GLES2/gl2.h>
8 #include <GLES2/gl2ext.h> 8 #include <GLES2/gl2ext.h>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 } 114 }
115 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 115 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
116 texture_ids->resize(count); 116 texture_ids->resize(count);
117 gles2->GenTextures(count, &texture_ids->at(0)); 117 gles2->GenTextures(count, &texture_ids->at(0));
118 for (int i = 0; i < count; ++i) { 118 for (int i = 0; i < count; ++i) {
119 gles2->ActiveTexture(GL_TEXTURE0); 119 gles2->ActiveTexture(GL_TEXTURE0);
120 uint32 texture_id = texture_ids->at(i); 120 uint32 texture_id = texture_ids->at(i);
121 gles2->BindTexture(texture_target, texture_id); 121 gles2->BindTexture(texture_target, texture_id);
122 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 122 gles2->TexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
123 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 123 gles2->TexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
124 gles2->TexParameterf(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 124 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
125 gles2->TexParameterf(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 125 gles2->TexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
126 if (texture_target == GL_TEXTURE_2D) { 126 if (texture_target == GL_TEXTURE_2D) {
127 gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(), 127 gles2->TexImage2D(texture_target, 0, GL_RGBA, size.width(), size.height(),
128 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 128 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
129 } 129 }
130 } 130 }
131 // We need a glFlush here to guarantee the decoder (in the GPU process) can 131 // We need a glFlush here to guarantee the decoder (in the GPU process) can
132 // use the texture ids we return here. Since textures are expected to be 132 // use the texture ids we return here. Since textures are expected to be
133 // reused, this should not be unacceptably expensive. 133 // reused, this should not be unacceptably expensive.
134 gles2->Flush(); 134 gles2->Flush();
135 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 135 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
136 *success = true; 136 *success = true;
137 waiter->Signal(); 137 waiter->Signal();
138 } 138 }
139 139
140 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) { 140 void RendererGpuVideoDecoderFactories::DeleteTexture(uint32 texture_id) {
141 DCHECK(!message_loop_->BelongsToCurrentThread()); 141 DCHECK(!message_loop_->BelongsToCurrentThread());
142 message_loop_->PostTask(FROM_HERE, base::Bind( 142 message_loop_->PostTask(FROM_HERE, base::Bind(
143 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id)); 143 &RendererGpuVideoDecoderFactories::AsyncDeleteTexture, this, texture_id));
144 } 144 }
145 145
146 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) { 146 void RendererGpuVideoDecoderFactories::AsyncDeleteTexture(uint32 texture_id) {
147 DCHECK(message_loop_->BelongsToCurrentThread()); 147 DCHECK(message_loop_->BelongsToCurrentThread());
148 if (!context_) 148 if (!context_)
149 return; 149 return;
150 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation(); 150 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
151 gles2->DeleteTextures(1, &texture_id); 151 gles2->DeleteTextures(1, &texture_id);
152 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR)); 152 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
153 } 153 }
154 154
155 void RendererGpuVideoDecoderFactories::ReadPixels(
156 uint32 texture_id, uint32 texture_target, const gfx::Size& size,
157 void* pixels) {
158 base::WaitableEvent waiter(false, false);
159 if (!message_loop_->BelongsToCurrentThread()) {
160 message_loop_->PostTask(FROM_HERE, base::Bind(
161 &RendererGpuVideoDecoderFactories::AsyncReadPixels, this,
162 texture_id, texture_target, size, pixels, &waiter));
163 waiter.Wait();
164 } else {
165 AsyncReadPixels(texture_id, texture_target, size, pixels, &waiter);
166 }
167 }
168
169 void RendererGpuVideoDecoderFactories::AsyncReadPixels(
170 uint32 texture_id, uint32 texture_target, const gfx::Size& size,
171 void* pixels, base::WaitableEvent* waiter) {
172 DCHECK(message_loop_->BelongsToCurrentThread());
173 if (!context_)
174 return;
175
176 gpu::gles2::GLES2Implementation* gles2 = context_->GetImplementation();
177
178 gles2->ActiveTexture(GL_TEXTURE0);
179 gles2->BindTexture(texture_target, texture_id);
180 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
181 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
182 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
183 gles2->TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
184
185 GLuint fb;
186 gles2->GenFramebuffers(1, &fb);
187 gles2->BindFramebuffer(GL_FRAMEBUFFER, fb);
188 gles2->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
189 texture_target, texture_id, 0);
190 gles2->ReadPixels(0, 0, size.width(), size.height(), GL_RGBA,
Ken Russell (switch to Gerrit) 2012/10/01 17:56:16 Depending on who uses this context (just HW video
Ami GONE FROM CHROMIUM 2012/10/01 18:16:12 Only HW decode uses it.
191 GL_UNSIGNED_BYTE, pixels);
192 gles2->DeleteFramebuffers(1, &fb);
193 DCHECK_EQ(gles2->GetError(), static_cast<GLenum>(GL_NO_ERROR));
194 waiter->Signal();
195 }
196
155 base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory( 197 base::SharedMemory* RendererGpuVideoDecoderFactories::CreateSharedMemory(
156 size_t size) { 198 size_t size) {
157 DCHECK_NE(MessageLoop::current(), ChildThread::current()->message_loop()); 199 DCHECK_NE(MessageLoop::current(), ChildThread::current()->message_loop());
158 base::SharedMemory* shm = NULL; 200 base::SharedMemory* shm = NULL;
159 base::WaitableEvent waiter(false, false); 201 base::WaitableEvent waiter(false, false);
160 ChildThread::current()->message_loop()->PostTask(FROM_HERE, base::Bind( 202 ChildThread::current()->message_loop()->PostTask(FROM_HERE, base::Bind(
161 &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this, 203 &RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory, this,
162 size, &shm, &waiter)); 204 size, &shm, &waiter));
163 waiter.Wait(); 205 waiter.Wait();
164 return shm; 206 return shm;
165 } 207 }
166 208
167 void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory( 209 void RendererGpuVideoDecoderFactories::AsyncCreateSharedMemory(
168 size_t size, base::SharedMemory** shm, base::WaitableEvent* waiter) { 210 size_t size, base::SharedMemory** shm, base::WaitableEvent* waiter) {
169 DCHECK_EQ(MessageLoop::current(), ChildThread::current()->message_loop()); 211 DCHECK_EQ(MessageLoop::current(), ChildThread::current()->message_loop());
170 *shm = ChildThread::current()->AllocateSharedMemory(size); 212 *shm = ChildThread::current()->AllocateSharedMemory(size);
171 waiter->Signal(); 213 waiter->Signal();
172 } 214 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698