| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/omx_video_decode_accelerator.h" | 5 #include "content/common/gpu/media/omx_video_decode_accelerator.h" |
| 6 | 6 |
| 7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "content/common/gpu/gpu_channel.h" | 9 #include "content/common/gpu/gpu_channel.h" |
| 10 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h" | 10 #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h" |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 } | 273 } |
| 274 | 274 |
| 275 return true; | 275 return true; |
| 276 } | 276 } |
| 277 | 277 |
| 278 void OmxVideoDecodeAccelerator::Decode( | 278 void OmxVideoDecodeAccelerator::Decode( |
| 279 const media::BitstreamBuffer& bitstream_buffer) { | 279 const media::BitstreamBuffer& bitstream_buffer) { |
| 280 DCHECK_EQ(message_loop_, MessageLoop::current()); | 280 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 281 DCHECK(!free_input_buffers_.empty()); | 281 DCHECK(!free_input_buffers_.empty()); |
| 282 | 282 |
| 283 if (current_state_change_ == RESETTING || |
| 284 !queued_bitstream_buffers_.empty()) { |
| 285 queued_bitstream_buffers_.push_back(bitstream_buffer); |
| 286 return; |
| 287 } |
| 288 |
| 283 RETURN_ON_FAILURE(current_state_change_ == NO_TRANSITION && | 289 RETURN_ON_FAILURE(current_state_change_ == NO_TRANSITION && |
| 284 (client_state_ == OMX_StateIdle || | 290 (client_state_ == OMX_StateIdle || |
| 285 client_state_ == OMX_StateExecuting), | 291 client_state_ == OMX_StateExecuting), |
| 286 "Call to Decode() during invalid state or transition: " | 292 "Call to Decode() during invalid state or transition: " |
| 287 << current_state_change_ << ", " << client_state_, | 293 << current_state_change_ << ", " << client_state_, |
| 288 ILLEGAL_STATE,); | 294 ILLEGAL_STATE,); |
| 289 | 295 |
| 290 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); | 296 OMX_BUFFERHEADERTYPE* omx_buffer = free_input_buffers_.front(); |
| 291 free_input_buffers_.pop(); | 297 free_input_buffers_.pop(); |
| 292 | 298 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 308 omx_buffer->nFlags &= ~OMX_BUFFERFLAG_EOS; | 314 omx_buffer->nFlags &= ~OMX_BUFFERFLAG_EOS; |
| 309 // Abuse the header's nTimeStamp field to propagate the bitstream buffer ID to | 315 // Abuse the header's nTimeStamp field to propagate the bitstream buffer ID to |
| 310 // the output buffer's nTimeStamp field, so we can report it back to the | 316 // the output buffer's nTimeStamp field, so we can report it back to the |
| 311 // client in PictureReady(). | 317 // client in PictureReady(). |
| 312 omx_buffer->nTimeStamp = bitstream_buffer.id(); | 318 omx_buffer->nTimeStamp = bitstream_buffer.id(); |
| 313 | 319 |
| 314 // Give this buffer to OMX. | 320 // Give this buffer to OMX. |
| 315 OMX_ERRORTYPE result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); | 321 OMX_ERRORTYPE result = OMX_EmptyThisBuffer(component_handle_, omx_buffer); |
| 316 RETURN_ON_OMX_FAILURE(result, "OMX_EmptyThisBuffer() failed", | 322 RETURN_ON_OMX_FAILURE(result, "OMX_EmptyThisBuffer() failed", |
| 317 PLATFORM_FAILURE,); | 323 PLATFORM_FAILURE,); |
| 318 | |
| 319 input_buffers_at_component_++; | 324 input_buffers_at_component_++; |
| 320 } | 325 } |
| 321 | 326 |
| 322 void OmxVideoDecodeAccelerator::AssignPictureBuffers( | 327 void OmxVideoDecodeAccelerator::AssignPictureBuffers( |
| 323 const std::vector<media::PictureBuffer>& buffers) { | 328 const std::vector<media::PictureBuffer>& buffers) { |
| 324 DCHECK_EQ(message_loop_, MessageLoop::current()); | 329 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 325 RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,); | 330 RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,); |
| 326 | 331 |
| 327 CHECK_EQ(output_buffers_at_component_, 0); | 332 CHECK_EQ(output_buffers_at_component_, 0); |
| 328 CHECK_EQ(fake_output_buffers_.size(), 0U); | 333 CHECK_EQ(fake_output_buffers_.size(), 0U); |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 498 void OmxVideoDecodeAccelerator::OnReachedPauseInResetting() { | 503 void OmxVideoDecodeAccelerator::OnReachedPauseInResetting() { |
| 499 DCHECK_EQ(client_state_, OMX_StateExecuting); | 504 DCHECK_EQ(client_state_, OMX_StateExecuting); |
| 500 client_state_ = OMX_StatePause; | 505 client_state_ = OMX_StatePause; |
| 501 FlushIOPorts(); | 506 FlushIOPorts(); |
| 502 } | 507 } |
| 503 | 508 |
| 504 void OmxVideoDecodeAccelerator::OnReachedExecutingInResetting() { | 509 void OmxVideoDecodeAccelerator::OnReachedExecutingInResetting() { |
| 505 DCHECK_EQ(client_state_, OMX_StatePause); | 510 DCHECK_EQ(client_state_, OMX_StatePause); |
| 506 client_state_ = OMX_StateExecuting; | 511 client_state_ = OMX_StateExecuting; |
| 507 current_state_change_ = NO_TRANSITION; | 512 current_state_change_ = NO_TRANSITION; |
| 508 if (client_) | 513 if (!client_) |
| 509 client_->NotifyResetDone(); | 514 return; |
| 515 |
| 516 // Drain queued bitstream & picture buffers that were held away from the |
| 517 // decoder during the reset. |
| 518 BitstreamBufferList buffers; |
| 519 buffers.swap(queued_bitstream_buffers_); |
| 520 for (size_t i = 0; i < buffers.size(); ++i) |
| 521 Decode(buffers[i]); |
| 522 // Ensure the Decode() calls above didn't end up re-enqueuing. |
| 523 DCHECK(queued_bitstream_buffers_.empty()); |
| 524 for (size_t i = 0; i < queued_picture_buffer_ids_.size(); ++i) |
| 525 ReusePictureBuffer(queued_picture_buffer_ids_[i]); |
| 526 queued_picture_buffer_ids_.clear(); |
| 527 |
| 528 client_->NotifyResetDone(); |
| 510 } | 529 } |
| 511 | 530 |
| 512 // Alert: HORROR ahead! OMX shutdown is an asynchronous dance but our clients | 531 // Alert: HORROR ahead! OMX shutdown is an asynchronous dance but our clients |
| 513 // enjoy the fire-and-forget nature of a synchronous Destroy() call that | 532 // enjoy the fire-and-forget nature of a synchronous Destroy() call that |
| 514 // ensures no further callbacks are made. Since the interface between OMX | 533 // ensures no further callbacks are made. Since the interface between OMX |
| 515 // callbacks and this class is a MessageLoop, we need to ensure the loop | 534 // callbacks and this class is a MessageLoop, we need to ensure the loop |
| 516 // outlives the shutdown dance, even during process shutdown. We do this by | 535 // outlives the shutdown dance, even during process shutdown. We do this by |
| 517 // repeatedly enqueuing a no-op task until shutdown is complete, since | 536 // repeatedly enqueuing a no-op task until shutdown is complete, since |
| 518 // MessageLoop's shutdown drains pending tasks. | 537 // MessageLoop's shutdown drains pending tasks. |
| 519 void OmxVideoDecodeAccelerator::BusyLoopInDestroying() { | 538 void OmxVideoDecodeAccelerator::BusyLoopInDestroying() { |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 return; | 744 return; |
| 726 } | 745 } |
| 727 CHECK(!fake_output_buffers_.size()); | 746 CHECK(!fake_output_buffers_.size()); |
| 728 | 747 |
| 729 if (current_state_change_ == FLUSHING && | 748 if (current_state_change_ == FLUSHING && |
| 730 buffer->nFlags & OMX_BUFFERFLAG_EOS) { | 749 buffer->nFlags & OMX_BUFFERFLAG_EOS) { |
| 731 DCHECK(!saw_eos_during_flush_); | 750 DCHECK(!saw_eos_during_flush_); |
| 732 saw_eos_during_flush_ = true; | 751 saw_eos_during_flush_ = true; |
| 733 } | 752 } |
| 734 | 753 |
| 754 DCHECK(buffer->pAppPrivate); |
| 755 media::Picture* picture = |
| 756 reinterpret_cast<media::Picture*>(buffer->pAppPrivate); |
| 757 int picture_buffer_id = picture->picture_buffer_id(); |
| 758 |
| 735 // During the transition from Executing to Idle, and during port-flushing, all | 759 // During the transition from Executing to Idle, and during port-flushing, all |
| 736 // pictures are sent back through here. Avoid giving them to the client. | 760 // pictures are sent back through here. Avoid giving them to the client. |
| 737 // Also avoid sending the (fake) EOS buffer to the client. | 761 // Also avoid sending the (fake) EOS buffer to the client. |
| 738 if ((current_state_change_ != NO_TRANSITION && | 762 if ((current_state_change_ != NO_TRANSITION && |
| 739 current_state_change_ != FLUSHING) || | 763 current_state_change_ != FLUSHING) || |
| 740 saw_eos_during_flush_) { | 764 saw_eos_during_flush_) { |
| 765 if (current_state_change_ == RESETTING) |
| 766 queued_picture_buffer_ids_.push_back(picture_buffer_id); |
| 741 return; | 767 return; |
| 742 } | 768 } |
| 743 | 769 |
| 744 CHECK(buffer->pAppPrivate); | |
| 745 media::Picture* picture = | |
| 746 reinterpret_cast<media::Picture*>(buffer->pAppPrivate); | |
| 747 // See Decode() for an explanation of this abuse of nTimeStamp. | 770 // See Decode() for an explanation of this abuse of nTimeStamp. |
| 748 picture->set_bitstream_buffer_id(buffer->nTimeStamp); | 771 picture->set_bitstream_buffer_id(buffer->nTimeStamp); |
| 749 if (client_) | 772 if (client_) |
| 750 client_->PictureReady(*picture); | 773 client_->PictureReady(*picture); |
| 751 } | 774 } |
| 752 | 775 |
| 753 void OmxVideoDecodeAccelerator::EmptyBufferDoneTask( | 776 void OmxVideoDecodeAccelerator::EmptyBufferDoneTask( |
| 754 OMX_BUFFERHEADERTYPE* buffer) { | 777 OMX_BUFFERHEADERTYPE* buffer) { |
| 755 DCHECK_EQ(message_loop_, MessageLoop::current()); | 778 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 756 DCHECK_GT(input_buffers_at_component_, 0); | 779 DCHECK_GT(input_buffers_at_component_, 0); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 970 | 993 |
| 971 bool OmxVideoDecodeAccelerator::SendCommandToPort( | 994 bool OmxVideoDecodeAccelerator::SendCommandToPort( |
| 972 OMX_COMMANDTYPE cmd, int port_index) { | 995 OMX_COMMANDTYPE cmd, int port_index) { |
| 973 DCHECK_EQ(message_loop_, MessageLoop::current()); | 996 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 974 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, | 997 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, |
| 975 cmd, port_index, 0); | 998 cmd, port_index, 0); |
| 976 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, | 999 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, |
| 977 PLATFORM_FAILURE, false); | 1000 PLATFORM_FAILURE, false); |
| 978 return true; | 1001 return true; |
| 979 } | 1002 } |
| OLD | NEW |