Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 /**
     19  * @file pvmf_media_input_node_outport.cpp
     20  * @brief Output port for media io interface wrapper node
     21  */
     22 
     23 #ifndef PVMF_MEDIA_INPUT_NODE_OUTPORT_H_INCLUDED
     24 #include "pvmf_media_input_node_outport.h"
     25 #endif
     26 #ifndef PVMF_MEDIA_INPUT_NODE_H_INCLUDED
     27 #include "pvmf_media_input_node.h"
     28 #endif
     29 #ifndef PVMF_FORMAT_TYPE_H_INCLUDED
     30 #include "pvmf_format_type.h"
     31 #endif
     32 
     33 #ifndef PVMF_MEDIA_MSG_FORMAT_IDS_H_INCLUDED
     34 #include "pvmf_media_msg_format_ids.h"
     35 #endif
     36 #ifndef PVMF_MEDIA_CMD_H_INCLUDED
     37 #include "pvmf_media_cmd.h"
     38 #endif
     39 
     40 #define PVMIO_MEDIADATA_POOLNUM 9
     41 
     42 // Logging macros
     43 #define LOG_STACK_TRACE(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, m);
     44 #define LOG_DEBUG(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, m);
     45 #define LOG_ERR(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iLogger,PVLOGMSG_ERR,m);
     46 #define LOGDATATRAFFIC(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_REL,iDataPathLogger,PVLOGMSG_INFO,m);
     47 
     48 ////////////////////////////////////////////////////////////////////////////
     49 PvmfMediaInputNodeOutPort::PvmfMediaInputNodeOutPort(PvmfMediaInputNode* aNode, const char* aName)
     50         : OsclTimerObject(OsclActiveObject::EPriorityNominal, "PvmfMediaInputNodeOutPort")
     51         , PvmfPortBaseImpl(PVMF_MEDIAIO_NODE_OUTPUT_PORT_TAG
     52                            //this port handles its own port activity
     53                            , this, aName)
     54         , iNode(aNode)
     55         , iState(PvmfMediaInputNodeOutPort::PORT_STATE_BUFFERING)
     56         , inum_text_sample(0)
     57         , imax_num_sample(0)
     58 {
     59     iCmdId = 0;
     60     AddToScheduler();
     61     iFormatType = PVMF_MIME_FORMAT_UNKNOWN;
     62     iPeer = NULL;
     63     iWriteState = EWriteOK;
     64     iMediaDataAllocMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (PVMIO_MEDIADATA_POOLNUM));
     65     iMediaDataMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (PVMIO_MEDIADATA_POOLNUM));
     66     iMediaDataAlloc = OSCL_NEW(PvmfMediaInputDataBufferAlloc, (iMediaDataAllocMemPool));
     67     iDataPathLogger = PVLogger::GetLoggerObject("datapath.sourcenode");
     68 
     69     iNode->iPrivateDataFsiFragmentAlloc.size(32, sizeof(OsclAny *)); //TODO REMOVE THE HARDCODED VALUE
     70 #ifdef _TEST_AE_EROR_HANDLING
     71     iTimeStampJunk = 0x000FFFFF;
     72 #endif
     73 }
     74 
     75 ////////////////////////////////////////////////////////////////////////////
     76 PvmfMediaInputNodeOutPort::~PvmfMediaInputNodeOutPort()
     77 {
     78     PvmfPortBaseImpl::ClearMsgQueues();
     79 
     80 
     81     if (iMediaDataAlloc != NULL)
     82     {
     83         OSCL_DELETE(iMediaDataAlloc);
     84     }
     85 
     86     if (iMediaDataAllocMemPool)
     87     {
     88         iMediaDataAllocMemPool->removeRef();
     89     }
     90 
     91     if (iMediaDataMemPool)
     92     {
     93         iMediaDataMemPool->removeRef();
     94     }
     95     iDataPathLogger = NULL;
     96 
     97     // we need to clear the activity handler, since otherwise the PvmfPortBaseImpl destructor
     98     // ends up calling back onto our HandlePortActivity method, which no longer exists because
     99     // this objects's destructor has already been called.
    100     SetActivityHandler(NULL);
    101 }
    102 
    103 ////////////////////////////////////////////////////////////////////////////
    104 void PvmfMediaInputNodeOutPort::Start()
    105 {
    106     iWriteState = EWriteOK;
    107 #ifdef _TEST_AE_ERROR_HANDLING
    108 
    109     if (iNode->iError_Out_Queue_Busy)
    110     {
    111         PvmfPortBaseImpl::SetCapacity(EPVIncomingDataQueue, 0);
    112         PvmfPortBaseImpl::SetReserve(EPVIncomingDataQueue, 0);
    113         PvmfPortBaseImpl::SetThreshold(EPVIncomingDataQueue, 0);
    114         PvmfPortBaseImpl::SetCapacity(EPVOutgoingDataQueue, 1);
    115         PvmfPortBaseImpl::SetReserve(EPVOutgoingDataQueue, 2);
    116         PvmfPortBaseImpl::SetThreshold(EPVOutgoingDataQueue, 100);
    117     }
    118     else
    119     {
    120         PvmfPortBaseImpl::SetCapacity(EPVIncomingDataQueue, 0);
    121         PvmfPortBaseImpl::SetReserve(EPVIncomingDataQueue, 0);
    122         PvmfPortBaseImpl::SetThreshold(EPVIncomingDataQueue, 0);
    123         PvmfPortBaseImpl::SetCapacity(EPVOutgoingDataQueue, 10);
    124         PvmfPortBaseImpl::SetReserve(EPVOutgoingDataQueue, 10);
    125         PvmfPortBaseImpl::SetThreshold(EPVOutgoingDataQueue, 70);
    126     }
    127 #else
    128     PvmfPortBaseImpl::SetCapacity(EPVIncomingDataQueue, 0);
    129     PvmfPortBaseImpl::SetReserve(EPVIncomingDataQueue, 0);
    130     PvmfPortBaseImpl::SetThreshold(EPVIncomingDataQueue, 0);
    131     PvmfPortBaseImpl::SetCapacity(EPVOutgoingDataQueue, 10);
    132     PvmfPortBaseImpl::SetReserve(EPVOutgoingDataQueue, 10);
    133     PvmfPortBaseImpl::SetThreshold(EPVOutgoingDataQueue, 70);
    134 
    135 #endif
    136     iState = PvmfMediaInputNodeOutPort::PORT_STATE_STARTED;
    137     if (iNode->iMediaIOState == PvmfMediaInputNode::MIO_STATE_STARTED)
    138     {
    139         RunIfNotReady();
    140     }
    141 }
    142 
    143 ////////////////////////////////////////////////////////////////////////////
    144 void PvmfMediaInputNodeOutPort::MediaIOStarted()
    145 {
    146     if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_STARTED)
    147         RunIfNotReady();
    148 }
    149 
    150 ////////////////////////////////////////////////////////////////////////////
    151 void PvmfMediaInputNodeOutPort::Pause()
    152 {
    153     iState = PvmfMediaInputNodeOutPort::PORT_STATE_BUFFERING;
    154 }
    155 
    156 ////////////////////////////////////////////////////////////////////////////
    157 void PvmfMediaInputNodeOutPort::Stop()
    158 {
    159     iWriteState = EWriteOK;
    160     PvmfPortBaseImpl::ClearMsgQueues();
    161     iState = PvmfMediaInputNodeOutPort::PORT_STATE_STOPPED;
    162 }
    163 
    164 ////////////////////////////////////////////////////////////////////////////
    165 PVMFStatus PvmfMediaInputNodeOutPort::Configure(PVMFFormatType aPortProperty,
    166         OSCL_String* aMime)
    167 {
    168     if (iConnectedPort)
    169     {
    170         // Must disconnect before changing port properties, so return error
    171         return PVMFFailure;
    172     }
    173 
    174     iFormatType = aPortProperty;
    175     iMimeType = *aMime;
    176     return PVMFSuccess;
    177 }
    178 
    179 ////////////////////////////////////////////////////////////////////////////
    180 OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::Connect(PVMFPortInterface* aPort)
    181 {
    182     PVMFStatus status = PvmfPortBaseImpl::Connect(aPort);
    183     if (status != PVMFSuccess)
    184         return status;
    185 
    186     iMediaInput = iNode->iMediaIOControl->createMediaTransfer(iNode->iMediaIOSession);
    187     if (iMediaInput)
    188         iMediaInput->setPeer(this);
    189     else
    190         return PVMFFailure;
    191 
    192     return PVMFSuccess;
    193 }
    194 
    195 ////////////////////////////////////////////////////////////////////////////
    196 OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::PeerConnect(PVMFPortInterface* aPort)
    197 {
    198     PVMFStatus status = PvmfPortBaseImpl::PeerConnect(aPort);
    199     if (status != PVMFSuccess)
    200         return status;
    201 
    202     iMediaInput = iNode->iMediaIOControl->createMediaTransfer(iNode->iMediaIOSession);
    203     if (iMediaInput)
    204         iMediaInput->setPeer(this);
    205     else
    206         return PVMFFailure;
    207 
    208     return PVMFSuccess;
    209 }
    210 
    211 ////////////////////////////////////////////////////////////////////////////
    212 OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::Disconnect()
    213 {
    214     PVMFStatus status = PvmfPortBaseImpl::Disconnect();
    215     if (status != PVMFSuccess)
    216         return status;
    217 
    218     iNode->iMediaIOControl->deleteMediaTransfer(iNode->iMediaIOSession, iMediaInput);
    219     if (iMediaInput)
    220         iMediaInput->setPeer(0);
    221     return PVMFSuccess;
    222 }
    223 
    224 ////////////////////////////////////////////////////////////////////////////
    225 OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::PeerDisconnect()
    226 {
    227     PVMFStatus status = PvmfPortBaseImpl::PeerDisconnect();
    228     if (status != PVMFSuccess)
    229         return status;
    230 
    231     if (iMediaInput)
    232         iMediaInput->setPeer(0);
    233     iNode->iMediaIOControl->deleteMediaTransfer(iNode->iMediaIOSession, iMediaInput);
    234     return PVMFSuccess;
    235 }
    236 
    237 ////////////////////////////////////////////////////////////////////////////
    238 void PvmfMediaInputNodeOutPort::setPeer(PvmiMediaTransfer *aPeer)
    239 {
    240     iPeer = aPeer;
    241 }
    242 
    243 ////////////////////////////////////////////////////////////////////////////
    244 void PvmfMediaInputNodeOutPort::useMemoryAllocators(OsclMemAllocator* write_alloc)
    245 {
    246     OSCL_UNUSED_ARG(write_alloc);
    247     OSCL_LEAVE(OsclErrNotSupported);
    248 }
    249 
    250 ////////////////////////////////////////////////////////////////////////////
    251 PVMFCommandId PvmfMediaInputNodeOutPort::writeAsync(uint8 format_type, int32 format_index,
    252         uint8* data, uint32 data_len,
    253         const PvmiMediaXferHeader& data_header_info,
    254         OsclAny* context)
    255 {
    256     if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_STOPPED)
    257     {
    258         // In Stopped state we are not going to accept any buffers
    259         OsclError::Leave(OsclErrNotReady);
    260         LOG_DEBUG((0, "Ignoring PvmfMediaInputNodeOutPort::writeAsync"));
    261         return -1;
    262     }
    263     if (iWriteState == EWriteOK)
    264     {
    265         if (PVMI_MEDIAXFER_FMT_TYPE_NOTIFICATION == format_type)
    266         {
    267             switch (format_index)
    268             {
    269                     //added for timed text support
    270                     //here it handles the configuration information for timed text and passes it to the composernode
    271 
    272                 case PVMI_MEDIAXFER_FMT_INDEX_FMT_SPECIFIC_INFO:
    273                 {
    274                     //we expect media input components to use cap-config to provide
    275                     //fmt specific info
    276                     LOG_ERR((0, "Fmt Specific Info over WriteAsync Not Supported"));
    277                     iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)NULL);
    278                     OsclError::Leave(OsclErrGeneral);
    279                 }
    280                 break;
    281                 case PVMI_MEDIAXFER_FMT_INDEX_END_OF_STREAM:
    282                 {
    283 
    284                     SendEndOfTrackCommand(data_header_info);
    285                     MediaIOStarted();
    286 
    287                     return iCmdId++;
    288                 }
    289                 break;
    290                 default:
    291                 {
    292                     LOG_ERR((0, "Ignoring Format Index :%d since not supported\n", format_index));
    293 
    294                     iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)NULL);
    295                     OsclError::Leave(OsclErrGeneral);
    296 
    297                 }
    298                 break;
    299             }
    300 
    301         }
    302 
    303         // TODO: Handle incoming data here. Create a media data using PvmiMIOSourceDataBufferAlloc::allocate,
    304         // save the data there, put the media data to outgoing queue.
    305         // If the port is started, schedule to send in Run
    306 
    307         else if (PVMI_MEDIAXFER_FMT_TYPE_DATA == format_type)
    308         {
    309             //if the outgoing queue is full, we can't accept data
    310             //now.
    311 
    312             if (IsOutgoingQueueBusy())
    313             {
    314                 iWriteState = EWriteBusy;
    315                 OsclError::Leave(OsclErrBusy);
    316             }
    317 
    318             // Create new media data buffer
    319             PVMFSharedMediaDataPtr mediaData;
    320             int32 err = 0;
    321 
    322             if (iCmdId == 0x7FFFFFFF)
    323                 iCmdId = 0;
    324 #ifdef _TEST_AE_ERROR_HANDLING
    325 
    326             if (data_header_info.stream_id == iNode->iTrackID)
    327             {
    328                 uint32 ii = 0;
    329                 while (iNode->iChunkCount > 0)
    330                 {
    331                     uint32 sz = data_len - 5;
    332 
    333                     for (ii = 0; ii <= sz; ii++)
    334                     {
    335                         uint8* ptr = data + ii;
    336                         *ptr = 0;
    337                     }
    338 
    339                     iNode->iChunkCount--;
    340                 }
    341 
    342             }
    343 #endif
    344 #ifdef _TEST_AE_ERROR_HANDLING
    345             if (iNode->iError_No_Memory)
    346             {
    347                 err = OsclErrBusy;
    348                 if (IsAdded())
    349                 {
    350                     RunIfNotReady();
    351                 }
    352             }
    353             else
    354             {
    355                 OSCL_TRY(err,
    356                          OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl = iMediaDataAlloc->allocate(iMediaInput, data,
    357                                  data_len, iCmdId, context);
    358                          mediaData = PVMFMediaData::createMediaData(mediaDataImpl, iMediaDataMemPool););
    359             }
    360 #else
    361             OSCL_TRY(err,
    362                      OsclSharedPtr<PVMFMediaDataImpl> mediaDataImpl = iMediaDataAlloc->allocate(iMediaInput, data,
    363                              data_len, iCmdId, context);
    364                      mediaData = PVMFMediaData::createMediaData(mediaDataImpl, iMediaDataMemPool););
    365 
    366 
    367 #endif
    368             if (err)
    369             {
    370                 iMediaDataAllocMemPool->notifyfreechunkavailable(*this);
    371                 iWriteState = EWriteBusy;
    372                 OsclError::Leave(OsclErrBusy);
    373             }
    374             // Set timestamp
    375 #ifdef _TEST_AE_ERROR_HANDLING
    376 
    377             if ((data_header_info.stream_id == iNode->iErrorTimeStamp.track_no) && (1 == iNode->iErrorTimeStamp.mode))
    378             {
    379 
    380                 if (iTimeStampJunk == 0)
    381                 {
    382                     iTimeStampJunk = 0x000FFFFF;
    383                 }
    384 
    385                 mediaData->setTimestamp(iTimeStampJunk);
    386                 iTimeStampJunk = iTimeStampJunk - 33;
    387             }
    388             else if ((data_header_info.stream_id == iNode->iErrorTimeStamp.track_no) && (2 == iNode->iErrorTimeStamp.mode))
    389             {
    390                 if (data_header_info.timestamp >= iNode->iErrorTimeStamp.duration)
    391                 {
    392                     mediaData->setTimestamp(0);
    393                 }
    394             }
    395             else if ((data_header_info.stream_id == iNode->iErrorTimeStamp.track_no) && (3 == iNode->iErrorTimeStamp.mode))
    396             {
    397                 mediaData->setTimestamp(0);
    398             }
    399             else
    400             {
    401                 mediaData->setTimestamp(data_header_info.timestamp);
    402             }
    403 #else
    404             mediaData->setTimestamp(data_header_info.timestamp);
    405 #endif
    406             mediaData->setSeqNum(data_header_info.seq_num);
    407             mediaData->setMediaFragFilledLen(0, data_len);
    408             mediaData->setStreamID(data_header_info.stream_id);
    409 
    410             PVMFStatus status = PVMFFailure;
    411             {
    412                 OsclRefCounterMemFrag privatedataFsiMemFrag;
    413                 OsclLeaveCode fsiErrorCode = OsclErrNone;
    414 
    415                 OSCL_TRY(fsiErrorCode, privatedataFsiMemFrag = iNode->iPrivateDataFsiFragmentAlloc.get(););
    416 
    417                 OSCL_FIRST_CATCH_ANY(fsiErrorCode,
    418                         LOG_ERR((0, "Failed to allocate memory for  FSI for private data"));
    419                         status = PVMFErrNoMemory;
    420                         iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);
    421                         OSCL_LEAVE(OsclErrNoMemory);
    422                         return -1; // this is going to make everything go out of scope
    423                         );
    424 
    425                 uint8 *fsiptr = (uint8*) privatedataFsiMemFrag.getMemFragPtr();
    426                 privatedataFsiMemFrag.getMemFrag().len = sizeof(OsclAny*);
    427                 oscl_memcpy(fsiptr, &(data_header_info.private_data_ptr), sizeof(OsclAny *)); // store ptr data into fsi
    428                 mediaData->setFormatSpecificInfo(privatedataFsiMemFrag);
    429             }
    430 
    431             LOGDATATRAFFIC((0, "PvmfMediaInputNodeOutPort::writeAsync:"
    432                             "StreamID=%d, TS=%d, Len=%d, SN=%d, MimeType=%s",
    433                             data_header_info.stream_id,  data_header_info.timestamp, data_len,
    434                             data_header_info.seq_num, iMimeType.get_cstr()));
    435             // Convert media data to MediaMsg
    436             PVMFSharedMediaMsgPtr mediaMsg;
    437             convertToPVMFMediaMsg(mediaMsg, mediaData);
    438 #ifdef _TEST_AE_ERROR_HANDLING
    439 
    440             if ((iNode->iErrorTrackID > 0) && (data_header_info.stream_id == (uint32)iNode->iErrorTrackID))
    441             {
    442                 status = PVMFSuccess;
    443             }
    444             else
    445             {
    446                 status = QueueOutgoingMsg(mediaMsg);
    447             }
    448 #else
    449             status = QueueOutgoingMsg(mediaMsg);
    450 
    451 #endif
    452             if (status != PVMFSuccess)
    453             {
    454                 iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);
    455                 OsclError::Leave(OsclErrGeneral);
    456             }
    457 
    458             if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_STARTED)
    459                 RunIfNotReady();
    460 
    461             return iCmdId++;
    462         }
    463         else
    464         {
    465             LOG_DEBUG((0, "Ignoring Format Type :%d since not supported\n", format_type));
    466             iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)NULL);
    467             OsclError::Leave(OsclErrGeneral);
    468         }
    469     }
    470     else
    471     {
    472         OsclError::Leave(OsclErrBusy);
    473     }
    474 
    475     return 0;
    476 
    477 }
    478 
    479 ////////////////////////////////////////////////////////////////////////////
    480 void PvmfMediaInputNodeOutPort::writeComplete(PVMFStatus status, PVMFCommandId write_cmd_id, OsclAny* context)
    481 {
    482     OSCL_UNUSED_ARG(context);
    483     OSCL_UNUSED_ARG(status);
    484     OSCL_UNUSED_ARG(write_cmd_id);
    485     OSCL_LEAVE(OsclErrNotSupported);
    486 }
    487 
    488 ////////////////////////////////////////////////////////////////////////////
    489 PVMFCommandId PvmfMediaInputNodeOutPort::readAsync(uint8* data, uint32 max_data_len, OsclAny* context,
    490         int32* formats, uint16 num_formats)
    491 {
    492     OSCL_UNUSED_ARG(data);
    493     OSCL_UNUSED_ARG(max_data_len);
    494     OSCL_UNUSED_ARG(context);
    495     OSCL_UNUSED_ARG(formats);
    496     OSCL_UNUSED_ARG(num_formats);
    497     OSCL_LEAVE(OsclErrNotSupported);
    498     return -1;
    499 }
    500 
    501 ////////////////////////////////////////////////////////////////////////////
    502 void PvmfMediaInputNodeOutPort::readComplete(PVMFStatus status, PVMFCommandId read_cmd_id,
    503         int32 format_index, const PvmiMediaXferHeader& data_header_info,
    504         OsclAny* context)
    505 {
    506     OSCL_UNUSED_ARG(status);
    507     OSCL_UNUSED_ARG(read_cmd_id);
    508     OSCL_UNUSED_ARG(format_index);
    509     OSCL_UNUSED_ARG(data_header_info);
    510     OSCL_UNUSED_ARG(context);
    511     OSCL_LEAVE(OsclErrNotSupported);
    512 }
    513 
    514 ////////////////////////////////////////////////////////////////////////////
    515 void PvmfMediaInputNodeOutPort::statusUpdate(uint32 status_flags)
    516 {
    517     OSCL_UNUSED_ARG(status_flags);
    518 }
    519 
    520 ////////////////////////////////////////////////////////////////////////////
    521 void PvmfMediaInputNodeOutPort::cancelCommand(PVMFCommandId command_id)
    522 {
    523     OSCL_UNUSED_ARG(command_id);
    524     OSCL_LEAVE(OsclErrNotSupported);
    525 }
    526 
    527 ////////////////////////////////////////////////////////////////////////////
    528 void PvmfMediaInputNodeOutPort::cancelAllCommands()
    529 {
    530     OSCL_LEAVE(OsclErrNotSupported);
    531 }
    532 
    533 ////////////////////////////////////////////////////////////////////////////
    534 //                  PvmiCapabilityAndConfig
    535 ////////////////////////////////////////////////////////////////////////////
    536 OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::setObserver(PvmiConfigAndCapabilityCmdObserver* aObserver)
    537 {
    538     // Not supported
    539     OSCL_UNUSED_ARG(aObserver);
    540 }
    541 
    542 ////////////////////////////////////////////////////////////////////////////
    543 OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::getParametersSync(PvmiMIOSession session,
    544         PvmiKeyType identifier,
    545         PvmiKvp*& parameters,
    546         int& num_parameter_elements,
    547         PvmiCapabilityContext context)
    548 {
    549     LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::getParametersSync"));
    550 
    551     if (!iNode || !iNode->iMediaIOConfig)
    552     {
    553         LOG_ERR((0, "PvmfMediaInputNodeOutPort::getParametersSync: Error - Config object for media IO not available"));
    554         return PVMFFailure;
    555 
    556     }
    557 
    558     return iNode->iMediaIOConfig->getParametersSync(session, identifier, parameters,
    559             num_parameter_elements, context);
    560 }
    561 
    562 ////////////////////////////////////////////////////////////////////////////
    563 OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::releaseParameters(PvmiMIOSession session,
    564         PvmiKvp* parameters,
    565         int num_elements)
    566 {
    567     LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::releaseParameters"));
    568 
    569     if (!iNode || !iNode->iMediaIOConfig)
    570     {
    571         LOG_ERR((0, "PvmfMediaInputNodeOutPort::releaseParameters: Error - Config object for media IO not available"));
    572         return PVMFFailure;
    573 
    574     }
    575 
    576     return iNode->iMediaIOConfig->releaseParameters(session, parameters, num_elements);
    577 }
    578 
    579 ////////////////////////////////////////////////////////////////////////////
    580 OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::createContext(PvmiMIOSession session, PvmiCapabilityContext& context)
    581 {
    582     OSCL_UNUSED_ARG(session);
    583     OSCL_UNUSED_ARG(context);
    584 }
    585 
    586 ////////////////////////////////////////////////////////////////////////////
    587 OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::setContextParameters(PvmiMIOSession session,
    588         PvmiCapabilityContext& context,
    589         PvmiKvp* parameters, int num_parameter_elements)
    590 {
    591     OSCL_UNUSED_ARG(session);
    592     OSCL_UNUSED_ARG(context);
    593     OSCL_UNUSED_ARG(parameters);
    594     OSCL_UNUSED_ARG(num_parameter_elements);
    595 }
    596 
    597 ////////////////////////////////////////////////////////////////////////////
    598 OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::DeleteContext(PvmiMIOSession session, PvmiCapabilityContext& context)
    599 {
    600     OSCL_UNUSED_ARG(session);
    601     OSCL_UNUSED_ARG(context);
    602 }
    603 
    604 ////////////////////////////////////////////////////////////////////////////
    605 OSCL_EXPORT_REF void PvmfMediaInputNodeOutPort::setParametersSync(PvmiMIOSession session, PvmiKvp* parameters,
    606         int num_elements, PvmiKvp*& ret_kvp)
    607 {
    608     LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::setParametersSync"));
    609 
    610     if (!iNode || !iNode->iMediaIOConfig)
    611     {
    612         LOG_ERR((0, "PvmfMediaInputNodeOutPort::setParametersSync: Error - Config object for media IO not available"));
    613         ret_kvp = parameters;
    614         OSCL_LEAVE(OsclErrGeneral);
    615     }
    616 
    617     iNode->iMediaIOConfig->setParametersSync(session, parameters, num_elements, ret_kvp);
    618 }
    619 
    620 ////////////////////////////////////////////////////////////////////////////
    621 OSCL_EXPORT_REF PVMFCommandId PvmfMediaInputNodeOutPort::setParametersAsync(PvmiMIOSession session,
    622         PvmiKvp* parameters,
    623         int num_elements,
    624         PvmiKvp*& ret_kvp,
    625         OsclAny* context)
    626 {
    627     OSCL_UNUSED_ARG(session);
    628     OSCL_UNUSED_ARG(parameters);
    629     OSCL_UNUSED_ARG(num_elements);
    630     OSCL_UNUSED_ARG(ret_kvp);
    631     OSCL_UNUSED_ARG(context);
    632     OsclError::Leave(OsclErrNotSupported);
    633     return -1;
    634 }
    635 
    636 ////////////////////////////////////////////////////////////////////////////
    637 OSCL_EXPORT_REF uint32 PvmfMediaInputNodeOutPort::getCapabilityMetric(PvmiMIOSession session)
    638 {
    639     OSCL_UNUSED_ARG(session);
    640     return 0;
    641 }
    642 
    643 ////////////////////////////////////////////////////////////////////////////
    644 OSCL_EXPORT_REF PVMFStatus PvmfMediaInputNodeOutPort::verifyParametersSync(PvmiMIOSession session,
    645         PvmiKvp* parameters, int num_elements)
    646 {
    647     LOG_STACK_TRACE((0, "PvmfMediaInputNodeOutPort::verifyParametersSync"));
    648 
    649     if (!iNode || !iNode->iMediaIOConfig)
    650     {
    651         LOG_ERR((0, "PvmfMediaInputNodeOutPort::verifyParametersSync: Error - Config object for media IO not available"));
    652         return PVMFFailure;
    653     }
    654 
    655     return iNode->iMediaIOConfig->verifyParametersSync(session, parameters, num_elements);
    656 }
    657 
    658 ////////////////////////////////////////////////////////////////////////////
    659 void PvmfMediaInputNodeOutPort::Run()
    660 {
    661     if (iState == PvmfMediaInputNodeOutPort::PORT_STATE_BUFFERING)
    662         return;
    663 
    664 #ifdef _TEST_AE_ERROR_HANDLING
    665     if (iNode->iError_No_Memory)
    666     {
    667         if (iMediaInput && iWriteState == EWriteBusy)
    668         {
    669             iWriteState = EWriteOK;
    670             iMediaInput->statusUpdate(PVMI_MEDIAXFER_STATUS_WRITE);
    671             iNode->iError_No_Memory = false;
    672         }
    673     }
    674 #endif
    675     if ((OutgoingMsgQueueSize() > 0) && (!IsConnectedPortBusy()))
    676     {
    677         //transfer data to connected port.
    678         PVMFStatus status = Send();
    679         if (status != PVMFSuccess)
    680             iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);
    681 
    682         //reschedule as long as there's data queued...
    683         if (OutgoingMsgQueueSize() > 0
    684                 && !IsConnectedPortBusy())
    685         {
    686             RunIfNotReady();
    687         }
    688 
    689         if (iNode->IsFlushPending())
    690         {
    691             if (IncomingMsgQueueSize() == 0 && OutgoingMsgQueueSize() == 0)
    692                 iNode->FlushComplete();
    693         }
    694     }
    695 }
    696 
    697 ////////////////////////////////////////////////////////////////////////////
    698 void PvmfMediaInputNodeOutPort::HandlePortActivity(const PVMFPortActivity& aActivity)
    699 {
    700     switch (aActivity.iType)
    701     {
    702         case PVMF_PORT_ACTIVITY_CONNECT:
    703         {
    704             //get the mimetype
    705             OsclAny* temp = NULL;
    706             iConnectedPort->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUID, temp);
    707             PvmiCapabilityAndConfig *config = OSCL_STATIC_CAST(PvmiCapabilityAndConfig*, temp);
    708 
    709             if (config != NULL)
    710             {
    711                 int numKvp = 0;
    712                 PvmiKvp* kvpPtr = NULL;
    713                 PVMFStatus status =
    714                     config->getParametersSync(NULL,
    715                                               (char*)INPUT_FORMATS_CUR_QUERY, kvpPtr, numKvp, NULL);
    716                 if (status == PVMFSuccess)
    717                 {
    718                     iFormatType = kvpPtr[0].value.pChar_value;
    719                     iMimeType = iFormatType.getMIMEStrPtr();
    720                 }
    721                 config->releaseParameters(NULL, kvpPtr, numKvp);
    722             }
    723         }
    724         break;
    725 
    726         case PVMF_PORT_ACTIVITY_DISCONNECT:
    727             break;
    728 
    729         case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
    730             //wakeup the AO when the first message arrives.
    731             if (OutgoingMsgQueueSize() == 1)
    732                 RunIfNotReady();
    733             break;
    734 
    735         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
    736             //wakeup the AO when the connected port is
    737             //ready to accept data again.
    738             RunIfNotReady();
    739             break;
    740 
    741         case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
    742             if (iMediaInput && (iWriteState == EWriteBusy))
    743             {
    744                 iWriteState = EWriteOK;
    745                 //let the peer know they can try to write again.
    746                 iMediaInput->statusUpdate(PVMI_MEDIAXFER_STATUS_WRITE);
    747             }
    748             break;
    749         case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_BUSY:
    750         {
    751             iWriteState = EWriteBusy;
    752         }
    753         break;
    754         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_BUSY:
    755             break;
    756         default:
    757             break;
    758     }
    759 }
    760 
    761 ////////////////////////////////////////////////////////////////////////////
    762 void PvmfMediaInputNodeOutPort::SendEndOfTrackCommand(const PvmiMediaXferHeader& data_header_info)
    763 {
    764     PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
    765 
    766     sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);
    767 
    768     // Set the timestamp
    769     sharedMediaCmdPtr->setTimestamp(data_header_info.timestamp);
    770 
    771     // Set the sequence number
    772     sharedMediaCmdPtr->setSeqNum(data_header_info.seq_num);
    773 
    774     PVMFSharedMediaMsgPtr mediaMsgOut;
    775     convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
    776 
    777     PVMFStatus status = QueueOutgoingMsg(mediaMsgOut);
    778     if (status != PVMFSuccess)
    779     {
    780         iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);
    781         OsclError::Leave(OsclErrGeneral);
    782     }
    783 
    784     LOGDATATRAFFIC((0, "PvmfMediaInputNodeOutPort::SendEndOfTrackCommand - EOS Sent:"
    785                     "StreamID=%d, TS=%d, SN=%d, MimeType=%s",
    786                     data_header_info.stream_id,  data_header_info.timestamp,
    787                     data_header_info.seq_num, iMimeType.get_cstr()));
    788 }
    789 
    790 void PvmfMediaInputNodeOutPort :: freechunkavailable(OsclAny*)
    791 {
    792     if (iWriteState == EWriteBusy)
    793     {
    794         iWriteState = EWriteOK;
    795         if (IsAdded())
    796         {
    797             iMediaInput->statusUpdate(PVMI_MEDIAXFER_STATUS_WRITE);
    798         }
    799     }
    800 }
    801