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

Side by Side Diff: media/gpu/avda_picture_buffer_manager.cc

Issue 2475133002: Split out AVDA cleanups from SetSurface() change. (Closed)
Patch Set: Cleanup. Created 4 years, 1 month 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 "media/gpu/avda_picture_buffer_manager.h" 5 #include "media/gpu/avda_picture_buffer_manager.h"
6 6
7 #include <EGL/egl.h> 7 #include <EGL/egl.h>
8 #include <EGL/eglext.h> 8 #include <EGL/eglext.h>
9 9
10 #include "base/android/build_info.h" 10 #include "base/android/build_info.h"
(...skipping 22 matching lines...) Expand all
33 #define RETURN_IF_NULL(ptr, ...) \ 33 #define RETURN_IF_NULL(ptr, ...) \
34 do { \ 34 do { \
35 if (!(ptr)) { \ 35 if (!(ptr)) { \
36 DLOG(ERROR) << "Got null for " << #ptr; \ 36 DLOG(ERROR) << "Got null for " << #ptr; \
37 state_provider_->PostError(FROM_HERE, \ 37 state_provider_->PostError(FROM_HERE, \
38 VideoDecodeAccelerator::ILLEGAL_STATE); \ 38 VideoDecodeAccelerator::ILLEGAL_STATE); \
39 return __VA_ARGS__; \ 39 return __VA_ARGS__; \
40 } \ 40 } \
41 } while (0) 41 } while (0)
42 42
43 // Return nullptr if !|ptr|.
44 #define RETURN_NULL_IF_NULL(ptr) RETURN_IF_NULL(ptr, nullptr)
45
46 namespace media { 43 namespace media {
47 namespace { 44 namespace {
48 45
49 // Creates a SurfaceTexture and attaches a new gl texture to it. |*service_id| 46 // Creates a SurfaceTexture and attaches a new gl texture to it. |*service_id|
50 // is set to the new texture id. 47 // is set to the new texture id.
51 scoped_refptr<gl::SurfaceTexture> CreateAttachedSurfaceTexture( 48 scoped_refptr<gl::SurfaceTexture> CreateAttachedSurfaceTexture(
52 base::WeakPtr<gpu::gles2::GLES2Decoder> gl_decoder, 49 base::WeakPtr<gpu::gles2::GLES2Decoder> gl_decoder,
53 GLuint* service_id) { 50 GLuint* service_id) {
54 GLuint texture_id; 51 GLuint texture_id;
55 glGenTextures(1, &texture_id); 52 glGenTextures(1, &texture_id);
(...skipping 14 matching lines...) Expand all
70 // SurfaceTexture and attach it lazily in the compositor's context. But that 67 // SurfaceTexture and attach it lazily in the compositor's context. But that
71 // was flaky because SurfaceTexture#detachFromGLContext() is buggy on a lot of 68 // was flaky because SurfaceTexture#detachFromGLContext() is buggy on a lot of
72 // devices. Now we attach it to the current context, which means we might have 69 // devices. Now we attach it to the current context, which means we might have
73 // to context switch later to call updateTexImage(). Fortunately, if virtual 70 // to context switch later to call updateTexImage(). Fortunately, if virtual
74 // contexts are in use, we won't have to context switch. 71 // contexts are in use, we won't have to context switch.
75 return gl::SurfaceTexture::Create(texture_id); 72 return gl::SurfaceTexture::Create(texture_id);
76 } 73 }
77 74
78 } // namespace 75 } // namespace
79 76
80 // Handle OnFrameAvailable callbacks safely. Since they occur asynchronously, 77 AVDAPictureBufferManager::AVDAPictureBufferManager(
81 // we take care that the object that wants them still exists. WeakPtrs cannot 78 AVDAStateProvider* state_provider)
82 // be used because OnFrameAvailable callbacks can occur on any thread. We also 79 : state_provider_(state_provider), media_codec_(nullptr) {}
83 // can't guarantee when the SurfaceTexture will quit sending callbacks to
84 // coordinate with the destruction of the AVDA and PictureBufferManager, so we
85 // have a separate object that the callback can own.
86 class AVDAPictureBufferManager::OnFrameAvailableHandler
87 : public base::RefCountedThreadSafe<OnFrameAvailableHandler> {
88 public:
89 // We do not retain ownership of |listener|. It must remain valid until after
90 // ClearListener() is called. This will register with |surface_texture| to
91 // receive OnFrameAvailable callbacks.
92 OnFrameAvailableHandler(AVDASharedState* listener,
93 gl::SurfaceTexture* surface_texture)
94 : listener_(listener) {
95 surface_texture->SetFrameAvailableCallbackOnAnyThread(
96 base::Bind(&OnFrameAvailableHandler::OnFrameAvailable,
97 scoped_refptr<OnFrameAvailableHandler>(this)));
98 }
99
100 // Forget about |listener_|, which is required before one deletes it.
101 // No further callbacks will happen once this completes.
102 void ClearListener() {
103 base::AutoLock lock(lock_);
104 listener_ = nullptr;
105 }
106
107 // Notify the listener if there is one.
108 void OnFrameAvailable() {
109 base::AutoLock auto_lock(lock_);
110 if (listener_)
111 listener_->SignalFrameAvailable();
112 }
113
114 private:
115 friend class base::RefCountedThreadSafe<OnFrameAvailableHandler>;
116
117 ~OnFrameAvailableHandler() { DCHECK(!listener_); }
118
119 // Protects changes to listener_.
120 base::Lock lock_;
121
122 // The AVDASharedState that wants the OnFrameAvailable callback.
123 AVDASharedState* listener_;
124
125 DISALLOW_COPY_AND_ASSIGN(OnFrameAvailableHandler);
126 };
127
128 AVDAPictureBufferManager::AVDAPictureBufferManager()
129 : state_provider_(nullptr), media_codec_(nullptr) {}
130 80
131 AVDAPictureBufferManager::~AVDAPictureBufferManager() {} 81 AVDAPictureBufferManager::~AVDAPictureBufferManager() {}
132 82
133 gl::ScopedJavaSurface AVDAPictureBufferManager::Initialize( 83 gl::ScopedJavaSurface AVDAPictureBufferManager::Initialize(int surface_id) {
134 AVDAStateProvider* state_provider,
135 int surface_view_id) {
136 state_provider_ = state_provider;
137 shared_state_ = new AVDASharedState(); 84 shared_state_ = new AVDASharedState();
138 85
139 // Acquire the SurfaceView surface if given a valid id. 86 // Acquire the SurfaceView surface if given a valid id.
140 if (surface_view_id != VideoDecodeAccelerator::Config::kNoSurfaceID) { 87 if (surface_id != SurfaceManager::kNoSurfaceID)
141 return gpu::GpuSurfaceLookup::GetInstance()->AcquireJavaSurface( 88 return gpu::GpuSurfaceLookup::GetInstance()->AcquireJavaSurface(surface_id);
142 surface_view_id);
143 }
144 89
145 // Otherwise create a SurfaceTexture. 90 // Otherwise create a SurfaceTexture.
146 GLuint service_id = 0; 91 GLuint service_id;
147 surface_texture_ = CreateAttachedSurfaceTexture( 92 surface_texture_ = CreateAttachedSurfaceTexture(
148 state_provider_->GetGlDecoder(), &service_id); 93 state_provider_->GetGlDecoder(), &service_id);
149 if (surface_texture_) {
150 on_frame_available_handler_ = new OnFrameAvailableHandler(
151 shared_state_.get(), surface_texture_.get());
152 }
153 shared_state_->SetSurfaceTexture(surface_texture_, service_id); 94 shared_state_->SetSurfaceTexture(surface_texture_, service_id);
154 return gl::ScopedJavaSurface(surface_texture_.get()); 95 return gl::ScopedJavaSurface(surface_texture_.get());
155 } 96 }
156 97
157 void AVDAPictureBufferManager::Destroy(const PictureBufferMap& buffers) { 98 void AVDAPictureBufferManager::Destroy(const PictureBufferMap& buffers) {
158 // Do nothing if Initialize() has not been called. 99 // Do nothing if Initialize() has not been called.
159 if (!shared_state_) 100 if (!shared_state_)
160 return; 101 return;
161 102
162 // If we have an OnFrameAvailable handler, tell it that we no longer want
163 // callbacks.
164 if (on_frame_available_handler_)
165 on_frame_available_handler_->ClearListener();
166
167 ReleaseCodecBuffers(buffers); 103 ReleaseCodecBuffers(buffers);
168 CodecChanged(nullptr); 104 CodecChanged(nullptr);
169 105
170 // Release the surface texture and any back buffers. This will preserve the 106 // Release the surface texture and any back buffers. This will preserve the
171 // front buffer, if any. 107 // front buffer, if any.
172 if (surface_texture_) 108 if (surface_texture_)
173 surface_texture_->ReleaseSurfaceTexture(); 109 surface_texture_->ReleaseSurfaceTexture();
174 } 110 }
175 111
176 uint32_t AVDAPictureBufferManager::GetTextureTarget() const { 112 uint32_t AVDAPictureBufferManager::GetTextureTarget() const {
177 // If we're using a surface texture, then we need an external texture target 113 // If we're using a surface texture, then we need an external texture target
178 // to sample from it. If not, then we'll use 2D transparent textures to draw 114 // to sample from it. If not, then we'll use 2D transparent textures to draw
179 // a transparent hole through which to see the SurfaceView. This is normally 115 // a transparent hole through which to see the SurfaceView. This is normally
180 // needed only for the devtools inspector, since the overlay mechanism handles 116 // needed only for the devtools inspector, since the overlay mechanism handles
181 // it otherwise. 117 // it otherwise.
182 return surface_texture_ ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D; 118 return surface_texture_ ? GL_TEXTURE_EXTERNAL_OES : GL_TEXTURE_2D;
183 } 119 }
184 120
185 gfx::Size AVDAPictureBufferManager::GetPictureBufferSize() const { 121 gfx::Size AVDAPictureBufferManager::GetPictureBufferSize() const {
186 // For SurfaceView, request a 1x1 2D texture to reduce memory during 122 // For SurfaceView, request a 1x1 2D texture to reduce memory during
187 // initialization. For SurfaceTexture, allocate a picture buffer that is the 123 // initialization. For SurfaceTexture, allocate a picture buffer that is the
188 // actual frame size. Note that it will be an external texture anyway, so it 124 // actual frame size. Note that it will be an external texture anyway, so it
189 // doesn't allocate an image of that size. However, it's still important to 125 // doesn't allocate an image of that size. However, it's still important to
190 // get the coded size right, so that VideoLayerImpl doesn't try to scale the 126 // get the coded size right, so that VideoLayerImpl doesn't try to scale the
191 // texture when building the quad for it. 127 // texture when building the quad for it.
192 return surface_texture_ ? state_provider_->GetSize() : gfx::Size(1, 1); 128 return surface_texture_ ? state_provider_->GetSize() : gfx::Size(1, 1);
193 } 129 }
194 130
195 gpu::gles2::TextureRef* AVDAPictureBufferManager::GetTextureForPicture( 131 void AVDAPictureBufferManager::SetImageForPicture(
196 const PictureBuffer& picture_buffer) { 132 const PictureBuffer& picture_buffer,
133 gpu::gles2::GLStreamTextureImage* image) {
197 auto gles_decoder = state_provider_->GetGlDecoder(); 134 auto gles_decoder = state_provider_->GetGlDecoder();
198 RETURN_NULL_IF_NULL(gles_decoder); 135 RETURN_IF_NULL(gles_decoder);
199 RETURN_NULL_IF_NULL(gles_decoder->GetContextGroup()); 136 RETURN_IF_NULL(gles_decoder->GetContextGroup());
200 137
201 gpu::gles2::TextureManager* texture_manager = 138 gpu::gles2::TextureManager* texture_manager =
202 gles_decoder->GetContextGroup()->texture_manager(); 139 gles_decoder->GetContextGroup()->texture_manager();
203 RETURN_NULL_IF_NULL(texture_manager); 140 RETURN_IF_NULL(texture_manager);
204 141
205 DCHECK_LE(1u, picture_buffer.client_texture_ids().size()); 142 DCHECK_LE(1u, picture_buffer.client_texture_ids().size());
206 gpu::gles2::TextureRef* texture_ref = 143 gpu::gles2::TextureRef* texture_ref =
207 texture_manager->GetTexture(picture_buffer.client_texture_ids()[0]); 144 texture_manager->GetTexture(picture_buffer.client_texture_ids()[0]);
208 RETURN_NULL_IF_NULL(texture_ref);
209
210 return texture_ref;
211 }
212
213 void AVDAPictureBufferManager::SetImageForPicture(
214 const PictureBuffer& picture_buffer,
215 const scoped_refptr<gpu::gles2::GLStreamTextureImage>& image) {
216 gpu::gles2::TextureRef* texture_ref = GetTextureForPicture(picture_buffer);
217 RETURN_IF_NULL(texture_ref); 145 RETURN_IF_NULL(texture_ref);
218 146
219 gpu::gles2::TextureManager* texture_manager =
220 state_provider_->GetGlDecoder()->GetContextGroup()->texture_manager();
221 RETURN_IF_NULL(texture_manager);
222
223 // Default to zero which will clear the stream texture service id if one was 147 // Default to zero which will clear the stream texture service id if one was
224 // previously set. 148 // previously set.
225 GLuint stream_texture_service_id = 0; 149 GLuint stream_texture_service_id = 0;
226 if (image) { 150 if (image) {
227 if (shared_state_->surface_texture_service_id() != 0) { 151 // Override the Texture's service id, so that it will use the one that is
228 // Override the Texture's service id, so that it will use the one that is 152 // attached to the SurfaceTexture.
229 // attached to the SurfaceTexture. 153 stream_texture_service_id = shared_state_->surface_texture_service_id();
230 stream_texture_service_id = shared_state_->surface_texture_service_id();
231 }
232 154
233 // Also set the parameters for the level if we're not clearing the image. 155 // Also set the parameters for the level if we're not clearing the image.
234 const gfx::Size size = state_provider_->GetSize(); 156 const gfx::Size size = state_provider_->GetSize();
235 texture_manager->SetLevelInfo(texture_ref, GetTextureTarget(), 0, GL_RGBA, 157 texture_manager->SetLevelInfo(texture_ref, GetTextureTarget(), 0, GL_RGBA,
236 size.width(), size.height(), 1, 0, GL_RGBA, 158 size.width(), size.height(), 1, 0, GL_RGBA,
237 GL_UNSIGNED_BYTE, gfx::Rect()); 159 GL_UNSIGNED_BYTE, gfx::Rect());
238 160
239 static_cast<AVDACodecImage*>(image.get()) 161 static_cast<AVDACodecImage*>(image)->set_texture(texture_ref->texture());
240 ->set_texture(texture_ref->texture());
241 } 162 }
242 163
243 // If we're clearing the image, or setting a SurfaceTexture backed image, we 164 // If we're clearing the image, or setting a SurfaceTexture backed image, we
244 // set the state to UNBOUND. For SurfaceTexture images, this ensures that the 165 // set the state to UNBOUND. For SurfaceTexture images, this ensures that the
245 // implementation will call CopyTexImage, which is where AVDACodecImage 166 // implementation will call CopyTexImage, which is where AVDACodecImage
246 // updates the SurfaceTexture to the right frame. 167 // updates the SurfaceTexture to the right frame.
247 auto image_state = gpu::gles2::Texture::UNBOUND; 168 auto image_state = gpu::gles2::Texture::UNBOUND;
248 // For SurfaceView we set the state to BOUND because ScheduleOverlayPlane 169 // For SurfaceView we set the state to BOUND because ScheduleOverlayPlane
249 // requires it. If something tries to sample from this texture it won't work, 170 // requires it. If something tries to sample from this texture it won't work,
250 // but there's no way to sample from a SurfaceView anyway, so it doesn't 171 // but there's no way to sample from a SurfaceView anyway, so it doesn't
251 // matter. 172 // matter.
252 if (image && !surface_texture_) 173 if (image && !surface_texture_)
253 image_state = gpu::gles2::Texture::BOUND; 174 image_state = gpu::gles2::Texture::BOUND;
254 texture_manager->SetLevelStreamTextureImage(texture_ref, GetTextureTarget(), 175 texture_manager->SetLevelStreamTextureImage(texture_ref, GetTextureTarget(),
255 0, image.get(), image_state, 176 0, image, image_state,
256 stream_texture_service_id); 177 stream_texture_service_id);
257 } 178 }
258 179
180 AVDACodecImage* AVDAPictureBufferManager::GetImageForPicture(
181 int picture_buffer_id) const {
182 auto it = codec_images_.find(picture_buffer_id);
183 return it == codec_images_.end() ? nullptr : it->second.get();
184 }
185
259 void AVDAPictureBufferManager::UseCodecBufferForPictureBuffer( 186 void AVDAPictureBufferManager::UseCodecBufferForPictureBuffer(
260 int32_t codec_buf_index, 187 int32_t codec_buf_index,
261 const PictureBuffer& picture_buffer) { 188 const PictureBuffer& picture_buffer) {
262 // Make sure that the decoder is available. 189 // Make sure that the decoder is available.
263 RETURN_IF_NULL(state_provider_->GetGlDecoder()); 190 RETURN_IF_NULL(state_provider_->GetGlDecoder());
264 191
265 // Notify the AVDACodecImage for picture_buffer that it should use the 192 // Notify the AVDACodecImage for picture_buffer that it should use the
266 // decoded buffer codec_buf_index to render this frame. 193 // decoded buffer codec_buf_index to render this frame.
267 AVDACodecImage* avda_image = 194 AVDACodecImage* avda_image = GetImageForPicture(picture_buffer.id());
268 shared_state_->GetImageForPicture(picture_buffer.id());
269 RETURN_IF_NULL(avda_image); 195 RETURN_IF_NULL(avda_image);
270 196
271 // Note that this is not a race, since we do not re-use a PictureBuffer 197 // Note that this is not a race, since we do not re-use a PictureBuffer
272 // until after the CC is done drawing it. 198 // until after the CC is done drawing it.
273 pictures_out_for_display_.push_back(picture_buffer.id()); 199 pictures_out_for_display_.push_back(picture_buffer.id());
274 avda_image->set_media_codec_buffer_index(codec_buf_index); 200 avda_image->set_media_codec_buffer_index(codec_buf_index);
275 avda_image->set_size(state_provider_->GetSize()); 201 avda_image->set_size(state_provider_->GetSize());
276 202
277 MaybeRenderEarly(); 203 MaybeRenderEarly();
278 } 204 }
279 205
280 void AVDAPictureBufferManager::AssignOnePictureBuffer( 206 void AVDAPictureBufferManager::AssignOnePictureBuffer(
281 const PictureBuffer& picture_buffer, 207 const PictureBuffer& picture_buffer,
282 bool have_context) { 208 bool have_context) {
283 // Attach a GLImage to each texture that will use the surface texture. 209 // Attach a GLImage to each texture that will use the surface texture.
284 // We use a refptr here in case SetImageForPicture fails.
285 scoped_refptr<gpu::gles2::GLStreamTextureImage> gl_image = 210 scoped_refptr<gpu::gles2::GLStreamTextureImage> gl_image =
286 new AVDACodecImage(picture_buffer.id(), shared_state_, media_codec_, 211 codec_images_[picture_buffer.id()] = new AVDACodecImage(
287 state_provider_->GetGlDecoder()); 212 shared_state_, media_codec_, state_provider_->GetGlDecoder());
288 SetImageForPicture(picture_buffer, gl_image); 213 SetImageForPicture(picture_buffer, gl_image.get());
289 214
290 if (!surface_texture_ && have_context) { 215 if (!surface_texture_ && have_context) {
291 // To make devtools work, we're using a 2D texture. Make it transparent, 216 // To make devtools work, we're using a 2D texture. Make it transparent,
292 // so that it draws a hole for the SV to show through. This is only 217 // so that it draws a hole for the SV to show through. This is only
293 // because devtools draws and reads back, which skips overlay processing. 218 // because devtools draws and reads back, which skips overlay processing.
294 // It's unclear why devtools renders twice -- once normally, and once 219 // It's unclear why devtools renders twice -- once normally, and once
295 // including a readback layer. The result is that the device screen 220 // including a readback layer. The result is that the device screen
296 // flashes as we alternately draw the overlay hole and this texture, 221 // flashes as we alternately draw the overlay hole and this texture,
297 // unless we make the texture transparent. 222 // unless we make the texture transparent.
298 static const uint8_t rgba[] = {0, 0, 0, 0}; 223 static const uint8_t rgba[] = {0, 0, 0, 0};
299 const gfx::Size size(1, 1); 224 const gfx::Size size(1, 1);
300 DCHECK_LE(1u, picture_buffer.service_texture_ids().size()); 225 DCHECK_LE(1u, picture_buffer.service_texture_ids().size());
301 glBindTexture(GL_TEXTURE_2D, picture_buffer.service_texture_ids()[0]); 226 glBindTexture(GL_TEXTURE_2D, picture_buffer.service_texture_ids()[0]);
302 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, 227 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0,
303 GL_RGBA, GL_UNSIGNED_BYTE, rgba); 228 GL_RGBA, GL_UNSIGNED_BYTE, rgba);
304 } 229 }
305 } 230 }
306 231
307 void AVDAPictureBufferManager::ReleaseCodecBufferForPicture( 232 void AVDAPictureBufferManager::ReleaseCodecBufferForPicture(
308 const PictureBuffer& picture_buffer) { 233 const PictureBuffer& picture_buffer) {
309 AVDACodecImage* avda_image = 234 AVDACodecImage* avda_image = GetImageForPicture(picture_buffer.id());
310 shared_state_->GetImageForPicture(picture_buffer.id());
311 RETURN_IF_NULL(avda_image); 235 RETURN_IF_NULL(avda_image);
312 avda_image->UpdateSurface(AVDACodecImage::UpdateMode::DISCARD_CODEC_BUFFER); 236 avda_image->UpdateSurface(AVDACodecImage::UpdateMode::DISCARD_CODEC_BUFFER);
313 } 237 }
314 238
315 void AVDAPictureBufferManager::ReuseOnePictureBuffer( 239 void AVDAPictureBufferManager::ReuseOnePictureBuffer(
316 const PictureBuffer& picture_buffer) { 240 const PictureBuffer& picture_buffer) {
317 pictures_out_for_display_.erase( 241 pictures_out_for_display_.erase(
318 std::remove(pictures_out_for_display_.begin(), 242 std::remove(pictures_out_for_display_.begin(),
319 pictures_out_for_display_.end(), picture_buffer.id()), 243 pictures_out_for_display_.end(), picture_buffer.id()),
320 pictures_out_for_display_.end()); 244 pictures_out_for_display_.end());
(...skipping 16 matching lines...) Expand all
337 if (pictures_out_for_display_.empty()) 261 if (pictures_out_for_display_.empty())
338 return; 262 return;
339 263
340 // See if we can consume the front buffer / render to the SurfaceView. Iterate 264 // See if we can consume the front buffer / render to the SurfaceView. Iterate
341 // in reverse to find the most recent front buffer. If none is found, the 265 // in reverse to find the most recent front buffer. If none is found, the
342 // |front_index| will point to the beginning of the array. 266 // |front_index| will point to the beginning of the array.
343 size_t front_index = pictures_out_for_display_.size() - 1; 267 size_t front_index = pictures_out_for_display_.size() - 1;
344 AVDACodecImage* first_renderable_image = nullptr; 268 AVDACodecImage* first_renderable_image = nullptr;
345 for (int i = front_index; i >= 0; --i) { 269 for (int i = front_index; i >= 0; --i) {
346 const int id = pictures_out_for_display_[i]; 270 const int id = pictures_out_for_display_[i];
347 AVDACodecImage* avda_image = shared_state_->GetImageForPicture(id); 271 AVDACodecImage* avda_image = GetImageForPicture(id);
348 if (!avda_image) 272 if (!avda_image)
349 continue; 273 continue;
350 274
351 // Update the front buffer index as we move along to shorten the number of 275 // Update the front buffer index as we move along to shorten the number of
352 // candidate images we look at for back buffer rendering. 276 // candidate images we look at for back buffer rendering.
353 front_index = i; 277 front_index = i;
354 first_renderable_image = avda_image; 278 first_renderable_image = avda_image;
355 279
356 // If we find a front buffer, stop and indicate that front buffer rendering 280 // If we find a front buffer, stop and indicate that front buffer rendering
357 // is not possible since another image is already in the front buffer. 281 // is not possible since another image is already in the front buffer.
(...skipping 10 matching lines...) Expand all
368 292
369 // Back buffer rendering is only available for surface textures. We'll always 293 // Back buffer rendering is only available for surface textures. We'll always
370 // have at least one front buffer, so the next buffer must be the backbuffer. 294 // have at least one front buffer, so the next buffer must be the backbuffer.
371 size_t backbuffer_index = front_index + 1; 295 size_t backbuffer_index = front_index + 1;
372 if (!surface_texture_ || backbuffer_index >= pictures_out_for_display_.size()) 296 if (!surface_texture_ || backbuffer_index >= pictures_out_for_display_.size())
373 return; 297 return;
374 298
375 // See if the back buffer is free. If so, then render the frame adjacent to 299 // See if the back buffer is free. If so, then render the frame adjacent to
376 // the front buffer. The listing is in render order, so we can just use the 300 // the front buffer. The listing is in render order, so we can just use the
377 // first unrendered frame if there is back buffer space. 301 // first unrendered frame if there is back buffer space.
378 first_renderable_image = shared_state_->GetImageForPicture( 302 first_renderable_image =
379 pictures_out_for_display_[backbuffer_index]); 303 GetImageForPicture(pictures_out_for_display_[backbuffer_index]);
380 if (!first_renderable_image || 304 if (!first_renderable_image ||
381 first_renderable_image->was_rendered_to_back_buffer()) { 305 first_renderable_image->was_rendered_to_back_buffer()) {
382 return; 306 return;
383 } 307 }
384 308
385 // Due to the loop in the beginning this should never be true. 309 // Due to the loop in the beginning this should never be true.
386 DCHECK(!first_renderable_image->was_rendered_to_front_buffer()); 310 DCHECK(!first_renderable_image->was_rendered_to_front_buffer());
387 first_renderable_image->UpdateSurface( 311 first_renderable_image->UpdateSurface(
388 AVDACodecImage::UpdateMode::RENDER_TO_BACK_BUFFER); 312 AVDACodecImage::UpdateMode::RENDER_TO_BACK_BUFFER);
389 } 313 }
390 314
391 void AVDAPictureBufferManager::CodecChanged(VideoCodecBridge* codec) { 315 void AVDAPictureBufferManager::CodecChanged(VideoCodecBridge* codec) {
392 media_codec_ = codec; 316 media_codec_ = codec;
393 shared_state_->CodecChanged(codec); 317 for (auto& image_kv : codec_images_)
318 image_kv.second->CodecChanged(codec);
319 shared_state_->clear_release_time();
394 } 320 }
395 321
396 bool AVDAPictureBufferManager::ArePicturesOverlayable() { 322 bool AVDAPictureBufferManager::ArePicturesOverlayable() {
397 // SurfaceView frames are always overlayable because that's the only way to 323 // SurfaceView frames are always overlayable because that's the only way to
398 // display them. 324 // display them.
399 return !surface_texture_; 325 return !surface_texture_;
400 } 326 }
401 327
402 } // namespace media 328 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698