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

Side by Side Diff: content/common/gpu/media/android_deferred_rendering_backing_strategy.cc

Issue 1639963002: AndroidVideoDecodeAccelerator can now render to a SurfaceView (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Get the unittest compiling and passing Created 4 years, 10 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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/common/gpu/media/android_deferred_rendering_backing_strategy.h " 5 #include "content/common/gpu/media/android_deferred_rendering_backing_strategy.h "
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop.h" 9 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "content/common/gpu/gpu_channel.h" 11 #include "content/common/gpu/gpu_channel.h"
12 #include "content/common/gpu/gpu_surface_lookup.h"
12 #include "content/common/gpu/media/avda_codec_image.h" 13 #include "content/common/gpu/media/avda_codec_image.h"
13 #include "content/common/gpu/media/avda_return_on_failure.h" 14 #include "content/common/gpu/media/avda_return_on_failure.h"
14 #include "content/common/gpu/media/avda_shared_state.h" 15 #include "content/common/gpu/media/avda_shared_state.h"
15 #include "gpu/command_buffer/service/texture_manager.h" 16 #include "gpu/command_buffer/service/texture_manager.h"
16 #include "ui/gl/android/surface_texture.h" 17 #include "ui/gl/android/surface_texture.h"
17 #include "ui/gl/gl_bindings.h" 18 #include "ui/gl/gl_bindings.h"
18 19
19 namespace content { 20 namespace content {
20 21
21 AndroidDeferredRenderingBackingStrategy:: 22 AndroidDeferredRenderingBackingStrategy::
22 AndroidDeferredRenderingBackingStrategy() 23 AndroidDeferredRenderingBackingStrategy(AVDAStateProvider* state_provider)
23 : state_provider_(nullptr), media_codec_(nullptr) {} 24 : state_provider_(state_provider), media_codec_(nullptr) {}
24 25
25 AndroidDeferredRenderingBackingStrategy:: 26 AndroidDeferredRenderingBackingStrategy::
26 ~AndroidDeferredRenderingBackingStrategy() {} 27 ~AndroidDeferredRenderingBackingStrategy() {}
27 28
28 void AndroidDeferredRenderingBackingStrategy::Initialize( 29 gfx::ScopedJavaSurface AndroidDeferredRenderingBackingStrategy::Initialize(
29 AVDAStateProvider* state_provider) { 30 int surface_view_id) {
30 state_provider_ = state_provider;
31 shared_state_ = new AVDASharedState(); 31 shared_state_ = new AVDASharedState();
32 32
33 gfx::ScopedJavaSurface surface;
34 if (surface_view_id != media::VideoDecodeAccelerator::Config::kNoSurfaceID) {
35 surface =
36 GpuSurfaceLookup::GetInstance()->AcquireJavaSurface(surface_view_id);
37 } else {
38 // Create a detached SurfaceTexture. Detaching it will silently fail to
39 // delete texture 0.
40 surface_texture_ = gfx::SurfaceTexture::Create(0);
41 surface_texture_->DetachFromGLContext();
42 surface = gfx::ScopedJavaSurface(surface_texture_.get());
43 }
44
33 // Create a texture for the SurfaceTexture to use. We don't attach it here 45 // Create a texture for the SurfaceTexture to use. We don't attach it here
34 // so that it gets attached in the compositor gl context in the common case. 46 // so that it gets attached in the compositor gl context in the common case.
35 GLuint service_id = 0; 47 GLuint service_id = 0;
liberato (no reviews please) 2016/01/29 23:28:46 can this be moved into the surface texture case? s
watk 2016/02/02 02:19:01 Unfortunately we DCHECK that it's non-zero in SetI
36 glGenTextures(1, &service_id); 48 glGenTextures(1, &service_id);
37 DCHECK(service_id); 49 DCHECK(service_id);
38 shared_state_->set_surface_texture_service_id(service_id); 50 shared_state_->set_surface_texture_service_id(service_id);
51
52 return surface;
39 } 53 }
40 54
41 void AndroidDeferredRenderingBackingStrategy::Cleanup( 55 void AndroidDeferredRenderingBackingStrategy::Cleanup(
42 bool have_context, 56 bool have_context,
43 const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) { 57 const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) {
44 // If we failed before Initialize, then do nothing. 58 // If we failed before Initialize, then do nothing.
45 if (!shared_state_) 59 if (!shared_state_)
46 return; 60 return;
47 61
48 // Make sure that no PictureBuffer textures refer to the SurfaceTexture or to 62 // Make sure that no PictureBuffer textures refer to the SurfaceTexture or to
49 // the service_id that we created for it. 63 // the service_id that we created for it.
50 for (const std::pair<int, media::PictureBuffer>& entry : buffers) 64 for (const std::pair<int, media::PictureBuffer>& entry : buffers)
51 SetImageForPicture(entry.second, nullptr); 65 SetImageForPicture(entry.second, nullptr);
52 66
53 // Now that no AVDACodecImages refer to the SurfaceTexture's texture, delete 67 // Now that no AVDACodecImages refer to the SurfaceTexture's texture, delete
54 // the texture name. 68 // the texture name.
55 GLuint service_id = shared_state_->surface_texture_service_id(); 69 GLuint service_id = shared_state_->surface_texture_service_id();
56 if (service_id > 0 && have_context) 70 if (service_id > 0 && have_context)
57 glDeleteTextures(1, &service_id); 71 glDeleteTextures(1, &service_id);
58 } 72 }
59 73
74 scoped_refptr<gfx::SurfaceTexture>
75 AndroidDeferredRenderingBackingStrategy::GetSurfaceTexture() const {
76 return surface_texture_;
77 }
78
60 uint32_t AndroidDeferredRenderingBackingStrategy::GetTextureTarget() const { 79 uint32_t AndroidDeferredRenderingBackingStrategy::GetTextureTarget() const {
61 return GL_TEXTURE_EXTERNAL_OES; 80 return GL_TEXTURE_EXTERNAL_OES;
62 } 81 }
63 82
64 scoped_refptr<gfx::SurfaceTexture>
65 AndroidDeferredRenderingBackingStrategy::CreateSurfaceTexture() {
66 // AVDACodecImage will handle attaching this to a texture later.
67 surface_texture_ = gfx::SurfaceTexture::Create(0);
68 // Detach from our GL context so that the GLImages can attach. It will
69 // silently fail to delete texture 0.
70 surface_texture_->DetachFromGLContext();
71
72 return surface_texture_;
73 }
74
75 gpu::gles2::TextureRef* 83 gpu::gles2::TextureRef*
76 AndroidDeferredRenderingBackingStrategy::GetTextureForPicture( 84 AndroidDeferredRenderingBackingStrategy::GetTextureForPicture(
77 const media::PictureBuffer& picture_buffer) { 85 const media::PictureBuffer& picture_buffer) {
78 RETURN_NULL_IF_NULL(state_provider_->GetGlDecoder()); 86 RETURN_NULL_IF_NULL(state_provider_->GetGlDecoder());
79 gpu::gles2::TextureManager* texture_manager = 87 gpu::gles2::TextureManager* texture_manager =
80 state_provider_->GetGlDecoder()->GetContextGroup()->texture_manager(); 88 state_provider_->GetGlDecoder()->GetContextGroup()->texture_manager();
81 RETURN_NULL_IF_NULL(texture_manager); 89 RETURN_NULL_IF_NULL(texture_manager);
82 gpu::gles2::TextureRef* texture_ref = 90 gpu::gles2::TextureRef* texture_ref =
83 texture_manager->GetTexture(picture_buffer.internal_texture_id()); 91 texture_manager->GetTexture(picture_buffer.internal_texture_id());
84 RETURN_NULL_IF_NULL(texture_ref); 92 RETURN_NULL_IF_NULL(texture_ref);
(...skipping 28 matching lines...) Expand all
113 size.width(), size.height(), 1, 0, GL_RGBA, 121 size.width(), size.height(), 1, 0, GL_RGBA,
114 GL_UNSIGNED_BYTE, gfx::Rect()); 122 GL_UNSIGNED_BYTE, gfx::Rect());
115 123
116 // Override the texture's service_id, so that it will use the one that 124 // Override the texture's service_id, so that it will use the one that
117 // will be / is attached to the SurfaceTexture. 125 // will be / is attached to the SurfaceTexture.
118 DCHECK(shared_state_->surface_texture_service_id()); 126 DCHECK(shared_state_->surface_texture_service_id());
119 texture_ref->texture()->SetUnownedServiceId( 127 texture_ref->texture()->SetUnownedServiceId(
120 shared_state_->surface_texture_service_id()); 128 shared_state_->surface_texture_service_id());
121 129
122 static_cast<AVDACodecImage*>(image.get()) 130 static_cast<AVDACodecImage*>(image.get())
123 ->setTexture(texture_ref->texture()); 131 ->SetTexture(texture_ref->texture());
124 } else { 132 } else {
125 // Clear the unowned service_id, so that this texture is no longer going 133 // Clear the unowned service_id, so that this texture is no longer going
126 // to depend on the surface texture at all. 134 // to depend on the surface texture at all.
127 texture_ref->texture()->SetUnownedServiceId(0); 135 texture_ref->texture()->SetUnownedServiceId(0);
128 } 136 }
129 137
138 // For SurfaceTexture we set the image to UNBOUND so that the implementation
139 // will call CopyTexImage, which is where AVDACodecImage updates the
140 // SurfaceTexture to the right frame.
141 // For SurfaceView we set the image to be BOUND because ScheduleOverlayPlane
142 // expects it. If something tries to sample from this texture it won't work,
143 // but there's no way to sample from a SurfaceView anyway, so it doesn't
144 // matter. The only way to use this texture is to schedule it as an overlay.
145 const gpu::gles2::Texture::ImageState image_state =
146 surface_texture_ ? gpu::gles2::Texture::UNBOUND
147 : gpu::gles2::Texture::BOUND;
130 texture_manager->SetLevelImage(texture_ref, GetTextureTarget(), 0, 148 texture_manager->SetLevelImage(texture_ref, GetTextureTarget(), 0,
131 image.get(), gpu::gles2::Texture::UNBOUND); 149 image.get(), image_state);
132 } 150 }
133 151
134 void AndroidDeferredRenderingBackingStrategy::UseCodecBufferForPictureBuffer( 152 void AndroidDeferredRenderingBackingStrategy::UseCodecBufferForPictureBuffer(
135 int32_t codec_buf_index, 153 int32_t codec_buf_index,
136 const media::PictureBuffer& picture_buffer) { 154 const media::PictureBuffer& picture_buffer) {
137 // Make sure that the decoder is available. 155 // Make sure that the decoder is available.
138 RETURN_IF_NULL(state_provider_->GetGlDecoder()); 156 RETURN_IF_NULL(state_provider_->GetGlDecoder());
139 157
140 // Notify the AVDACodecImage for picture_buffer that it should use the 158 // Notify the AVDACodecImage for picture_buffer that it should use the
141 // decoded buffer codec_buf_index to render this frame. 159 // decoded buffer codec_buf_index to render this frame.
142 AVDACodecImage* avImage = GetImageForPicture(picture_buffer); 160 AVDACodecImage* avda_image = GetImageForPicture(picture_buffer);
143 RETURN_IF_NULL(avImage); 161 RETURN_IF_NULL(avda_image);
144 DCHECK_EQ(avImage->GetMediaCodecBufferIndex(), -1); 162 DCHECK_EQ(avda_image->GetMediaCodecBufferIndex(), -1);
145 // Note that this is not a race, since we do not re-use a PictureBuffer 163 // Note that this is not a race, since we do not re-use a PictureBuffer
146 // until after the CC is done drawing it. 164 // until after the CC is done drawing it.
147 avImage->SetMediaCodecBufferIndex(codec_buf_index); 165 avda_image->SetMediaCodecBufferIndex(codec_buf_index);
148 avImage->SetSize(state_provider_->GetSize()); 166 avda_image->SetSize(state_provider_->GetSize());
149 } 167 }
150 168
151 void AndroidDeferredRenderingBackingStrategy::AssignOnePictureBuffer( 169 void AndroidDeferredRenderingBackingStrategy::AssignOnePictureBuffer(
152 const media::PictureBuffer& picture_buffer) { 170 const media::PictureBuffer& picture_buffer) {
153 // Attach a GLImage to each texture that will use the surface texture. 171 // Attach a GLImage to each texture that will use the surface texture.
154 // We use a refptr here in case SetImageForPicture fails. 172 // We use a refptr here in case SetImageForPicture fails.
155 scoped_refptr<gl::GLImage> gl_image( 173 scoped_refptr<gl::GLImage> gl_image =
156 new AVDACodecImage(shared_state_, media_codec_, 174 new AVDACodecImage(shared_state_, media_codec_,
157 state_provider_->GetGlDecoder(), surface_texture_)); 175 state_provider_->GetGlDecoder(), surface_texture_);
158 SetImageForPicture(picture_buffer, gl_image); 176 SetImageForPicture(picture_buffer, gl_image);
159 } 177 }
160 178
161 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture( 179 void AndroidDeferredRenderingBackingStrategy::ReleaseCodecBufferForPicture(
162 const media::PictureBuffer& picture_buffer) { 180 const media::PictureBuffer& picture_buffer) {
163 AVDACodecImage* avImage = GetImageForPicture(picture_buffer); 181 AVDACodecImage* avda_image = GetImageForPicture(picture_buffer);
164 182
165 // See if there is a media codec buffer still attached to this image. 183 // See if there is a media codec buffer still attached to this image.
166 const int32_t codec_buffer = avImage->GetMediaCodecBufferIndex(); 184 const int32_t codec_buffer = avda_image->GetMediaCodecBufferIndex();
167 185
168 if (codec_buffer >= 0) { 186 if (codec_buffer >= 0) {
169 // PictureBuffer wasn't displayed, so release the buffer. 187 // PictureBuffer wasn't displayed, so release the buffer.
170 media_codec_->ReleaseOutputBuffer(codec_buffer, false); 188 media_codec_->ReleaseOutputBuffer(codec_buffer, false);
171 avImage->SetMediaCodecBufferIndex(-1); 189 avda_image->SetMediaCodecBufferIndex(-1);
172 } 190 }
173 } 191 }
174 192
175 void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer( 193 void AndroidDeferredRenderingBackingStrategy::ReuseOnePictureBuffer(
176 const media::PictureBuffer& picture_buffer) { 194 const media::PictureBuffer& picture_buffer) {
177 // At this point, the CC must be done with the picture. We can't really 195 // At this point, the CC must be done with the picture. We can't really
178 // check for that here directly. it's guaranteed in gpu_video_decoder.cc, 196 // check for that here directly. it's guaranteed in gpu_video_decoder.cc,
179 // when it waits on the sync point before releasing the mailbox. That sync 197 // when it waits on the sync point before releasing the mailbox. That sync
180 // point is inserted by destroying the resource in VideoLayerImpl::DidDraw. 198 // point is inserted by destroying the resource in VideoLayerImpl::DidDraw.
181 ReleaseCodecBufferForPicture(picture_buffer); 199 ReleaseCodecBufferForPicture(picture_buffer);
(...skipping 11 matching lines...) Expand all
193 SetImageForPicture(picture_buffer, nullptr); 211 SetImageForPicture(picture_buffer, nullptr);
194 } 212 }
195 213
196 void AndroidDeferredRenderingBackingStrategy::CodecChanged( 214 void AndroidDeferredRenderingBackingStrategy::CodecChanged(
197 media::VideoCodecBridge* codec, 215 media::VideoCodecBridge* codec,
198 const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) { 216 const AndroidVideoDecodeAccelerator::OutputBufferMap& buffers) {
199 // Clear any outstanding codec buffer indices, since the new codec (if any) 217 // Clear any outstanding codec buffer indices, since the new codec (if any)
200 // doesn't know about them. 218 // doesn't know about them.
201 media_codec_ = codec; 219 media_codec_ = codec;
202 for (const std::pair<int, media::PictureBuffer>& entry : buffers) { 220 for (const std::pair<int, media::PictureBuffer>& entry : buffers) {
203 AVDACodecImage* avImage = GetImageForPicture(entry.second); 221 AVDACodecImage* avda_image = GetImageForPicture(entry.second);
204 avImage->SetMediaCodec(codec); 222 avda_image->SetMediaCodec(codec);
205 avImage->SetMediaCodecBufferIndex(-1); 223 avda_image->SetMediaCodecBufferIndex(-1);
206 } 224 }
207 } 225 }
208 226
209 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() { 227 void AndroidDeferredRenderingBackingStrategy::OnFrameAvailable() {
210 shared_state_->SignalFrameAvailable(); 228 shared_state_->SignalFrameAvailable();
211 } 229 }
212 230
231 bool AndroidDeferredRenderingBackingStrategy::PicturesAreOverlayable() {
232 // SurfaceView frames are always overlayable because that's the only way to
233 // display them.
234 return !surface_texture_;
235 }
236
213 } // namespace content 237 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698