blob: 628cd1e1cb200603e568ed2dbfc7038fb6728337 [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.
* -------------------------------------------------------------------
*/
/**
* @file pvmf_media_input_node_outport.cpp
* @brief Output port for media io interface wrapper node
*/
#ifndef PVMF_MEDIA_INPUT_NODE_OUTPORT_H_INCLUDED
#include "pvmf_media_input_node_outport.h"
#endif
#ifndef PVMF_MEDIA_INPUT_NODE_H_INCLUDED
#include "pvmf_media_input_node.h"
#endif
#ifndef PVMF_FORMAT_TYPE_H_INCLUDED
#include "pvmf_format_type.h"
#endif
#ifndef PVMF_MEDIA_MSG_FORMAT_IDS_H_INCLUDED
#include "pvmf_media_msg_format_ids.h"
#endif
#ifndef PVMF_MEDIA_CMD_H_INCLUDED
#include "pvmf_media_cmd.h"
#endif
#define PVMIO_MEDIADATA_POOLNUM 9
// Logging macros
#define LOG_STACK_TRACE(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, m);
#define LOG_DEBUG(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, m);
#define LOG_ERR(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iLogger,PVLOGMSG_ERR,m);
#define LOGDATATRAFFIC(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iDataPathLogger,PVLOGMSG_INFO,m);
////////////////////////////////////////////////////////////////////////////
PvmfMediaInputNodeOutPort::PvmfMediaInputNodeOutPort(PvmfMediaInputNode* aNode, const char* aName)
: OsclTimerObject(OsclActiveObject::EPriorityNominal, "PvmfMediaInputNodeOutPort")
, PvmfPortBaseImpl(PVMF_MEDIAIO_NODE_OUTPUT_PORT_TAG
//this port handles its own port activity
, this, aName)
, iNode(aNode)
, iState(PvmfMediaInputNodeOutPort::PORT_STATE_BUFFERING)
, inum_text_sample(0)
, imax_num_sample(0)
{
iCmdId = 0;
AddToScheduler();
iFormatType = PVMF_MIME_FORMAT_UNKNOWN;
iPeer = NULL;
iWriteState = EWriteOK;
iMediaDataAllocMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (PVMIO_MEDIADATA_POOLNUM));
iMediaDataMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (PVMIO_MEDIADATA_POOLNUM));
iMediaDataAlloc = OSCL_NEW(PvmfMediaInputDataBufferAlloc, (iMediaDataAllocMemPool));
iDataPathLogger = PVLogger::GetLoggerObject("datapath.sourcenode");
#ifdef _TEST_AE_EROR_HANDLING
iTimeStampJunk = 0x000FFFFF;
#endif
}
////////////////////////////////////////////////////////////////////////////
PvmfMediaInputNodeOutPort::~PvmfMediaInputNodeOutPort()
{
PvmfPortBaseImpl::ClearMsgQueues();
if (iMediaDataAlloc != NULL)
{
OSCL_DELETE(iMediaDataAlloc);
}
if (iMediaDataAllocMemPool)
{
iMediaDataAllocMemPool->removeRef();
}
if (iMediaDataMemPool)
{
iMediaDataMemPool->removeRef();
}
iDataPathLogger = NULL;
// we need to clear the activity handler, since otherwise the PvmfPortBaseImpl destructor
// ends up calling back onto our HandlePortActivity method, which no longer exists because
// this objects's destructor has already been called.
SetActivityHandler(NULL);
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::Start()
{
iWriteState = EWriteOK;
#ifdef _TEST_AE_ERROR_HANDLING
if (iNode->iError_Out_Queue_Busy)
{
PvmfPortBaseImpl::SetCapacity(EPVIncomingDataQueue, 0);
PvmfPortBaseImpl::SetReserve(EPVIncomingDataQueue, 0);
PvmfPortBaseImpl::SetThreshold(EPVIncomingDataQueue, 0);
PvmfPortBaseImpl::SetCapacity(EPVOutgoingDataQueue, 1);
PvmfPortBaseImpl::SetReserve(EPVOutgoingDataQueue, 2);
PvmfPortBaseImpl::SetThreshold(EPVOutgoingDataQueue, 100);
}
else
{
PvmfPortBaseImpl::SetCapacity(EPVIncomingDataQueue, 0);
PvmfPortBaseImpl::SetReserve(EPVIncomingDataQueue, 0);
PvmfPortBaseImpl::SetThreshold(EPVIncomingDataQueue, 0);
PvmfPortBaseImpl::SetCapacity(EPVOutgoingDataQueue, 10);
PvmfPortBaseImpl::SetReserve(EPVOutgoingDataQueue, 10);
PvmfPortBaseImpl::SetThreshold(EPVOutgoingDataQueue, 70);
}
#else
PvmfPortBaseImpl::SetCapacity(EPVIncomingDataQueue, 0);
PvmfPortBaseImpl::SetReserve(EPVIncomingDataQueue, 0);
PvmfPortBaseImpl::SetThreshold(EPVIncomingDataQueue, 0);
PvmfPortBaseImpl::SetCapacity(EPVOutgoingDataQueue, 10);
PvmfPortBaseImpl::SetReserve(EPVOutgoingDataQueue, 10);
PvmfPortBaseImpl::SetThreshold(EPVOutgoingDataQueue, 70);
#endif
iState = PvmfMediaInputNodeOutPort::PORT_STATE_STARTED;
if (iNode->iMediaIOState == PvmfMediaInputNode::MIO_STATE_STARTED)
{
RunIfNotReady();
}
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::MediaIOStarted()
{
if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_STARTED)
RunIfNotReady();
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::Pause()
{
iState = PvmfMediaInputNodeOutPort::PORT_STATE_BUFFERING;
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::Stop()
{
iWriteState = EWriteOK;
PvmfPortBaseImpl::ClearMsgQueues();
iState = PvmfMediaInputNodeOutPort::PORT_STATE_STOPPED;
}
////////////////////////////////////////////////////////////////////////////
PVMFStatus PvmfMediaInputNodeOutPort::Configure(PVMFFormatType aPortProperty,
OSCL_String* aMime)
{
if (iConnectedPort)
{
// Must disconnect before changing port properties, so return error
return PVMFFailure;
}
iFormatType = aPortProperty;
iMimeType = *aMime;
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::Connect(PVMFPortInterface* aPort)
{
PVMFStatus status = PvmfPortBaseImpl::Connect(aPort);
if (status != PVMFSuccess)
return status;
iMediaInput = iNode->iMediaIOControl->createMediaTransfer(iNode->iMediaIOSession);
if (iMediaInput)
iMediaInput->setPeer(this);
else
return PVMFFailure;
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::PeerConnect(PVMFPortInterface* aPort)
{
PVMFStatus status = PvmfPortBaseImpl::PeerConnect(aPort);
if (status != PVMFSuccess)
return status;
iMediaInput = iNode->iMediaIOControl->createMediaTransfer(iNode->iMediaIOSession);
if (iMediaInput)
iMediaInput->setPeer(this);
else
return PVMFFailure;
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::Disconnect()
{
PVMFStatus status = PvmfPortBaseImpl::Disconnect();
if (status != PVMFSuccess)
return status;
iNode->iMediaIOControl->deleteMediaTransfer(iNode->iMediaIOSession, iMediaInput);
if (iMediaInput)
iMediaInput->setPeer(0);
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::PeerDisconnect()
{
PVMFStatus status = PvmfPortBaseImpl::PeerDisconnect();
if (status != PVMFSuccess)
return status;
if (iMediaInput)
iMediaInput->setPeer(0);
iNode->iMediaIOControl->deleteMediaTransfer(iNode->iMediaIOSession, iMediaInput);
return PVMFSuccess;
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::setPeer(PvmiMediaTransfer *aPeer)
{
iPeer = aPeer;
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::useMemoryAllocators(OsclMemAllocator* write_alloc)
{
OSCL_UNUSED_ARG(write_alloc);
OSCL_LEAVE(OsclErrNotSupported);
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PvmfMediaInputNodeOutPort::writeAsync(uint8 format_type, int32 format_index,
uint8* data, uint32 data_len,
const PvmiMediaXferHeader& data_header_info,
OsclAny* context)
{
if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_STOPPED)
{
// In Stopped state we are not going to accept any buffers
OsclError::Leave(OsclErrNotReady);
LOG_DEBUG((0, "Ignoring PvmfMediaInputNodeOutPort::writeAsync"));
return -1;
}
if (iWriteState == EWriteOK)
{
if (PVMI_MEDIAXFER_FMT_TYPE_NOTIFICATION == format_type)
{
switch (format_index)
{
//added for timed text support
//here it handles the configuration information for timed text and passes it to the composernode
case PVMI_MEDIAXFER_FMT_INDEX_FMT_SPECIFIC_INFO:
{
//we expect media input components to use cap-config to provide
//fmt specific info
LOG_ERR((0, "Fmt Specific Info over WriteAsync Not Supported"));
iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)NULL);
OsclError::Leave(OsclErrGeneral);
}
break;
case PVMI_MEDIAXFER_FMT_INDEX_END_OF_STREAM:
{
SendEndOfTrackCommand(data_header_info);
MediaIOStarted();
return iCmdId++;
}
break;
default:
{
LOG_ERR((0, "Ignoring Format Index :%d since not supported\n", format_index));
iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)NULL);
OsclError::Leave(OsclErrGeneral);
}
break;
}
}
// TODO: Handle incoming data here. Create a media data using PvmiMIOSourceDataBufferAlloc::allocate,
// save the data there, put the media data to outgoing queue.
// If the port is started, schedule to send in Run
else if (PVMI_MEDIAXFER_FMT_TYPE_DATA == format_type)
{
//if the outgoing queue is full, we can't accept data
//now.
if (IsOutgoingQueueBusy())
{
iWriteState = EWriteBusy;
OsclError::Leave(OsclErrBusy);
}
// Create new media data buffer
PVMFSharedMediaDataPtr mediaData;
int32 err = 0;
if (iCmdId == 0x7FFFFFFF)
iCmdId = 0;
#ifdef _TEST_AE_ERROR_HANDLING
if (data_header_info.stream_id == iNode->iTrackID)
{
uint32 ii = 0;
while (iNode->iChunkCount > 0)
{
uint32 sz = data_len - 5;
for (ii = 0; ii <= sz; ii++)
{
uint8* ptr = data + ii;
*ptr = 0;
}
iNode->iChunkCount--;
}
}
#endif
#ifdef _TEST_AE_ERROR_HANDLING
if (iNode->iError_No_Memory)
{
err = OsclErrBusy;
if (IsAdded())
{
RunIfNotReady();
}
}
else
{
OSCL_TRY(err,
OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl = iMediaDataAlloc->allocate(iMediaInput, data,
data_len, iCmdId, context);
mediaData = PVMFMediaData::createMediaData(mediaDataImpl, iMediaDataMemPool););
}
#else
OSCL_TRY(err,
OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl = iMediaDataAlloc->allocate(iMediaInput, data,
data_len, iCmdId, context);
mediaData = PVMFMediaData::createMediaData(mediaDataImpl, iMediaDataMemPool););
#endif
if (err)
{
iMediaDataAllocMemPool->notifyfreechunkavailable(*this);
iWriteState = EWriteBusy;
OsclError::Leave(OsclErrBusy);
}
// Set timestamp
#ifdef _TEST_AE_ERROR_HANDLING
if ((data_header_info.stream_id == iNode->iErrorTimeStamp.track_no) && (1 == iNode->iErrorTimeStamp.mode))
{
if (iTimeStampJunk == 0)
{
iTimeStampJunk = 0x000FFFFF;
}
mediaData->setTimestamp(iTimeStampJunk);
iTimeStampJunk = iTimeStampJunk - 33;
}
else if ((data_header_info.stream_id == iNode->iErrorTimeStamp.track_no) && (2 == iNode->iErrorTimeStamp.mode))
{
if (data_header_info.timestamp >= iNode->iErrorTimeStamp.duration)
{
mediaData->setTimestamp(0);
}
}
else if ((data_header_info.stream_id == iNode->iErrorTimeStamp.track_no) && (3 == iNode->iErrorTimeStamp.mode))
{
mediaData->setTimestamp(0);
}
else
{
mediaData->setTimestamp(data_header_info.timestamp);
}
#else
mediaData->setTimestamp(data_header_info.timestamp);
#endif
mediaData->setSeqNum(data_header_info.seq_num);
mediaData->setMediaFragFilledLen(0, data_len);
mediaData->setStreamID(data_header_info.stream_id);
LOGDATATRAFFIC((0, "PvmfMediaInputNodeOutPort::writeAsync:"
"StreamID=%d, TS=%d, Len=%d, SN=%d, MimeType=%s",
data_header_info.stream_id, data_header_info.timestamp, data_len,
data_header_info.seq_num, iMimeType.get_cstr()));
// Convert media data to MediaMsg
PVMFSharedMediaMsgPtr mediaMsg;
convertToPVMFMediaMsg(mediaMsg, mediaData);
PVMFStatus status;
#ifdef _TEST_AE_ERROR_HANDLING
if ((iNode->iErrorTrackID > 0) && (data_header_info.stream_id == (uint32)iNode->iErrorTrackID))
{
status = PVMFSuccess;
}
else
{
status = QueueOutgoingMsg(mediaMsg);
}
#else
status = QueueOutgoingMsg(mediaMsg);
#endif
if (status != PVMFSuccess)
{
iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);
OsclError::Leave(OsclErrGeneral);
}
if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_STARTED)
RunIfNotReady();
return iCmdId++;
}
else
{
LOG_DEBUG((0, "Ignoring Format Type :%d since not supported\n", format_type));
iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)NULL);
OsclError::Leave(OsclErrGeneral);
}
}
else
{
OsclError::Leave(OsclErrBusy);
}
return 0;
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::writeComplete(PVMFStatus status, PVMFCommandId write_cmd_id, OsclAny* context)
{
OSCL_UNUSED_ARG(context);
OSCL_UNUSED_ARG(status);
OSCL_UNUSED_ARG(write_cmd_id);
OSCL_LEAVE(OsclErrNotSupported);
}
////////////////////////////////////////////////////////////////////////////
PVMFCommandId PvmfMediaInputNodeOutPort::readAsync(uint8* data, uint32 max_data_len, OsclAny* context,
int32* formats, uint16 num_formats)
{
OSCL_UNUSED_ARG(data);
OSCL_UNUSED_ARG(max_data_len);
OSCL_UNUSED_ARG(context);
OSCL_UNUSED_ARG(formats);
OSCL_UNUSED_ARG(num_formats);
OSCL_LEAVE(OsclErrNotSupported);
return -1;
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::readComplete(PVMFStatus status, PVMFCommandId read_cmd_id,
int32 format_index, const PvmiMediaXferHeader& data_header_info,
OsclAny* context)
{
OSCL_UNUSED_ARG(status);
OSCL_UNUSED_ARG(read_cmd_id);
OSCL_UNUSED_ARG(format_index);
OSCL_UNUSED_ARG(data_header_info);
OSCL_UNUSED_ARG(context);
OSCL_LEAVE(OsclErrNotSupported);
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::statusUpdate(uint32 status_flags)
{
OSCL_UNUSED_ARG(status_flags);
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::cancelCommand(PVMFCommandId command_id)
{
OSCL_UNUSED_ARG(command_id);
OSCL_LEAVE(OsclErrNotSupported);
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::cancelAllCommands()
{
OSCL_LEAVE(OsclErrNotSupported);
}
////////////////////////////////////////////////////////////////////////////
// PvmiCapabilityAndConfig
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver)
{
// Not supported
OSCL_UNUSED_ARG(aObserver);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::getParametersSync(PvmiMIOSession session,
PvmiKeyType identifier,
PvmiKvp*& parameters,
int& num_parameter_elements,
PvmiCapabilityContext context)
{
LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::getParametersSync"));
if (!iNode || !iNode->iMediaIOConfig)
{
LOG_ERR((0, "PvmfMediaInputNodeOutPort::getParametersSync: Error - Config object for media IO not available"));
return PVMFFailure;
}
return iNode->iMediaIOConfig->getParametersSync(session, identifier, parameters,
num_parameter_elements, context);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::releaseParameters(PvmiMIOSession session,
PvmiKvp* parameters,
int num_elements)
{
LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::releaseParameters"));
if (!iNode || !iNode->iMediaIOConfig)
{
LOG_ERR((0, "PvmfMediaInputNodeOutPort::releaseParameters: Error - Config object for media IO not available"));
return PVMFFailure;
}
return iNode->iMediaIOConfig->releaseParameters(session, parameters, num_elements);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::createContext(PvmiMIOSession session, PvmiCapabilityContext& context)
{
OSCL_UNUSED_ARG(session);
OSCL_UNUSED_ARG(context);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::setContextParameters(PvmiMIOSession session,
PvmiCapabilityContext& context,
PvmiKvp* parameters, int num_parameter_elements)
{
OSCL_UNUSED_ARG(session);
OSCL_UNUSED_ARG(context);
OSCL_UNUSED_ARG(parameters);
OSCL_UNUSED_ARG(num_parameter_elements);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::DeleteContext(PvmiMIOSession session, PvmiCapabilityContext& context)
{
OSCL_UNUSED_ARG(session);
OSCL_UNUSED_ARG(context);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::setParametersSync(PvmiMIOSession session, PvmiKvp* parameters,
int num_elements, PvmiKvp*& ret_kvp)
{
LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::setParametersSync"));
if (!iNode || !iNode->iMediaIOConfig)
{
LOG_ERR((0, "PvmfMediaInputNodeOutPort::setParametersSync: Error - Config object for media IO not available"));
ret_kvp = parameters;
OSCL_LEAVE(OsclErrGeneral);
}
iNode->iMediaIOConfig->setParametersSync(session, parameters, num_elements, ret_kvp);
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNodeOutPort::setParametersAsync(PvmiMIOSession session,
PvmiKvp* parameters,
int num_elements,
PvmiKvp*& ret_kvp,
OsclAny* context)
{
OSCL_UNUSED_ARG(session);
OSCL_UNUSED_ARG(parameters);
OSCL_UNUSED_ARG(num_elements);
OSCL_UNUSED_ARG(ret_kvp);
OSCL_UNUSED_ARG(context);
OsclError::Leave(OsclErrNotSupported);
return -1;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF uint32 PvmfMediaInputNodeOutPort::getCapabilityMetric(PvmiMIOSession session)
{
OSCL_UNUSED_ARG(session);
return 0;
}
////////////////////////////////////////////////////////////////////////////
OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::verifyParametersSync(PvmiMIOSession session,
PvmiKvp* parameters, int num_elements)
{
LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::verifyParametersSync"));
if (!iNode || !iNode->iMediaIOConfig)
{
LOG_ERR((0, "PvmfMediaInputNodeOutPort::verifyParametersSync: Error - Config object for media IO not available"));
return PVMFFailure;
}
return iNode->iMediaIOConfig->verifyParametersSync(session, parameters, num_elements);
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::Run()
{
if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_BUFFERING)
return;
#ifdef _TEST_AE_ERROR_HANDLING
if (iNode->iError_No_Memory)
{
if (iMediaInput && iWriteState == EWriteBusy)
{
iWriteState = EWriteOK;
iMediaInput->statusUpdate(PVMI_MEDIAXFER_STATUS_WRITE);
iNode->iError_No_Memory = false;
}
}
#endif
if ((OutgoingMsgQueueSize() > 0) && (!IsConnectedPortBusy()))
{
//transfer data to connected port.
PVMFStatus status = Send();
if (status != PVMFSuccess)
iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);
//reschedule as long as there's data queued...
if (OutgoingMsgQueueSize() > 0
&& !IsConnectedPortBusy())
{
RunIfNotReady();
}
if (iNode->IsFlushPending())
{
if (IncomingMsgQueueSize() == 0 && OutgoingMsgQueueSize() == 0)
iNode->FlushComplete();
}
}
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::HandlePortActivity(const PVMFPortActivity& aActivity)
{
switch (aActivity.iType)
{
case PVMF_PORT_ACTIVITY_CONNECT:
{
//get the mimetype
OsclAny* temp = NULL;
iConnectedPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, temp);
PvmiCapabilityAndConfig *config = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, temp);
if (config != NULL)
{
int numKvp = 0;
PvmiKvp* kvpPtr = NULL;
PVMFStatus status =
config->getParametersSync(NULL,
(char*)INPUT_FORMATS_CUR_QUERY, kvpPtr, numKvp, NULL);
if (status == PVMFSuccess)
{
iFormatType = kvpPtr[0].value.pChar_value;
iMimeType = iFormatType.getMIMEStrPtr();
}
config->releaseParameters(NULL, kvpPtr, numKvp);
}
}
break;
case PVMF_PORT_ACTIVITY_DISCONNECT:
break;
case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
//wakeup the AO when the first message arrives.
if (OutgoingMsgQueueSize() == 1)
RunIfNotReady();
break;
case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
//wakeup the AO when the connected port is
//ready to accept data again.
RunIfNotReady();
break;
case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
if (iMediaInput && (iWriteState == EWriteBusy))
{
iWriteState = EWriteOK;
//let the peer know they can try to write again.
iMediaInput->statusUpdate(PVMI_MEDIAXFER_STATUS_WRITE);
}
break;
case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_BUSY:
{
iWriteState = EWriteBusy;
}
break;
case PVMF_PORT_ACTIVITY_CONNECTED_PORT_BUSY:
break;
default:
break;
}
}
////////////////////////////////////////////////////////////////////////////
void PvmfMediaInputNodeOutPort::SendEndOfTrackCommand(const PvmiMediaXferHeader& data_header_info)
{
PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);
// Set the timestamp
sharedMediaCmdPtr->setTimestamp(data_header_info.timestamp);
// Set the sequence number
sharedMediaCmdPtr->setSeqNum(data_header_info.seq_num);
PVMFSharedMediaMsgPtr mediaMsgOut;
convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
PVMFStatus status = QueueOutgoingMsg(mediaMsgOut);
if (status != PVMFSuccess)
{
iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);
OsclError::Leave(OsclErrGeneral);
}
LOGDATATRAFFIC((0, "PvmfMediaInputNodeOutPort::SendEndOfTrackCommand - EOS Sent:"
"StreamID=%d, TS=%d, SN=%d, MimeType=%s",
data_header_info.stream_id, data_header_info.timestamp,
data_header_info.seq_num, iMimeType.get_cstr()));
}
void PvmfMediaInputNodeOutPort :: freechunkavailable(OsclAny*)
{
if (iWriteState == EWriteBusy)
{
iWriteState = EWriteOK;
if (IsAdded())
{
iMediaInput->statusUpdate(PVMI_MEDIAXFER_STATUS_WRITE);
}
}
}