| // Copyright 2016 Google Inc. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef STARBOARD_RASPI_SHARED_OPEN_MAX_OPEN_MAX_COMPONENT_H_ |
| #define STARBOARD_RASPI_SHARED_OPEN_MAX_OPEN_MAX_COMPONENT_H_ |
| |
| // OMX_SKIP64BIT is required for using VC GPU code. |
| #define OMX_SKIP64BIT 1 |
| |
| #include <IL/OMX_Broadcom.h> |
| #include <interface/vcos/vcos.h> |
| #include <interface/vcos/vcos_logging.h> |
| #include <interface/vmcs_host/vchost.h> |
| #include <vector> |
| |
| #include "starboard/condition_variable.h" |
| #include "starboard/log.h" |
| #include "starboard/mutex.h" |
| #include "starboard/shared/internal_only.h" |
| #include "starboard/shared/starboard/player/video_frame_internal.h" |
| #include "starboard/time.h" |
| |
| namespace starboard { |
| namespace raspi { |
| namespace shared { |
| namespace open_max { |
| |
| template <typename ParamType, OMX_INDEXTYPE index> |
| struct OMXParam : public ParamType { |
| static const OMX_INDEXTYPE Index = index; |
| |
| OMXParam() : ParamType() { |
| ParamType::nSize = sizeof(ParamType); |
| ParamType::nVersion.nVersion = OMX_VERSION; |
| } |
| }; |
| |
| typedef OMXParam<OMX_PARAM_PORTDEFINITIONTYPE, OMX_IndexParamPortDefinition> |
| OMXParamPortDefinition; |
| typedef OMXParam<OMX_VIDEO_PARAM_PORTFORMATTYPE, OMX_IndexParamVideoPortFormat> |
| OMXVideoParamPortFormat; |
| |
| class OpenMaxComponent { |
| public: |
| typedef starboard::shared::starboard::player::VideoFrame VideoFrame; |
| |
| explicit OpenMaxComponent(const char* name, size_t minimum_output_size = 0); |
| ~OpenMaxComponent(); |
| |
| void Start(); |
| void Flush(); |
| |
| void WriteData(const void* data, size_t size, SbTime timestamp); |
| void WriteEOS(); |
| |
| bool ReadVideoFrame(VideoFrame* frame); |
| |
| template <typename ParamType> |
| void GetInputPortParam(ParamType* param) const { |
| param->nPortIndex = input_port_; |
| OMX_ERRORTYPE error = OMX_GetParameter(handle_, ParamType::Index, param); |
| SB_DCHECK(error == OMX_ErrorNone) << std::hex << "OMX_GetParameter(" |
| << ParamType::Index |
| << ") failed with error " << error; |
| } |
| |
| template <typename ParamType> |
| void GetOutputPortParam(ParamType* param) const { |
| param->nPortIndex = output_port_; |
| OMX_ERRORTYPE error = OMX_GetParameter(handle_, ParamType::Index, param); |
| SB_DCHECK(error == OMX_ErrorNone) << std::hex << "OMX_GetParameter(" |
| << ParamType::Index |
| << ") failed with error " << error; |
| } |
| |
| template <typename ParamType> |
| void SetPortParam(const ParamType& param) const { |
| OMX_ERRORTYPE error = OMX_SetParameter(handle_, ParamType::Index, |
| const_cast<ParamType*>(¶m)); |
| SB_DCHECK(error == OMX_ErrorNone) << std::hex << "OMX_SetParameter(" |
| << ParamType::Index |
| << ") failed with error " << error; |
| } |
| |
| private: |
| typedef std::vector<OMX_BUFFERHEADERTYPE*> BufferHeaders; |
| |
| struct EventDescription { |
| OMX_EVENTTYPE event; |
| OMX_U32 data1; |
| OMX_U32 data2; |
| OMX_PTR event_data; |
| }; |
| |
| typedef std::vector<EventDescription> EventDescriptions; |
| |
| void SendCommand(OMX_COMMANDTYPE command, int param); |
| void WaitForCommandCompletion(); |
| void SendCommandAndWaitForCompletion(OMX_COMMANDTYPE command, int param); |
| void EnableInputPortAndAllocateBuffers(); |
| void EnableOutputPortAndAllocateBuffer(); |
| OMX_BUFFERHEADERTYPE* GetUnusedInputBuffer(); |
| |
| OMX_ERRORTYPE OnEvent(OMX_EVENTTYPE event, |
| OMX_U32 data1, |
| OMX_U32 data2, |
| OMX_PTR event_data); |
| OMX_ERRORTYPE OnEmptyBufferDone(OMX_BUFFERHEADERTYPE* buffer); |
| void OnFillBufferDone(OMX_BUFFERHEADERTYPE* buffer); |
| |
| static OMX_ERRORTYPE EventHandler(OMX_HANDLETYPE handle, |
| OMX_PTR app_data, |
| OMX_EVENTTYPE event, |
| OMX_U32 data1, |
| OMX_U32 data2, |
| OMX_PTR event_data); |
| static OMX_ERRORTYPE EmptyBufferDone(OMX_HANDLETYPE handle, |
| OMX_PTR app_data, |
| OMX_BUFFERHEADERTYPE* buffer); |
| static OMX_ERRORTYPE FillBufferDone(OMX_HANDLETYPE handle, |
| OMX_PTR app_data, |
| OMX_BUFFERHEADERTYPE* buffer); |
| |
| Mutex mutex_; |
| ConditionVariable condition_variable_; |
| const size_t minimum_output_size_; |
| OMX_HANDLETYPE handle_; |
| int input_port_; |
| int output_port_; |
| bool output_setting_changed_; |
| EventDescriptions event_descriptions_; |
| BufferHeaders unused_buffers_; |
| OMX_BUFFERHEADERTYPE* output_buffer_; |
| OMXParamPortDefinition output_port_definition_; |
| bool output_buffer_filled_; |
| }; |
| |
| } // namespace open_max |
| } // namespace shared |
| } // namespace raspi |
| } // namespace starboard |
| |
| #endif // STARBOARD_RASPI_SHARED_OPEN_MAX_OPEN_MAX_COMPONENT_H_ |