blob: d9b5295a08cfc62e922d2455c0fe9d57a5bcc3b1 [file] [log] [blame]
// 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 <queue>
#include <vector>
#include "starboard/condition_variable.h"
#include "starboard/log.h"
#include "starboard/mutex.h"
#include "starboard/shared/internal_only.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:
explicit OpenMaxComponent(const char* name);
virtual ~OpenMaxComponent();
void Start();
void Flush();
void WriteData(const void* data, size_t size, SbTime timestamp);
void WriteEOS();
OMX_BUFFERHEADERTYPE* PeekNextOutputBuffer();
void DropNextOutputBuffer();
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*>(&param));
SB_DCHECK(error == OMX_ErrorNone) << std::hex << "OMX_SetParameter("
<< ParamType::Index
<< ") failed with error " << error;
}
private:
struct EventDescription {
OMX_EVENTTYPE event;
OMX_U32 data1;
OMX_U32 data2;
OMX_PTR event_data;
};
typedef std::vector<EventDescription> EventDescriptions;
virtual bool OnEnableInputPort(OMXParamPortDefinition* port_definition) {
return false;
}
virtual bool OnEnableOutputPort(OMXParamPortDefinition* port_definition) {
return false;
}
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_;
OMX_HANDLETYPE handle_;
int input_port_;
int output_port_;
bool output_setting_changed_;
EventDescriptions event_descriptions_;
std::vector<OMX_BUFFERHEADERTYPE*> input_buffers_;
std::queue<OMX_BUFFERHEADERTYPE*> unused_input_buffers_;
std::vector<OMX_BUFFERHEADERTYPE*> output_buffers_;
std::queue<OMX_BUFFERHEADERTYPE*> filled_output_buffers_;
OMXParamPortDefinition output_port_definition_;
bool output_port_enabled_;
};
} // namespace open_max
} // namespace shared
} // namespace raspi
} // namespace starboard
#endif // STARBOARD_RASPI_SHARED_OPEN_MAX_OPEN_MAX_COMPONENT_H_