| 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/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 return OMX_VIDEO_AVCProfileMax; | 77 return OMX_VIDEO_AVCProfileMax; |
| 78 } | 78 } |
| 79 } | 79 } |
| 80 | 80 |
| 81 // Helper macros for dealing with failure. If |result| evaluates false, emit | 81 // Helper macros for dealing with failure. If |result| evaluates false, emit |
| 82 // |log| to ERROR, register |error| with the decoder, and return |ret_val| | 82 // |log| to ERROR, register |error| with the decoder, and return |ret_val| |
| 83 // (which may be omitted for functions that return void). | 83 // (which may be omitted for functions that return void). |
| 84 #define RETURN_ON_FAILURE(result, log, error, ret_val) \ | 84 #define RETURN_ON_FAILURE(result, log, error, ret_val) \ |
| 85 do { \ | 85 do { \ |
| 86 if (!(result)) { \ | 86 if (!(result)) { \ |
| 87 LOG(ERROR) << log; \ | 87 DLOG(ERROR) << log; \ |
| 88 StopOnError(error); \ | 88 StopOnError(error); \ |
| 89 return ret_val; \ | 89 return ret_val; \ |
| 90 } \ | 90 } \ |
| 91 } while (0) | 91 } while (0) |
| 92 | 92 |
| 93 // OMX-specific version of RETURN_ON_FAILURE which compares with OMX_ErrorNone. | 93 // OMX-specific version of RETURN_ON_FAILURE which compares with OMX_ErrorNone. |
| 94 #define RETURN_ON_OMX_FAILURE(omx_result, log, error, ret_val) \ | 94 #define RETURN_ON_OMX_FAILURE(omx_result, log, error, ret_val) \ |
| 95 RETURN_ON_FAILURE( \ | 95 RETURN_ON_FAILURE( \ |
| 96 ((omx_result) == OMX_ErrorNone), \ | 96 ((omx_result) == OMX_ErrorNone), \ |
| 97 log << ", OMX result: 0x" << std::hex << omx_result, \ | 97 log << ", OMX result: 0x" << std::hex << omx_result, \ |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 RETURN_ON_OMX_FAILURE(result, "OMX_EmptyThisBuffer() failed", | 332 RETURN_ON_OMX_FAILURE(result, "OMX_EmptyThisBuffer() failed", |
| 333 PLATFORM_FAILURE,); | 333 PLATFORM_FAILURE,); |
| 334 input_buffers_at_component_++; | 334 input_buffers_at_component_++; |
| 335 } | 335 } |
| 336 | 336 |
| 337 void OmxVideoDecodeAccelerator::AssignPictureBuffers( | 337 void OmxVideoDecodeAccelerator::AssignPictureBuffers( |
| 338 const std::vector<media::PictureBuffer>& buffers) { | 338 const std::vector<media::PictureBuffer>& buffers) { |
| 339 DCHECK_EQ(message_loop_, MessageLoop::current()); | 339 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 340 RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,); | 340 RETURN_ON_FAILURE(CanFillBuffer(), "Can't fill buffer", ILLEGAL_STATE,); |
| 341 | 341 |
| 342 CHECK_EQ(output_buffers_at_component_, 0); | 342 DCHECK_EQ(output_buffers_at_component_, 0); |
| 343 CHECK_EQ(fake_output_buffers_.size(), 0U); | 343 DCHECK_EQ(fake_output_buffers_.size(), 0U); |
| 344 CHECK_EQ(pictures_.size(), 0U); | 344 DCHECK_EQ(pictures_.size(), 0U); |
| 345 | 345 |
| 346 static Gles2TextureToEglImageTranslator texture2eglImage_translator; | 346 static Gles2TextureToEglImageTranslator texture2eglImage_translator; |
| 347 for (size_t i = 0; i < buffers.size(); ++i) { | 347 for (size_t i = 0; i < buffers.size(); ++i) { |
| 348 EGLImageKHR egl_image = texture2eglImage_translator.TranslateToEglImage( | 348 EGLImageKHR egl_image = texture2eglImage_translator.TranslateToEglImage( |
| 349 egl_display_, egl_context_, buffers[i].texture_id()); | 349 egl_display_, egl_context_, buffers[i].texture_id()); |
| 350 CHECK(pictures_.insert(std::make_pair( | 350 CHECK(pictures_.insert(std::make_pair( |
| 351 buffers[i].id(), OutputPicture(buffers[i], NULL, egl_image))).second); | 351 buffers[i].id(), OutputPicture(buffers[i], NULL, egl_image))).second); |
| 352 } | 352 } |
| 353 | 353 |
| 354 if (pictures_.size() < kNumPictureBuffers) | 354 if (pictures_.size() < kNumPictureBuffers) |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 } | 598 } |
| 599 | 599 |
| 600 void OmxVideoDecodeAccelerator::OnReachedInvalidInErroring() { | 600 void OmxVideoDecodeAccelerator::OnReachedInvalidInErroring() { |
| 601 client_state_ = OMX_StateInvalid; | 601 client_state_ = OMX_StateInvalid; |
| 602 ShutdownComponent(); | 602 ShutdownComponent(); |
| 603 } | 603 } |
| 604 | 604 |
| 605 void OmxVideoDecodeAccelerator::ShutdownComponent() { | 605 void OmxVideoDecodeAccelerator::ShutdownComponent() { |
| 606 OMX_ERRORTYPE result = omx_free_handle(component_handle_); | 606 OMX_ERRORTYPE result = omx_free_handle(component_handle_); |
| 607 if (result != OMX_ErrorNone) | 607 if (result != OMX_ErrorNone) |
| 608 LOG(ERROR) << "OMX_FreeHandle() error. Error code: " << result; | 608 DLOG(ERROR) << "OMX_FreeHandle() error. Error code: " << result; |
| 609 component_handle_ = NULL; | 609 component_handle_ = NULL; |
| 610 client_state_ = OMX_StateMax; | 610 client_state_ = OMX_StateMax; |
| 611 // This Release() call must happen *after* any access to |*this| because it | 611 // This Release() call must happen *after* any access to |*this| because it |
| 612 // might result in |this| being deleted. | 612 // might result in |this| being deleted. |
| 613 Release(); // Since OMX no longer has |this| to call back to. | 613 Release(); // Since OMX no longer has |this| to call back to. |
| 614 omx_deinit(); | 614 omx_deinit(); |
| 615 } | 615 } |
| 616 | 616 |
| 617 void OmxVideoDecodeAccelerator::StopOnError( | 617 void OmxVideoDecodeAccelerator::StopOnError( |
| 618 media::VideoDecodeAccelerator::Error error) { | 618 media::VideoDecodeAccelerator::Error error) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 } | 688 } |
| 689 | 689 |
| 690 void OmxVideoDecodeAccelerator::FreeOutputBuffers() { | 690 void OmxVideoDecodeAccelerator::FreeOutputBuffers() { |
| 691 DCHECK_EQ(message_loop_, MessageLoop::current()); | 691 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 692 // Calls to OMX to free buffers. | 692 // Calls to OMX to free buffers. |
| 693 OMX_ERRORTYPE result; | 693 OMX_ERRORTYPE result; |
| 694 static Gles2TextureToEglImageTranslator texture2eglImage_translator; | 694 static Gles2TextureToEglImageTranslator texture2eglImage_translator; |
| 695 for (OutputPictureById::iterator it = pictures_.begin(); | 695 for (OutputPictureById::iterator it = pictures_.begin(); |
| 696 it != pictures_.end(); ++it) { | 696 it != pictures_.end(); ++it) { |
| 697 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header; | 697 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header; |
| 698 CHECK(omx_buffer); | 698 DCHECK(omx_buffer); |
| 699 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate); | 699 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate); |
| 700 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer); | 700 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer); |
| 701 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer", PLATFORM_FAILURE,); | 701 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer", PLATFORM_FAILURE,); |
| 702 texture2eglImage_translator.DestroyEglImage(egl_display_, | 702 texture2eglImage_translator.DestroyEglImage(egl_display_, |
| 703 it->second.egl_image); | 703 it->second.egl_image); |
| 704 if (client_) | 704 if (client_) |
| 705 client_->DismissPictureBuffer(it->first); | 705 client_->DismissPictureBuffer(it->first); |
| 706 } | 706 } |
| 707 pictures_.clear(); | 707 pictures_.clear(); |
| 708 } | 708 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 reinterpret_cast<media::Picture*>(buffer->pAppPrivate); | 761 reinterpret_cast<media::Picture*>(buffer->pAppPrivate); |
| 762 int picture_buffer_id = picture ? picture->picture_buffer_id() : -1; | 762 int picture_buffer_id = picture ? picture->picture_buffer_id() : -1; |
| 763 TRACE_EVENT2("Video Decoder", "OVDA::FillBufferDoneTask", | 763 TRACE_EVENT2("Video Decoder", "OVDA::FillBufferDoneTask", |
| 764 "Buffer id", buffer->nTimeStamp, | 764 "Buffer id", buffer->nTimeStamp, |
| 765 "Picture id", picture_buffer_id); | 765 "Picture id", picture_buffer_id); |
| 766 DCHECK_EQ(message_loop_, MessageLoop::current()); | 766 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 767 DCHECK_GT(output_buffers_at_component_, 0); | 767 DCHECK_GT(output_buffers_at_component_, 0); |
| 768 --output_buffers_at_component_; | 768 --output_buffers_at_component_; |
| 769 | 769 |
| 770 if (fake_output_buffers_.size() && fake_output_buffers_.count(buffer)) { | 770 if (fake_output_buffers_.size() && fake_output_buffers_.count(buffer)) { |
| 771 CHECK_EQ(fake_output_buffers_.erase(buffer), 1U); | 771 DCHECK_EQ(fake_output_buffers_.erase(buffer), 1U); |
| 772 OMX_ERRORTYPE result = | 772 OMX_ERRORTYPE result = |
| 773 OMX_FreeBuffer(component_handle_, output_port_, buffer); | 773 OMX_FreeBuffer(component_handle_, output_port_, buffer); |
| 774 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer failed", PLATFORM_FAILURE,); | 774 RETURN_ON_OMX_FAILURE(result, "OMX_FreeBuffer failed", PLATFORM_FAILURE,); |
| 775 return; | 775 return; |
| 776 } | 776 } |
| 777 CHECK(!fake_output_buffers_.size()); | 777 DCHECK(!fake_output_buffers_.size()); |
| 778 | 778 |
| 779 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { | 779 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) { |
| 780 // Avoid sending the (fake) EOS buffer to the client. | 780 // Avoid sending the (fake) EOS buffer to the client. |
| 781 return; | 781 return; |
| 782 } | 782 } |
| 783 | 783 |
| 784 // During the transition from Executing to Idle, and during port-flushing, all | 784 // During the transition from Executing to Idle, and during port-flushing, all |
| 785 // pictures are sent back through here. Avoid giving them to the client. | 785 // pictures are sent back through here. Avoid giving them to the client. |
| 786 if (current_state_change_ != NO_TRANSITION && | 786 if (current_state_change_ != NO_TRANSITION && |
| 787 current_state_change_ != FLUSHING) { | 787 current_state_change_ != FLUSHING) { |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1025 | 1025 |
| 1026 bool OmxVideoDecodeAccelerator::SendCommandToPort( | 1026 bool OmxVideoDecodeAccelerator::SendCommandToPort( |
| 1027 OMX_COMMANDTYPE cmd, int port_index) { | 1027 OMX_COMMANDTYPE cmd, int port_index) { |
| 1028 DCHECK_EQ(message_loop_, MessageLoop::current()); | 1028 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 1029 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, | 1029 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, |
| 1030 cmd, port_index, 0); | 1030 cmd, port_index, 0); |
| 1031 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, | 1031 RETURN_ON_OMX_FAILURE(result, "SendCommand() failed" << cmd, |
| 1032 PLATFORM_FAILURE, false); | 1032 PLATFORM_FAILURE, false); |
| 1033 return true; | 1033 return true; |
| 1034 } | 1034 } |
| OLD | NEW |