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 |