| 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-inl.h" | 7 #include "base/stl_util-inl.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 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 389 const std::vector<media::GLESBuffer>& buffers) { | 389 const std::vector<media::GLESBuffer>& buffers) { |
| 390 DCHECK_EQ(message_loop_, MessageLoop::current()); | 390 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 391 if (!CanFillBuffer()) { | 391 if (!CanFillBuffer()) { |
| 392 StopOnError(VIDEODECODERERROR_UNINITIALIZED); | 392 StopOnError(VIDEODECODERERROR_UNINITIALIZED); |
| 393 return; | 393 return; |
| 394 } | 394 } |
| 395 CHECK_EQ(output_buffers_at_component_, 0); | 395 CHECK_EQ(output_buffers_at_component_, 0); |
| 396 CHECK_EQ(fake_output_buffers_.size(), 0U); | 396 CHECK_EQ(fake_output_buffers_.size(), 0U); |
| 397 CHECK_EQ(pictures_.size(), 0U); | 397 CHECK_EQ(pictures_.size(), 0U); |
| 398 | 398 |
| 399 static Gles2TextureToEglImageTranslator texture2eglImage_translator; |
| 399 for (size_t i = 0; i < buffers.size(); ++i) { | 400 for (size_t i = 0; i < buffers.size(); ++i) { |
| 401 EGLImageKHR egl_image = texture2eglImage_translator.TranslateToEglImage( |
| 402 egl_display_, egl_context_, buffers[i].texture_id()); |
| 400 CHECK(pictures_.insert(std::make_pair( | 403 CHECK(pictures_.insert(std::make_pair( |
| 401 buffers[i].id(), OutputPicture(buffers[i], NULL))).second); | 404 buffers[i].id(), OutputPicture(buffers[i], NULL, egl_image))).second); |
| 402 } | 405 } |
| 403 | 406 |
| 404 if (pictures_.size() < kNumPictureBuffers) | 407 if (pictures_.size() < kNumPictureBuffers) |
| 405 return; // get all the buffers first. | 408 return; // get all the buffers first. |
| 406 DCHECK_EQ(pictures_.size(), kNumPictureBuffers); | 409 DCHECK_EQ(pictures_.size(), kNumPictureBuffers); |
| 407 | 410 |
| 408 if (!AllocateOutputBuffers()) { | 411 if (!AllocateOutputBuffers()) { |
| 409 LOG(ERROR) << "OMX_AllocateBuffer() Output buffer error"; | 412 LOG(ERROR) << "OMX_AllocateBuffer() Output buffer error"; |
| 410 StopOnError(VIDEODECODERERROR_MEMFAILURE); | 413 StopOnError(VIDEODECODERERROR_MEMFAILURE); |
| 411 return; | 414 return; |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 700 buffer->nInputPortIndex = input_port_; | 703 buffer->nInputPortIndex = input_port_; |
| 701 buffer->nOffset = 0; | 704 buffer->nOffset = 0; |
| 702 buffer->nFlags = 0; | 705 buffer->nFlags = 0; |
| 703 free_input_buffers_.push(buffer); | 706 free_input_buffers_.push(buffer); |
| 704 } | 707 } |
| 705 return true; | 708 return true; |
| 706 } | 709 } |
| 707 | 710 |
| 708 bool OmxVideoDecodeAccelerator::AllocateOutputBuffers() { | 711 bool OmxVideoDecodeAccelerator::AllocateOutputBuffers() { |
| 709 DCHECK_EQ(message_loop_, MessageLoop::current()); | 712 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 710 static Gles2TextureToEglImageTranslator texture2eglImage_translator; | |
| 711 | 713 |
| 712 DCHECK(!pictures_.empty()); | 714 DCHECK(!pictures_.empty()); |
| 713 gfx::Size decoded_pixel_size(pictures_.begin()->second.gles_buffer.size()); | 715 gfx::Size decoded_pixel_size(pictures_.begin()->second.gles_buffer.size()); |
| 714 gfx::Size visible_pixel_size(pictures_.begin()->second.gles_buffer.size()); | 716 gfx::Size visible_pixel_size(pictures_.begin()->second.gles_buffer.size()); |
| 715 for (OutputPictureById::iterator it = pictures_.begin(); | 717 for (OutputPictureById::iterator it = pictures_.begin(); |
| 716 it != pictures_.end(); ++it) { | 718 it != pictures_.end(); ++it) { |
| 717 media::GLESBuffer& gles_buffer = it->second.gles_buffer; | 719 media::GLESBuffer& gles_buffer = it->second.gles_buffer; |
| 718 OMX_BUFFERHEADERTYPE** omx_buffer = &it->second.omx_buffer_header; | 720 OMX_BUFFERHEADERTYPE** omx_buffer = &it->second.omx_buffer_header; |
| 719 DCHECK(!*omx_buffer); | 721 DCHECK(!*omx_buffer); |
| 720 void* egl = texture2eglImage_translator.TranslateToEglImage( | |
| 721 egl_display_, egl_context_, gles_buffer.texture_id()); | |
| 722 OMX_ERRORTYPE result = OMX_UseEGLImage( | 722 OMX_ERRORTYPE result = OMX_UseEGLImage( |
| 723 component_handle_, omx_buffer, output_port_, &gles_buffer, egl); | 723 component_handle_, omx_buffer, output_port_, &gles_buffer, |
| 724 it->second.egl_image); |
| 724 if (result != OMX_ErrorNone) { | 725 if (result != OMX_ErrorNone) { |
| 725 LOG(ERROR) << "OMX_UseEGLImage failed with: " << result; | 726 LOG(ERROR) << "OMX_UseEGLImage failed with: " << result; |
| 726 return false; | 727 return false; |
| 727 } | 728 } |
| 728 // Here we set a garbage bitstream buffer id, and then overwrite it before | 729 // Here we set a garbage bitstream buffer id, and then overwrite it before |
| 729 // passing to PictureReady. | 730 // passing to PictureReady. |
| 730 int garbage_bitstream_buffer_id = -1; | 731 int garbage_bitstream_buffer_id = -1; |
| 731 (*omx_buffer)->pAppPrivate = | 732 (*omx_buffer)->pAppPrivate = |
| 732 new media::Picture(gles_buffer.id(), garbage_bitstream_buffer_id, | 733 new media::Picture(gles_buffer.id(), garbage_bitstream_buffer_id, |
| 733 decoded_pixel_size, visible_pixel_size); | 734 decoded_pixel_size, visible_pixel_size); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 750 return; | 751 return; |
| 751 } | 752 } |
| 752 } | 753 } |
| 753 VLOG(1) << "Input buffers freed."; | 754 VLOG(1) << "Input buffers freed."; |
| 754 } | 755 } |
| 755 | 756 |
| 756 void OmxVideoDecodeAccelerator::FreeOutputBuffers() { | 757 void OmxVideoDecodeAccelerator::FreeOutputBuffers() { |
| 757 DCHECK_EQ(message_loop_, MessageLoop::current()); | 758 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 758 // Calls to OMX to free buffers. | 759 // Calls to OMX to free buffers. |
| 759 OMX_ERRORTYPE result; | 760 OMX_ERRORTYPE result; |
| 761 static Gles2TextureToEglImageTranslator texture2eglImage_translator; |
| 760 for (OutputPictureById::iterator it = pictures_.begin(); | 762 for (OutputPictureById::iterator it = pictures_.begin(); |
| 761 it != pictures_.end(); ++it) { | 763 it != pictures_.end(); ++it) { |
| 762 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header; | 764 OMX_BUFFERHEADERTYPE* omx_buffer = it->second.omx_buffer_header; |
| 763 CHECK(omx_buffer); | 765 CHECK(omx_buffer); |
| 764 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate); | 766 delete reinterpret_cast<media::Picture*>(omx_buffer->pAppPrivate); |
| 765 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer); | 767 result = OMX_FreeBuffer(component_handle_, output_port_, omx_buffer); |
| 766 if (result != OMX_ErrorNone) { | 768 if (result != OMX_ErrorNone) { |
| 767 LOG(ERROR) << "OMX_FreeBuffer failed with: " << result; | 769 LOG(ERROR) << "OMX_FreeBuffer failed with: " << result; |
| 768 StopOnError(VIDEODECODERERROR_INVALIDINPUT); | 770 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 769 return; | 771 return; |
| 770 } | 772 } |
| 773 texture2eglImage_translator.DestroyEglImage(egl_display_, |
| 774 it->second.egl_image); |
| 771 client_->DismissPictureBuffer(it->first); | 775 client_->DismissPictureBuffer(it->first); |
| 772 } | 776 } |
| 773 pictures_.clear(); | 777 pictures_.clear(); |
| 774 } | 778 } |
| 775 | 779 |
| 776 void OmxVideoDecodeAccelerator::OnIndexParamPortDefinitionChanged(int port) { | 780 void OmxVideoDecodeAccelerator::OnIndexParamPortDefinitionChanged(int port) { |
| 777 DCHECK_EQ(message_loop_, MessageLoop::current()); | 781 DCHECK_EQ(message_loop_, MessageLoop::current()); |
| 778 DCHECK_EQ(port, output_port_); | 782 DCHECK_EQ(port, output_port_); |
| 779 DCHECK(!on_port_disable_event_func_); | 783 DCHECK(!on_port_disable_event_func_); |
| 780 on_port_disable_event_func_ = | 784 on_port_disable_event_func_ = |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1054 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, | 1058 OMX_ERRORTYPE result = OMX_SendCommand(component_handle_, |
| 1055 cmd, port_index, 0); | 1059 cmd, port_index, 0); |
| 1056 if (result != OMX_ErrorNone) { | 1060 if (result != OMX_ErrorNone) { |
| 1057 LOG(ERROR) << "SendCommand() failed" << cmd << ":" << result; | 1061 LOG(ERROR) << "SendCommand() failed" << cmd << ":" << result; |
| 1058 StopOnError(VIDEODECODERERROR_INVALIDINPUT); | 1062 StopOnError(VIDEODECODERERROR_INVALIDINPUT); |
| 1059 return; | 1063 return; |
| 1060 } | 1064 } |
| 1061 } | 1065 } |
| 1062 | 1066 |
| 1063 DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator); | 1067 DISABLE_RUNNABLE_METHOD_REFCOUNT(OmxVideoDecodeAccelerator); |
| OLD | NEW |