OLD | NEW |
---|---|
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/common/gpu/media/gpu_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/gpu_video_decode_accelerator.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
173 // Notify client that picture buffer is now unused. | 173 // Notify client that picture buffer is now unused. |
174 if (!Send(new AcceleratedVideoDecoderHostMsg_DismissPictureBuffer( | 174 if (!Send(new AcceleratedVideoDecoderHostMsg_DismissPictureBuffer( |
175 host_route_id_, picture_buffer_id))) { | 175 host_route_id_, picture_buffer_id))) { |
176 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer) " | 176 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_DismissPictureBuffer) " |
177 << "failed"; | 177 << "failed"; |
178 } | 178 } |
179 } | 179 } |
180 | 180 |
181 void GpuVideoDecodeAccelerator::PictureReady( | 181 void GpuVideoDecodeAccelerator::PictureReady( |
182 const media::Picture& picture) { | 182 const media::Picture& picture) { |
183 // VDA may call PictureReady on IO thread. SetTextureCleared should run on | |
184 // the child thread. VDA is responsible to call PictureReady on the child | |
185 // thread when a picture buffer is delivered the first time. | |
186 if (child_message_loop_->BelongsToCurrentThread()) | |
piman
2013/09/26 16:50:01
nit: needs brackets per style guide.
wuchengli
2013/09/30 16:11:21
Done.
| |
187 if (!SetTextureCleared(picture)) | |
188 return; | |
piman
2013/09/26 16:50:01
Is there a way to DCHECK that we don't get here on
wuchengli
2013/09/30 16:11:21
Done.
| |
189 | |
183 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( | 190 if (!Send(new AcceleratedVideoDecoderHostMsg_PictureReady( |
184 host_route_id_, | 191 host_route_id_, |
185 picture.picture_buffer_id(), | 192 picture.picture_buffer_id(), |
186 picture.bitstream_buffer_id()))) { | 193 picture.bitstream_buffer_id()))) { |
187 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; | 194 DLOG(ERROR) << "Send(AcceleratedVideoDecoderHostMsg_PictureReady) failed"; |
188 } | 195 } |
189 } | 196 } |
190 | 197 |
191 void GpuVideoDecodeAccelerator::NotifyError( | 198 void GpuVideoDecodeAccelerator::NotifyError( |
192 media::VideoDecodeAccelerator::Error error) { | 199 media::VideoDecodeAccelerator::Error error) { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
320 } | 327 } |
321 gpu::gles2::Texture* info = texture_ref->texture(); | 328 gpu::gles2::Texture* info = texture_ref->texture(); |
322 if (info->target() != texture_target_) { | 329 if (info->target() != texture_target_) { |
323 DLOG(ERROR) << "Texture target mismatch for texture id " | 330 DLOG(ERROR) << "Texture target mismatch for texture id " |
324 << texture_ids[i]; | 331 << texture_ids[i]; |
325 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); | 332 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); |
326 return; | 333 return; |
327 } | 334 } |
328 if (texture_target_ == GL_TEXTURE_EXTERNAL_OES) { | 335 if (texture_target_ == GL_TEXTURE_EXTERNAL_OES) { |
329 // GL_TEXTURE_EXTERNAL_OES textures have their dimensions defined by the | 336 // GL_TEXTURE_EXTERNAL_OES textures have their dimensions defined by the |
330 // underlying EGLImage. Use |texture_dimensions_| for this size. The | 337 // underlying EGLImage. Use |texture_dimensions_| for this size. |
331 // textures cannot be rendered to or cleared, so we set |cleared| true to | |
332 // skip clearing. | |
333 texture_manager->SetLevelInfo(texture_ref, | 338 texture_manager->SetLevelInfo(texture_ref, |
334 GL_TEXTURE_EXTERNAL_OES, | 339 GL_TEXTURE_EXTERNAL_OES, |
335 0, | 340 0, |
336 0, | 341 0, |
337 texture_dimensions_.width(), | 342 texture_dimensions_.width(), |
338 texture_dimensions_.height(), | 343 texture_dimensions_.height(), |
339 1, | 344 1, |
340 0, | 345 0, |
341 0, | 346 0, |
342 0, | 347 0, |
343 true); | 348 false); |
344 } else { | 349 } else { |
345 // For other targets, texture dimensions should already be defined. | 350 // For other targets, texture dimensions should already be defined. |
346 GLsizei width = 0, height = 0; | 351 GLsizei width = 0, height = 0; |
347 info->GetLevelSize(texture_target_, 0, &width, &height); | 352 info->GetLevelSize(texture_target_, 0, &width, &height); |
348 if (width != texture_dimensions_.width() || | 353 if (width != texture_dimensions_.width() || |
349 height != texture_dimensions_.height()) { | 354 height != texture_dimensions_.height()) { |
350 DLOG(ERROR) << "Size mismatch for texture id " << texture_ids[i]; | 355 DLOG(ERROR) << "Size mismatch for texture id " << texture_ids[i]; |
351 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); | 356 NotifyError(media::VideoDecodeAccelerator::INVALID_ARGUMENT); |
352 return; | 357 return; |
353 } | 358 } |
354 } | 359 } |
355 if (!texture_manager->ClearRenderableLevels(command_decoder, texture_ref)) { | |
356 DLOG(ERROR) << "Failed to Clear texture id " << texture_ids[i]; | |
357 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | |
358 return; | |
359 } | |
360 uint32 service_texture_id; | 360 uint32 service_texture_id; |
361 if (!command_decoder->GetServiceTextureId( | 361 if (!command_decoder->GetServiceTextureId( |
362 texture_ids[i], &service_texture_id)) { | 362 texture_ids[i], &service_texture_id)) { |
363 DLOG(ERROR) << "Failed to translate texture!"; | 363 DLOG(ERROR) << "Failed to translate texture!"; |
364 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | 364 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); |
365 return; | 365 return; |
366 } | 366 } |
367 buffers.push_back(media::PictureBuffer( | 367 buffers.push_back(media::PictureBuffer( |
368 buffer_ids[i], texture_dimensions_, service_texture_id)); | 368 buffer_ids[i], texture_dimensions_, service_texture_id)); |
369 } | 369 } |
370 buffer_ids_ = buffer_ids; | |
371 texture_ids_ = texture_ids; | |
370 video_decode_accelerator_->AssignPictureBuffers(buffers); | 372 video_decode_accelerator_->AssignPictureBuffers(buffers); |
371 } | 373 } |
372 | 374 |
373 void GpuVideoDecodeAccelerator::OnReusePictureBuffer( | 375 void GpuVideoDecodeAccelerator::OnReusePictureBuffer( |
374 int32 picture_buffer_id) { | 376 int32 picture_buffer_id) { |
375 DCHECK(video_decode_accelerator_.get()); | 377 DCHECK(video_decode_accelerator_.get()); |
376 video_decode_accelerator_->ReusePictureBuffer(picture_buffer_id); | 378 video_decode_accelerator_->ReusePictureBuffer(picture_buffer_id); |
377 } | 379 } |
378 | 380 |
379 void GpuVideoDecodeAccelerator::OnFlush() { | 381 void GpuVideoDecodeAccelerator::OnFlush() { |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
439 } | 441 } |
440 | 442 |
441 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { | 443 bool GpuVideoDecodeAccelerator::Send(IPC::Message* message) { |
442 DCHECK(stub_); | 444 DCHECK(stub_); |
443 if (filter_.get() && io_message_loop_->BelongsToCurrentThread()) | 445 if (filter_.get() && io_message_loop_->BelongsToCurrentThread()) |
444 return filter_->SendOnIOThread(message); | 446 return filter_->SendOnIOThread(message); |
445 DCHECK(child_message_loop_->BelongsToCurrentThread()); | 447 DCHECK(child_message_loop_->BelongsToCurrentThread()); |
446 return stub_->channel()->Send(message); | 448 return stub_->channel()->Send(message); |
447 } | 449 } |
448 | 450 |
451 bool GpuVideoDecodeAccelerator::SetTextureCleared( | |
452 const media::Picture& picture) { | |
453 DCHECK(child_message_loop_->BelongsToCurrentThread()); | |
454 uint32 i; | |
455 for (i = 0; i < buffer_ids_.size(); i++) | |
piman
2013/09/26 16:50:01
nit: needs brackets per style guide
wuchengli
2013/09/30 16:11:21
Done. Code was changed.
| |
456 if (picture.picture_buffer_id() == buffer_ids_[i]) | |
457 break; | |
458 if (i >= buffer_ids_.size()) | |
459 return true; | |
460 | |
461 gpu::gles2::TextureManager* texture_manager = | |
462 stub_->decoder()->GetContextGroup()->texture_manager(); | |
463 gpu::gles2::TextureRef* texture_ref = texture_manager->GetTexture( | |
464 texture_ids_[i]); | |
piman
2013/09/26 16:50:01
Can you, instead, keep a scoped_refptr<TextureRef>
wuchengli
2013/09/30 16:11:21
Done.
| |
465 if (!texture_ref) { | |
466 DLOG(ERROR) << "Failed to find texture id " << texture_ids_[i]; | |
467 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | |
468 return false; | |
469 } | |
470 gpu::gles2::Texture* info = texture_ref->texture(); | |
471 if (info->target() != texture_target_) { | |
472 DLOG(ERROR) << "Texture target mismatch for texture id " << texture_ids_[i]; | |
473 NotifyError(media::VideoDecodeAccelerator::PLATFORM_FAILURE); | |
474 return false; | |
475 } | |
476 texture_manager->SetLevelCleared(texture_ref, info->target(), 0, true); | |
477 buffer_ids_.erase(buffer_ids_.begin() + i); | |
478 texture_ids_.erase(texture_ids_.begin() + i); | |
Ami GONE FROM CHROMIUM
2013/09/26 16:21:56
Would require less book-keeping as a vector of pai
piman
2013/09/26 16:50:01
+1 on map, given the linear lookup above.
wuchengli
2013/09/30 16:11:21
Done. Changed to a map.
| |
479 return true; | |
480 } | |
481 | |
449 } // namespace content | 482 } // namespace content |
OLD | NEW |