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 |