blob: 9085c1b3b88fe77e68fdb685a3ae5d9201edb95e [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 <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*>(&param));
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_