diff options
| author | Andy Qiu <junhai.qiu@intel.com> | 2011-06-14 22:30:46 -0700 |
|---|---|---|
| committer | Patrick Tjin <pattjin@google.com> | 2014-07-21 22:02:44 -0700 |
| commit | e7ace334fb7c64f7b32aa3746e5a11bcefa60bfb (patch) | |
| tree | 430588acd5460fad3a2fa1e775654c2484b0391c | |
| parent | 14591cb5304857914530e2fc993a62a6ced11552 (diff) | |
| download | android_hardware_intel_common_omx-components-e7ace334fb7c64f7b32aa3746e5a11bcefa60bfb.tar.gz android_hardware_intel_common_omx-components-e7ace334fb7c64f7b32aa3746e5a11bcefa60bfb.tar.bz2 android_hardware_intel_common_omx-components-e7ace334fb7c64f7b32aa3746e5a11bcefa60bfb.zip | |
new repartitioned omx video codec.
Change-Id: Ia8bfcb10589edbf71c79f10b977d67a1d0ccbee5
BZ: 3372
25 files changed, 3536 insertions, 0 deletions
@@ -21,6 +21,7 @@ include $(VENDORS_INTEL_MRST_COMPONENTS_ROOT)/psb-dec/Android.mk include $(VENDORS_INTEL_MRST_COMPONENTS_ROOT)/avc-enc/Android.mk include $(VENDORS_INTEL_MRST_COMPONENTS_ROOT)/h263-enc/Android.mk include $(VENDORS_INTEL_MRST_COMPONENTS_ROOT)/m4v-enc/Android.mk +include $(VENDORS_INTEL_MRST_COMPONENTS_ROOT)/videocodec/Android.mk #intel audio codecs #-include $(VENDORS_INTEL_MRST_COMPONENTS_ROOT)/sst-stub-base/Android.mk diff --git a/videocodec/Android.mk b/videocodec/Android.mk new file mode 100644 index 0000000..a405dc8 --- /dev/null +++ b/videocodec/Android.mk @@ -0,0 +1,117 @@ +ifeq ($(strip $(BOARD_USES_WRS_OMXIL_CORE)),true)
+LOCAL_PATH := $(call my-dir)
+
+VENDORS_INTEL_MRST_LIBMIX_ROOT := hardware/intel/PRIVATE/libmix
+
+include $(CLEAR_VARS)
+
+LOCAL_CPPFLAGS :=
+LOCAL_LDFLAGS :=
+
+LOCAL_SHARED_LIBRARIES := \
+libwrs_omxil_common \
+ libva_videodecoder \
+ liblog
+
+LOCAL_C_INCLUDES := \
+ $(WRS_OMXIL_CORE_ROOT)/utils/inc \
+ $(WRS_OMXIL_CORE_ROOT)/base/inc \
+ $(WRS_OMXIL_CORE_ROOT)/core/inc/khronos/openmax/include \
+ $(PV_INCLUDES) \
+ $(VENDORS_INTEL_MRST_LIBMIX_ROOT)/videodecoder \
+ $(TARGET_OUT_HEADERS)/libva
+
+LOCAL_SRC_FILES := \
+ OMXComponentCodecBase.cpp\
+ OMXVideoDecoderBase.cpp\
+ OMXVideoDecoderAVC.cpp
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libOMXVideoDecoderAVC
+include $(BUILD_SHARED_LIBRARY)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_CPPFLAGS :=
+LOCAL_LDFLAGS :=
+
+LOCAL_SHARED_LIBRARIES := \
+ libwrs_omxil_common \
+ libva_videodecoder \
+ liblog
+
+LOCAL_C_INCLUDES := \
+ $(WRS_OMXIL_CORE_ROOT)/utils/inc \
+ $(WRS_OMXIL_CORE_ROOT)/base/inc \
+ $(WRS_OMXIL_CORE_ROOT)/core/inc/khronos/openmax/include \
+ $(PV_INCLUDES) \
+ $(VENDORS_INTEL_MRST_LIBMIX_ROOT)/videodecoder \
+ $(TARGET_OUT_HEADERS)/libva
+
+LOCAL_SRC_FILES := \
+ OMXComponentCodecBase.cpp\
+ OMXVideoDecoderBase.cpp\
+ OMXVideoDecoderMPEG4.cpp
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libOMXVideoDecoderMPEG4
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_CPPFLAGS :=
+LOCAL_LDFLAGS :=
+
+LOCAL_SHARED_LIBRARIES := \
+ libwrs_omxil_common \
+ libva_videodecoder \
+ liblog
+
+LOCAL_C_INCLUDES := \
+ $(WRS_OMXIL_CORE_ROOT)/utils/inc \
+ $(WRS_OMXIL_CORE_ROOT)/base/inc \
+ $(WRS_OMXIL_CORE_ROOT)/core/inc/khronos/openmax/include \
+ $(PV_INCLUDES) \
+ $(VENDORS_INTEL_MRST_LIBMIX_ROOT)/videodecoder \
+ $(TARGET_OUT_HEADERS)/libva
+
+LOCAL_SRC_FILES := \
+ OMXComponentCodecBase.cpp\
+ OMXVideoDecoderBase.cpp\
+ OMXVideoDecoderH263.cpp
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libOMXVideoDecoderH263
+include $(BUILD_SHARED_LIBRARY)
+
+
+include $(CLEAR_VARS)
+
+LOCAL_CPPFLAGS :=
+LOCAL_LDFLAGS :=
+
+LOCAL_SHARED_LIBRARIES := \
+ libwrs_omxil_common \
+ libva_videodecoder \
+ liblog
+
+LOCAL_C_INCLUDES := \
+ $(WRS_OMXIL_CORE_ROOT)/utils/inc \
+ $(WRS_OMXIL_CORE_ROOT)/base/inc \
+ $(WRS_OMXIL_CORE_ROOT)/core/inc/khronos/openmax/include \
+ $(PV_INCLUDES) \
+ $(VENDORS_INTEL_MRST_LIBMIX_ROOT)/videodecoder \
+ $(TARGET_OUT_HEADERS)/libva
+
+LOCAL_SRC_FILES := \
+ OMXComponentCodecBase.cpp\
+ OMXVideoDecoderBase.cpp\
+ OMXVideoDecoderWMV.cpp
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libOMXVideoDecoderWMV
+include $(BUILD_SHARED_LIBRARY)
+
+
+endif
diff --git a/videocodec/OMXComponentCodecBase.cpp b/videocodec/OMXComponentCodecBase.cpp new file mode 100644 index 0000000..e119a5e --- /dev/null +++ b/videocodec/OMXComponentCodecBase.cpp @@ -0,0 +1,207 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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. +*/ + +#define LOG_NDEBUG 0 +#define LOG_TAG "OMXComponentCodecBase" +#include <utils/Log.h> +#include "OMXComponentCodecBase.h" + + +OMXComponentCodecBase::OMXComponentCodecBase() + : mHandlerList(NULL) { + pthread_mutex_init(&mSerializationLock, NULL); +} + +OMXComponentCodecBase::~OMXComponentCodecBase(){ + HandlerEntry *p = NULL; + while (mHandlerList) { + p = mHandlerList->next; + delete mHandlerList; + mHandlerList = p; + } + + if (this->ports) { + delete this->ports; + this->ports = NULL; + } + + pthread_mutex_destroy(&mSerializationLock); +} + +OMX_ERRORTYPE OMXComponentCodecBase::ComponentAllocatePorts(void) { + OMX_ERRORTYPE ret = OMX_ErrorNone; + + this->ports = new PortBase* [NUMBER_PORTS]; + if (this->ports == NULL) { + return OMX_ErrorInsufficientResources; + } + + ret = InitInputPort(); + CHECK_RETURN_VALUE("InitInputPort"); + + ret = InitOutputPort(); + CHECK_RETURN_VALUE("InitOutputPort"); + + this->nr_ports = NUMBER_PORTS; + + // OMX_PORT_PARAM_TYPE + // Return to OMX client through index OMX_IndexParamVideoInit/OMX_IndexParamAudioInit + // TODO: replace portparam with mPortParam + memset(&this->portparam, 0, sizeof(this->portparam)); + SetTypeHeader(&this->portparam, sizeof(this->portparam)); + this->portparam.nPorts = NUMBER_PORTS; + this->portparam.nStartPortNumber = INPORT_INDEX; + + return ret; +} + + +OMX_ERRORTYPE OMXComponentCodecBase::ComponentGetParameter( + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentParameterStructure) { + + OMXHANDLER handler = FindHandler(nIndex, true); + if (handler == NULL) { + LOGE("ComponentGetParameter: No handler for index %d", nIndex); + return OMX_ErrorUnsupportedIndex; + } + + LOGV("ComponentGetParameter: Index = 0x%x", nIndex); + return (*handler)(this, pComponentParameterStructure); +} + +OMX_ERRORTYPE OMXComponentCodecBase::ComponentSetParameter( + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentParameterStructure) { + + OMXHANDLER handler = FindHandler(nIndex, false); + if (handler == NULL) { + LOGE("ComponentSetParameter: No handler for index %d", nIndex); + return OMX_ErrorUnsupportedIndex; + } + + LOGV("ComponentSetParameter: Index = 0x%x", nIndex); + return (*handler)(this, pComponentParameterStructure); +} + +OMX_ERRORTYPE OMXComponentCodecBase::ComponentGetConfig( + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) { + + OMXHANDLER handler = FindHandler(nIndex, true); + if (handler == NULL) { + LOGE("ComponentGetConfig: No handler for index %d", nIndex); + return OMX_ErrorUnsupportedIndex; + } + + LOGV("ComponentGetConfig: Index = 0x%x", nIndex); + return (*handler)(this, pComponentConfigStructure); +} + +OMX_ERRORTYPE OMXComponentCodecBase::ComponentSetConfig( + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure) { + + OMXHANDLER handler = FindHandler(nIndex, false); + if (handler == NULL) { + LOGE("ComponentSetConfig: No handler for index %d", nIndex); + return OMX_ErrorUnsupportedIndex; + } + + LOGV("ComponentSetConfig: Index = 0x%x", nIndex); + return (*handler)(this, pComponentConfigStructure); +} + +OMX_ERRORTYPE OMXComponentCodecBase::ProcessorInit(void) { + LOGV("OMXComponentCodecBase::ProcessorInit"); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXComponentCodecBase::ProcessorDeinit(void) { + LOGV("OMXComponentCodecBase::ProcessorDeinit"); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXComponentCodecBase::ProcessorStart(void) { + LOGV("OMXComponentCodecBase::ProcessorStart"); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXComponentCodecBase::ProcessorStop(void) { + LOGV("OMXComponentCodecBase::ProcessorStop"); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXComponentCodecBase::ProcessorPause(void) { + LOGV("OMXComponentCodecBase::ProcessorPause"); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXComponentCodecBase::ProcessorResume(void) { + LOGV("OMXComponentCodecBase::ProcessorResume"); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXComponentCodecBase::AddHandler( + OMX_INDEXTYPE type, + OMXComponentCodecBase::OMXHANDLER getter, + OMXComponentCodecBase::OMXHANDLER setter) { + + HandlerEntry *p = mHandlerList; + HandlerEntry *last = NULL; + while (p) { + if (p->type == type) { + p->getter = getter; + p->setter = setter; + return OMX_ErrorNone; + } + last = p; + p = p->next; + } + p = new HandlerEntry; + if (p == NULL) { + return OMX_ErrorInsufficientResources; + } + p->type = type; + p->getter = getter; + p->setter = setter; + p->next = NULL; + + if (last) { + last->next = p; + } else { + mHandlerList = p; + } + return OMX_ErrorNone; +} + +OMXComponentCodecBase::OMXHANDLER OMXComponentCodecBase::FindHandler(OMX_INDEXTYPE type, bool get) { + HandlerEntry *p = mHandlerList; + while (p) { + if (p->type == type) { + return get ? p->getter : p->setter; + } + p = p->next; + } + return NULL; +} + +OMX_ERRORTYPE OMXComponentCodecBase::BuildHandlerList(void) { + return OMX_ErrorNone; +} + + diff --git a/videocodec/OMXComponentCodecBase.h b/videocodec/OMXComponentCodecBase.h new file mode 100644 index 0000000..7d9e0e8 --- /dev/null +++ b/videocodec/OMXComponentCodecBase.h @@ -0,0 +1,99 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 OMX_COMPONENT_CODEC_BASE_H_ +#define OMX_COMPONENT_CODEC_BASE_H_ + +#include <unistd.h> + +#include <OMX_Core.h> +#include <OMX_Component.h> +#include <OMX_IndexExt.h> +#include <OMX_VideoExt.h> +#include <OMX_IntelErrorTypes.h> + +#include <portbase.h> +#include <portvideo.h> + +#include <componentbase.h> +#include "OMXComponentDefines.h" + + + +class OMXComponentCodecBase : public ComponentBase { +public: + OMXComponentCodecBase(); + virtual ~OMXComponentCodecBase(); + +protected: + virtual OMX_ERRORTYPE ComponentAllocatePorts(void); + virtual OMX_ERRORTYPE InitInputPort(void) = 0; + virtual OMX_ERRORTYPE InitOutputPort(void) = 0; + + virtual OMX_ERRORTYPE ComponentGetParameter( + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentParameterStructure); + + virtual OMX_ERRORTYPE ComponentSetParameter( + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentParameterStructure); + + virtual OMX_ERRORTYPE ComponentGetConfig( + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); + + virtual OMX_ERRORTYPE ComponentSetConfig( + OMX_INDEXTYPE nIndex, + OMX_PTR pComponentConfigStructure); + + virtual OMX_ERRORTYPE ProcessorInit(void); /* Loaded to Idle */ + virtual OMX_ERRORTYPE ProcessorDeinit(void);/* Idle to Loaded */ + virtual OMX_ERRORTYPE ProcessorStart(void); /* Idle to Executing/Pause */ + virtual OMX_ERRORTYPE ProcessorStop(void); /* Executing/Pause to Idle */ + virtual OMX_ERRORTYPE ProcessorPause(void); /* Executing to Pause */ + virtual OMX_ERRORTYPE ProcessorResume(void);/* Pause to Executing */ + + // Derived class must implement ProcessorFlush and ProcessorProcess + + enum { + INPORT_INDEX = 0, + OUTPORT_INDEX = 1, + NUMBER_PORTS = 2, + }; + + typedef OMX_ERRORTYPE (*OMXHANDLER)(void *inst, OMX_PTR p); + virtual OMX_ERRORTYPE AddHandler(OMX_INDEXTYPE type, OMXHANDLER getter, OMXHANDLER setter); + virtual OMX_ERRORTYPE BuildHandlerList(void); + +private: + // return getter or setter + OMXHANDLER FindHandler(OMX_INDEXTYPE type, bool get); + +protected: + pthread_mutex_t mSerializationLock; + +private: + struct HandlerEntry { + OMX_INDEXTYPE type; + OMXHANDLER getter; + OMXHANDLER setter; + HandlerEntry *next; + }; + + HandlerEntry *mHandlerList; +}; + +#endif /* OMX_COMPONENT_CODEC_BASE_H_ */ diff --git a/videocodec/OMXComponentDefines.h b/videocodec/OMXComponentDefines.h new file mode 100644 index 0000000..7ee9f57 --- /dev/null +++ b/videocodec/OMXComponentDefines.h @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 OMX_COMPONENT_DEFINES_H_ +#define OMX_COMPONENT_DEFINES_H_ + + + +#define DECLARE_HANDLER(CLASS, FUNC)\ + static OMX_ERRORTYPE Get##FUNC(void *inst, OMX_PTR pStructure) {\ + return ((CLASS*)inst)->Get##FUNC(pStructure);\ + }\ + static OMX_ERRORTYPE Set##FUNC(void *inst, OMX_PTR pStructure) {\ + return ((CLASS*)inst)->Set##FUNC(pStructure);\ + }\ + OMX_ERRORTYPE Get##FUNC(OMX_PTR pStructure);\ + OMX_ERRORTYPE Set##FUNC(OMX_PTR pStructure); + +#define CHECK_TYPE_HEADER(P)\ + ret = CheckTypeHeader((P), sizeof(*(P)));\ + if (ret != OMX_ErrorNone) {\ + LOGE("Invalid type header.");\ + return ret;\ + } + +#define CHECK_PORT_INDEX(P, INDEX)\ + if ((P)->nPortIndex != INDEX) {\ + LOGE("Bad port index %lu, expected: %d", (P)->nPortIndex, INDEX);\ + return OMX_ErrorBadPortIndex;\ + } + +#define CHECK_ENUMERATION_RANGE(INDEX, RANGE)\ + if (INDEX >= RANGE) {\ + LOGE("No more enumeration.");\ + return OMX_ErrorNoMore;\ + } + +#define CHECK_PORT_INDEX_RANGE(P)\ + if ((P)->nPortIndex != 0 && (P)->nPortIndex != 1) {\ + LOGE("Port out of range %lu", (P)->nPortIndex);\ + return OMX_ErrorBadPortIndex;\ + } + +#define CHECK_RETURN_VALUE(FUNC)\ + if (ret != OMX_ErrorNone) {\ + LOGE(FUNC" failed: Error code = 0x%x", ret);\ + return ret;\ + } + +#define CHECK_SET_PARAM_STATE()\ + OMX_STATETYPE state;\ + CBaseGetState((void *)GetComponentHandle(), &state);\ + if (state != OMX_StateLoaded && state != OMX_StateWaitForResources) {\ + LOGE("Invalid state to set param.");\ + return OMX_ErrorIncorrectStateOperation;\ + } + +#define CHECK_SET_CONFIG_STATE()\ + OMX_STATETYPE state;\ + CBaseGetState((void *)GetComponentHandle(), &state);\ + if (state == OMX_StateLoaded || state == OMX_StateWaitForResources) {\ + LOGE("Invalid state to set config");\ + return OMX_ErrorNone;\ + } + +#define DECLARE_OMX_COMPONENT(NAME, ROLE, CLASS) \ + static const char *gName = (const char *)(NAME);\ + static const char *gRole = (const char *)(ROLE);\ + OMX_ERRORTYPE CreateInstance(OMX_PTR *instance) {\ + *instance = NULL;\ + ComponentBase *inst = new CLASS;\ + if (!inst) {\ + return OMX_ErrorInsufficientResources;\ + }\ + *instance = inst;\ + return OMX_ErrorNone;\ + }\ + struct wrs_omxil_cmodule_ops_s gOps = {CreateInstance};\ + struct wrs_omxil_cmodule_s WRS_OMXIL_CMODULE_SYMBOL = {gName, &gRole, 1, &gOps}; + +#endif /* OMX_COMPONENT_DEFINES_H_ */ diff --git a/videocodec/OMXVideoDecoderAVC.cpp b/videocodec/OMXVideoDecoderAVC.cpp new file mode 100644 index 0000000..7bec5af --- /dev/null +++ b/videocodec/OMXVideoDecoderAVC.cpp @@ -0,0 +1,272 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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. +*/ + + +#define LOG_NDEBUG 0 +#define LOG_TAG "OMXVideoDecoderAVC" +#include <utils/Log.h> +#include "OMXVideoDecoderAVC.h" + +// Be sure to have an equal string in VideoDecoderHost.cpp (libmix) +static const char* AVC_MIME_TYPE = "video/h264"; +#define INVALID_PTS (OMX_S64)-1 + + +OMXVideoDecoderAVC::OMXVideoDecoderAVC() + : mAccumulateBuffer(NULL), + mBufferSize(0), + mFilledLen(0), + mTimeStamp(INVALID_PTS) { + LOGV("OMXVideoDecoderAVC is constructed."); + mVideoDecoder = createVideoDecoder(AVC_MIME_TYPE); + if (!mVideoDecoder) { + LOGE("createVideoDecoder failed for \"%s\"", AVC_MIME_TYPE); + } + BuildHandlerList(); +} + +OMXVideoDecoderAVC::~OMXVideoDecoderAVC() { + LOGV("OMXVideoDecoderAVC is destructed."); +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) { + //OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS + memset(&mDecodeSettings, 0, sizeof(mDecodeSettings)); + SetTypeHeader(&mDecodeSettings, sizeof(mDecodeSettings)); + mDecodeSettings.nMaxNumberOfReferenceFrame = NUM_REFERENCE_FRAME; + + // OMX_PARAM_PORTDEFINITIONTYPE + paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT; + paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE; + paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)AVC_MIME_TYPE; + paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + + // OMX_VIDEO_PARAM_AVCTYPE + memset(&mParamAvc, 0, sizeof(mParamAvc)); + SetTypeHeader(&mParamAvc, sizeof(mParamAvc)); + mParamAvc.nPortIndex = INPORT_INDEX; + // TODO: check eProfile/eLevel + mParamAvc.eProfile = OMX_VIDEO_AVCProfileHigh; //OMX_VIDEO_AVCProfileBaseline; + mParamAvc.eLevel = OMX_VIDEO_AVCLevel41; //OMX_VIDEO_AVCLevel1; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorInit(void) { + return OMXVideoDecoderBase::ProcessorInit(); +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorDeinit(void) { + if (mAccumulateBuffer) { + delete mAccumulateBuffer; + } + mAccumulateBuffer = NULL; + mBufferSize = 0; + mFilledLen = 0; + mTimeStamp = INVALID_PTS; + + return OMXVideoDecoderBase::ProcessorDeinit(); +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorFlush(OMX_U32 portIndex) { + mFilledLen = 0; + mTimeStamp = INVALID_PTS; + return OMXVideoDecoderBase::ProcessorFlush(portIndex); +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + return OMXVideoDecoderBase::ProcessorProcess(buffers, retains, numberBuffers); +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::PrepareConfigBuffer(VideoConfigBuffer *p) { + OMX_ERRORTYPE ret; + ret = OMXVideoDecoderBase::PrepareConfigBuffer(p); + CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareConfigBuffer"); + + if (mDecodeSettings.nMaxWidth == 0 || + mDecodeSettings.nMaxHeight == 0) { + return OMX_ErrorNone; + } + + LOGW("AVC Video decoder used in Video Conferencing Mode."); + + // For video conferencing application + p->width = mDecodeSettings.nMaxWidth; + p->height = mDecodeSettings.nMaxHeight; + p->profile = VAProfileH264ConstrainedBaseline; + p->surfaceNumber = mDecodeSettings.nMaxNumberOfReferenceFrame + EXTRA_REFERENCE_FRAME; + p->flag = WANT_ERROR_CONCEALMENT | WANT_LOW_DELAY | HAS_SURFACE_NUMBER | HAS_VA_PROFILE; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { + OMX_ERRORTYPE ret; + ret = OMXVideoDecoderBase::PrepareDecodeBuffer(buffer, retain, p); + CHECK_RETURN_VALUE("OMXVideoDecoderBase::PrepareDecodeBuffer"); + + // OMX_BUFFERFLAG_CODECCONFIG is an optional flag + // if flag is set, buffer will only contain codec data. + if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + LOGV("Received AVC codec data."); + return ret; + } + + // OMX_BUFFERFLAG_ENDOFFRAME is an optional flag + if (buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) { + // TODO: if OMX_BUFFERFLAG_ENDOFFRAME indicates end of a NAL unit and in OMXVideoDecodeBase + // we set buffer flag to HAS_COMPLETE_FRAME, corruption will happen + mTimeStamp = buffer->nTimeStamp; + if (mFilledLen == 0) { + // buffer is not accumulated and it contains a complete frame + return ret; + } + // buffer contains the last part of fragmented frame + ret = AccumulateBuffer(buffer); + CHECK_RETURN_VALUE("AccumulateBuffer"); + ret = FillDecodeBuffer(p); + CHECK_RETURN_VALUE("FillDecodeBuffer"); + return ret; + } + + LOGW("Received fragmented buffer."); + // use time stamp to determine frame boundary + if (mTimeStamp == INVALID_PTS) { + // first ever buffer + mTimeStamp = buffer->nTimeStamp; + } + + if (mTimeStamp != buffer->nTimeStamp && mFilledLen != 0) { + // buffer accumulated contains a complete frame + ret = FillDecodeBuffer(p); + CHECK_RETURN_VALUE("FillDecodeBuffer"); + // retain the current buffer + *retain = BUFFER_RETAIN_GETAGAIN; + } else { + // buffer accumulation for beginning of fragmented buffer (mFilledLen == 0) or + // middle/end of fragmented buffer (mFilledLen != 0) + ret = AccumulateBuffer(buffer); + CHECK_RETURN_VALUE("AccumulateBuffer"); + ret = OMX_ErrorNotReady; + } + + if (buffer->nFilledLen != 0) { + mTimeStamp = buffer->nTimeStamp; + } + return ret; +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::AccumulateBuffer(OMX_BUFFERHEADERTYPE *buffer) { + // check if allocated buffer is big enough + if (mFilledLen + buffer->nFilledLen > mBufferSize) { + mBufferSize = mFilledLen + buffer->nFilledLen; + if (mBufferSize < INPORT_BUFFER_SIZE) { + mBufferSize = INPORT_BUFFER_SIZE; + } + if (mBufferSize == 0) { + return OMX_ErrorBadParameter; + } + OMX_U8 *temp = new OMX_U8 [mBufferSize]; + if (temp == NULL) { + mBufferSize = 0; + return OMX_ErrorInsufficientResources; + } + if (mFilledLen != 0) { + memcpy(temp, mAccumulateBuffer, mFilledLen); + } + if (mAccumulateBuffer) { + delete [] mAccumulateBuffer; + } + mAccumulateBuffer = temp; + } + if (buffer->nFilledLen != 0) { + memcpy(mAccumulateBuffer + mFilledLen, buffer->pBuffer + buffer->nOffset, buffer->nFilledLen); + } + mFilledLen += buffer->nFilledLen; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::FillDecodeBuffer(VideoDecodeBuffer *p) { + p->data = mAccumulateBuffer; + p->size = mFilledLen; + p->timeStamp = mTimeStamp; + p->flag = HAS_COMPLETE_FRAME; + + mFilledLen = 0; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::BuildHandlerList(void) { + OMXVideoDecoderBase::BuildHandlerList(); + AddHandler(OMX_IndexParamVideoAvc, GetParamVideoAvc, SetParamVideoAvc); + AddHandler((OMX_INDEXTYPE)OMX_IndexParamIntelAVCDecodeSettings, GetParamIntelAVCDecodeSettings, SetParamIntelAVCDecodeSettings); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::GetParamVideoAvc(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + + memcpy(p, &mParamAvc, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::SetParamVideoAvc(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + // TODO: do we need to check if port is enabled? + // TODO: see SetPortAvcParam implementation - Can we make simple copy???? + memcpy(&mParamAvc, p, sizeof(mParamAvc)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::GetParamIntelAVCDecodeSettings(OMX_PTR pStructure) { + return OMX_ErrorNotImplemented; +} + +OMX_ERRORTYPE OMXVideoDecoderAVC::SetParamIntelAVCDecodeSettings(OMX_PTR pStructure) { + LOGW("SetParamIntelAVCDecodeSettings"); + + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS *p = (OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + if(p->nMaxNumberOfReferenceFrame == 0) { + // TODO: check if we just return in this case. + p->nMaxNumberOfReferenceFrame = NUM_REFERENCE_FRAME; + } + LOGI("Maximum width = %lu, height = %lu, dpb = %lu", p->nMaxWidth, p->nMaxHeight, p->nMaxNumberOfReferenceFrame); + mDecodeSettings = *p; + + return OMX_ErrorNone; +} + + +DECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.AVC", "video_decoder.avc", OMXVideoDecoderAVC); diff --git a/videocodec/OMXVideoDecoderAVC.h b/videocodec/OMXVideoDecoderAVC.h new file mode 100644 index 0000000..832449c --- /dev/null +++ b/videocodec/OMXVideoDecoderAVC.h @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 OMX_VIDEO_DECODER_AVC_H_ +#define OMX_VIDEO_DECODER_AVC_H_ + + +#include "OMXVideoDecoderBase.h" + +class OMXVideoDecoderAVC : public OMXVideoDecoderBase { +public: + OMXVideoDecoderAVC(); + virtual ~OMXVideoDecoderAVC(); + +protected: + virtual OMX_ERRORTYPE InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput); + virtual OMX_ERRORTYPE ProcessorInit(void); + virtual OMX_ERRORTYPE ProcessorDeinit(void); + virtual OMX_ERRORTYPE ProcessorFlush(OMX_U32 portIndex); + virtual OMX_ERRORTYPE ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers); + + virtual OMX_ERRORTYPE PrepareConfigBuffer(VideoConfigBuffer *p); + virtual OMX_ERRORTYPE PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p); + + virtual OMX_ERRORTYPE BuildHandlerList(void); + DECLARE_HANDLER(OMXVideoDecoderAVC, ParamVideoAvc); + DECLARE_HANDLER(OMXVideoDecoderAVC, ParamIntelAVCDecodeSettings); + +private: + inline OMX_ERRORTYPE AccumulateBuffer(OMX_BUFFERHEADERTYPE *buffer); + inline OMX_ERRORTYPE FillDecodeBuffer(VideoDecodeBuffer *p); + +private: + enum { + // OMX_PARAM_PORTDEFINITIONTYPE + INPORT_MIN_BUFFER_COUNT = 1, + INPORT_ACTUAL_BUFFER_COUNT = 5, + INPORT_BUFFER_SIZE = 1382400, + + // for OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS + // default number of reference frame + NUM_REFERENCE_FRAME = 4, + + // extra number of reference frame to allocate for video conferencing use case. + // total number of reference frame allocated by default in video conferencing use case is 10. + EXTRA_REFERENCE_FRAME = 6, + }; + + OMX_VIDEO_PARAM_AVCTYPE mParamAvc; + + // This parameter is used for video conferencing use case. Application or OMX client can preset + // maximum video size and maximum reference frame (default value is NUM_REFERENCE_FRAME). Using these + // information OMX AVC decoder can start up video decoder library without paring configuration data, or start up + // video decoder at earlier stage. + // If actual video size is less than the maximum video size, frame cropping will be used in the encoder side. + OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS mDecodeSettings; + +private: + OMX_U8 *mAccumulateBuffer; + OMX_U32 mBufferSize; + OMX_U32 mFilledLen; + OMX_TICKS mTimeStamp; +}; + +#endif /* OMX_VIDEO_DECODER_AVC_H_ */ diff --git a/videocodec/OMXVideoDecoderBase.cpp b/videocodec/OMXVideoDecoderBase.cpp new file mode 100644 index 0000000..f3d9f80 --- /dev/null +++ b/videocodec/OMXVideoDecoderBase.cpp @@ -0,0 +1,538 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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. +*/ + +#define LOG_NDEBUG 0 +#define LOG_TAG "OMXVideoDecoderBase" +#include <utils/Log.h> +#include "OMXVideoDecoderBase.h" +#include "vabuffer.h" + +static const char* VA_RAW_MIME_TYPE = "video/x-raw-va"; +static const uint32_t VA_COLOR_FORMAT = 0x7FA00E00; + +OMXVideoDecoderBase::OMXVideoDecoderBase() + : mVideoDecoder(NULL) { +} + +OMXVideoDecoderBase::~OMXVideoDecoderBase() { + releaseVideoDecoder(mVideoDecoder); + + if (this->ports) { + if (this->ports[INPORT_INDEX]) { + delete this->ports[INPORT_INDEX]; + this->ports[INPORT_INDEX] = NULL; + } + + if (this->ports[OUTPORT_INDEX]) { + delete this->ports[OUTPORT_INDEX]; + this->ports[OUTPORT_INDEX] = NULL; + } + } +} + +OMX_ERRORTYPE OMXVideoDecoderBase::InitInputPort(void) { + this->ports[INPORT_INDEX] = new PortVideo; + if (this->ports[INPORT_INDEX] == NULL) { + return OMX_ErrorInsufficientResources; + } + + PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]); + + // OMX_PARAM_PORTDEFINITIONTYPE + OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput; + memset(¶mPortDefinitionInput, 0, sizeof(paramPortDefinitionInput)); + SetTypeHeader(¶mPortDefinitionInput, sizeof(paramPortDefinitionInput)); + paramPortDefinitionInput.nPortIndex = INPORT_INDEX; + paramPortDefinitionInput.eDir = OMX_DirInput; + paramPortDefinitionInput.nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionInput.nBufferCountMin = INPORT_MIN_BUFFER_COUNT; + paramPortDefinitionInput.nBufferSize = INPORT_BUFFER_SIZE; + paramPortDefinitionInput.bEnabled = OMX_TRUE; + paramPortDefinitionInput.bPopulated = OMX_FALSE; + paramPortDefinitionInput.eDomain = OMX_PortDomainVideo; + paramPortDefinitionInput.format.video.cMIMEType = NULL; // to be overridden + paramPortDefinitionInput.format.video.pNativeRender = NULL; + paramPortDefinitionInput.format.video.nFrameWidth = 176; + paramPortDefinitionInput.format.video.nFrameHeight = 144; + paramPortDefinitionInput.format.video.nStride = 0; + paramPortDefinitionInput.format.video.nSliceHeight = 0; + paramPortDefinitionInput.format.video.nBitrate = 64000; + paramPortDefinitionInput.format.video.xFramerate = 15 << 16; + // TODO: check if we need to set bFlagErrorConcealment to OMX_TRUE + paramPortDefinitionInput.format.video.bFlagErrorConcealment = OMX_FALSE; + paramPortDefinitionInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; // to be overridden + paramPortDefinitionInput.format.video.eColorFormat = OMX_COLOR_FormatUnused; + paramPortDefinitionInput.format.video.pNativeWindow = NULL; + paramPortDefinitionInput.bBuffersContiguous = OMX_FALSE; + paramPortDefinitionInput.nBufferAlignment = 0; + + // Derived class must implement this interface and override any field if needed. + // eCompressionFormat and and cMIMEType must be overridden + InitInputPortFormatSpecific(¶mPortDefinitionInput); + + port->SetPortDefinition(¶mPortDefinitionInput, true); + + // OMX_VIDEO_PARAM_PORTFORMATTYPE + OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat; + memset(¶mPortFormat, 0, sizeof(paramPortFormat)); + SetTypeHeader(¶mPortFormat, sizeof(paramPortFormat)); + paramPortFormat.nPortIndex = INPORT_INDEX; + paramPortFormat.nIndex = 0; + paramPortFormat.eCompressionFormat = paramPortDefinitionInput.format.video.eCompressionFormat; + paramPortFormat.eColorFormat = paramPortDefinitionInput.format.video.eColorFormat; + paramPortFormat.xFramerate = paramPortDefinitionInput.format.video.xFramerate; + + port->SetPortVideoParam(¶mPortFormat, true); + + return OMX_ErrorNone; +} + + +OMX_ERRORTYPE OMXVideoDecoderBase::InitOutputPort(void) { + this->ports[OUTPORT_INDEX] = new PortVideo; + if (this->ports[OUTPORT_INDEX] == NULL) { + return OMX_ErrorInsufficientResources; + } + + PortVideo *port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); + + // OMX_PARAM_PORTDEFINITIONTYPE + OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput; + + memset(¶mPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput)); + SetTypeHeader(¶mPortDefinitionOutput, sizeof(paramPortDefinitionOutput)); + + paramPortDefinitionOutput.nPortIndex = OUTPORT_INDEX; + paramPortDefinitionOutput.eDir = OMX_DirOutput; + paramPortDefinitionOutput.nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionOutput.nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT; + paramPortDefinitionOutput.nBufferSize = sizeof(VideoRenderBuffer); + + paramPortDefinitionOutput.bEnabled = OMX_TRUE; + paramPortDefinitionOutput.bPopulated = OMX_FALSE; + paramPortDefinitionOutput.eDomain = OMX_PortDomainVideo; + paramPortDefinitionOutput.format.video.cMIMEType = (OMX_STRING)VA_RAW_MIME_TYPE; + paramPortDefinitionOutput.format.video.pNativeRender = NULL; + paramPortDefinitionOutput.format.video.nFrameWidth = 176; + paramPortDefinitionOutput.format.video.nFrameHeight = 144; + paramPortDefinitionOutput.format.video.nStride = 176; + paramPortDefinitionOutput.format.video.nSliceHeight = 144; + paramPortDefinitionOutput.format.video.nBitrate = 64000; + paramPortDefinitionOutput.format.video.xFramerate = 15 << 16; + paramPortDefinitionOutput.format.video.bFlagErrorConcealment = OMX_FALSE; + paramPortDefinitionOutput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + paramPortDefinitionOutput.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)VA_COLOR_FORMAT; + paramPortDefinitionOutput.format.video.pNativeWindow = NULL; + paramPortDefinitionOutput.bBuffersContiguous = OMX_FALSE; + paramPortDefinitionOutput.nBufferAlignment = 0; + + // no format specific to initialize output port + InitOutputPortFormatSpecific(¶mPortDefinitionOutput); + + port->SetPortDefinition(¶mPortDefinitionOutput, true); + + // OMX_VIDEO_PARAM_PORTFORMATTYPE + OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat; + SetTypeHeader(¶mPortFormat, sizeof(paramPortFormat)); + paramPortFormat.nPortIndex = OUTPORT_INDEX; + paramPortFormat.nIndex = 0; + paramPortFormat.eCompressionFormat = paramPortDefinitionOutput.format.video.eCompressionFormat; + paramPortFormat.eColorFormat = paramPortDefinitionOutput.format.video.eColorFormat; + paramPortFormat.xFramerate = paramPortDefinitionOutput.format.video.xFramerate; + + port->SetPortVideoParam(¶mPortFormat, true); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput) { + // no format specific to initialize output port + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorInit(void) { + OMX_ERRORTYPE ret; + ret = OMXComponentCodecBase::ProcessorInit(); + CHECK_RETURN_VALUE("OMXComponentCodecBase::ProcessorInit"); + + if (mVideoDecoder == NULL) { + LOGE("ProcessorInit: Video decoder is not created."); + return OMX_ErrorDynamicResourcesUnavailable; + } + + VideoConfigBuffer configBuffer; + ret = PrepareConfigBuffer(&configBuffer); + CHECK_RETURN_VALUE("PrepareConfigBuffer"); + + //pthread_mutex_lock(&mSerializationLock); + Decode_Status status = mVideoDecoder->start(&configBuffer); + //pthread_mutex_unlock(&mSerializationLock); + + if (status != DECODE_SUCCESS) { + return TranslateDecodeStatus(status); + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorDeinit(void) { + if (mVideoDecoder == NULL) { + LOGE("ProcessorDeinit: Video decoder is not created."); + return OMX_ErrorDynamicResourcesUnavailable; + } + //pthread_mutex_lock(&mSerializationLock); + mVideoDecoder->stop(); + //pthread_mutex_unlock(&mSerializationLock); + + return OMXComponentCodecBase::ProcessorDeinit(); +} + +OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorStop(void) { + // There is no need to return all retained buffers as we don't accumulate buffer + //this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); + + // TODO: this is new code + ProcessorFlush(OMX_ALL); + + return OMXComponentCodecBase::ProcessorStop(); +} + +OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorFlush(OMX_U32 portIndex) { + LOGI("Flushing port# %lu.", portIndex); + if (mVideoDecoder == NULL) { + LOGE("ProcessorFlush: Video decoder is not created."); + return OMX_ErrorDynamicResourcesUnavailable; + } + + // Portbase has returned all retained buffers. + if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) { + //pthread_mutex_lock(&mSerializationLock); + mVideoDecoder->flush(); + //pthread_mutex_unlock(&mSerializationLock); + } + // TODO: do we need to flush output port? + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + OMX_ERRORTYPE ret; + Decode_Status status; + + // fill render buffer without draining decoder output queue + ret = FillRenderBuffer(buffers[OUTPORT_INDEX], 0); + if (ret == OMX_ErrorNone) { + retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + // TODO: continue decoding + return ret; + } else if (ret != OMX_ErrorNotReady) { + return ret; + } + + VideoDecodeBuffer decodeBuffer; + // PrepareDecodeBuffer will set retain to either BUFFER_RETAIN_GETAGAIN or BUFFER_RETAIN_NOT_RETAIN + ret = PrepareDecodeBuffer(buffers[INPORT_INDEX], &retains[INPORT_INDEX], &decodeBuffer); + if (ret == OMX_ErrorNotReady) { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + return OMX_ErrorNone; + } else if (ret != OMX_ErrorNone) { + return ret; + } + + if (decodeBuffer.size != 0) { + //pthread_mutex_lock(&mSerializationLock); + status = mVideoDecoder->decode(&decodeBuffer); + //pthread_mutex_unlock(&mSerializationLock); + + if (status == DECODE_FORMAT_CHANGE) { + ret = HandleFormatChange(); + CHECK_RETURN_VALUE("HandleFormatChange"); + buffers[OUTPORT_INDEX]->nFilledLen = 0; + // don't use the output buffer if format is changed. + return OMX_ErrorNone; + } else if (status == DECODE_NO_CONFIG) { + LOGW("Decoder returns DECODE_NO_CONFIG."); + retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + return OMX_ErrorNone; + } else if (status == DECODE_NO_REFERENCE) { + LOGW("Decoder returns DECODE_NO_REFERENCE."); + retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + return OMX_ErrorNone; + } + else if (status != DECODE_SUCCESS && status != DECODE_FRAME_DROPPED) { + return TranslateDecodeStatus(status); + } + } + // drain the decoder output queue when in EOS state and fill the render buffer + ret = FillRenderBuffer(buffers[OUTPORT_INDEX], buffers[INPORT_INDEX]->nFlags); + if (ret == OMX_ErrorNotReady) { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + ret = OMX_ErrorNone; + } + return ret; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::PrepareConfigBuffer(VideoConfigBuffer *p) { + // default config buffer preparation + memset(p, 0, sizeof(VideoConfigBuffer)); + + const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = this->ports[INPORT_INDEX]->GetPortDefinition(); + if (paramPortDefinitionInput == NULL) { + return OMX_ErrorBadParameter; + } + + p->width = paramPortDefinitionInput->format.video.nFrameWidth; + p->height = paramPortDefinitionInput->format.video.nFrameHeight; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { + // default decode buffer preparation + memset(p, 0, sizeof(VideoDecodeBuffer)); + if (buffer->nFilledLen == 0) { + LOGW("Len of filled data to decode is 0."); + return OMX_ErrorNone; //OMX_ErrorBadParameter; + } + + if (buffer->pBuffer == NULL) { + LOGE("Buffer to decode is empty."); + return OMX_ErrorBadParameter; + } + + if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + LOGI("Buffer has OMX_BUFFERFLAG_CODECCONFIG flag."); + } + + if (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) { + // TODO: Handle OMX_BUFFERFLAG_DECODEONLY : drop the decoded frame without rendering it. + LOGW("Buffer has OMX_BUFFERFLAG_DECODEONLY flag."); + } + + p->data = buffer->pBuffer + buffer->nOffset; + p->size = buffer->nFilledLen; + p->timeStamp = buffer->nTimeStamp; + if (buffer->nFlags & OMX_BUFFERFLAG_ENDOFFRAME) { + // TODO: OMX_BUFFERFLAG_ENDOFFRAME can be used to indicate end of a NAL unit. + // setting this flag may cause corruption if buffer does not contain end-of-frame data. + p->flag = HAS_COMPLETE_FRAME; + } + + *retain= BUFFER_RETAIN_NOT_RETAIN; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::FillRenderBuffer(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 inportBufferFlags) { + bool draining = (inportBufferFlags & OMX_BUFFERFLAG_EOS); + //pthread_mutex_lock(&mSerializationLock); + const VideoRenderBuffer *renderBuffer = mVideoDecoder->getOutput(draining); + //pthread_mutex_unlock(&mSerializationLock); + if (renderBuffer == NULL) { + buffer->nFilledLen = 0; + if (draining) { + LOGI("EOS received"); + buffer->nFlags = OMX_BUFFERFLAG_EOS; + return OMX_ErrorNone; + } + return OMX_ErrorNotReady; + } + buffer->nFlags = OMX_BUFFERFLAG_ENDOFFRAME; + buffer->nFilledLen = sizeof(VABuffer); + buffer->nTimeStamp = renderBuffer->timeStamp; + VABuffer *p = (VABuffer *)(buffer->pBuffer + buffer->nOffset); + + // TODO: pass cropping data to VABuffer + p->surface = renderBuffer->surface; + p->display = renderBuffer->display; + p->frame_structure = renderBuffer->scanFormat; + + //LOGV("outputting frame %.2f", buffer->nTimeStamp/1E6); + + // TODO: set "RenderDone" in next "FillRenderBuffer" with the same OMX buffer header. + // this indicates surface is "rendered" and can be reused for decoding. + renderBuffer->renderDone = true; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::HandleFormatChange(void) { + LOGW("Video format is changed."); + //pthread_mutex_lock(&mSerializationLock); + const VideoFormatInfo *formatInfo = mVideoDecoder->getFormatInfo(); + //pthread_mutex_unlock(&mSerializationLock); + + // Sync port definition as it may change. + OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput, paramPortDefinitionOutput; + + memcpy(¶mPortDefinitionInput, + this->ports[INPORT_INDEX]->GetPortDefinition(), + sizeof(paramPortDefinitionInput)); + + memcpy(¶mPortDefinitionOutput, + this->ports[OUTPORT_INDEX]->GetPortDefinition(), + sizeof(paramPortDefinitionOutput)); + + int width = formatInfo->width; + int height = formatInfo->height; + int stride = formatInfo->width; + int sliceHeight = formatInfo->height; + + int widthCropped = formatInfo->width - formatInfo->cropLeft - formatInfo->cropRight; + int heightCropped = formatInfo->height - formatInfo->cropTop - formatInfo->cropBottom; + int strideCropped = widthCropped; + int sliceHeightCropped = heightCropped; + + LOGV("Original size = %lu x %lu, new size = %d x %d, cropped size = %d x %d", + paramPortDefinitionInput.format.video.nFrameWidth, + paramPortDefinitionInput.format.video.nFrameHeight, + width, height, widthCropped, heightCropped); + + + if (width == paramPortDefinitionInput.format.video.nFrameWidth && + height == paramPortDefinitionInput.format.video.nFrameHeight && + widthCropped == paramPortDefinitionOutput.format.video.nFrameWidth && + heightCropped == paramPortDefinitionOutput.format.video.nFrameHeight) { + // reporting portsetting change may crash media player. + LOGW("Change of portsetting is not reported as size is not changed."); + return OMX_ErrorNone; + } + + paramPortDefinitionInput.format.video.nFrameWidth = width; + paramPortDefinitionInput.format.video.nFrameHeight = height; + paramPortDefinitionInput.format.video.nStride = stride; + paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight; + + paramPortDefinitionOutput.format.video.nFrameWidth = widthCropped; + paramPortDefinitionOutput.format.video.nFrameHeight = heightCropped; + paramPortDefinitionOutput.format.video.nStride = strideCropped; + paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeightCropped; + + + this->ports[INPORT_INDEX]->SetPortDefinition(¶mPortDefinitionInput, true); + this->ports[OUTPORT_INDEX]->SetPortDefinition(¶mPortDefinitionOutput, true); + + this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged(); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::TranslateDecodeStatus(Decode_Status status) { + switch (status) { + case DECODE_NEED_RESTART: + LOGE("Decoder returned DECODE_NEED_RESTART"); + return (OMX_ERRORTYPE)OMX_ErrorIntelVideoNotPermitted; + case DECODE_NO_CONFIG: + LOGE("Decoder returned DECODE_NO_CONFIG"); + return (OMX_ERRORTYPE)OMX_ErrorIntelMissingConfig; + case DECODE_NO_SURFACE: + LOGE("Decoder returned DECODE_NO_SURFACE"); + return OMX_ErrorDynamicResourcesUnavailable; + case DECODE_NO_REFERENCE: + LOGE("Decoder returned DECODE_NO_REFERENCE"); + return OMX_ErrorDynamicResourcesUnavailable; // TO DO + case DECODE_NO_PARSER: + LOGE("Decoder returned DECODE_NO_PARSER"); + return OMX_ErrorDynamicResourcesUnavailable; + case DECODE_INVALID_DATA: + LOGE("Decoder returned DECODE_INVALID_DATA"); + return OMX_ErrorBadParameter; + case DECODE_DRIVER_FAIL: + LOGE("Decoder returned DECODE_DRIVER_FAIL"); + return OMX_ErrorHardware; + case DECODE_PARSER_FAIL: + LOGE("Decoder returned DECODE_PARSER_FAIL"); + return (OMX_ERRORTYPE)OMX_ErrorIntelProcessStream; // OMX_ErrorStreamCorrupt + case DECODE_MEMORY_FAIL: + LOGE("Decoder returned DECODE_MEMORY_FAIL"); + return OMX_ErrorInsufficientResources; + case DECODE_FAIL: + LOGE("Decoder returned DECODE_FAIL"); + return OMX_ErrorUndefined; + case DECODE_SUCCESS: + return OMX_ErrorNone; + case DECODE_FORMAT_CHANGE: + LOGW("Decoder returned DECODE_FORMAT_CHANGE"); + return OMX_ErrorNone; + case DECODE_FRAME_DROPPED: + LOGI("Decoder returned DECODE_FRAME_DROPPED"); + return OMX_ErrorNone; + default: + LOGW("Decoder returned unknown error"); + return OMX_ErrorUndefined; + } +} + +OMX_ERRORTYPE OMXVideoDecoderBase::BuildHandlerList(void) { + OMXComponentCodecBase::BuildHandlerList(); + AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat); + //AddHandler(PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX, GetCapabilityFlags, SetCapabilityFlags); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::GetParamVideoPortFormat(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX_RANGE(p); + CHECK_ENUMERATION_RANGE(p->nIndex, 1); + + PortVideo *port = NULL; + port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); + memcpy(p, port->GetPortVideoParam(), sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::SetParamVideoPortFormat(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX_RANGE(p); + CHECK_SET_PARAM_STATE(); + + // TODO: do we need to check if port is enabled? + PortVideo *port = NULL; + port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); + port->SetPortVideoParam(p, false); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::GetCapabilityFlags(OMX_PTR pStructure) { +#if 0 + OMX_ERRORTYPE ret; + PV_OMXComponentCapabilityFlagsType *p = (PV_OMXComponentCapabilityFlagsType *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX_RANGE(p); + + p->iIsOMXComponentMultiThreaded = OMX_TRUE; + p->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + p->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_TRUE; + p->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE; + p->iOMXComponentSupportsPartialFrames = OMX_TRUE; + p->iOMXComponentCanHandleIncompleteFrames = OMX_TRUE; + p->iOMXComponentUsesNALStartCodes = OMX_FALSE; + p->iOMXComponentUsesFullAVCFrames = OMX_FALSE; +#endif + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderBase::SetCapabilityFlags(OMX_PTR pStructure) { + LOGE("SetCapabilityFlags is not supported."); + return OMX_ErrorUnsupportedSetting; +} + diff --git a/videocodec/OMXVideoDecoderBase.h b/videocodec/OMXVideoDecoderBase.h new file mode 100644 index 0000000..7e75860 --- /dev/null +++ b/videocodec/OMXVideoDecoderBase.h @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 OMX_VIDEO_DECODER_BASE_H_ +#define OMX_VIDEO_DECODER_BASE_H_ + + +#include "OMXComponentCodecBase.h" +#include "VideoDecoderInterface.h" +#include "VideoDecoderHost.h" + +class OMXVideoDecoderBase : public OMXComponentCodecBase { +public: + OMXVideoDecoderBase(); + virtual ~OMXVideoDecoderBase(); + +protected: + virtual OMX_ERRORTYPE InitInputPort(void); + virtual OMX_ERRORTYPE InitOutputPort(void); + virtual OMX_ERRORTYPE InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *input) = 0; + virtual OMX_ERRORTYPE InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *output); + + virtual OMX_ERRORTYPE ProcessorInit(void); + virtual OMX_ERRORTYPE ProcessorDeinit(void); + //virtual OMX_ERRORTYPE ProcessorStart(void); + virtual OMX_ERRORTYPE ProcessorStop(void); + //virtual OMX_ERRORTYPE ProcessorPause(void); + //virtual OMX_ERRORTYPE ProcessorResume(void); + virtual OMX_ERRORTYPE ProcessorFlush(OMX_U32 portIndex); + virtual OMX_ERRORTYPE ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers); + + virtual OMX_ERRORTYPE PrepareConfigBuffer(VideoConfigBuffer *p); + virtual OMX_ERRORTYPE PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p); + virtual OMX_ERRORTYPE FillRenderBuffer(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 inportBufferFlags); + virtual OMX_ERRORTYPE HandleFormatChange(void); + virtual OMX_ERRORTYPE TranslateDecodeStatus(Decode_Status status); + + virtual OMX_ERRORTYPE BuildHandlerList(void); + DECLARE_HANDLER(OMXVideoDecoderBase, ParamVideoPortFormat); + DECLARE_HANDLER(OMXVideoDecoderBase, CapabilityFlags); + +private: + enum { + // OMX_PARAM_PORTDEFINITIONTYPE + INPORT_MIN_BUFFER_COUNT = 1, + INPORT_ACTUAL_BUFFER_COUNT = 256, + INPORT_BUFFER_SIZE = 1382400, + + // OMX_PARAM_PORTDEFINITIONTYPE + OUTPORT_MIN_BUFFER_COUNT = 1, + OUTPORT_ACTUAL_BUFFER_COUNT = 2, + OUTPORT_BUFFER_SIZE = 1382400, + }; + +protected: + IVideoDecoder *mVideoDecoder; +}; + +#endif /* OMX_VIDEO_DECODER_BASE_H_ */ diff --git a/videocodec/OMXVideoDecoderH263.cpp b/videocodec/OMXVideoDecoderH263.cpp new file mode 100644 index 0000000..ce5434c --- /dev/null +++ b/videocodec/OMXVideoDecoderH263.cpp @@ -0,0 +1,113 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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. +*/ + + +// #define LOG_NDEBUG 0 +#define LOG_TAG "OMXVideoDecoderH263" +#include <utils/Log.h> +#include "OMXVideoDecoderH263.h" + +// Be sure to have an equal string in VideoDecoderHost.cpp (libmix) +static const char* H263_MIME_TYPE = "video/h263"; + +OMXVideoDecoderH263::OMXVideoDecoderH263() { + LOGV("OMXVideoDecoderH263 is constructed."); + mVideoDecoder = createVideoDecoder(H263_MIME_TYPE); + if (!mVideoDecoder) { + LOGE("createVideoDecoder failed for \"%s\"", H263_MIME_TYPE); + } + BuildHandlerList(); +} + +OMXVideoDecoderH263::~OMXVideoDecoderH263() { + LOGV("OMXVideoDecoderH263 is destructed."); +} + +OMX_ERRORTYPE OMXVideoDecoderH263::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) { + // OMX_PARAM_PORTDEFINITIONTYPE + paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT; + paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE; + paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)H263_MIME_TYPE; + paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + + // OMX_VIDEO_PARAM_H263TYPE + memset(&mParamH263, 0, sizeof(mParamH263)); + SetTypeHeader(&mParamH263, sizeof(mParamH263)); + mParamH263.nPortIndex = INPORT_INDEX; + // TODO: check eProfile/eLevel + mParamH263.eProfile = OMX_VIDEO_H263ProfileBaseline; + mParamH263.eLevel = OMX_VIDEO_H263Level70; //OMX_VIDEO_H263Level10; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderH263::ProcessorInit(void) { + return OMXVideoDecoderBase::ProcessorInit(); +} + +OMX_ERRORTYPE OMXVideoDecoderH263::ProcessorDeinit(void) { + return OMXVideoDecoderBase::ProcessorDeinit(); +} + +OMX_ERRORTYPE OMXVideoDecoderH263::ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + return OMXVideoDecoderBase::ProcessorProcess(buffers, retains, numberBuffers); +} + +OMX_ERRORTYPE OMXVideoDecoderH263::PrepareConfigBuffer(VideoConfigBuffer *p) { + return OMXVideoDecoderBase::PrepareConfigBuffer(p); +} + +OMX_ERRORTYPE OMXVideoDecoderH263::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { + return OMXVideoDecoderBase::PrepareDecodeBuffer(buffer, retain, p); +} + +OMX_ERRORTYPE OMXVideoDecoderH263::BuildHandlerList(void) { + OMXVideoDecoderBase::BuildHandlerList(); + AddHandler(OMX_IndexParamVideoH263, GetParamVideoH263, SetParamVideoH263); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderH263::GetParamVideoH263(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_H263TYPE *p = (OMX_VIDEO_PARAM_H263TYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + + memcpy(p, &mParamH263, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderH263::SetParamVideoH263(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_H263TYPE *p = (OMX_VIDEO_PARAM_H263TYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + // TODO: do we need to check if port is enabled? + // TODO: see SetPortH263Param implementation - Can we make simple copy???? + memcpy(&mParamH263, p, sizeof(mParamH263)); + return OMX_ErrorNone; +} + + +DECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.H263", "video_decoder.h263", OMXVideoDecoderH263); + diff --git a/videocodec/OMXVideoDecoderH263.h b/videocodec/OMXVideoDecoderH263.h new file mode 100644 index 0000000..cfedb78 --- /dev/null +++ b/videocodec/OMXVideoDecoderH263.h @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 OMX_VIDEO_DECODER_H263_H_ +#define OMX_VIDEO_DECODER_H263_H_ + + +#include "OMXVideoDecoderBase.h" + +class OMXVideoDecoderH263 : public OMXVideoDecoderBase { +public: + OMXVideoDecoderH263(); + virtual ~OMXVideoDecoderH263(); + +protected: + virtual OMX_ERRORTYPE InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput); + virtual OMX_ERRORTYPE ProcessorInit(void); + virtual OMX_ERRORTYPE ProcessorDeinit(void); + virtual OMX_ERRORTYPE ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers); + + virtual OMX_ERRORTYPE PrepareConfigBuffer(VideoConfigBuffer *p); + virtual OMX_ERRORTYPE PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p); + + virtual OMX_ERRORTYPE BuildHandlerList(void); + DECLARE_HANDLER(OMXVideoDecoderH263, ParamVideoH263); + +private: + enum { + // OMX_PARAM_PORTDEFINITIONTYPE + INPORT_MIN_BUFFER_COUNT = 1, + INPORT_ACTUAL_BUFFER_COUNT = 5, + INPORT_BUFFER_SIZE = 1382400, + }; + + OMX_VIDEO_PARAM_H263TYPE mParamH263; +}; + + +#endif /* OMX_VIDEO_DECODER_H263_H_ */ diff --git a/videocodec/OMXVideoDecoderMPEG4.cpp b/videocodec/OMXVideoDecoderMPEG4.cpp new file mode 100644 index 0000000..850899a --- /dev/null +++ b/videocodec/OMXVideoDecoderMPEG4.cpp @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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. +*/ + + +// #define LOG_NDEBUG 0 +#define LOG_TAG "OMXVideoDecoderMPEG4" +#include <utils/Log.h> +#include "OMXVideoDecoderMPEG4.h" + +// Be sure to have an equal string in VideoDecoderHost.cpp (libmix) +static const char* MPEG4_MIME_TYPE = "video/mpeg4"; + +OMXVideoDecoderMPEG4::OMXVideoDecoderMPEG4() { + LOGV("OMXVideoDecoderMPEG4 is constructed."); + mVideoDecoder = createVideoDecoder(MPEG4_MIME_TYPE); + if (!mVideoDecoder) { + LOGE("createVideoDecoder failed for \"%s\"", MPEG4_MIME_TYPE); + } + BuildHandlerList(); +} + +OMXVideoDecoderMPEG4::~OMXVideoDecoderMPEG4() { + LOGV("OMXVideoDecoderMPEG4 is destructed."); +} + +OMX_ERRORTYPE OMXVideoDecoderMPEG4::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) { + // OMX_PARAM_PORTDEFINITIONTYPE + paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT; + paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE; + paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)MPEG4_MIME_TYPE; + paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + + // OMX_VIDEO_PARAM_MPEG4TYPE + memset(&mParamMpeg4, 0, sizeof(mParamMpeg4)); + SetTypeHeader(&mParamMpeg4, sizeof(mParamMpeg4)); + mParamMpeg4.nPortIndex = INPORT_INDEX; + // TODO: check eProfile/eLevel + mParamMpeg4.eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; //OMX_VIDEO_MPEG4ProfileSimple; + mParamMpeg4.eLevel = OMX_VIDEO_MPEG4Level3; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderMPEG4::ProcessorInit(void) { + return OMXVideoDecoderBase::ProcessorInit(); +} + +OMX_ERRORTYPE OMXVideoDecoderMPEG4::ProcessorDeinit(void) { + return OMXVideoDecoderBase::ProcessorDeinit(); +} + +OMX_ERRORTYPE OMXVideoDecoderMPEG4::ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + return OMXVideoDecoderBase::ProcessorProcess(buffers, retains, numberBuffers); +} + +OMX_ERRORTYPE OMXVideoDecoderMPEG4::PrepareConfigBuffer(VideoConfigBuffer *p) { + return OMXVideoDecoderBase::PrepareConfigBuffer(p); +} + +OMX_ERRORTYPE OMXVideoDecoderMPEG4::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { + return OMXVideoDecoderBase::PrepareDecodeBuffer(buffer, retain, p); +} + +OMX_ERRORTYPE OMXVideoDecoderMPEG4::BuildHandlerList(void) { + OMXVideoDecoderBase::BuildHandlerList(); + AddHandler(OMX_IndexParamVideoMpeg4, GetParamVideoMpeg4, SetParamVideoMpeg4); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderMPEG4::GetParamVideoMpeg4(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_MPEG4TYPE *p = (OMX_VIDEO_PARAM_MPEG4TYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + + memcpy(p, &mParamMpeg4, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderMPEG4::SetParamVideoMpeg4(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_MPEG4TYPE *p = (OMX_VIDEO_PARAM_MPEG4TYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + // TODO: do we need to check if port is enabled? + // TODO: see SetPortMpeg4Param implementation - Can we make simple copy???? + memcpy(&mParamMpeg4, p, sizeof(mParamMpeg4)); + return OMX_ErrorNone; +} + + +DECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.MPEG4", "video_decoder.mpeg4", OMXVideoDecoderMPEG4); + + diff --git a/videocodec/OMXVideoDecoderMPEG4.h b/videocodec/OMXVideoDecoderMPEG4.h new file mode 100644 index 0000000..43fab7b --- /dev/null +++ b/videocodec/OMXVideoDecoderMPEG4.h @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 OMX_VIDEO_DECODER_MPEG4_H_ +#define OMX_VIDEO_DECODER_MPEG4_H_ + + +#include "OMXVideoDecoderBase.h" + +class OMXVideoDecoderMPEG4 : public OMXVideoDecoderBase { +public: + OMXVideoDecoderMPEG4(); + virtual ~OMXVideoDecoderMPEG4(); + +protected: + virtual OMX_ERRORTYPE InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput); + virtual OMX_ERRORTYPE ProcessorInit(void); + virtual OMX_ERRORTYPE ProcessorDeinit(void); + virtual OMX_ERRORTYPE ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers); + + virtual OMX_ERRORTYPE PrepareConfigBuffer(VideoConfigBuffer *p); + virtual OMX_ERRORTYPE PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p); + + virtual OMX_ERRORTYPE BuildHandlerList(void); + DECLARE_HANDLER(OMXVideoDecoderMPEG4, ParamVideoMpeg4); + +private: + enum { + // OMX_PARAM_PORTDEFINITIONTYPE + INPORT_MIN_BUFFER_COUNT = 1, + INPORT_ACTUAL_BUFFER_COUNT = 5, + INPORT_BUFFER_SIZE = 1382400, + }; + + OMX_VIDEO_PARAM_MPEG4TYPE mParamMpeg4; +}; + +#endif /* OMX_VIDEO_DECODER_MPEG4_H_ */ diff --git a/videocodec/OMXVideoDecoderWMV.cpp b/videocodec/OMXVideoDecoderWMV.cpp new file mode 100644 index 0000000..e97c693 --- /dev/null +++ b/videocodec/OMXVideoDecoderWMV.cpp @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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. +*/ + + +// #define LOG_NDEBUG 0 +#define LOG_TAG "OMXVideoDecoderWMV" +#include <utils/Log.h> +#include "OMXVideoDecoderWMV.h" + +// Be sure to have an equal string in VideoDecoderHost.cpp (libmix) +static const char* WMV_MIME_TYPE = "video/wmv"; + +OMXVideoDecoderWMV::OMXVideoDecoderWMV() { + LOGV("OMXVideoDecoderWMV is constructed."); + mVideoDecoder = createVideoDecoder(WMV_MIME_TYPE); + if (!mVideoDecoder) { + LOGE("createVideoDecoder failed for \"%s\"", WMV_MIME_TYPE); + } + BuildHandlerList(); +} + +OMXVideoDecoderWMV::~OMXVideoDecoderWMV() { + LOGV("OMXVideoDecoderWMV is destructed."); +} + +OMX_ERRORTYPE OMXVideoDecoderWMV::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) { + // OMX_PARAM_PORTDEFINITIONTYPE + paramPortDefinitionInput->nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionInput->nBufferCountMin = INPORT_MIN_BUFFER_COUNT; + paramPortDefinitionInput->nBufferSize = INPORT_BUFFER_SIZE; + paramPortDefinitionInput->format.video.cMIMEType = (OMX_STRING)WMV_MIME_TYPE; + paramPortDefinitionInput->format.video.eCompressionFormat = OMX_VIDEO_CodingWMV; + + // OMX_VIDEO_PARAM_WMVTYPE + memset(&mParamWmv, 0, sizeof(mParamWmv)); + SetTypeHeader(&mParamWmv, sizeof(mParamWmv)); + mParamWmv.nPortIndex = INPORT_INDEX; + mParamWmv.eFormat = OMX_VIDEO_WMVFormat9; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderWMV::ProcessorInit(void) { + return OMXVideoDecoderBase::ProcessorInit(); +} + +OMX_ERRORTYPE OMXVideoDecoderWMV::ProcessorDeinit(void) { + return OMXVideoDecoderBase::ProcessorDeinit(); +} + +OMX_ERRORTYPE OMXVideoDecoderWMV::ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + return OMXVideoDecoderBase::ProcessorProcess(buffers, retains, numberBuffers); +} + +OMX_ERRORTYPE OMXVideoDecoderWMV::PrepareConfigBuffer(VideoConfigBuffer *p) { + return OMXVideoDecoderBase::PrepareConfigBuffer(p); +} + +OMX_ERRORTYPE OMXVideoDecoderWMV::PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p) { + return OMXVideoDecoderBase::PrepareDecodeBuffer(buffer, retain, p); +} + +OMX_ERRORTYPE OMXVideoDecoderWMV::BuildHandlerList(void) { + OMXVideoDecoderBase::BuildHandlerList(); + AddHandler(OMX_IndexParamVideoWmv, GetParamVideoWmv, SetParamVideoWmv); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderWMV::GetParamVideoWmv(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_WMVTYPE *p = (OMX_VIDEO_PARAM_WMVTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + + memcpy(p, &mParamWmv, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoDecoderWMV::SetParamVideoWmv(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_WMVTYPE *p = (OMX_VIDEO_PARAM_WMVTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, INPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + // TODO: do we need to check if port is enabled? + memcpy(&mParamWmv, p, sizeof(mParamWmv)); + return OMX_ErrorNone; +} + + +DECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.WMV", "video_decoder.wmv", OMXVideoDecoderWMV); + + diff --git a/videocodec/OMXVideoDecoderWMV.h b/videocodec/OMXVideoDecoderWMV.h new file mode 100644 index 0000000..963d9ab --- /dev/null +++ b/videocodec/OMXVideoDecoderWMV.h @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 OMX_VIDEO_DECODER_WMV_H_ +#define OMX_VIDEO_DECODER_WMV_H_ + + +#include "OMXVideoDecoderBase.h" + +class OMXVideoDecoderWMV : public OMXVideoDecoderBase { +public: + OMXVideoDecoderWMV(); + virtual ~OMXVideoDecoderWMV(); + +protected: + virtual OMX_ERRORTYPE InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput); + virtual OMX_ERRORTYPE ProcessorInit(void); + virtual OMX_ERRORTYPE ProcessorDeinit(void); + virtual OMX_ERRORTYPE ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers); + + virtual OMX_ERRORTYPE PrepareConfigBuffer(VideoConfigBuffer *p); + virtual OMX_ERRORTYPE PrepareDecodeBuffer(OMX_BUFFERHEADERTYPE *buffer, buffer_retain_t *retain, VideoDecodeBuffer *p); + + virtual OMX_ERRORTYPE BuildHandlerList(void); + DECLARE_HANDLER(OMXVideoDecoderWMV, ParamVideoWmv); + +private: + enum { + // OMX_PARAM_PORTDEFINITIONTYPE + INPORT_MIN_BUFFER_COUNT = 1, + INPORT_ACTUAL_BUFFER_COUNT = 5, + INPORT_BUFFER_SIZE = 1382400, + }; + + OMX_VIDEO_PARAM_WMVTYPE mParamWmv; +}; + +#endif /* OMX_VIDEO_DECODER_WMV_H_ */ diff --git a/videocodec/OMXVideoEncoderAVC.cpp b/videocodec/OMXVideoEncoderAVC.cpp new file mode 100644 index 0000000..3ba1cf2 --- /dev/null +++ b/videocodec/OMXVideoEncoderAVC.cpp @@ -0,0 +1,321 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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. +*/ + + +// #define LOG_NDEBUG 0 +#define LOG_TAG "OMXVideoEncoderAVC" +#include <utils/Log.h> +#include "OMXVideoEncoderAVC.h" + +static const char* AVC_MIME_TYPE = "video/h264"; + + +OMXVideoEncoderAVC::OMXVideoEncoderAVC() { + LOGV("OMXVideoEncoderAVC is constructed."); + BuildHandlerList(); +} + +OMXVideoEncoderAVC::~OMXVideoEncoderAVC() { + LOGV("OMXVideoEncoderAVC is destructed."); +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput) { + // OMX_VIDEO_PARAM_AVCTYPE + memset(&mParamAvc, 0, sizeof(mParamAvc)); + SetTypeHeader(&mParamAvc, sizeof(mParamAvc)); + mParamAvc.nPortIndex = OUTPORT_INDEX; + mParamAvc.eProfile = OMX_VIDEO_AVCProfileBaseline; + mParamAvc.eLevel = OMX_VIDEO_AVCLevel1; + + // OMX_NALSTREAMFORMATTYPE + memset(&mNalStreamFormat, 0, sizeof(mNalStreamFormat)); + SetTypeHeader(&mNalStreamFormat, sizeof(mNalStreamFormat)); + mNalStreamFormat.nPortIndex = OUTPORT_INDEX; + // TODO: check if this is desired Nalu Format + mNalStreamFormat.eNaluFormat = OMX_NaluFormatStartCodesSeparateFirstHeader; //OMX_NaluFormatZeroByteInterleaveLength; + + // OMX_VIDEO_CONFIG_AVCINTRAPERIOD + memset(&mConfigAvcIntraPeriod, 0, sizeof(mConfigAvcIntraPeriod)); + SetTypeHeader(&mConfigAvcIntraPeriod, sizeof(mConfigAvcIntraPeriod)); + mConfigAvcIntraPeriod.nPortIndex = OUTPORT_INDEX; + // TODO: need to be populated from Video Encoder + mConfigAvcIntraPeriod.nIDRPeriod = 0; + mConfigAvcIntraPeriod.nPFrames = 0; + + // OMX_VIDEO_CONFIG_NALSIZE + memset(&mConfigNalSize, 0, sizeof(mConfigNalSize)); + SetTypeHeader(&mConfigNalSize, sizeof(mConfigNalSize)); + mConfigNalSize.nPortIndex = OUTPORT_INDEX; + mConfigNalSize.nNaluBytes = 0; + + // OMX_VIDEO_PARAM_INTEL_AVCVUI +#if 0 + memset(&mParamIntelAvcVui, 0, sizeof(mParamIntelAvcVui)); + SetTypeHeader(&mParamIntelAvcVui, sizeof(mParamIntelAvcVui)); + mParamIntelAvcVui.nPortIndex = OUTPORT_INDEX; + mParamIntelAvcVui.bVuiGeneration = OMX_FALSE; +#endif + + // override OMX_PARAM_PORTDEFINITIONTYPE + paramPortDefinitionOutput->nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionOutput->nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT; + paramPortDefinitionOutput->nBufferSize = OUTPORT_BUFFER_SIZE; + paramPortDefinitionOutput->format.video.cMIMEType = (OMX_STRING)AVC_MIME_TYPE; + paramPortDefinitionOutput->format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + + // override OMX_VIDEO_PARAM_PROFILELEVELTYPE + // TODO: check if profile/level supported is correct + mParamProfileLevel.eProfile = mParamAvc.eProfile; + mParamProfileLevel.eLevel = mParamAvc.eLevel; + + // override OMX_VIDEO_PARAM_BITRATETYPE + mParamBitrate.nTargetBitrate = 192000; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorInit(void) { + return OMXVideoEncoderBase::ProcessorInit(); +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorDeinit(void) { + return OMXVideoEncoderBase::ProcessorDeinit(); +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + return OMXVideoEncoderBase::ProcessorProcess(buffers, retains, numberBuffers); +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::BuildHandlerList(void) { + OMXVideoEncoderBase::BuildHandlerList(); + AddHandler(OMX_IndexParamVideoAvc, GetParamVideoAvc, SetParamVideoAvc); + AddHandler((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormat, GetParamNalStreamFormat, SetParamNalStreamFormat); + AddHandler((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormatSupported, GetParamNalStreamFormatSupported, SetParamNalStreamFormatSupported); + AddHandler((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormatSelect, GetParamNalStreamFormatSelect, SetParamNalStreamFormatSelect); + AddHandler(OMX_IndexConfigVideoAVCIntraPeriod, GetConfigVideoAVCIntraPeriod, SetConfigVideoAVCIntraPeriod); + AddHandler(OMX_IndexConfigVideoNalSize, GetConfigVideoNalSize, SetConfigVideoNalSize); + //AddHandler(OMX_IndexParamIntelAVCVUI, GetParamIntelAVCVUI, SetParamIntelAVCVUI); + AddHandler((OMX_INDEXTYPE)OMX_IndexParamVideoBytestream, GetParamVideoBytestream, SetParamVideoBytestream); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamVideoAvc(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + memcpy(p, &mParamAvc, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamVideoAvc(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_AVCTYPE *p = (OMX_VIDEO_PARAM_AVCTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + // TODO: do we need to check if port is enabled? + // TODO: see SetPortAvcParam implementation - Can we make simple copy???? + memcpy(&mParamAvc, p, sizeof(mParamAvc)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormat(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + // TODO: check if this is desired format + p->eNaluFormat = OMX_NaluFormatStartCodesSeparateFirstHeader; //OMX_NaluFormatStartCodes; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamNalStreamFormat(OMX_PTR pStructure) { + LOGW("SetParamNalStreamFormat is not supported."); + return OMX_ErrorUnsupportedSetting; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormatSupported(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + p->eNaluFormat = (OMX_NALUFORMATSTYPE) + (OMX_NaluFormatStartCodes | + OMX_NaluFormatStartCodesSeparateFirstHeader); + + // TODO: check if this is desired format + // OMX_NaluFormatFourByteInterleaveLength | + //OMX_NaluFormatZeroByteInterleaveLength); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamNalStreamFormatSupported(OMX_PTR pStructure) { + LOGW("SetParamNalStreamFormatSupported is not supported."); + return OMX_ErrorUnsupportedSetting; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormatSelect(OMX_PTR pStructure) { + LOGW("GetParamNalStreamFormatSelect is not supported."); + return OMX_ErrorUnsupportedSetting; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamNalStreamFormatSelect(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // return OMX_ErrorIncorrectStateOperation if not in Loaded state + CHECK_SET_PARAM_STATE(); + + if (p->eNaluFormat != OMX_NaluFormatStartCodes && + p->eNaluFormat != OMX_NaluFormatStartCodesSeparateFirstHeader) { + //p->eNaluFormat != OMX_NaluFormatFourByteInterleaveLength && + //p->eNaluFormat != OMX_NaluFormatZeroByteInterleaveLength) { + // TODO: check if this is desried + return OMX_ErrorBadParameter; + } + + mNalStreamFormat = *p; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::GetConfigVideoAVCIntraPeriod(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_CONFIG_AVCINTRAPERIOD *p = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + // TODO: populate mConfigAvcIntraPeriod from VideoEncoder + // return OMX_ErrorNotReady if VideoEncoder is not created. + memcpy(p, &mConfigAvcIntraPeriod, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigVideoAVCIntraPeriod(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_CONFIG_AVCINTRAPERIOD *p = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) + mConfigAvcIntraPeriod = *p; + + // return OMX_ErrorNone if not in Executing state + // TODO: return OMX_ErrorIncorrectStateOperation? + CHECK_SET_CONFIG_STATE(); + + // TODO: apply AVC Intra Period configuration in Executing state + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::GetConfigVideoNalSize(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_CONFIG_NALSIZE *p = (OMX_VIDEO_CONFIG_NALSIZE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + memcpy(p, &mConfigNalSize, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigVideoNalSize(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { + LOGE("SetConfigVideoNalSize failed. Feature is disabled."); + return OMX_ErrorUnsupportedIndex; + } + OMX_VIDEO_CONFIG_NALSIZE *p = (OMX_VIDEO_CONFIG_NALSIZE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) + mConfigNalSize = *p; + + // return OMX_ErrorNone if not in Executing state + // TODO: return OMX_ErrorIncorrectStateOperation? + CHECK_SET_CONFIG_STATE(); + + if (mParamIntelBitrate.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) { + LOGE("SetConfigVideoNalSize failed. Feature is supported only in VCM."); + return OMX_ErrorUnsupportedSetting; + } + // TODO: apply NAL Size configuration in Executing state + return OMX_ErrorNone; +} + + +OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamIntelAVCVUI(OMX_PTR pStructure) { +#if 0 + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_INTEL_AVCVUI *p = (OMX_VIDEO_PARAM_INTEL_AVCVUI *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + memcpy(p, mParamIntelAvcVui, sizeof(*p)); +#endif + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamIntelAVCVUI(OMX_PTR pStructure) { +#if 0 + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_INTEL_AVCVUI *p = (OMX_VIDEO_PARAM_INTEL_AVCVUI *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // set only in Loaded state (ComponentSetParam) + CHECK_SET_PARAM_STATE(); + + mParamIntelAvcVui = *p; +#endif + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamVideoBytestream(OMX_PTR pStructure) { + return OMX_ErrorUnsupportedSetting; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamVideoBytestream(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_BYTESTREAMTYPE *p = (OMX_VIDEO_PARAM_BYTESTREAMTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // set only in Loaded state (ComponentSetParam) + CHECK_SET_PARAM_STATE(); + + if (p->bBytestream == OMX_TRUE) { + mNalStreamFormat.eNaluFormat = OMX_NaluFormatStartCodes; + } else { + // TODO: do we need to override the Nalu format? + mNalStreamFormat.eNaluFormat = OMX_NaluFormatZeroByteInterleaveLength; + } + + return OMX_ErrorNone; +} + + +DECLARE_OMX_COMPONENT("OMX.Intel.VideoEncoder.AVC", "video_encoder.avc", OMXVideoEncoderAVC); diff --git a/videocodec/OMXVideoEncoderAVC.h b/videocodec/OMXVideoEncoderAVC.h new file mode 100644 index 0000000..509f604 --- /dev/null +++ b/videocodec/OMXVideoEncoderAVC.h @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 OMX_VIDEO_ENCODER_AVC_H_ +#define OMX_VIDEO_ENCODER_AVC_H_ + + +#include "OMXVideoEncoderBase.h" + +class OMXVideoEncoderAVC : public OMXVideoEncoderBase { +public: + OMXVideoEncoderAVC(); + virtual ~OMXVideoEncoderAVC(); + +protected: + virtual OMX_ERRORTYPE InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput); + virtual OMX_ERRORTYPE ProcessorInit(void); + virtual OMX_ERRORTYPE ProcessorDeinit(void); + virtual OMX_ERRORTYPE ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers); + + virtual OMX_ERRORTYPE BuildHandlerList(void); + + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamVideoAvc); + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamNalStreamFormat); + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamNalStreamFormatSupported); + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamNalStreamFormatSelect); + DECLARE_HANDLER(OMXVideoEncoderAVC, ConfigVideoAVCIntraPeriod); + DECLARE_HANDLER(OMXVideoEncoderAVC, ConfigVideoNalSize); + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamIntelAVCVUI); + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamVideoBytestream); + + +private: + enum { + // OMX_PARAM_PORTDEFINITIONTYPE + OUTPORT_MIN_BUFFER_COUNT = 1, + OUTPORT_ACTUAL_BUFFER_COUNT = 10, + OUTPORT_BUFFER_SIZE = 1382400, + // for OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS + NUM_REFERENCE_FRAME = 4, + }; + + OMX_VIDEO_PARAM_AVCTYPE mParamAvc; + OMX_NALSTREAMFORMATTYPE mNalStreamFormat; + OMX_VIDEO_CONFIG_AVCINTRAPERIOD mConfigAvcIntraPeriod; + OMX_VIDEO_CONFIG_NALSIZE mConfigNalSize; + //OMX_VIDEO_PARAM_INTEL_AVCVUI mParamIntelAvcVui; +}; + +#endif /* OMX_VIDEO_ENCODER_AVC_H_ */ diff --git a/videocodec/OMXVideoEncoderBase.cpp b/videocodec/OMXVideoEncoderBase.cpp new file mode 100644 index 0000000..4535b4a --- /dev/null +++ b/videocodec/OMXVideoEncoderBase.cpp @@ -0,0 +1,693 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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. +*/ + + +// #define LOG_NDEBUG 0 +#define LOG_TAG "OMXVideoEncoderBase" +#include <utils/Log.h> +#include "OMXVideoEncoderBase.h" + +static const char* RAW_MIME_TYPE = "video/raw"; + +OMXVideoEncoderBase::OMXVideoEncoderBase() { +} + +OMXVideoEncoderBase::~OMXVideoEncoderBase() { + if (this->ports) { + if (this->ports[INPORT_INDEX]) { + delete this->ports[INPORT_INDEX]; + this->ports[INPORT_INDEX] = NULL; + } + + if (this->ports[OUTPORT_INDEX]) { + delete this->ports[OUTPORT_INDEX]; + this->ports[OUTPORT_INDEX] = NULL; + } + } +} + +OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPort(void) { + this->ports[INPORT_INDEX] = new PortVideo; + if (this->ports[INPORT_INDEX] == NULL) { + return OMX_ErrorInsufficientResources; + } + + PortVideo *port = static_cast<PortVideo *>(this->ports[INPORT_INDEX]); + + // OMX_PARAM_PORTDEFINITIONTYPE + OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput; + memset(¶mPortDefinitionInput, 0, sizeof(paramPortDefinitionInput)); + SetTypeHeader(¶mPortDefinitionInput, sizeof(paramPortDefinitionInput)); + paramPortDefinitionInput.nPortIndex = INPORT_INDEX; + paramPortDefinitionInput.eDir = OMX_DirInput; + paramPortDefinitionInput.nBufferCountActual = INPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionInput.nBufferCountMin = INPORT_MIN_BUFFER_COUNT; + paramPortDefinitionInput.nBufferSize = INPORT_BUFFER_SIZE; + paramPortDefinitionInput.bEnabled = OMX_TRUE; + paramPortDefinitionInput.bPopulated = OMX_FALSE; + paramPortDefinitionInput.eDomain = OMX_PortDomainVideo; + paramPortDefinitionInput.format.video.cMIMEType = (OMX_STRING)RAW_MIME_TYPE; + paramPortDefinitionInput.format.video.pNativeRender = NULL; + paramPortDefinitionInput.format.video.nFrameWidth = 176; + paramPortDefinitionInput.format.video.nFrameHeight = 144; + paramPortDefinitionInput.format.video.nStride = 0; + paramPortDefinitionInput.format.video.nSliceHeight = 0; + paramPortDefinitionInput.format.video.nBitrate = 64000; + paramPortDefinitionInput.format.video.xFramerate = 15 << 16; + paramPortDefinitionInput.format.video.bFlagErrorConcealment = OMX_FALSE; + paramPortDefinitionInput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + paramPortDefinitionInput.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + paramPortDefinitionInput.format.video.pNativeWindow = NULL; + paramPortDefinitionInput.bBuffersContiguous = OMX_FALSE; + paramPortDefinitionInput.nBufferAlignment = 0; + + // Nothing specific to initialize input port. + InitInputPortFormatSpecific(¶mPortDefinitionInput); + + port->SetPortDefinition(¶mPortDefinitionInput, true); + + // OMX_VIDEO_PARAM_PORTFORMATTYPE + OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat; + memset(¶mPortFormat, 0, sizeof(paramPortFormat)); + SetTypeHeader(¶mPortFormat, sizeof(paramPortFormat)); + paramPortFormat.nPortIndex = INPORT_INDEX; + paramPortFormat.nIndex = 0; + paramPortFormat.eCompressionFormat = paramPortDefinitionInput.format.video.eCompressionFormat; + paramPortFormat.eColorFormat = paramPortDefinitionInput.format.video.eColorFormat; + paramPortFormat.xFramerate = paramPortDefinitionInput.format.video.xFramerate; + + port->SetPortVideoParam(¶mPortFormat, true); + + return OMX_ErrorNone; +} + + +OMX_ERRORTYPE OMXVideoEncoderBase::InitOutputPort(void) { + this->ports[OUTPORT_INDEX] = new PortVideo; + if (this->ports[OUTPORT_INDEX] == NULL) { + return OMX_ErrorInsufficientResources; + } + + PortVideo *port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]); + + // OMX_VIDEO_PARAM_BITRATETYPE + memset(&mParamBitrate, 0, sizeof(mParamBitrate)); + SetTypeHeader(&mParamBitrate, sizeof(mParamBitrate)); + mParamBitrate.nPortIndex = OUTPORT_INDEX; + mParamBitrate.eControlRate = OMX_Video_ControlRateConstant; + mParamBitrate.nTargetBitrate = 192000; // to be overridden + + // OMX_VIDEO_CONFIG_PRI_INFOTYPE + memset(&mConfigPriInfo, 0, sizeof(mConfigPriInfo)); + SetTypeHeader(&mConfigPriInfo, sizeof(mConfigPriInfo)); + mConfigPriInfo.nPortIndex = OUTPORT_INDEX; + mConfigPriInfo.nCapacity = 0; + mConfigPriInfo.nHolder = NULL; + + // OMX_VIDEO_PARAM_INTEL_BITRATETYPE + memset(&mParamIntelBitrate, 0, sizeof(mParamIntelBitrate)); + SetTypeHeader(&mParamIntelBitrate, sizeof(mParamIntelBitrate)); + mParamIntelBitrate.nPortIndex = OUTPORT_INDEX; + mParamIntelBitrate.eControlRate = OMX_Video_Intel_ControlRateMax; + mParamIntelBitrate.nTargetBitrate = 0; // to be overridden ? + + // OMX_VIDEO_CONFIG_INTEL_BITRATETYPE + memset(&mConfigIntelBitrate, 0, sizeof(mConfigIntelBitrate)); + SetTypeHeader(&mConfigIntelBitrate, sizeof(mConfigIntelBitrate)); + mConfigIntelBitrate.nPortIndex = OUTPORT_INDEX; + mConfigIntelBitrate.nMaxEncodeBitrate = 4000 * 1024; // Maximum bitrate + mConfigIntelBitrate.nTargetPercentage = 95; // Target bitrate as percentage of maximum bitrate; e.g. 95 is 95% + mConfigIntelBitrate.nWindowSize = 1000; // Window size in milliseconds allowed for bitrate to reach target + mConfigIntelBitrate.nInitialQP = 36; // Initial QP for I frames + mConfigIntelBitrate.nMinQP = 18; + + // OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS + memset(&mConfigIntelSliceNumbers, 0, sizeof(mConfigIntelSliceNumbers)); + SetTypeHeader(&mConfigIntelSliceNumbers, sizeof(mConfigIntelSliceNumbers)); + mConfigIntelSliceNumbers.nPortIndex = OUTPORT_INDEX; + mConfigIntelSliceNumbers.nISliceNumber = 1; + mConfigIntelSliceNumbers.nPSliceNumber = 1; + + // OMX_VIDEO_CONFIG_INTEL_AIR + memset(&mConfigIntelAir, 0, sizeof(mConfigIntelAir)); + SetTypeHeader(&mConfigIntelAir, sizeof(mConfigIntelAir)); + mConfigIntelAir.nPortIndex = OUTPORT_INDEX; + mConfigIntelAir.bAirEnable = OMX_FALSE; + mConfigIntelAir.bAirAuto = OMX_FALSE; + mConfigIntelAir.nAirMBs = 0; + mConfigIntelAir.nAirThreshold = 0; + + // OMX_CONFIG_FRAMERATETYPE + memset(&mConfigFramerate, 0, sizeof(mConfigFramerate)); + SetTypeHeader(&mConfigFramerate, sizeof(mConfigFramerate)); + mConfigFramerate.nPortIndex = OUTPORT_INDEX; + mConfigFramerate.xEncodeFramerate = 0; // Q16 format + +#if 0 + // OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL + memset(&mParamIntelAdaptiveSliceControl, 0, sizeof(mParamIntelAdaptiveSliceControl)); + SetTypeHeader(&mParamIntelAdaptiveSliceControl, sizeof(mParamIntelAdaptiveSliceControl)); + mParamIntelAdaptiveSliceControl.nPortIndex = OUTPORT_INDEX; + mParamIntelAdaptiveSliceControl.bEnable = OMX_FALSE; + mParamIntelAdaptiveSliceControl.nMinPSliceNumber = 5; + mParamIntelAdaptiveSliceControl.nNumPFramesToSkip = 8; + mParamIntelAdaptiveSliceControl.nSliceSizeThreshold = 1200; +#endif + + // OMX_VIDEO_PARAM_PROFILELEVELTYPE + memset(&mParamProfileLevel, 0, sizeof(mParamProfileLevel)); + SetTypeHeader(&mParamProfileLevel, sizeof(mParamProfileLevel)); + mParamProfileLevel.nPortIndex = OUTPORT_INDEX; + mParamProfileLevel.eProfile = 0; // undefined profile, to be overridden + mParamProfileLevel.eLevel = 0; // undefined level, to be overridden + + + // OMX_PARAM_PORTDEFINITIONTYPE + OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput; + memset(¶mPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput)); + SetTypeHeader(¶mPortDefinitionOutput, sizeof(paramPortDefinitionOutput)); + paramPortDefinitionOutput.nPortIndex = OUTPORT_INDEX; + paramPortDefinitionOutput.eDir = OMX_DirOutput; + paramPortDefinitionOutput.nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; // to be overridden + paramPortDefinitionOutput.nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT; + paramPortDefinitionOutput.nBufferSize = OUTPORT_BUFFER_SIZE; // to be overridden + paramPortDefinitionOutput.bEnabled = OMX_TRUE; + paramPortDefinitionOutput.bPopulated = OMX_FALSE; + paramPortDefinitionOutput.eDomain = OMX_PortDomainVideo; + paramPortDefinitionOutput.format.video.cMIMEType = NULL; // to be overridden + paramPortDefinitionOutput.format.video.pNativeRender = NULL; + paramPortDefinitionOutput.format.video.nFrameWidth = 176; + paramPortDefinitionOutput.format.video.nFrameHeight = 144; + paramPortDefinitionOutput.format.video.nStride = 176; + paramPortDefinitionOutput.format.video.nSliceHeight = 144; + paramPortDefinitionOutput.format.video.nBitrate = 64000; + paramPortDefinitionOutput.format.video.xFramerate = 15 << 16; + paramPortDefinitionOutput.format.video.bFlagErrorConcealment = OMX_FALSE; + paramPortDefinitionOutput.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; // to be overridden + paramPortDefinitionOutput.format.video.eColorFormat = OMX_COLOR_FormatUnused; + paramPortDefinitionOutput.format.video.pNativeWindow = NULL; + paramPortDefinitionOutput.bBuffersContiguous = OMX_FALSE; + paramPortDefinitionOutput.nBufferAlignment = 0; + + InitOutputPortFormatSpecific(¶mPortDefinitionOutput); + + port->SetPortDefinition(¶mPortDefinitionOutput, true); + + // OMX_VIDEO_PARAM_PORTFORMATTYPE + OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat; + memset(¶mPortFormat, 0, sizeof(paramPortFormat)); + SetTypeHeader(¶mPortFormat, sizeof(paramPortFormat)); + paramPortFormat.nPortIndex = OUTPORT_INDEX; + paramPortFormat.nIndex = 0; + paramPortFormat.eCompressionFormat = paramPortDefinitionOutput.format.video.eCompressionFormat; + paramPortFormat.eColorFormat = paramPortDefinitionOutput.format.video.eColorFormat; + paramPortFormat.xFramerate = paramPortDefinitionOutput.format.video.xFramerate; + + port->SetPortVideoParam(¶mPortFormat, true); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput) { + // no format specific to initialize input + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorInit(void) { + OMX_ERRORTYPE ret; + ret = OMXComponentCodecBase::ProcessorInit(); + CHECK_RETURN_VALUE("OMXComponentCodecBase::ProcessorInit"); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorDeinit(void) { + OMX_ERRORTYPE ret; + return OMXComponentCodecBase::ProcessorDeinit(); +} + +OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorStop(void) { + OMX_ERRORTYPE ret; + this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); + return OMXComponentCodecBase::ProcessorStop(); +} + +OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorFlush(OMX_U32 portIndex) { + if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) { + this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + return OMX_ErrorNotImplemented; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::EnableBufferSharing(void) +{ + BufferShareStatus ret; + + if (mBufferSharingState != BUFFER_SHARING_INVALID) { + LOGE("EnableBufferSharing: Invalid buffer sharing state: %d", mBufferSharingState); + return OMX_ErrorUndefined; + } + + mBufferSharingCount = 4; + mBufferSharingInfo = NULL; + mBufferSharingLib = BufferShareRegistry::getInstance(); + + ret = mBufferSharingLib->encoderRequestToEnableSharingMode(); + if (ret != BS_SUCCESS) { + LOGE("encoderRequestToEnableSharingMode failed. Error = %d", ret); + return OMX_ErrorUndefined; + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::DisableBufferSharing(void) +{ + BufferShareStatus ret; + + if ((mBufferSharingState != BUFFER_SHARING_INVALID) && + (mBufferSharingState != BUFFER_SHARING_LOADED)) { + LOGE("DisableBufferSharing: Invalid buffer sharing state: %d", mBufferSharingState); + return OMX_ErrorUndefined; + } + + if (mBufferSharingState == BUFFER_SHARING_INVALID) { + return OMX_ErrorNone; + } + + if (mBufferSharingInfo) { + delete [] mBufferSharingInfo; + } + mBufferSharingInfo = NULL; + + ret = mBufferSharingLib->encoderRequestToDisableSharingMode(); + if (ret != BS_SUCCESS) { + LOGE("encoderRequestToDisableSharingMode failed. Error = %d", ret); + return OMX_ErrorUndefined; + } + + mBufferSharingState = BUFFER_SHARING_INVALID; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::StartBufferSharing(void) { + // TODO: consolidate the following APIs + + /* + CheckAndEnableBufferSharingMode + RequestShareBuffers + RegisterShareBuffersToPort + RegisterShareBuffersToLib + EnterBufferSharingMode + */ + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::StopBufferSharing(void) { + if ((mBufferSharingState != BUFFER_SHARING_INVALID) && + (mBufferSharingState != BUFFER_SHARING_EXECUTING)) { + LOGE("StopBufferSharing: Invalid buffer sharing state: %d", mBufferSharingState); + return OMX_ErrorUndefined; + } + + if (mBufferSharingState == BUFFER_SHARING_INVALID) { + return OMX_ErrorNone; + } + + BufferShareStatus ret = mBufferSharingLib->encoderExitSharingMode(); + if (ret != BS_SUCCESS) { + LOGE("encoderExitSharingMode failed. Error = %d", ret); + return OMX_ErrorUndefined; + } + + mBufferSharingState = BUFFER_SHARING_LOADED; + return OMX_ErrorNone; +} + + +OMX_ERRORTYPE OMXVideoEncoderBase::BuildHandlerList(void) { + OMXComponentCodecBase::BuildHandlerList(); + AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat); + AddHandler(OMX_IndexParamVideoBitrate, GetParamVideoBitrate, SetParamVideoBitrate); + AddHandler((OMX_INDEXTYPE)OMX_IndexIntelPrivateInfo, GetIntelPrivateInfo, SetIntelPrivateInfo); + AddHandler((OMX_INDEXTYPE)OMX_IndexParamIntelBitrate, GetParamIntelBitrate, SetParamIntelBitrate); + AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelBitrate, GetConfigIntelBitrate, SetConfigIntelBitrate); + AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelSliceNumbers, GetConfigIntelSliceNumbers, SetConfigIntelSliceNumbers); + AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelAIR, GetConfigIntelAIR, SetConfigIntelAIR); + AddHandler(OMX_IndexConfigVideoFramerate, GetConfigVideoFramerate, SetConfigVideoFramerate); + AddHandler(OMX_IndexConfigVideoIntraVOPRefresh, GetConfigVideoIntraVOPRefresh, SetConfigVideoIntraVOPRefresh); + //AddHandler(OMX_IndexParamIntelAdaptiveSliceControl, GetParamIntelAdaptiveSliceControl, SetParamIntelAdaptiveSliceControl); + AddHandler(OMX_IndexParamVideoProfileLevelQuerySupported, GetParamVideoProfileLevelQuerySupported, SetParamVideoProfileLevelQuerySupported); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoPortFormat(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX_RANGE(p); + CHECK_ENUMERATION_RANGE(p->nIndex, 1); + + PortVideo *port = NULL; + port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); + memcpy(p, port->GetPortVideoParam(), sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoPortFormat(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_PORTFORMATTYPE *p = (OMX_VIDEO_PARAM_PORTFORMATTYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX_RANGE(p); + CHECK_SET_PARAM_STATE(); + + // TODO: do we need to check if port is enabled? + PortVideo *port = NULL; + port = static_cast<PortVideo *>(this->ports[p->nPortIndex]); + port->SetPortVideoParam(p, false); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoBitrate(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_BITRATETYPE *p = (OMX_VIDEO_PARAM_BITRATETYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + memcpy(p, &mParamBitrate, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoBitrate(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_BITRATETYPE *p = (OMX_VIDEO_PARAM_BITRATETYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + // This disables other type of bitrate control mechanism + // TODO: check if it is desired + mParamIntelBitrate.eControlRate = OMX_Video_Intel_ControlRateMax; + + // TODO: can we override mParamBitrate.nPortIndex (See SetPortBitrateParam) + mParamBitrate.eControlRate = p->eControlRate; + mParamBitrate.nTargetBitrate = p->nTargetBitrate; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::GetIntelPrivateInfo(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_CONFIG_PRI_INFOTYPE *p = (OMX_VIDEO_CONFIG_PRI_INFOTYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + memcpy(p, &mConfigPriInfo, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::SetIntelPrivateInfo(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_CONFIG_PRI_INFOTYPE *p = (OMX_VIDEO_CONFIG_PRI_INFOTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // OMX_VIDEO_CONFIG_PRI_INFOTYPE is static parameter? + CHECK_SET_PARAM_STATE(); + + // TODO: can we override mConfigPriInfo.nPortIndex (See SetPortPrivateInfoParam) + + if(p->nHolder != NULL) { + // TODO: do we need to free nHolder? + if (mConfigPriInfo.nHolder) { + free(mConfigPriInfo.nHolder); + } + mConfigPriInfo.nCapacity = p->nCapacity; + // TODO: nCapacity is in 8-bit unit or 32-bit unit? + // TODO: check memory allocation + mConfigPriInfo.nHolder = (OMX_PTR)malloc(sizeof(OMX_U32) * p->nCapacity); + memcpy(mConfigPriInfo.nHolder, p->nHolder, sizeof(OMX_U32) * p->nCapacity); + } else { + mConfigPriInfo.nCapacity = 0; + mConfigPriInfo.nHolder = NULL; + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::GetParamIntelBitrate(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_INTEL_BITRATETYPE *p = (OMX_VIDEO_PARAM_INTEL_BITRATETYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + memcpy(p, &mParamIntelBitrate, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::SetParamIntelBitrate(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_INTEL_BITRATETYPE *p = (OMX_VIDEO_PARAM_INTEL_BITRATETYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + mParamIntelBitrate = *p; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelBitrate(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *p = (OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + memcpy(p, &mConfigIntelBitrate, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelBitrate(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { + LOGE("SetConfigIntelBitrate failed. Feature is disabled."); + return OMX_ErrorUnsupportedIndex; + } + OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *p = (OMX_VIDEO_CONFIG_INTEL_BITRATETYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) + mConfigIntelBitrate = *p; + + // return OMX_ErrorNone if not in Executing state + // TODO: return OMX_ErrorIncorrectStateOperation? + CHECK_SET_CONFIG_STATE(); + + if (mParamIntelBitrate.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) { + LOGE("SetConfigIntelBitrate failed. Feature is supported only in VCM."); + return OMX_ErrorUnsupportedSetting; + } + // TODO: apply Bitrate configuration in Executing state + return OMX_ErrorNone; +} + + +OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelSliceNumbers(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *p = (OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + memcpy(p, &mConfigIntelSliceNumbers, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelSliceNumbers(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { + LOGE("SetConfigIntelSliceNumbers failed. Feature is disabled."); + return OMX_ErrorUnsupportedIndex; + } + OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *p = (OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) + mConfigIntelSliceNumbers = *p; + + // return OMX_ErrorNone if not in Executing state + // TODO: return OMX_ErrorIncorrectStateOperation? + CHECK_SET_CONFIG_STATE(); + + if (mParamIntelBitrate.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) { + LOGE("SetConfigIntelSliceNumbers failed. Feature is supported only in VCM."); + return OMX_ErrorUnsupportedSetting; + } + // TODO: apply Slice numbers configuration in Executing state + return OMX_ErrorNone; +} + + +OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelAIR(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_CONFIG_INTEL_AIR *p = (OMX_VIDEO_CONFIG_INTEL_AIR *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + memcpy(p, &mConfigIntelAir, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelAIR(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { + LOGE("SetConfigIntelAIR failed. Feature is disabled."); + return OMX_ErrorUnsupportedIndex; + } + OMX_VIDEO_CONFIG_INTEL_AIR *p = (OMX_VIDEO_CONFIG_INTEL_AIR *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) + mConfigIntelAir = *p; + + // return OMX_ErrorNone if not in Executing state + // TODO: return OMX_ErrorIncorrectStateOperation? + CHECK_SET_CONFIG_STATE(); + + if (mParamIntelBitrate.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) { + LOGE("SetConfigIntelAIR failed. Feature is supported only in VCM."); + return OMX_ErrorUnsupportedSetting; + } + // TODO: apply AIR configuration in Executing state + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoFramerate(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_CONFIG_FRAMERATETYPE *p = (OMX_CONFIG_FRAMERATETYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + memcpy(p, &mConfigFramerate, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoFramerate(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { + LOGE("SetConfigVideoFramerate failed. Feature is disabled."); + return OMX_ErrorUnsupportedIndex; + } + OMX_CONFIG_FRAMERATETYPE *p = (OMX_CONFIG_FRAMERATETYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) + mConfigFramerate = *p; + + // return OMX_ErrorNone if not in Executing state + // TODO, return OMX_ErrorIncorrectStateOperation? + CHECK_SET_CONFIG_STATE(); + + if (mParamIntelBitrate.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) { + LOGE("SetConfigIntelAIR failed. Feature is supported only in VCM."); + return OMX_ErrorUnsupportedSetting; + } + // TODO: apply Framerate configuration in Executing state + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoIntraVOPRefresh(OMX_PTR pStructure) { + LOGW("GetConfigVideoIntraVOPRefresh is not supported."); + return OMX_ErrorUnsupportedSetting; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoIntraVOPRefresh(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_CONFIG_INTRAREFRESHVOPTYPE *p = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // return OMX_ErrorNone if not in Executing state + // TODO: return OMX_ErrorIncorrectStateOperation? + CHECK_SET_CONFIG_STATE(); + + // TODO: apply VOP refresh configuration in Executing state + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::GetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) { +#if 0 + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *p = (OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + memcpy(p, mParamIntelAdaptiveSliceControl, sizeof(*p)); +#endif + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::SetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) { +#if 0 + OMX_ERRORTYPE ret; + if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { + LOGE("SetParamIntelAdaptiveSliceControl failed. Feature is disabled."); + return OMX_ErrorUnsupportedIndex; + } + OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *p = (OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // set only in Loaded state (ComponentSetParam) + CHECK_SET_PARAM_STATE(); + + mParamIntelAdaptiveSliceControl = *p; +#endif + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::GetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // assign values instead of memory coping to avoid nProfileIndex being overridden + p->eProfile = mParamProfileLevel.eProfile; + p->eLevel = mParamProfileLevel.eLevel; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoProfileLevelQuerySupported(OMX_PTR pStructure) { + LOGW("SetParamVideoProfileLevelQuerySupported is not supported."); + return OMX_ErrorUnsupportedSetting; +} + diff --git a/videocodec/OMXVideoEncoderBase.h b/videocodec/OMXVideoEncoderBase.h new file mode 100644 index 0000000..341bb44 --- /dev/null +++ b/videocodec/OMXVideoEncoderBase.h @@ -0,0 +1,110 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 OMX_VIDEO_ENCODER_BASE_H_ +#define OMX_VIDEO_ENCODER_BASE_H_ + + +#include "OMXComponentCodecBase.h" +#include <IntelBufferSharing.h> +//#include "VideoEncoderInterface.h" + +using android::sp; +using android::BufferShareRegistry; + +class OMXVideoEncoderBase : public OMXComponentCodecBase { +public: + OMXVideoEncoderBase(); + virtual ~OMXVideoEncoderBase(); + +protected: + virtual OMX_ERRORTYPE InitInputPort(void); + virtual OMX_ERRORTYPE InitOutputPort(void); + virtual OMX_ERRORTYPE InitInputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput); + virtual OMX_ERRORTYPE InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput) = 0; + + virtual OMX_ERRORTYPE ProcessorInit(void); + virtual OMX_ERRORTYPE ProcessorDeinit(void); + //virtual OMX_ERRORTYPE ProcessorStart(void); + virtual OMX_ERRORTYPE ProcessorStop(void); + //virtual OMX_ERRORTYPE ProcessorPause(void); + //virtual OMX_ERRORTYPE ProcessorResume(void); + virtual OMX_ERRORTYPE ProcessorFlush(OMX_U32 portIndex); + virtual OMX_ERRORTYPE ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers); + + virtual OMX_ERRORTYPE BuildHandlerList(void); + + DECLARE_HANDLER(OMXVideoEncoderBase, ParamVideoPortFormat); + DECLARE_HANDLER(OMXVideoEncoderBase, ParamVideoBitrate); + DECLARE_HANDLER(OMXVideoEncoderBase, IntelPrivateInfo); + DECLARE_HANDLER(OMXVideoEncoderBase, ParamIntelBitrate); + DECLARE_HANDLER(OMXVideoEncoderBase, ConfigIntelBitrate); + DECLARE_HANDLER(OMXVideoEncoderBase, ConfigIntelSliceNumbers); + DECLARE_HANDLER(OMXVideoEncoderBase, ConfigIntelAIR); + DECLARE_HANDLER(OMXVideoEncoderBase, ConfigVideoFramerate); + DECLARE_HANDLER(OMXVideoEncoderBase, ConfigVideoIntraVOPRefresh); + DECLARE_HANDLER(OMXVideoEncoderBase, ParamIntelAdaptiveSliceControl); + DECLARE_HANDLER(OMXVideoEncoderBase, ParamVideoProfileLevelQuerySupported); + +protected: + virtual OMX_ERRORTYPE EnableBufferSharing(void); + virtual OMX_ERRORTYPE DisableBufferSharing(void); + virtual OMX_ERRORTYPE StartBufferSharing(void); + virtual OMX_ERRORTYPE StopBufferSharing(void); + + +protected: + //IVideoEncoder *mVideoEncoder; + OMX_VIDEO_PARAM_BITRATETYPE mParamBitrate; + OMX_VIDEO_CONFIG_PRI_INFOTYPE mConfigPriInfo; + OMX_VIDEO_PARAM_INTEL_BITRATETYPE mParamIntelBitrate; + OMX_VIDEO_CONFIG_INTEL_BITRATETYPE mConfigIntelBitrate; + OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS mConfigIntelSliceNumbers; + OMX_VIDEO_CONFIG_INTEL_AIR mConfigIntelAir; + OMX_CONFIG_FRAMERATETYPE mConfigFramerate; +// OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL mParamIntelAdaptiveSliceControl; + OMX_VIDEO_PARAM_PROFILELEVELTYPE mParamProfileLevel; + +private: + enum { + // OMX_PARAM_PORTDEFINITIONTYPE + INPORT_MIN_BUFFER_COUNT = 1, + INPORT_ACTUAL_BUFFER_COUNT = 5, + INPORT_BUFFER_SIZE = 1382400, + + // OMX_PARAM_PORTDEFINITIONTYPE + OUTPORT_MIN_BUFFER_COUNT = 1, + OUTPORT_ACTUAL_BUFFER_COUNT = 2, + OUTPORT_BUFFER_SIZE = 1382400, + }; + + sp<BufferShareRegistry> mBufferSharingLib; + int mBufferSharingCount; + SharedBufferType* mBufferSharingInfo; + + enum { + BUFFER_SHARING_INVALID, + BUFFER_SHARING_LOADED, + BUFFER_SHARING_EXECUTING + } mBufferSharingState; +}; + +#endif /* OMX_VIDEO_ENCODER_BASE_H_ */ diff --git a/videocodec/OMXVideoEncoderH263.cpp b/videocodec/OMXVideoEncoderH263.cpp new file mode 100644 index 0000000..eb213cd --- /dev/null +++ b/videocodec/OMXVideoEncoderH263.cpp @@ -0,0 +1,108 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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. +*/ + + +// #define LOG_NDEBUG 0 +#define LOG_TAG "OMXVideoEncoderH263" +#include <utils/Log.h> +#include "OMXVideoEncoderH263.h" + +static const char* H263_MIME_TYPE = "video/h263"; + +OMXVideoEncoderH263::OMXVideoEncoderH263() { + LOGV("OMXVideoEncoderH263 is constructed."); + BuildHandlerList(); +} + +OMXVideoEncoderH263::~OMXVideoEncoderH263() { + LOGV("OMXVideoEncoderH263 is destructed."); +} + +OMX_ERRORTYPE OMXVideoEncoderH263::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput) { + // OMX_VIDEO_PARAM_H263TYPE + memset(&mParamH263, 0, sizeof(mParamH263)); + SetTypeHeader(&mParamH263, sizeof(mParamH263)); + mParamH263.nPortIndex = OUTPORT_INDEX; + mParamH263.eProfile = OMX_VIDEO_H263ProfileBaseline; + // TODO: check eLevel, 10 in Froyo + mParamH263.eLevel = OMX_VIDEO_H263Level70; //OMX_VIDEO_H263Level10; + + // override OMX_PARAM_PORTDEFINITIONTYPE + paramPortDefinitionOutput->nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionOutput->nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT; + paramPortDefinitionOutput->nBufferSize = OUTPORT_BUFFER_SIZE; + paramPortDefinitionOutput->format.video.cMIMEType = (OMX_STRING)H263_MIME_TYPE; + paramPortDefinitionOutput->format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + + // override OMX_VIDEO_PARAM_PROFILELEVELTYPE + // TODO: check if profile/level supported is correct + mParamProfileLevel.eProfile = mParamH263.eProfile; + mParamProfileLevel.eLevel = mParamH263.eLevel; //OMX_VIDEO_H263Level70 + + // override OMX_VIDEO_PARAM_BITRATETYPE + mParamBitrate.nTargetBitrate = 64000; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderH263::ProcessorInit(void) { + return OMXVideoEncoderBase::ProcessorInit(); +} + +OMX_ERRORTYPE OMXVideoEncoderH263::ProcessorDeinit(void) { + return OMXVideoEncoderBase::ProcessorDeinit(); +} + +OMX_ERRORTYPE OMXVideoEncoderH263::ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + return OMXVideoEncoderBase::ProcessorProcess(buffers, retains, numberBuffers); +} + +OMX_ERRORTYPE OMXVideoEncoderH263::BuildHandlerList(void) { + OMXVideoEncoderBase::BuildHandlerList(); + AddHandler(OMX_IndexParamVideoH263, GetParamVideoH263, SetParamVideoH263); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderH263::GetParamVideoH263(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_H263TYPE *p = (OMX_VIDEO_PARAM_H263TYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + memcpy(p, &mParamH263, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderH263::SetParamVideoH263(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_H263TYPE *p = (OMX_VIDEO_PARAM_H263TYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + // TODO: do we need to check if port is enabled? + // TODO: see SetPortH263Param implementation - Can we make simple copy???? + memcpy(&mParamH263, p, sizeof(mParamH263)); + return OMX_ErrorNone; +} + + +DECLARE_OMX_COMPONENT("OMX.Intel.VideoEncoder.H263", "video_encoder.h263", OMXVideoEncoderH263); + diff --git a/videocodec/OMXVideoEncoderH263.h b/videocodec/OMXVideoEncoderH263.h new file mode 100644 index 0000000..f0d156b --- /dev/null +++ b/videocodec/OMXVideoEncoderH263.h @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 OMX_VIDEO_DECODER_H263_H_ +#define OMX_VIDEO_DECODER_H263_H_ + + +#include "OMXVideoEncoderBase.h" + +class OMXVideoEncoderH263 : public OMXVideoEncoderBase { +public: + OMXVideoEncoderH263(); + virtual ~OMXVideoEncoderH263(); + +protected: + virtual OMX_ERRORTYPE InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput); + virtual OMX_ERRORTYPE ProcessorInit(void); + virtual OMX_ERRORTYPE ProcessorDeinit(void); + virtual OMX_ERRORTYPE ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers); + + virtual OMX_ERRORTYPE BuildHandlerList(void); + + DECLARE_HANDLER(OMXVideoEncoderH263, ParamVideoH263); + +private: + enum { + // OMX_PARAM_PORTDEFINITIONTYPE + OUTPORT_MIN_BUFFER_COUNT = 1, + OUTPORT_ACTUAL_BUFFER_COUNT = 2, + OUTPORT_BUFFER_SIZE = 1382400, + }; + + OMX_VIDEO_PARAM_H263TYPE mParamH263; +}; + + +#endif /* OMX_VIDEO_DECODER_H263_H_ */ diff --git a/videocodec/OMXVideoEncoderMPEG4.cpp b/videocodec/OMXVideoEncoderMPEG4.cpp new file mode 100644 index 0000000..da58e74 --- /dev/null +++ b/videocodec/OMXVideoEncoderMPEG4.cpp @@ -0,0 +1,106 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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. +*/ + + +// #define LOG_NDEBUG 0 +#define LOG_TAG "OMXVideoEncoderMPEG4" +#include <utils/Log.h> +#include "OMXVideoEncoderMPEG4.h" + +static const char* MPEG4_MIME_TYPE = "video/mpeg4"; + +OMXVideoEncoderMPEG4::OMXVideoEncoderMPEG4() { + LOGV("OMXVideoEncoderMPEG4 is constructed."); + BuildHandlerList(); +} + +OMXVideoEncoderMPEG4::~OMXVideoEncoderMPEG4() { + LOGV("OMXVideoEncoderMPEG4 is destructed."); +} + +OMX_ERRORTYPE OMXVideoEncoderMPEG4::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput) { + // OMX_VIDEO_PARAM_MPEG4TYPE + memset(&mParamMpeg4, 0, sizeof(mParamMpeg4)); + SetTypeHeader(&mParamMpeg4, sizeof(mParamMpeg4)); + mParamMpeg4.nPortIndex = OUTPORT_INDEX; + mParamMpeg4.eProfile = OMX_VIDEO_MPEG4ProfileSimple; + // TODO: Check eLevel (Level3 in Froyo) + mParamMpeg4.eLevel = OMX_VIDEO_MPEG4Level5; //OMX_VIDEO_MPEG4Level3; + + // override OMX_PARAM_PORTDEFINITIONTYPE + paramPortDefinitionOutput->nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; + paramPortDefinitionOutput->nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT; + paramPortDefinitionOutput->nBufferSize = OUTPORT_BUFFER_SIZE; + paramPortDefinitionOutput->format.video.cMIMEType = (OMX_STRING)MPEG4_MIME_TYPE; + paramPortDefinitionOutput->format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + + // override OMX_VIDEO_PARAM_PROFILELEVELTYPE + // TODO: check if profile/level supported is correct + mParamProfileLevel.eProfile = mParamMpeg4.eProfile; + mParamProfileLevel.eLevel = mParamMpeg4.eLevel; //OMX_VIDEO_MPEG4Level5; + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderMPEG4::ProcessorInit(void) { + return OMXVideoEncoderBase::ProcessorInit(); +} + +OMX_ERRORTYPE OMXVideoEncoderMPEG4::ProcessorDeinit(void) { + return OMXVideoEncoderBase::ProcessorDeinit(); +} + +OMX_ERRORTYPE OMXVideoEncoderMPEG4::ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + return OMXVideoEncoderBase::ProcessorProcess(buffers, retains, numberBuffers); +} + +OMX_ERRORTYPE OMXVideoEncoderMPEG4::BuildHandlerList(void) { + OMXVideoEncoderBase::BuildHandlerList(); + AddHandler(OMX_IndexParamVideoMpeg4, GetParamVideoMpeg4, SetParamVideoMpeg4); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderMPEG4::GetParamVideoMpeg4(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_MPEG4TYPE *p = (OMX_VIDEO_PARAM_MPEG4TYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + memcpy(p, &mParamMpeg4, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderMPEG4::SetParamVideoMpeg4(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_PARAM_MPEG4TYPE *p = (OMX_VIDEO_PARAM_MPEG4TYPE *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + CHECK_SET_PARAM_STATE(); + + // TODO: do we need to check if port is enabled? + // TODO: see SetPortMpeg4Param implementation - Can we make simple copy???? + memcpy(&mParamMpeg4, p, sizeof(mParamMpeg4)); + return OMX_ErrorNone; +} + + +DECLARE_OMX_COMPONENT("OMX.Intel.VideoEncoder.MPEG4", "video_encoder.mpeg4", OMXVideoEncoderMPEG4); + + diff --git a/videocodec/OMXVideoEncoderMPEG4.h b/videocodec/OMXVideoEncoderMPEG4.h new file mode 100644 index 0000000..6ad4e7c --- /dev/null +++ b/videocodec/OMXVideoEncoderMPEG4.h @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 OMX_VIDEO_ENCODER_MPEG4_H_ +#define OMX_VIDEO_ENCODER_MPEG4_H_ + + +#include "OMXVideoEncoderBase.h" + +class OMXVideoEncoderMPEG4 : public OMXVideoEncoderBase { +public: + OMXVideoEncoderMPEG4(); + virtual ~OMXVideoEncoderMPEG4(); + +protected: + virtual OMX_ERRORTYPE InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput); + virtual OMX_ERRORTYPE ProcessorInit(void); + virtual OMX_ERRORTYPE ProcessorDeinit(void); + virtual OMX_ERRORTYPE ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers); + + virtual OMX_ERRORTYPE BuildHandlerList(void); + + DECLARE_HANDLER(OMXVideoEncoderMPEG4, ParamVideoMpeg4); + +private: + enum { + // OMX_PARAM_PORTDEFINITIONTYPE + OUTPORT_MIN_BUFFER_COUNT = 1, + OUTPORT_ACTUAL_BUFFER_COUNT = 2, + OUTPORT_BUFFER_SIZE = 1382400, + }; + + OMX_VIDEO_PARAM_MPEG4TYPE mParamMpeg4; +}; + +#endif /* OMX_VIDEO_ENCODER_MPEG4_H_ */ diff --git a/videocodec/vabuffer.h b/videocodec/vabuffer.h new file mode 100644 index 0000000..3bfa624 --- /dev/null +++ b/videocodec/vabuffer.h @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2009-2011 Intel Corporation. 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 __VA_BUFFER_H__ +#define __VA_BUFFER_H__ + +struct VABuffer +{ + VASurfaceID surface; + VADisplay display; + unsigned int frame_structure; +}; + +#endif /* __VA_BUFFER_H__ */ + diff --git a/wrs_omxil_components.list b/wrs_omxil_components.list index 535ec51..5aa98ea 100644 --- a/wrs_omxil_components.list +++ b/wrs_omxil_components.list @@ -10,3 +10,7 @@ libomx_ipp_amrwbenc.so libomx_ipp_amrnbenc.so libomx_ipp_amrwbdec.so libomx_ipp_amrnbdec.so +libOMXVideoDecoderAVC.so +libOMXVideoDecoderH263.so +libOMXVideoDecoderWMV.so +libOMXVideoDecoderMPEG4.so |
