Chromium Code Reviews| 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 |