blob: 2d332415cc469a4fa4d79f49aefaed356c010463 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* 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.
* -------------------------------------------------------------------
*/
#include "pvmf_omx_basedec_port.h"
#include "pvmf_omx_basedec_node.h"
OSCL_EXPORT_REF PVMFOMXDecPort::PVMFOMXDecPort(int32 aTag, PVMFNodeInterface* aNode, const char*name)
: PvmfPortBaseImpl(aTag, aNode, name)
{
iOMXNode = (PVMFOMXBaseDecNode *) aNode;
Construct();
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PVMFOMXDecPort::Construct()
{
iLogger = PVLogger::GetLoggerObject(PortName());
oscl_memset(&iStats, 0, sizeof(PvmfPortBaseImplStats));
iNumFramesGenerated = 0;
iNumFramesConsumed = 0;
iTrackConfig = NULL;
iTrackConfigSize = 0;
if ((oscl_strcmp(PortName(), PVMF_OMX_VIDEO_DEC_INPUT_PORT_NAME) == 0) || (oscl_strcmp(PortName(), PVMF_OMX_VIDEO_DEC_OUTPUT_PORT_NAME) == 0))
{
PvmiCapabilityAndConfigPortFormatImpl::Construct(
PVMF_OMX_VIDEO_DEC_PORT_INPUT_FORMATS
, PVMF_OMX_VIDEO_DEC_PORT_INPUT_FORMATS_VALTYPE);
}
else if ((oscl_strcmp(PortName(), PVMF_OMX_AUDIO_DEC_INPUT_PORT_NAME) == 0) || (oscl_strcmp(PortName(), PVMF_OMX_AUDIO_DEC_OUTPUT_PORT_NAME) == 0))
{
PvmiCapabilityAndConfigPortFormatImpl::Construct(
PVMF_OMX_AUDIO_DEC_PORT_INPUT_FORMATS
, PVMF_OMX_AUDIO_DEC_PORT_INPUT_FORMATS_VALTYPE);
}
}
OSCL_EXPORT_REF PVMFOMXDecPort::~PVMFOMXDecPort()
{
if (iTrackConfig != NULL)
{
OSCL_FREE(iTrackConfig);
iTrackConfigSize = 0;
}
Disconnect();
ClearMsgQueues();
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF bool PVMFOMXDecPort::IsFormatSupported(PVMFFormatType aFmt)
{
bool isSupported = false;
if ((oscl_strcmp(PortName(), PVMF_OMX_VIDEO_DEC_INPUT_PORT_NAME) == 0) || (oscl_strcmp(PortName(), PVMF_OMX_VIDEO_DEC_OUTPUT_PORT_NAME) == 0))
{
isSupported = ((aFmt == PVMF_MIME_YUV420) ||
(aFmt == PVMF_MIME_H264_VIDEO_RAW) ||
(aFmt == PVMF_MIME_H264_VIDEO_MP4) ||
(aFmt == PVMF_MIME_H264_VIDEO) ||
(aFmt == PVMF_MIME_M4V) ||
(aFmt == PVMF_MIME_H2631998) ||
(aFmt == PVMF_MIME_H2632000) ||
(aFmt == PVMF_MIME_WMV)
);
}
else if ((oscl_strcmp(PortName(), PVMF_OMX_AUDIO_DEC_INPUT_PORT_NAME) == 0) || (oscl_strcmp(PortName(), PVMF_OMX_AUDIO_DEC_OUTPUT_PORT_NAME) == 0))
{
isSupported = ((aFmt == PVMF_MIME_PCM16) ||
(aFmt == PVMF_MIME_LATM) ||
(aFmt == PVMF_MIME_MPEG4_AUDIO) ||
(aFmt == PVMF_MIME_3640) ||
(aFmt == PVMF_MIME_ADIF) ||
(aFmt == PVMF_MIME_ASF_MPEG4_AUDIO) ||
(aFmt == PVMF_MIME_AAC_SIZEHDR) ||
(aFmt == PVMF_MIME_AMR_IF2) ||
(aFmt == PVMF_MIME_AMR_IETF) ||
(aFmt == PVMF_MIME_AMR) ||
(aFmt == PVMF_MIME_AMRWB_IETF) ||
(aFmt == PVMF_MIME_AMRWB) ||
(aFmt == PVMF_MIME_MP3) ||
(aFmt == PVMF_MIME_WMA)
);
}
return isSupported;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PVMFOMXDecPort::FormatUpdated()
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO
, (0, "%s::FormatUpdated %s", PortName(), iFormat.getMIMEStrPtr()));
}
OSCL_EXPORT_REF bool
PVMFOMXDecPort::releaseParametersSync(PvmiKvp*& aParameters, int& aNumParamElements)
{
if ((iConnectedPort) && (iTag == PVMF_OMX_DEC_NODE_PORT_TYPE_OUTPUT))
{
OsclAny* temp = NULL;
iConnectedPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, temp);
PvmiCapabilityAndConfig *config = (PvmiCapabilityAndConfig*)temp;
if (config != NULL)
{
config->releaseParameters(NULL, aParameters, aNumParamElements);
}
return true;
}
return false;
}
OSCL_EXPORT_REF bool
PVMFOMXDecPort::pvmiGetBufferAllocatorSpecificInfoSync(PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements)
{
if ((iConnectedPort) && (iTag == PVMF_OMX_DEC_NODE_PORT_TYPE_OUTPUT))
{
OsclAny* temp = NULL;
iConnectedPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, temp);
PvmiCapabilityAndConfig *config = (PvmiCapabilityAndConfig*)temp;
if (config != NULL)
{
PVMFStatus status =
config->getParametersSync(NULL, (PvmiKeyType)aIdentifier, aParameters, aNumParamElements, NULL);
if (PVMFSuccess == status)
{
// config->releaseParameters(NULL, aParameters, aNumParamElements);
}
}
return true;
}
return false;
}
OSCL_EXPORT_REF bool
PVMFOMXDecPort::pvmiSetPortFormatSpecificInfoSync(OsclRefCounterMemFrag& aMemFrag, PvmiKeyType KvpKey)
{
if ((iConnectedPort) &&
(iTag == PVMF_OMX_DEC_NODE_PORT_TYPE_OUTPUT))
{
OsclAny* temp = NULL;
iConnectedPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, temp);
PvmiCapabilityAndConfig *config = (PvmiCapabilityAndConfig*)temp;
/*
* Create PvmiKvp for capability settings
*/
if ((config) && (aMemFrag.getMemFragSize() > 0))
{
PvmiKvp kvp;
kvp.length = oscl_strlen(KvpKey) + 1; // +1 for \0
kvp.key = KvpKey;
if (kvp.key == NULL)
{
return false;
}
kvp.value.key_specific_value = (OsclAny*)(aMemFrag.getMemFragPtr());
kvp.capacity = aMemFrag.getMemFragSize();
PvmiKvp* retKvp = NULL; // for return value
int32 err;
OSCL_TRY(err, config->setParametersSync(NULL, &kvp, 1, retKvp););
OSCL_FIRST_CATCH_ANY(err, OSCL_LEAVE(-1));
}
return true;
}
return false;
}
OSCL_EXPORT_REF PVMFStatus PVMFOMXDecPort::Connect(PVMFPortInterface* aPort)
{
if (!aPort)
{
return PVMFErrArgument;
}
if (iConnectedPort)
{
return PVMFFailure;
}
OsclAny* temp;
aPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, temp);
PvmiCapabilityAndConfig *config = (PvmiCapabilityAndConfig*)temp;
if (config != NULL)
{
PvmiKvp* kvp;
int numKvp = 0;
PVMFStatus status =
config->getParametersSync(NULL, (PvmiKeyType)PVMF_FORMAT_SPECIFIC_INFO_KEY, kvp, numKvp, NULL);
if (status == PVMFSuccess)
{
if (iTrackConfig != NULL)
{
OSCL_FREE(iTrackConfig);
iTrackConfigSize = 0;
}
if (kvp)
{
iTrackConfigSize = kvp->capacity;
iTrackConfig = (uint8*)(OSCL_MALLOC(sizeof(uint8) * iTrackConfigSize));
oscl_memcpy(iTrackConfig, kvp->value.key_specific_value, iTrackConfigSize);
}
config->releaseParameters(NULL, kvp, numKvp);
}
}
// Automatically connect the peer.
if (aPort->PeerConnect(this) != PVMFSuccess)
{
return PVMFFailure;
}
iConnectedPort = aPort;
PortActivity(PVMF_PORT_ACTIVITY_CONNECT);
return PVMFSuccess;
}
// needed for WMV port exchange
OSCL_EXPORT_REF void PVMFOMXDecPort::setParametersSync(PvmiMIOSession aSession,
PvmiKvp* aParameters,
int num_elements,
PvmiKvp * & aRet_kvp)
{
// if port connect needs format specific info
if (aParameters && pv_mime_strcmp(aParameters->key, PVMF_FORMAT_SPECIFIC_INFO_KEY) == 0)
{
if (iTrackConfig != NULL)
{
OSCL_FREE(iTrackConfig);
iTrackConfigSize = 0;
}
iTrackConfigSize = aParameters->capacity;
iTrackConfig = (uint8*)(OSCL_MALLOC(sizeof(uint8) * iTrackConfigSize));
oscl_memcpy(iTrackConfig, aParameters->value.key_specific_value, iTrackConfigSize);
return;
}
// call the base class function
PvmiCapabilityAndConfigPortFormatImpl::setParametersSync(aSession, aParameters, num_elements, aRet_kvp);
}
OSCL_EXPORT_REF PVMFStatus PVMFOMXDecPort::verifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements)
{
OSCL_UNUSED_ARG(aSession);
// in case of WMV or WMA call the Node verify to make sure that the parameters are OK
// (the node will also make sure that the downstream node is OK with the change
// if necessary)
if (iFormat == PVMF_MIME_WMV || iFormat == PVMF_MIME_WMA)
{
if (iOMXNode->VerifyParametersSync(aSession, aParameters, num_elements))
{
return PVMFSuccess;
}
else
{
return PVMFErrNotSupported;
}
}
else
{
return PVMFSuccess;
}
}
OSCL_EXPORT_REF PVMFStatus PVMFOMXDecPort::verifyConnectedPortParametersSync(const char* aFormatValType,
OsclAny* aConfig)
{
PVMFStatus status = PVMFErrNotSupported;
OsclAny* temp;
if (iConnectedPort)
{
iConnectedPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, temp);
}
else
return PVMFFailure;
PvmiCapabilityAndConfig *capConfig = (PvmiCapabilityAndConfig*)temp;
if (capConfig != NULL)
{
if (pv_mime_strcmp(aFormatValType, PVMF_FORMAT_SPECIFIC_INFO_KEY) == 0)
{
OsclRefCounterMemFrag* aFormatValue = (OsclRefCounterMemFrag*)aConfig;
if (aFormatValue->getMemFragSize() > 0)
{
OsclMemAllocator alloc;
PvmiKvp kvp;
kvp.key = NULL;
kvp.length = oscl_strlen(aFormatValType) + 1; // +1 for \0
kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
if (kvp.key == NULL)
{
return PVMFErrNoMemory;
}
oscl_strncpy(kvp.key, aFormatValType, kvp.length);
kvp.value.key_specific_value = (OsclAny*)(aFormatValue->getMemFragPtr());
kvp.capacity = aFormatValue->getMemFragSize();
int32 err;
OSCL_TRY(err, status = capConfig->verifyParametersSync(NULL, &kvp, 1););
/* ignore the error for now */
alloc.deallocate((OsclAny*)(kvp.key));
return status;
}
}
else if (pv_mime_strcmp(aFormatValType, PVMF_BITRATE_VALUE_KEY) == 0 ||
pv_mime_strcmp(aFormatValType, PVMF_FRAMERATE_VALUE_KEY) == 0)
{
if (aConfig != NULL)
{
OsclMemAllocator alloc;
PvmiKvp kvp;
kvp.key = NULL;
kvp.length = oscl_strlen(aFormatValType) + 1; // +1 for \0
kvp.key = (PvmiKeyType)alloc.ALLOCATE(kvp.length);
if (kvp.key == NULL)
{
return PVMFErrNoMemory;
}
oscl_strncpy(kvp.key, aFormatValType, kvp.length);
uint32* bitrate = (uint32*)aConfig;
kvp.value.uint32_value = *bitrate;
int32 err;
OSCL_TRY(err, status = capConfig->verifyParametersSync(NULL, &kvp, 1););
/* ignore the error for now */
alloc.deallocate((OsclAny*)(kvp.key));
return status;
}
}
return PVMFErrArgument;
}
return PVMFFailure;
}