blob: 4b6dc5989e0404f816b1a28153d2b89c529e6790 [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_amrffparser_node.h"
#include "pvmf_amrffparser_defs.h"
#include "amr_parsernode_tunables.h"
#include "pvmf_amrffparser_port.h"
#include "amrfileparser.h"
#include "media_clock_converter.h"
#include "pv_gau.h"
#include "pvlogger.h"
#include "oscl_error_codes.h"
#include "pvmf_fileformat_events.h"
#include "pvmf_basic_errorinfomessage.h"
#include "pvmf_errorinfomessage_extension.h"
#include "pvmf_media_cmd.h"
#include "pvmf_media_msg_format_ids.h"
#include "pv_mime_string_utils.h"
#include "oscl_snprintf.h"
#include "pvmf_local_data_source.h"
#include "pvmi_kvp_util.h"
#include "pvmf_amrffparser_events.h"
#include "oscl_exclusive_ptr.h"
#include "pvmf_source_context_data.h"
static const char PVAMR_ALL_METADATA_KEY[] = "all";
static const char PVAMRMETADATA_DURATION_KEY[] = "duration";
static const char PVAMRMETADATA_NUMTRACKS_KEY[] = "num-tracks";
static const char PVAMRMETADATA_TRACKINFO_BITRATE_KEY[] = "track-info/bit-rate";
static const char PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY[] = "track-info/audio/format";
static const char PVAMRMETADATA_CLIP_TYPE_KEY[] = "clip-type";
static const char PVAMRMETADATA_RANDOM_ACCESS_DENIED_KEY[] = "random-access-denied";
static const char PVAMRMETADATA_SEMICOLON[] = ";";
static const char PVAMRMETADATA_TIMESCALE[] = "timescale=";
static const char PVAMRMETADATA_INDEX0[] = "index=0";
#define AMR_SAMPLE_DURATION 20
PVMFAMRFFParserNode::PVMFAMRFFParserNode(int32 aPriority) :
OsclTimerObject(aPriority, "PVAMRFFParserNode"),
iOutPort(NULL),
iLogger(NULL),
iAMRParser(NULL),
iExtensionRefCount(0)
{
iFileHandle = NULL;
iLogger = NULL;
iDataPathLogger = NULL;
iClockLogger = NULL;
iDownloadComplete = false;
iFileSizeLastConvertedToTime = 0;
iLastNPTCalcInConvertSizeToTime = 0;
iExtensionRefCount = 0;
iUseCPMPluginRegistry = false;
iCPM = NULL;
iCPMSessionID = 0xFFFFFFFF;
iCPMContentType = PVMF_CPM_CONTENT_FORMAT_UNKNOWN;
iCPMContentAccessFactory = NULL;
iCPMInitCmdId = 0;
iCPMOpenSessionCmdId = 0;
iCPMRegisterContentCmdId = 0;
iCPMGetLicenseInterfaceCmdId = 0;
iCPMRequestUsageId = 0;
iCPMUsageCompleteCmdId = 0;
iCPMCloseSessionCmdId = 0;
iCPMResetCmdId = 0;
iCPMCancelGetLicenseCmdId = 0;
iRequestedUsage.key = NULL;
iApprovedUsage.key = NULL;
iAuthorizationDataKvp.key = NULL;
iCPMMetaDataExtensionInterface = NULL;
iCPMGetMetaDataKeysCmdId = 0;
iCPMGetMetaDataValuesCmdId = 0;
iAMRParserNodeMetadataValueCount = 0;
iDownloadProgressInterface = NULL;
iDownloadFileSize = 0;
iAMRHeaderSize = AMR_HEADER_SIZE;
iDataStreamInterface = NULL;
iDataStreamFactory = NULL;
iDataStreamReadCapacityObserver = NULL;
iAutoPaused = false;
iStreamID = 0;
oSourceIsCurrent = false;
iInterfaceState = EPVMFNodeCreated;
iUseCPMPluginRegistry = false;
iFileHandle = NULL;
iCountToClaculateRDATimeInterval = 1;
int32 err;
OSCL_TRY(err,
//Create the input command queue. Use a reserve to avoid lots of dynamic memory allocation.
iInputCommands.Construct(PVMF_AMRFFPARSER_NODE_COMMAND_ID_START, PVMF_AMRFFPARSER_NODE_COMMAND_VECTOR_RESERVE);
//Create the "current command" queue. It will only contain one
//command at a time, so use a reserve of 1.
iCurrentCommand.Construct(0, 1);
iCancelCommand.Construct(0, 1);
iSelectedTrackList.reserve(1);
//Set the node capability data.
//This node can support an unlimited number of ports.
iCapability.iCanSupportMultipleInputPorts = false;
iCapability.iCanSupportMultipleOutputPorts = false;
iCapability.iHasMaxNumberOfPorts = true;
iCapability.iMaxNumberOfPorts = 1;
iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMR_IETF);
iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMR_IF2);
iCapability.iOutputFormatCapability.push_back(PVMF_MIME_AMRWB_IETF);
);
if (err != OsclErrNone)
{
//if a leave happened, cleanup and re-throw the error
iInputCommands.clear();
iCurrentCommand.clear();
iCancelCommand.clear();
iCapability.iInputFormatCapability.clear();
iCapability.iOutputFormatCapability.clear();
OSCL_CLEANUP_BASE_CLASS(PVMFNodeInterface);
OSCL_CLEANUP_BASE_CLASS(OsclTimerObject);
OSCL_LEAVE(err);
}
Construct();
}
PVMFAMRFFParserNode::~PVMFAMRFFParserNode()
{
if (iRequestedUsage.key)
{
OSCL_ARRAY_DELETE(iRequestedUsage.key);
iRequestedUsage.key = NULL;
}
if (iApprovedUsage.key)
{
OSCL_ARRAY_DELETE(iApprovedUsage.key);
iApprovedUsage.key = NULL;
}
if (iAuthorizationDataKvp.key)
{
OSCL_ARRAY_DELETE(iAuthorizationDataKvp.key);
iAuthorizationDataKvp.key = NULL;
}
if (iCPM != NULL)
{
iCPM->ThreadLogoff();
PVMFCPMFactory::DestroyContentPolicyManager(iCPM);
iCPM = NULL;
}
if (iDownloadProgressInterface != NULL)
{
iDownloadProgressInterface->cancelResumeNotification();
}
//Cleanup commands
//The command queues are self-deleting, but we want to
//notify the observer of unprocessed commands.
while (!iCurrentCommand.empty())
{
CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFFailure);
}
while (!iCancelCommand.empty())
{
CommandComplete(iCancelCommand, iCancelCommand.front(), PVMFFailure);
}
while (!iInputCommands.empty())
{
CommandComplete(iInputCommands, iInputCommands.front(), PVMFFailure);
}
if (iExtensionRefCount > 0)
{
OSCL_ASSERT(false);
}
Cancel();
//Cleanup allocated ports
ReleaseAllPorts();
CleanupFileSource();
iFileServer.Close();
}
PVMFStatus PVMFAMRFFParserNode::ThreadLogon()
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::ThreadLogon() Called"));
if (iInterfaceState == EPVMFNodeCreated)
{
if (!IsAdded())
{
AddToScheduler();
}
iLogger = PVLogger::GetLoggerObject("PVMFAMRParserNode");
iDataPathLogger = PVLogger::GetLoggerObject("datapath.sourcenode.amrparsernode");
iClockLogger = PVLogger::GetLoggerObject("clock");
iFileServer.Connect();
SetState(EPVMFNodeIdle);
return PVMFSuccess;
}
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::ThreadLogon() - Invalid State"));
return PVMFErrInvalidState;
}
PVMFStatus PVMFAMRFFParserNode::GetCapability(PVMFNodeCapability& aNodeCapability)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::GetCapability() called"));
// TODO: Return the appropriate format capability
aNodeCapability = iCapability;
return PVMFSuccess;
}
PVMFPortIter* PVMFAMRFFParserNode::GetPorts(const PVMFPortFilter* aFilter)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFASFParserNode::GetPorts() called"));
OSCL_UNUSED_ARG(aFilter);
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFASFParserNode::GetPorts() Not Implemented"));
// TODO: Return the currently available ports
return NULL;
}
PVMFCommandId PVMFAMRFFParserNode::QueryUUID(PVMFSessionId s, const PvmfMimeString& aMimeType,
Oscl_Vector<PVUuid, OsclMemAllocator>& aUuids,
bool aExactUuidsOnly, const OsclAny* aContext)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::QueryUUID called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s,
PVMF_AMR_PARSER_NODE_QUERYUUID,
aMimeType,
aUuids,
aExactUuidsOnly,
aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::QueryInterface(PVMFSessionId s, const PVUuid& aUuid,
PVInterface*& aInterfacePtr,
const OsclAny* aContext)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::QueryInterface called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s,
PVMF_AMR_PARSER_NODE_QUERYINTERFACE,
aUuid,
aInterfacePtr,
aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::RequestPort(PVMFSessionId s, int32 aPortTag, const PvmfMimeString* aPortConfig, const OsclAny* aContext)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::RequestPort called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s,
PVMF_AMR_PARSER_NODE_REQUESTPORT,
aPortTag,
aPortConfig,
aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::ReleasePort(PVMFSessionId s, PVMFPortInterface& aPort, const OsclAny* aContext)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::ReleasePort called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_RELEASEPORT, aPort, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::Init(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::Init called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_INIT, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::Prepare(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::Prepare called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_PREPARE, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::Start(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::Start called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_START, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::Stop(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:Stop"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_STOP, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::Pause(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::Stop called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_PAUSE, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::Flush(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:Flush"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_FLUSH, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::Reset(PVMFSessionId s, const OsclAny* aContext)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::Flush called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_RESET, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::CancelAllCommands(PVMFSessionId s, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:CancelAllCommands"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_CANCELALLCOMMANDS, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::CancelCommand(PVMFSessionId s, PVMFCommandId aCmdId, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:CancelCommand"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(s, PVMF_AMR_PARSER_NODE_CANCELCOMMAND, aCmdId, aContext);
return QueueCommandL(cmd);
}
void PVMFAMRFFParserNode::Construct()
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::Construct()"));
iFileServer.Connect();
iAvailableMetadataKeys.reserve(4);
iAvailableMetadataKeys.clear();
}
void PVMFAMRFFParserNode::Run()
{
if (!iInputCommands.empty())
{
if (ProcessCommand())
{
/*
* note: need to check the state before re-scheduling
* since the node could have been reset in the ProcessCommand
* call.
*/
if (iInterfaceState != EPVMFNodeCreated)
{
RunIfNotReady();
}
return;
}
}
// Send outgoing messages
if (iInterfaceState == EPVMFNodeStarted || FlushPending())
{
PVAMRFFNodeTrackPortInfo* trackPortInfoPtr = NULL;
if (!GetTrackInfo(iOutPort, trackPortInfoPtr))
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVAMRParserNode::Run: Error - GetTrackInfo failed"));
return;
}
ProcessPortActivity(trackPortInfoPtr);
if (CheckForPortRescheduling())
{
/*
* Re-schedule since there is atleast one port that needs processing
*/
RunIfNotReady();
}
}
if (FlushPending()
&& iOutPort
&& iOutPort->OutgoingMsgQueueSize() == 0)
{
SetState(EPVMFNodePrepared);
iOutPort->ResumeInput();
CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
}
}
PVMFStatus PVMFAMRFFParserNode::ProcessOutgoingMsg(PVAMRFFNodeTrackPortInfo* aTrackInfoPtr)
{
/*
* Called by the AO to process one message off the outgoing
* message queue for the given port. This routine will
* try to send the data to the connected port.
*/
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::ProcessOutgoingMsg() Called aPort=0x%x", aTrackInfoPtr->iPort));
PVMFStatus status = aTrackInfoPtr->iPort->Send();
if (status == PVMFErrBusy)
{
/* Connected port is busy */
aTrackInfoPtr->oProcessOutgoingMessages = false;
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::ProcessOutgoingMsg() Connected port is in busy state"));
}
else if (status != PVMFSuccess)
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::ProcessOutgoingMsg() - aTrackInfoPtr->iPort->Send() Failed"));
}
return status;
}
PVMFStatus PVMFAMRFFParserNode::DoGetMetadataKeys(PVMFAMRFFNodeCommand& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::DoGetNodeMetadataKeys() In"));
/* Get Metadata keys from CPM for protected content only */
if ((iCPMMetaDataExtensionInterface != NULL))
{
GetCPMMetaDataKeys();
return PVMFPending;
}
return (CompleteGetMetadataKeys(aCmd));
}
PVMFStatus
PVMFAMRFFParserNode::CompleteGetMetadataKeys(PVMFAMRFFNodeCommand& aCmd)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::CompleteGetMetadataKeys Called"));
PVMFMetadataList* keylistptr = NULL;
uint32 starting_index;
int32 max_entries;
char* query_key;
aCmd.PVMFAMRFFNodeCommand::Parse(keylistptr, starting_index, max_entries, query_key);
if (keylistptr == NULL)
{
return PVMFErrArgument;
}
if ((starting_index > (iAvailableMetadataKeys.size() - 1)) || max_entries == 0)
{
return PVMFErrArgument;
}
uint32 num_entries = 0;
int32 num_added = 0;
uint32 lcv = 0;
for (lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++)
{
if (query_key == NULL)
{
++num_entries;
if (num_entries > starting_index)
{
// Past the starting index so copy the key
PVMFStatus status = PushValueToList(iAvailableMetadataKeys, keylistptr, lcv);
if (PVMFErrNoMemory == status)
{
return status;
}
num_added++;
}
}
else
{
// Check if the key matches the query key
if (pv_mime_strcmp(iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0)
{
// This key is counted
++num_entries;
if (num_entries > starting_index)
{
// Past the starting index so copy the key
PVMFStatus status = PushValueToList(iAvailableMetadataKeys, keylistptr, lcv);
if (PVMFErrNoMemory == status)
{
return status;
}
num_added++;
}
}
}
// Check if max number of entries have been copied
if (max_entries > 0 && num_added >= max_entries)
{
break;
}
}
for (lcv = 0; lcv < iCPMMetadataKeys.size(); lcv++)
{
if (query_key == NULL)
{
/* No query key so this key is counted */
++num_entries;
if (num_entries > (uint32)starting_index)
{
/* Past the starting index so copy the key */
PVMFStatus status = PushValueToList(iCPMMetadataKeys, keylistptr, lcv);
if (PVMFErrNoMemory == status)
{
return status;
}
num_added++;
}
}
else
{
/* Check if the key matches the query key */
if (pv_mime_strcmp(iCPMMetadataKeys[lcv].get_cstr(), query_key) >= 0)
{
++num_entries;
if (num_entries > (uint32)starting_index)
{
/* Past the starting index so copy the key */
PVMFStatus status = PushValueToList(iCPMMetadataKeys, keylistptr, lcv);
if (PVMFErrNoMemory == status)
{
return status;
}
num_added++;
}
}
}
/* Check if max number of entries have been copied */
if ((max_entries > 0) && (num_added >= max_entries))
{
break;
}
}
return PVMFSuccess;
}
PVMFStatus PVMFAMRFFParserNode::DoGetMetadataValues(PVMFAMRFFNodeCommand& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::DoGetMetadataValues() In"));
// File must be parsed
if (!iAMRParser)
{
return PVMFErrInvalidState;
}
PVMFMetadataList* keylistptr_in = NULL;
PVMFMetadataList* keylistptr = NULL;
Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL;
uint32 starting_index;
int32 max_entries;
aCmd.PVMFAMRFFNodeCommand::Parse(keylistptr_in, valuelistptr, starting_index, max_entries);
if (keylistptr_in == NULL || valuelistptr == NULL)
{
return PVMFErrArgument;
}
keylistptr = keylistptr_in;
//If numkeys is one, just check to see if the request
//is for ALL metadata
if (keylistptr_in->size() == 1)
{
if (oscl_strncmp((*keylistptr)[0].get_cstr(),
PVAMR_ALL_METADATA_KEY,
oscl_strlen(PVAMR_ALL_METADATA_KEY)) == 0)
{
//use the complete metadata key list
keylistptr = &iAvailableMetadataKeys;
}
}
uint32 numkeys = keylistptr->size();
if (starting_index > (numkeys - 1) || numkeys == 0 || max_entries == 0)
{
// Don't do anything
return PVMFErrArgument;
}
uint32 numvalentries = 0;
int32 numentriesadded = 0;
for (uint32 lcv = 0; lcv < numkeys; lcv++)
{
int32 leavecode = 0;
PvmiKvp KeyVal;
KeyVal.key = NULL;
if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_DURATION_KEY) == 0 &&
iAMRFileInfo.iDuration > 0)
{
// Movie Duration
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
char timescalestr[20];
oscl_snprintf(timescalestr, 20, ";%s%d", PVAMRMETADATA_TIMESCALE, iAMRFileInfo.iTimescale);
timescalestr[19] = '\0';
uint32 duration = Oscl_Int64_Utils::get_uint64_lower32(iAMRFileInfo.iDuration);
int32 retval =
PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal,
PVAMRMETADATA_DURATION_KEY,
duration,
timescalestr);
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_NUMTRACKS_KEY) == 0)
{
// Number of tracks
// Increment the counter for the number of values found so far
++numvalentries;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
uint32 numtracks = 1;
PVMFStatus retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, PVAMRMETADATA_NUMTRACKS_KEY, numtracks);
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_TRACKINFO_BITRATE_KEY) == 0) &&
iAMRFileInfo.iBitrate > 0)
{
// Bitrate
// Increment the counter for the number of values found so far
++numvalentries;
int32 retval = 0;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s", PVAMRMETADATA_INDEX0);
indexparam[15] = '\0';
uint32 bitrate = iAMRFileInfo.iBitrate;
retval = PVMFCreateKVPUtils::CreateKVPForUInt32Value(KeyVal, PVAMRMETADATA_TRACKINFO_BITRATE_KEY, bitrate, indexparam);
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
else if (oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_RANDOM_ACCESS_DENIED_KEY) == 0)
{
/*
* Random Access
* Increment the counter for the number of values found so far
*/
++numvalentries;
/* Create a value entry if past the starting index */
if (numvalentries > (uint32)starting_index)
{
bool random_access_denied = false;
PVMFStatus retval =
PVMFCreateKVPUtils::CreateKVPForBoolValue(KeyVal,
PVAMRMETADATA_RANDOM_ACCESS_DENIED_KEY,
random_access_denied,
NULL);
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if (oscl_strncmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_CLIP_TYPE_KEY, oscl_strlen(PVAMRMETADATA_CLIP_TYPE_KEY)) == 0)
{
/*
* Clip Type
* Increment the counter for the number of values found so far
*/
++numvalentries;
/* Create a value entry if past the starting index */
if (numvalentries > (uint32)starting_index)
{
uint32 len = 0;
char* clipType = NULL;
{
len = oscl_strlen("local");
clipType = OSCL_ARRAY_NEW(char, len + 1);
oscl_memset(clipType, 0, len + 1);
oscl_strncpy(clipType, ("local"), len);
}
PVMFStatus retval =
PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal,
PVAMRMETADATA_CLIP_TYPE_KEY,
clipType);
OSCL_ARRAY_DELETE(clipType);
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY) == 0) &&
iAMRFileInfo.iAmrFormat != EAMRUnrecognized)
{
// Format
// Increment the counter for the number of values found so far
++numvalentries;
int32 retval = 0;
// Create a value entry if past the starting index
if (numvalentries > starting_index)
{
char indexparam[16];
oscl_snprintf(indexparam, 16, ";%s", PVAMRMETADATA_INDEX0);
indexparam[15] = '\0';
switch (iAMRFileInfo.iAmrFormat)
{
case EAMRIF2:
retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal, PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY, _STRLIT_CHAR(PVMF_MIME_AMR_IF2), indexparam);
break;
case EAMRETS:
case EAMRIETF_SingleNB:
case EAMRIETF_MultiNB:
case EAMRIETF_SingleWB:
case EAMRIETF_MultiWB:
case EAMRWMF:
retval = PVMFCreateKVPUtils::CreateKVPForCharStringValue(KeyVal, PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY, _STRLIT_CHAR(PVMF_MIME_AMR_IETF), indexparam);
break;
case EAMRUnrecognized:
default:
// Should not enter here
OSCL_ASSERT(false);
break;
}
if (retval != PVMFSuccess && retval != PVMFErrArgument)
{
break;
}
}
}
if (KeyVal.key != NULL)
{
// Add the entry to the list
leavecode = PushBackKeyVal(valuelistptr, KeyVal);
if (leavecode != 0)
{
switch (GetValTypeFromKeyString(KeyVal.key))
{
case PVMI_KVPVALTYPE_CHARPTR:
if (KeyVal.value.pChar_value != NULL)
{
OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
KeyVal.value.pChar_value = NULL;
}
break;
default:
// Add more case statements if other value types are returned
break;
}
OSCL_ARRAY_DELETE(KeyVal.key);
KeyVal.key = NULL;
}
else
{
// Increment the counter for number of value entries added to the list
++numentriesadded;
}
// Check if the max number of value entries were added
if (max_entries > 0 && numentriesadded >= max_entries)
{
// Maximum number of values added so break out of the loop
break;
}
}
}
iAMRParserNodeMetadataValueCount = (*valuelistptr).size();
if ((iCPMMetaDataExtensionInterface != NULL))
{
iCPMGetMetaDataValuesCmdId =
iCPMMetaDataExtensionInterface->GetNodeMetadataValues(iCPMSessionID,
(*keylistptr_in),
(*valuelistptr),
0);
return PVMFPending;
}
return PVMFSuccess;
}
PVMFStatus PVMFAMRFFParserNode::DoSetDataSourcePosition(PVMFAMRFFNodeCommand& aCmd)
{
//file must be parsed
if (!iAMRParser)
{
return PVMFErrInvalidState;
}
if (iSelectedTrackList.size() == 0)
{
return PVMFErrInvalidState;
}
uint32 targetNPT = 0;
uint32* actualNPT = NULL;
uint32* actualMediaDataTS = NULL;
bool seektosyncpoint = false;
uint32 streamID = 0;
aCmd.PVMFAMRFFNodeCommand::Parse(targetNPT, actualNPT, actualMediaDataTS, seektosyncpoint, streamID);
Oscl_Vector<PVAMRFFNodeTrackPortInfo, PVMFAMRParserNodeAllocator>::iterator it;
for (it = iSelectedTrackList.begin(); it != iSelectedTrackList.end(); it++)
{
it->iSendBOS = true;
}
//save the stream id for next media segment
iStreamID = streamID;
*actualNPT = 0;
*actualMediaDataTS = 0;
// Peek the next sample to get the duration of the last sample
uint32 timestamp;
int32 result = iAMRParser->PeekNextTimestamp(&timestamp);
if (result != bitstreamObject::EVERYTHING_OK)
{
return PVMFErrResource;
}
// get media data TS (should be equal to iContinuousTimeStamp)
uint32 millisecTS = iSelectedTrackList[0].iClockConverter->get_converted_ts(1000);
*actualMediaDataTS = millisecTS;
// see if targetNPT is greater or equal than clip duration.
uint32 durationms = 0;
uint32 duration = durationms = Oscl_Int64_Utils::get_uint64_lower32(iAMRFileInfo.iDuration);
uint32 timescale = iAMRFileInfo.iTimescale;
if (timescale > 0 && timescale != 1000)
{
// Convert to milliseconds
MediaClockConverter mcc(timescale);
mcc.update_clock(duration);
durationms = mcc.get_converted_ts(1000);
}
if (targetNPT >= durationms)
{
// report EOS for the track.
for (uint32 i = 0; i < iSelectedTrackList.size(); ++i)
{
iSelectedTrackList[i].iSeqNum = 0;
iSelectedTrackList[i].oEOSReached = true;
iSelectedTrackList[i].oQueueOutgoingMessages = true;
iSelectedTrackList[i].oEOSSent = false;
}
result = iAMRParser->ResetPlayback(0);
if (result != bitstreamObject::EVERYTHING_OK)
{
return PVMFErrResource;
}
*actualNPT = durationms;
return PVMFSuccess;
}
// Reposition
// If new position is past the end of clip, AMR FF should set the position to the last frame
result = iAMRParser->ResetPlayback(targetNPT);
if (result != bitstreamObject::EVERYTHING_OK)
{
if (bitstreamObject::END_OF_FILE == result)
{
for (uint32 i = 0; i < iSelectedTrackList.size(); ++i)
{
iSelectedTrackList[i].iSeqNum = 0;
iSelectedTrackList[i].oEOSReached = true;
iSelectedTrackList[i].oQueueOutgoingMessages = true;
iSelectedTrackList[i].oEOSSent = false;
}
result = iAMRParser->ResetPlayback(0);
if (result != bitstreamObject::EVERYTHING_OK)
{
return PVMFErrResource;
}
*actualNPT = result;
return PVMFSuccess;
}
else if (bitstreamObject::DATA_INSUFFICIENT == result)
{
// This condition could mean 2 things
// 1) End Of File reached for a local content
// 2) Insufficient data condition met for PDL use-case
// For 1 treat it as End of File and send End of Track
// For 2 we dont support reposition until the clip is fully downloaded,
// if the clip is fully downloaded and then we get Insufficient data condition
// treat it as End Of File.
if (iDownloadProgressInterface != NULL)
{
// Check if the file is completely Downloaded or not
if (!iDownloadComplete)
{
// File not downloaded completely, return not Supported
return PVMFErrNotSupported;
}
}
// Here either file is completely downlaoded if doing PDL or it is a local file,
// treat it as End of File in both cases
for (uint32 i = 0; i < iSelectedTrackList.size(); ++i)
{
iSelectedTrackList[i].iSeqNum = 0;
iSelectedTrackList[i].oEOSReached = true;
iSelectedTrackList[i].oQueueOutgoingMessages = true;
iSelectedTrackList[i].oEOSSent = false;
}
result = iAMRParser->ResetPlayback(0);
if (result != bitstreamObject::EVERYTHING_OK)
{
return PVMFErrResource;
}
*actualNPT = result;
return PVMFSuccess;
}
else
{
return PVMFErrResource;
}
}
//Peek new position to get the actual new timestamp
uint32 newtimestamp;
result = iAMRParser->PeekNextTimestamp(&newtimestamp);
if (result != bitstreamObject::EVERYTHING_OK)
{
return PVMFErrResource;
}
*actualNPT = newtimestamp;
ResetAllTracks();
return PVMFSuccess;
}
PVMFStatus PVMFAMRFFParserNode::DoQueryDataSourcePosition(PVMFAMRFFNodeCommand& aCmd)
{
//file must be parsed
if (!iAMRParser)
{
return PVMFErrInvalidState;
}
if (iSelectedTrackList.size() == 0)
{
return PVMFErrInvalidState;
}
uint32 targetNPT = 0;
uint32* actualNPT = NULL;
bool seektosyncpoint = false;
aCmd.PVMFAMRFFNodeCommand::Parse(targetNPT, actualNPT, seektosyncpoint);
if (actualNPT == NULL)
{
return PVMFErrArgument;
}
// Query
// If new position is past the end of clip, AMR FF should set the position to the last frame
*actualNPT = iAMRParser->SeekPointFromTimestamp(targetNPT);
return PVMFSuccess;
}
PVMFStatus PVMFAMRFFParserNode::DoSetDataSourceRate(PVMFAMRFFNodeCommand& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::DoSetDataSourceRate() In"));
OSCL_UNUSED_ARG(aCmd);
return PVMFSuccess;
}
bool PVMFAMRFFParserNode::SendEndOfTrackCommand(PVAMRFFNodeTrackPortInfo& aTrackPortInfo)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::SendEndOfTrackCommand() "));
PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);
sharedMediaCmdPtr->setStreamID(iStreamID);
uint32 timestamp = Oscl_Int64_Utils::get_uint64_lower32(aTrackPortInfo.iContinuousTimeStamp);
sharedMediaCmdPtr->setTimestamp(timestamp);
sharedMediaCmdPtr->setSeqNum(aTrackPortInfo.iSeqNum++);
PVMFSharedMediaMsgPtr mediaMsgOut;
convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
if (aTrackPortInfo.iPort->QueueOutgoingMsg(mediaMsgOut) != PVMFSuccess)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::SendEndOfTrackCommand() Failed-- Busy "));
return false;
}
aTrackPortInfo.oQueueOutgoingMessages = false;
aTrackPortInfo.oProcessOutgoingMessages = true;
return true;
}
void PVMFAMRFFParserNode::HandlePortActivity(const PVMFPortActivity &aActivity)
{
switch (aActivity.iType)
{
case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::PortActivity: Outgoing Msg"));
RunIfNotReady();
break;
case PVMF_PORT_ACTIVITY_INCOMING_MSG:
break;
case PVMF_PORT_ACTIVITY_CONNECT:
break;
case PVMF_PORT_ACTIVITY_DISCONNECT:
//nothing needed.
case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::PortActivity: Connected port ready"));
//This message is send by destination port to notify that the earlier Send
//call that failed due to its busy status can be resumed now.
if (iOutPort
&& iOutPort->OutgoingMsgQueueSize() > 0)
{
RunIfNotReady();
}
break;
case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::PortActivity: Outgoing Queue ready"));
//this message is sent by the OutgoingQueue when it recovers from
//the queue full status
RunIfNotReady();
break;
default:
break;
}
}
bool PVMFAMRFFParserNode::ProcessCommand()
{
//This call will process the first node command in the input queue.
//Can't do anything when an asynchronous cancel is in progress-- just
//need to wait on completion.
if (!iCancelCommand.empty())
return false;
//If a command is in progress, only a hi-pri command can interrupt it.
if (!iCurrentCommand.empty() && !iInputCommands.front().hipri() && iInputCommands.front().iCmd != PVMF_AMR_PARSER_NODE_CMD_CANCEL_GET_LICENSE)
{
return false;
}
//The newest or highest pri command is in the front of the queue.
OSCL_ASSERT(!iInputCommands.empty());
PVMFAMRFFNodeCommand& aCmd = iInputCommands.front();
PVMFStatus cmdstatus;
OsclAny* eventdata = NULL;
if (aCmd.hipri())
{
switch (aCmd.iCmd)
{
case PVMF_AMR_PARSER_NODE_CANCELALLCOMMANDS:
DoCancelAllCommands(aCmd);
break;
case PVMF_AMR_PARSER_NODE_CANCELCOMMAND:
DoCancelCommand(aCmd);
break;
default:
CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
break;
}
//If completion is pending, move the command from
//the input queue to the cancel queue.
//This is necessary since the input queue could get
//rearranged by new commands coming in.
}
else
{
//Process the normal pri commands.
switch (aCmd.iCmd)
{
case PVMF_AMR_PARSER_NODE_QUERYUUID:
DoQueryUuid(aCmd);
break;
case PVMF_AMR_PARSER_NODE_QUERYINTERFACE:
DoQueryInterface(aCmd);
break;
case PVMF_AMR_PARSER_NODE_REQUESTPORT:
{
PVMFPortInterface*port;
DoRequestPort(aCmd, port);
eventdata = (OsclAny*)port;
}
break;
case PVMF_AMR_PARSER_NODE_RELEASEPORT:
DoReleasePort(aCmd);
break;
case PVMF_AMR_PARSER_NODE_INIT:
cmdstatus = DoInit(aCmd);
if (cmdstatus != PVMFPending)
{
CommandComplete(iInputCommands, aCmd, cmdstatus);
}
else
{
MoveCmdToCurrentQueue(aCmd);
}
break;
case PVMF_AMR_PARSER_NODE_PREPARE:
DoPrepare(aCmd);
break;
case PVMF_AMR_PARSER_NODE_START:
DoStart(aCmd);
break;
case PVMF_AMR_PARSER_NODE_STOP:
DoStop(aCmd);
break;
case PVMF_AMR_PARSER_NODE_FLUSH:
DoFlush(aCmd);
break;
case PVMF_AMR_PARSER_NODE_PAUSE:
DoPause(aCmd);
break;
case PVMF_AMR_PARSER_NODE_RESET:
DoReset(aCmd);
break;
case PVMF_AMR_PARSER_NODE_GETNODEMETADATAKEYS:
{
cmdstatus = DoGetMetadataKeys(aCmd);
if (cmdstatus != PVMFPending)
{
CommandComplete(iInputCommands, aCmd, cmdstatus);
}
else
{
MoveCmdToCurrentQueue(aCmd);
}
}
break;
case PVMF_AMR_PARSER_NODE_GETNODEMETADATAVALUES:
{
cmdstatus = DoGetMetadataValues(aCmd);
if (cmdstatus != PVMFPending)
{
CommandComplete(iInputCommands, aCmd, cmdstatus);
}
else
{
MoveCmdToCurrentQueue(aCmd);
}
}
break;
case PVMF_AMR_PARSER_NODE_SET_DATASOURCE_POSITION:
{
cmdstatus = DoSetDataSourcePosition(aCmd);
if (cmdstatus != PVMFPending)
{
CommandComplete(iInputCommands, aCmd, cmdstatus);
}
else
{
MoveCmdToCurrentQueue(aCmd);
}
}
break;
case PVMF_AMR_PARSER_NODE_QUERY_DATASOURCE_POSITION:
{
cmdstatus = DoQueryDataSourcePosition(aCmd);
if (cmdstatus != PVMFPending)
{
CommandComplete(iInputCommands, aCmd, cmdstatus);
}
else
{
MoveCmdToCurrentQueue(aCmd);
}
}
break;
case PVMF_AMR_PARSER_NODE_SET_DATASOURCE_RATE:
{
PVMFStatus status = DoSetDataSourceRate(aCmd);
CommandComplete(iInputCommands, aCmd, status);
}
break;
case PVMF_AMR_PARSER_NODE_GET_LICENSE_W:
{
PVMFStatus status = DoGetLicense(aCmd, true);
if (status == PVMFPending)
{
MoveCmdToCurrentQueue(aCmd);
}
else
{
CommandComplete(iInputCommands, aCmd, status);
}
}
break;
case PVMF_AMR_PARSER_NODE_GET_LICENSE:
{
PVMFStatus status = DoGetLicense(aCmd);
if (status == PVMFPending)
{
MoveCmdToCurrentQueue(aCmd);
}
else
{
CommandComplete(iInputCommands, aCmd, status);
}
}
break;
case PVMF_AMR_PARSER_NODE_CMD_CANCEL_GET_LICENSE:
cmdstatus = DoCancelGetLicense(aCmd);
switch (cmdstatus)
{
case PVMFPending:
MoveCmdToCancelQueue(aCmd);
//wait on CPM callback.
break;
default:
CommandComplete(iInputCommands, aCmd, cmdstatus);
break;
}
break;
default:
OSCL_ASSERT(false);
CommandComplete(iInputCommands, aCmd, PVMFFailure);
break;
}
}
return true;
}
void PVMFAMRFFParserNode::SetState(TPVMFNodeInterfaceState s)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:SetState"));
PVMFNodeInterface::SetState(s);
}
void PVMFAMRFFParserNode::ReportErrorEvent(PVMFEventType aEventType, OsclAny* aEventData, PVUuid* aEventUUID, int32* aEventCode)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:ReportErrorEvent Type %d Data %d"
, aEventType, aEventData));
if (aEventUUID && aEventCode)
{
PVMFBasicErrorInfoMessage* eventmsg;
PVMF_AMR_PARSER_NODE_NEW(NULL,
PVMFBasicErrorInfoMessage,
(*aEventCode, *aEventUUID, NULL),
eventmsg);
PVMFAsyncEvent asyncevent(PVMFErrorEvent,
aEventType,
NULL,
OSCL_STATIC_CAST(PVInterface*, eventmsg),
aEventData,
NULL,
0);
PVMFNodeInterface::ReportErrorEvent(asyncevent);
eventmsg->removeRef();
}
else
{
PVMFNodeInterface::ReportErrorEvent(aEventType, aEventData);
}
/* Transition the node to an error state */
iInterfaceState = EPVMFNodeError;
}
void PVMFAMRFFParserNode::ReportInfoEvent(PVMFEventType aEventType, OsclAny* aEventData, PVUuid* aEventUUID, int32* aEventCode)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:ReportInfoEvent Type %d Data %d"
, aEventType, aEventData));
if (aEventUUID && aEventCode)
{
PVMFBasicErrorInfoMessage* eventmsg;
PVMF_AMR_PARSER_NODE_NEW(NULL,
PVMFBasicErrorInfoMessage,
(*aEventCode, *aEventUUID, NULL),
eventmsg);
PVMFAsyncEvent asyncevent(PVMFInfoEvent,
aEventType,
NULL,
OSCL_STATIC_CAST(PVInterface*, eventmsg),
aEventData,
NULL,
0);
PVMFNodeInterface::ReportInfoEvent(asyncevent);
eventmsg->removeRef();
}
else
{
PVMFNodeInterface::ReportInfoEvent(aEventType, aEventData);
}
}
void PVMFAMRFFParserNode::DoQueryUuid(PVMFAMRFFNodeCommand& aCmd)
{
OSCL_String* mimetype;
Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec;
bool exactmatch;
aCmd.PVMFAMRFFNodeCommandBase::Parse(mimetype, uuidvec, exactmatch);
if (*mimetype == PVMF_DATA_SOURCE_INIT_INTERFACE_MIMETYPE)
{
PVUuid uuid(PVMF_DATA_SOURCE_INIT_INTERFACE_UUID);
uuidvec->push_back(uuid);
}
else if (*mimetype == PVMF_TRACK_SELECTION_INTERFACE_MIMETYPE)
{
PVUuid uuid(PVMF_TRACK_SELECTION_INTERFACE_UUID);
uuidvec->push_back(uuid);
}
else if (*mimetype == PVMF_DATA_SOURCE_PLAYBACK_CONTROL_INTERFACE_MIMETYPE)
{
PVUuid uuid(PvmfDataSourcePlaybackControlUuid);
uuidvec->push_back(uuid);
}
else if (*mimetype == PVMF_META_DATA_EXTENSION_INTERFACE_MIMETYPE)
{
PVUuid uuid(KPVMFMetadataExtensionUuid);
uuidvec->push_back(uuid);
}
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
void PVMFAMRFFParserNode::DoQueryInterface(PVMFAMRFFNodeCommand& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::DoQueryInterface"));
PVUuid* uuid;
PVInterface** ptr;
aCmd.PVMFAMRFFNodeCommandBase::Parse(uuid, ptr);
if (queryInterface(*uuid, *ptr))
{
(*ptr)->addRef();
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
}
else
{
*ptr = NULL;
CommandComplete(iInputCommands, aCmd, PVMFErrNotSupported);
}
return;
}
PVMFStatus PVMFAMRFFParserNode::DoInit(PVMFAMRFFNodeCommand& aCmd)
{
OSCL_UNUSED_ARG(aCmd);
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::DoInitNode() In"));
if (iInterfaceState != EPVMFNodeIdle)
{
return PVMFErrInvalidState;
}
if (iCPM)
{
/*
* Go thru CPM commands before parsing the file in case
* of a new source file.
* - Init CPM
* - Open Session
* - Register Content
* - Get Content Type
* - Approve Usage
* In case the source file has already been parsed skip to
* - Approve Usage
*/
if (oSourceIsCurrent == false)
{
InitCPM();
}
else
{
RequestUsage();
}
return PVMFPending;
}
else
{
if (CheckForAMRHeaderAvailability() == PVMFSuccess)
{
ParseAMRFile();
SetState(EPVMFNodeInitialized);
return PVMFSuccess;
}
}
return PVMFSuccess;
}
PVMFStatus PVMFAMRFFParserNode::ParseAMRFile()
{
iAMRParser = OSCL_NEW(CAMRFileParser, ());
if (!iAMRParser)
{
return PVMFErrNoMemory;
}
PVMFDataStreamFactory* dsFactory = iCPMContentAccessFactory;
bool calcDuration = true;
if ((dsFactory == NULL) && (iDataStreamFactory != NULL))
{
dsFactory = iDataStreamFactory;
calcDuration = false;
}
if (iAMRParser->InitAMRFile(iSourceURL, calcDuration, &iFileServer, dsFactory, iFileHandle, iCountToClaculateRDATimeInterval))
{
iAvailableMetadataKeys.clear();
if (iAMRParser->RetrieveFileInfo(iAMRFileInfo))
{
PVMFStatus status = InitMetaData();
if (status == PVMFSuccess)
{
return PVMFSuccess;
}
else
{
CleanupFileSource();
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::ParseAMRFile() - InitMetaData Failed"));
CommandComplete(iCurrentCommand,
iCurrentCommand.front(),
status
);
}
}
else
{
return PVMFErrResource;
}
}
else
{
//cleanup if failure
OSCL_DELETE(iAMRParser);
iAMRParser = NULL;
return PVMFErrResource;
}
return PVMFSuccess;
}
void PVMFAMRFFParserNode::DoPrepare(PVMFAMRFFNodeCommand& aCmd)
{
if (iInterfaceState != EPVMFNodeInitialized)
{
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
return;
}
SetState(EPVMFNodePrepared);
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
void PVMFAMRFFParserNode::DoStart(PVMFAMRFFNodeCommand& aCmd)
{
if (iInterfaceState != EPVMFNodePrepared &&
iInterfaceState != EPVMFNodePaused)
{
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
return;
}
SetState(EPVMFNodeStarted);
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
void PVMFAMRFFParserNode::DoStop(PVMFAMRFFNodeCommand& aCmd)
{
iStreamID = 0;
if (iInterfaceState != EPVMFNodeStarted &&
iInterfaceState != EPVMFNodePaused)
{
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
return;
}
if (iDataStreamInterface != NULL)
{
PVInterface* iFace = OSCL_STATIC_CAST(PVInterface*, iDataStreamInterface);
PVUuid uuid = PVMIDataStreamSyncInterfaceUuid;
iDataStreamFactory->DestroyPVMFCPMPluginAccessInterface(uuid, iFace);
iDataStreamInterface = NULL;
}
// stop and reset position to beginning
ResetAllTracks();
// Reset the AMR FF to beginning
if (iAMRParser)
{
iAMRParser->ResetPlayback(0);
}
//clear msg queue
if (iOutPort)
{
iOutPort->ClearMsgQueues();
}
SetState(EPVMFNodePrepared);
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
void PVMFAMRFFParserNode::DoPause(PVMFAMRFFNodeCommand& aCmd)
{
if (iInterfaceState != EPVMFNodeStarted)
{
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
return;
}
SetState(EPVMFNodePaused);
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
void PVMFAMRFFParserNode::DoFlush(PVMFAMRFFNodeCommand& aCmd)
{
if (iInterfaceState != EPVMFNodeStarted &&
iInterfaceState != EPVMFNodePaused)
{
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
return;
}
/*
* the flush is asynchronous. move the command from
* the input command queue to the current command, where
* it will remain until the flush completes.
*/
MoveCmdToCurrentQueue(aCmd);
return;
}
bool PVMFAMRFFParserNode::FlushPending()
{
return (iCurrentCommand.size() > 0
&& iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_FLUSH);
}
void PVMFAMRFFParserNode::DoReset(PVMFAMRFFNodeCommand& aCmd)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::DoReset() Called"));
if (iDownloadProgressInterface != NULL)
{
iDownloadProgressInterface->cancelResumeNotification();
}
MoveCmdToCurrentQueue(aCmd);
if (iFileHandle != NULL)
{
/* Indicates that the init was successfull */
if ((iCPM))
{
SendUsageComplete();
}
else
{
CompleteReset();
}
}
else
{
/*
* Reset without init completing, so just reset the parser node,
* no CPM stuff necessary
*/
CompleteReset();
}
}
void
PVMFAMRFFParserNode::MoveCmdToCurrentQueue(PVMFAMRFFNodeCommand& aCmd)
{
int32 err;
OSCL_TRY(err, iCurrentCommand.StoreL(aCmd););
if (err != OsclErrNone)
{
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
iInputCommands.Erase(&aCmd);
return;
}
void
PVMFAMRFFParserNode::MoveCmdToCancelQueue(PVMFAMRFFNodeCommand& aCmd)
{
/*
* note: the StoreL cannot fail since the queue is never more than 1 deep
* and we reserved space.
*/
iCancelCommand.StoreL(aCmd);
iInputCommands.Erase(&aCmd);
}
void PVMFAMRFFParserNode::DoCancelAllCommands(PVMFAMRFFNodeCommand& aCmd)
{
while (!iCurrentCommand.empty())
{
MoveCmdToCancelQueue(aCmd);
}
//next cancel all queued commands
//start at element 1 since this cancel command is element 0.
while (iInputCommands.size() > 1)
{
CommandComplete(iInputCommands, iInputCommands[1], PVMFErrCancelled);
}
//finally, report cancel complete.
CommandComplete(iInputCommands, iInputCommands[0], PVMFSuccess);
return;
}
void PVMFAMRFFParserNode::DoCancelCommand(PVMFAMRFFNodeCommand& aCmd)
{
PVMFCommandId id;
aCmd.PVMFAMRFFNodeCommandBase::Parse(id);
{
PVMFAMRFFNodeCommand* cmd = iCurrentCommand.FindById(id);
if (cmd)
{
//cancel the queued command
MoveCmdToCancelQueue(*cmd);
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
}
{
PVMFAMRFFNodeCommand* cmd = iInputCommands.FindById(id, 1);
if (cmd)
{
//cancel the queued command
CommandComplete(iInputCommands, *cmd, PVMFErrCancelled);
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
}
CommandComplete(iInputCommands, aCmd, PVMFErrArgument);
return;
}
void PVMFAMRFFParserNode::DoRequestPort(PVMFAMRFFNodeCommand& aCmd, PVMFPortInterface*&aPort)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::DoRequestPort() In"));
aPort = NULL;
if ((iInterfaceState != EPVMFNodePrepared) || (!iAMRParser))
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFASFParserNode::DoRequestPort() - Invalid State"));
CommandComplete(iInputCommands, aCmd, PVMFErrInvalidState);
return;
}
int32 tag = 0;
OSCL_String* mime_string;
aCmd.PVMFAMRFFNodeCommandBase::Parse(tag, mime_string);
if (tag != PVMF_AMRFFPARSER_NODE_PORT_TYPE_SOURCE)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
(0, "PVMFAMRFFParserNode::DoRequestPort: Error - Invalid port tag"));
CommandComplete(iInputCommands, aCmd, PVMFFailure);
return;
}
if (iOutPort)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::DoRequestPort: Error - port already exists"));
CommandComplete(iInputCommands, aCmd, PVMFFailure);
return;
}
if ((int32)aCmd.iParam1 == PVMF_AMRFFPARSER_NODE_PORT_TYPE_SOURCE)
{
iOutPort = OSCL_NEW(PVMFAMRFFParserOutPort, (PVMF_AMRFFPARSER_NODE_PORT_TYPE_SOURCE, this));
if (!iOutPort)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::DoRequestPort: Error - no memory"));
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
if (mime_string)
{
PVMFFormatType fmt = mime_string->get_str();
if (!iOutPort->IsFormatSupported(fmt))
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::DoRequestPort: Error - format not supported"));
OSCL_DELETE(iOutPort);
iOutPort = NULL;
CommandComplete(iInputCommands, aCmd, PVMFFailure);
return;
}
}
MediaClockConverter* clockconv = NULL;
OsclMemPoolFixedChunkAllocator* trackdatamempool = NULL;
PVMFSimpleMediaBufferCombinedAlloc* mediadataimplalloc = NULL;
PVMFMemPoolFixedChunkAllocator* mediadatamempool = NULL;
int32 leavecode = 0;
OSCL_TRY(leavecode,
clockconv = OSCL_NEW(MediaClockConverter, (iAMRFileInfo.iTimescale));
trackdatamempool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (PVAMRFF_MEDIADATA_POOLNUM));
mediadataimplalloc = OSCL_NEW(PVMFSimpleMediaBufferCombinedAlloc, (trackdatamempool));
mediadatamempool = OSCL_NEW(PVMFMemPoolFixedChunkAllocator, ("AmrFFPar", PVAMRFF_MEDIADATA_POOLNUM, PVAMRFF_MEDIADATA_CHUNKSIZE));
);
if (leavecode || !clockconv || !trackdatamempool || !mediadataimplalloc || !mediadatamempool)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::DoRequestPort: Error - unable to create clockconv, trackdatamempool, mediadataimplalloc, and mediadatamempool"));
if (iOutPort)
{
OSCL_DELETE(iOutPort);
iOutPort = NULL;
}
if (clockconv)
{
OSCL_DELETE(clockconv);
}
if (trackdatamempool)
{
OSCL_DELETE(trackdatamempool);
}
if (mediadataimplalloc)
{
OSCL_DELETE(mediadataimplalloc);
}
if (mediadatamempool)
{
OSCL_DELETE(mediadatamempool);
}
CommandComplete(iInputCommands, aCmd, PVMFErrNoMemory);
return;
}
mediadatamempool->enablenullpointerreturn();
PVAMRFFNodeTrackPortInfo trackportinfo;
trackportinfo.iTrackId = 0; // Only support 1 channel so far
trackportinfo.iTag = PVMF_AMRFFPARSER_NODE_PORT_TYPE_SOURCE;
trackportinfo.iPort = iOutPort;
trackportinfo.iClockConverter = clockconv;
trackportinfo.iTrackDataMemoryPool = trackdatamempool;
trackportinfo.iMediaDataImplAlloc = mediadataimplalloc;
trackportinfo.iMediaDataMemPool = mediadatamempool;
aPort = iOutPort;
OsclMemPoolResizableAllocator* trackDataResizableMemPool = NULL;
trackportinfo.iResizableDataMemoryPoolSize = PVMF_AMR_PARSER_NODE_MAX_AUDIO_DATA_MEM_POOL_SIZE;
PVMF_AMR_PARSER_NODE_NEW(NULL,
OsclMemPoolResizableAllocator,
(trackportinfo.iResizableDataMemoryPoolSize,
PVMF_AMR_PARSER_NODE_DATA_MEM_POOL_GROWTH_LIMIT),
trackDataResizableMemPool);
PVUuid eventuuid = PVMFAMRParserNodeEventTypesUUID;
int32 errcode = PVMFAMRFFParserErrTrackMediaMsgAllocatorCreationFailed;
PVMFResizableSimpleMediaMsgAlloc* resizableSimpleMediaDataImplAlloc = NULL;
OsclExclusivePtr<PVMFResizableSimpleMediaMsgAlloc> resizableSimpleMediaDataImplAllocAutoPtr;
PVMF_AMR_PARSER_NODE_NEW(NULL,
PVMFResizableSimpleMediaMsgAlloc,
(trackDataResizableMemPool),
resizableSimpleMediaDataImplAlloc);
if (trackDataResizableMemPool == NULL)
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::DoRequestPort() - trackDataResizableMemPool Alloc Failed"));
CommandComplete(iInputCommands,
aCmd,
PVMFErrNoMemory,
NULL,
&eventuuid,
&errcode);
return;
}
trackDataResizableMemPool->enablenullpointerreturn();
trackportinfo.iResizableSimpleMediaMsgAlloc = resizableSimpleMediaDataImplAlloc;
trackportinfo.iResizableDataMemoryPool = trackDataResizableMemPool;
trackportinfo.iNode = this;
uint8* typeSpecificInfoBuff = iAMRParser->getCodecSpecificInfo();
uint32 typeSpecificDataLength = MAX_NUM_PACKED_INPUT_BYTES;
if ((int32)typeSpecificDataLength > 0)
{
OsclMemAllocDestructDealloc<uint8> my_alloc;
OsclRefCounter* my_refcnt;
uint aligned_refcnt_size =
oscl_mem_aligned_size(sizeof(OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >));
uint aligned_type_specific_info_size =
oscl_mem_aligned_size(typeSpecificDataLength);
uint8* my_ptr = NULL;
int32 errcode = 0;
OSCL_TRY(errcode,
my_ptr = (uint8*) my_alloc.ALLOCATE(aligned_refcnt_size + aligned_type_specific_info_size));
if (errcode != OsclErrNone)
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::PopulateTrackInfoVec - Unable to Allocate Memory"));
}
my_refcnt = OSCL_PLACEMENT_NEW(my_ptr, OsclRefCounterSA< OsclMemAllocDestructDealloc<uint8> >(my_ptr));
my_ptr += aligned_refcnt_size;
OsclMemoryFragment memfrag;
memfrag.len = typeSpecificDataLength;
memfrag.ptr = typeSpecificInfoBuff;
OsclRefCounterMemFrag tmpRefcntMemFrag(memfrag, my_refcnt, memfrag.len);
trackportinfo.iFormatSpecificConfig = tmpRefcntMemFrag;
}
iSelectedTrackList.push_back(trackportinfo);
CommandComplete(iInputCommands, aCmd, PVMFSuccess, (OsclAny*)aPort);
return;
}
else
{
// don't support other types yet
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::DoRequestPort: Error - type not supported"));
CommandComplete(iInputCommands, aCmd, PVMFFailure);
return;
}
}
void PVMFAMRFFParserNode::DoReleasePort(PVMFAMRFFNodeCommand& aCmd)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::DoReleasePort"));
// search for the matching port address
// disconnect it, if needed
// cleanup the buffers associated with it
// delete the port
// set the address to NULL
// Remove the selected track from the track list
for (uint32 i = 0; i < iSelectedTrackList.size(); i++)
{
if (iSelectedTrackList[i].iPort == aCmd.iParam1)
{
// Found the element. So erase it
iSelectedTrackList[i].iMediaData.Unbind();
OSCL_DELETE(((PVMFAMRFFParserOutPort*)iSelectedTrackList[i].iPort));
iSelectedTrackList[i].iPort = NULL;
iOutPort = NULL;
if (iSelectedTrackList[i].iClockConverter)
{
OSCL_DELETE(iSelectedTrackList[i].iClockConverter);
}
if (iSelectedTrackList[i].iTrackDataMemoryPool)
{
iSelectedTrackList[i].iTrackDataMemoryPool->removeRef();
iSelectedTrackList[i].iTrackDataMemoryPool = NULL;
}
if (iSelectedTrackList[i].iMediaDataImplAlloc)
{
OSCL_DELETE(iSelectedTrackList[i].iMediaDataImplAlloc);
}
if (iSelectedTrackList[i].iMediaDataMemPool)
{
iSelectedTrackList[i].iMediaDataMemPool->CancelFreeChunkAvailableCallback();
iSelectedTrackList[i].iMediaDataMemPool->removeRef();
iSelectedTrackList[i].iMediaDataMemPool = NULL;
}
if (iSelectedTrackList[i].iResizableSimpleMediaMsgAlloc != NULL)
{
PVMF_AMR_PARSER_NODE_DELETE(NULL,
PVMFResizableSimpleMediaMsgAlloc,
iSelectedTrackList[i].iResizableSimpleMediaMsgAlloc);
iSelectedTrackList[i].iResizableSimpleMediaMsgAlloc = NULL;
}
if (iSelectedTrackList[i].iResizableDataMemoryPool != NULL)
{
iSelectedTrackList[i].iResizableDataMemoryPool->removeRef();
iSelectedTrackList[i].iResizableDataMemoryPool = NULL;
}
iSelectedTrackList.erase(&iSelectedTrackList[i]);
CommandComplete(iInputCommands, aCmd, PVMFSuccess);
return;
}
}
//if we get here the track was not found
CommandComplete(iInputCommands, aCmd, PVMFErrBadHandle);
return;
}
void PVMFAMRFFParserNode::ResetAllTracks()
{
for (uint32 i = 0; i < iSelectedTrackList.size(); ++i)
{
iSelectedTrackList[i].iMediaData.Unbind();
iSelectedTrackList[i].iSeqNum = 0;
iSelectedTrackList[i].iFirstFrame = true;
iSelectedTrackList[i].oEOSSent = false;
iSelectedTrackList[i].oEOSReached = false;
iSelectedTrackList[i].oQueueOutgoingMessages = true;
}
}
bool PVMFAMRFFParserNode::ReleaseAllPorts()
{
while (!iSelectedTrackList.empty())
{
iSelectedTrackList[0].iPort->Disconnect();
iSelectedTrackList[0].iMediaData.Unbind();
OSCL_DELETE(((PVMFAMRFFParserOutPort*)iSelectedTrackList[0].iPort));
if (iSelectedTrackList[0].iClockConverter)
{
OSCL_DELETE(iSelectedTrackList[0].iClockConverter);
}
if (iSelectedTrackList[0].iTrackDataMemoryPool)
{
iSelectedTrackList[0].iTrackDataMemoryPool->removeRef();
iSelectedTrackList[0].iTrackDataMemoryPool = NULL;
}
if (iSelectedTrackList[0].iMediaDataImplAlloc)
{
OSCL_DELETE(iSelectedTrackList[0].iMediaDataImplAlloc);
}
if (iSelectedTrackList[0].iMediaDataMemPool)
{
iSelectedTrackList[0].iMediaDataMemPool->CancelFreeChunkAvailableCallback();
iSelectedTrackList[0].iMediaDataMemPool->removeRef();
iSelectedTrackList[0].iMediaDataMemPool = NULL;
}
iOutPort = NULL;
if (iSelectedTrackList[0].iResizableSimpleMediaMsgAlloc != NULL)
{
PVMF_AMR_PARSER_NODE_DELETE(NULL,
PVMFResizableSimpleMediaMsgAlloc,
iSelectedTrackList[0].iResizableSimpleMediaMsgAlloc);
iSelectedTrackList[0].iResizableSimpleMediaMsgAlloc = NULL;
}
if (iSelectedTrackList[0].iResizableDataMemoryPool != NULL)
{
iSelectedTrackList[0].iResizableDataMemoryPool->removeRef();
iSelectedTrackList[0].iResizableDataMemoryPool = NULL;
}
iSelectedTrackList.erase(iSelectedTrackList.begin());
}
return true;
}
void PVMFAMRFFParserNode::CleanupFileSource()
{
iAvailableMetadataKeys.clear();
if (iAMRParser)
{
OSCL_DELETE(iAMRParser);
}
iAMRParser = NULL;
iUseCPMPluginRegistry = false;
iCPMSourceData.iFileHandle = NULL;
iAMRParserNodeMetadataValueCount = 0;
if (iCPMContentAccessFactory != NULL)
{
iCPMContentAccessFactory->removeRef();
iCPMContentAccessFactory = NULL;
}
if (iDataStreamFactory != NULL)
{
iDataStreamFactory->removeRef();
iDataStreamFactory = NULL;
}
iCPMContentType = PVMF_CPM_CONTENT_FORMAT_UNKNOWN;
iPreviewMode = false;
oSourceIsCurrent = false;
if (iFileHandle)
{
OSCL_DELETE(iFileHandle);
}
iFileHandle = NULL;
}
void PVMFAMRFFParserNode::CommandComplete(PVMFAMRFFNodeCmdQ& aCmdQ, PVMFAMRFFNodeCommand& aCmd, PVMFStatus aStatus, PVInterface*aExtMsg, OsclAny* aEventData)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFAMRFFParserNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
, aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
PVInterface* extif = NULL;
PVMFBasicErrorInfoMessage* errormsg = NULL;
if (aExtMsg)
{
extif = aExtMsg;
}
PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
PVMFSessionId session = aCmd.iSession;
/* Erase the command from the queue. */
aCmdQ.Erase(&aCmd);
/* Report completion to the session observer.*/
ReportCmdCompleteEvent(session, resp);
if (errormsg)
{
errormsg->removeRef();
}
}
void PVMFAMRFFParserNode::CommandComplete(PVMFAMRFFNodeCmdQ& aCmdQ,
PVMFAMRFFNodeCommand& aCmd,
PVMFStatus aStatus,
OsclAny* aEventData,
PVUuid* aEventUUID,
int32* aEventCode,
PVInterface* aExtMsg)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::CommandComplete() In Id %d Cmd %d Status %d Context %d Data %d",
aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
PVInterface* extif = NULL;
PVMFBasicErrorInfoMessage* errormsg = NULL;
if (aExtMsg)
{
extif = aExtMsg;
}
else if (aEventUUID && aEventCode)
{
errormsg =
OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
}
PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
PVMFSessionId session = aCmd.iSession;
/* Erase the command from the queue. */
if (!aCmdQ.empty())
{
aCmdQ.Erase(&aCmd);
}
/* Report completion to the session observer.*/
ReportCmdCompleteEvent(session, resp);
if (errormsg)
{
errormsg->removeRef();
}
}
PVMFCommandId PVMFAMRFFParserNode::QueueCommandL(PVMFAMRFFNodeCommand& aCmd)
{
if (IsAdded())
{
PVMFCommandId id;
id = iInputCommands.AddL(aCmd);
/* Wakeup the AO */
RunIfNotReady();
return id;
}
OSCL_LEAVE(OsclErrInvalidState);
return -1;
}
void PVMFAMRFFParserNode::addRef()
{
++iExtensionRefCount;
}
void PVMFAMRFFParserNode::removeRef()
{
--iExtensionRefCount;
}
PVMFStatus PVMFAMRFFParserNode::QueryInterfaceSync(PVMFSessionId aSession,
const PVUuid& aUuid,
PVInterface*& aInterfacePtr)
{
OSCL_UNUSED_ARG(aSession);
aInterfacePtr = NULL;
if (queryInterface(aUuid, aInterfacePtr))
{
aInterfacePtr->addRef();
return PVMFSuccess;
}
return PVMFErrNotSupported;
}
bool PVMFAMRFFParserNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
{
if (uuid == PVMF_DATA_SOURCE_INIT_INTERFACE_UUID)
{
PVMFDataSourceInitializationExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFDataSourceInitializationExtensionInterface*, this);
iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
}
else if (uuid == PVMF_TRACK_SELECTION_INTERFACE_UUID)
{
PVMFTrackSelectionExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFTrackSelectionExtensionInterface*, this);
iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
}
else if (uuid == KPVMFMetadataExtensionUuid)
{
PVMFMetadataExtensionInterface* myInterface = OSCL_STATIC_CAST(PVMFMetadataExtensionInterface*, this);
iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
}
else if (uuid == PvmfDataSourcePlaybackControlUuid)
{
PvmfDataSourcePlaybackControlInterface* myInterface = OSCL_STATIC_CAST(PvmfDataSourcePlaybackControlInterface*, this);
iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
}
else if (uuid == PVMIDatastreamuserInterfaceUuid)
{
PVMIDatastreamuserInterface* myInterface = OSCL_STATIC_CAST(PVMIDatastreamuserInterface*, this);
iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
}
else if (uuid == PVMF_FF_PROGDOWNLOAD_SUPPORT_INTERFACE_UUID)
{
PVMFFormatProgDownloadSupportInterface* myInterface = OSCL_STATIC_CAST(PVMFFormatProgDownloadSupportInterface*, this);
iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
}
else if (uuid == PVMFCPMPluginLicenseInterfaceUuid)
{
PVMFCPMPluginLicenseInterface* myInterface = OSCL_STATIC_CAST(PVMFCPMPluginLicenseInterface*, this);
iface = OSCL_STATIC_CAST(PVInterface*, myInterface);
}
else
{
return false;
}
return true;
}
PVMFStatus PVMFAMRFFParserNode::SetSourceInitializationData(OSCL_wString& aSourceURL, PVMFFormatType& aSourceFormat, OsclAny* aSourceData)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::SetSourceInitializationData() called"));
if (aSourceFormat == PVMF_MIME_AMRFF)
{
/* Clean up any previous sources */
CleanupFileSource();
iSourceFormat = aSourceFormat;
iSourceURL = aSourceURL;
if (aSourceData)
{
// Old context object? query for local datasource availability
PVInterface* pvInterface =
OSCL_STATIC_CAST(PVInterface*, aSourceData);
PVInterface* localDataSrc = NULL;
PVUuid localDataSrcUuid(PVMF_LOCAL_DATASOURCE_UUID);
if (pvInterface->queryInterface(localDataSrcUuid, localDataSrc))
{
PVMFLocalDataSource* context =
OSCL_STATIC_CAST(PVMFLocalDataSource*, localDataSrc);
iPreviewMode = context->iPreviewMode;
if (context->iFileHandle)
{
PVMF_AMR_PARSER_NODE_NEW(NULL,
OsclFileHandle,
(*(context->iFileHandle)),
iFileHandle);
iCPMSourceData.iFileHandle = iFileHandle;
}
iCPMSourceData.iPreviewMode = iPreviewMode;
iCPMSourceData.iIntent = context->iIntent;
}
else
{
// New context object ?
PVInterface* sourceDataContext = NULL;
PVInterface* commonDataContext = NULL;
PVUuid sourceContextUuid(PVMF_SOURCE_CONTEXT_DATA_UUID);
PVUuid commonContextUuid(PVMF_SOURCE_CONTEXT_DATA_COMMON_UUID);
if (pvInterface->queryInterface(sourceContextUuid, sourceDataContext) &&
sourceDataContext->queryInterface(commonContextUuid, commonDataContext))
{
PVMFSourceContextDataCommon* context =
OSCL_STATIC_CAST(PVMFSourceContextDataCommon*, commonDataContext);
iPreviewMode = context->iPreviewMode;
if (context->iFileHandle)
{
PVMF_AMR_PARSER_NODE_NEW(NULL,
OsclFileHandle,
(*(context->iFileHandle)),
iFileHandle);
iCPMSourceData.iFileHandle = iFileHandle;
}
iCPMSourceData.iPreviewMode = iPreviewMode;
iCPMSourceData.iIntent = context->iIntent;
}
}
}
/*
* create a CPM object here...
*/
iUseCPMPluginRegistry = true;
{
//cleanup any prior instance
if (iCPM)
{
iCPM->ThreadLogoff();
PVMFCPMFactory::DestroyContentPolicyManager(iCPM);
iCPM = NULL;
}
iCPM = PVMFCPMFactory::CreateContentPolicyManager(*this);
//thread logon may leave if there are no plugins
int32 err;
OSCL_TRY(err, iCPM->ThreadLogon(););
OSCL_FIRST_CATCH_ANY(err,
iCPM->ThreadLogoff();
PVMFCPMFactory::DestroyContentPolicyManager(iCPM);
iCPM = NULL;
iUseCPMPluginRegistry = false;
);
}
return PVMFSuccess;
}
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::SetSourceInitializationData - Unsupported Format"));
return PVMFFailure;
}
PVMFStatus PVMFAMRFFParserNode::SetClientPlayBackClock(PVMFMediaClock* aClientClock)
{
OSCL_UNUSED_ARG(aClientClock);
return PVMFSuccess;
}
PVMFStatus PVMFAMRFFParserNode::SetEstimatedServerClock(PVMFMediaClock* aClientClock)
{
OSCL_UNUSED_ARG(aClientClock);
return PVMFSuccess;
}
PVMFStatus PVMFAMRFFParserNode::GetMediaPresentationInfo(PVMFMediaPresentationInfo& aInfo)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::GetMediaPresentationInfo() called"));
if (!iAMRParser)
{
return PVMFFailure;
}
aInfo.setDurationValue(iAMRFileInfo.iDuration);
// Current version of AAC parser is limited to 1 channel
PVMFTrackInfo tmpTrackInfo;
tmpTrackInfo.setPortTag(PVMF_AMRFFPARSER_NODE_PORT_TYPE_SOURCE);
tmpTrackInfo.setTrackID(0);
TPVAmrFileInfo amrinfo;
if (!iAMRParser->RetrieveFileInfo(amrinfo)) return PVMFErrNotSupported;
switch (amrinfo.iAmrFormat)
{
// Supported formats
case EAMRIF2: // IF2
case EAMRIETF_SingleNB: // IETF
case EAMRIETF_SingleWB:
break;
// Everything else is not supported
case EAMRETS:
case EAMRIETF_MultiNB:
case EAMRIETF_MultiWB:
case EAMRWMF:
case EAMRUnrecognized:
default:
return PVMFErrNotSupported;
}
tmpTrackInfo.setTrackBitRate(amrinfo.iBitrate);
tmpTrackInfo.setTrackDurationTimeScale((uint64)amrinfo.iTimescale);
tmpTrackInfo.setTrackDurationValue(amrinfo.iDuration);
OSCL_FastString mime_type = _STRLIT_CHAR(PVMF_MIME_AMR_IETF);
if (amrinfo.iAmrFormat == EAMRIF2)
{
mime_type = _STRLIT_CHAR(PVMF_MIME_AMR_IF2);
}
else if (EAMRIETF_SingleWB == amrinfo.iAmrFormat)
mime_type = _STRLIT_CHAR(PVMF_MIME_AMRWB_IETF);
tmpTrackInfo.setTrackMimeType(mime_type);
aInfo.addTrackInfo(tmpTrackInfo);
return PVMFSuccess;
}
PVMFStatus PVMFAMRFFParserNode::SelectTracks(PVMFMediaPresentationInfo& aInfo)
{
OSCL_UNUSED_ARG(aInfo);
return PVMFSuccess;
}
uint32 PVMFAMRFFParserNode::GetNumMetadataKeys(char* aQueryKeyString)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::GetNumMetadataKeys() called"));
uint32 num_entries = 0;
if (aQueryKeyString == NULL)
{
// No query key so just return all the available keys
num_entries = iAvailableMetadataKeys.size();
}
else
{
// Determine the number of metadata keys based on the query key string provided
for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++)
{
// Check if the key matches the query key
if (pv_mime_strcmp(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) >= 0)
{
num_entries++;
}
}
}
for (uint32 i = 0; i < iCPMMetadataKeys.size(); i++)
{
if (pv_mime_strcmp(iCPMMetadataKeys[i].get_cstr(),
aQueryKeyString) >= 0)
{
num_entries++;
}
}
if ((iCPMMetaDataExtensionInterface != NULL))
{
num_entries +=
iCPMMetaDataExtensionInterface->GetNumMetadataKeys(aQueryKeyString);
}
return num_entries;
}
uint32 PVMFAMRFFParserNode::GetNumMetadataValues(PVMFMetadataList& aKeyList)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::GetNumMetadataValues() called"));
uint32 numkeys = aKeyList.size();
if (!iAMRParser || numkeys == 0)
{
return 0;
}
// Count the number of metadata value entries based on the key list provided
uint32 numvalentries = 0;
for (uint32 lcv = 0; lcv < numkeys; lcv++)
{
if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_DURATION_KEY) == 0 &&
iAMRFileInfo.iDuration > 0)
{
// Movie Duration
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_NUMTRACKS_KEY) == 0)
{
// Number of tracks
++numvalentries;
}
else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_TRACKINFO_BITRATE_KEY) == 0) &&
iAMRFileInfo.iBitrate > 0)
{
// Bitrate
++numvalentries;
}
else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY) == 0) &&
iAMRFileInfo.iAmrFormat != EAMRUnrecognized)
{
// Format
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_RANDOM_ACCESS_DENIED_KEY) == 0)
{
/*
* Random Access
* Increment the counter for the number of values found so far
*/
++numvalentries;
}
else if (oscl_strcmp(aKeyList[lcv].get_cstr(), PVAMRMETADATA_CLIP_TYPE_KEY) == 0)
{
/*
* clip-type
* Increment the counter for the number of values found so far
*/
++numvalentries;
}
}
if ((iCPMMetaDataExtensionInterface != NULL))
{
numvalentries +=
iCPMMetaDataExtensionInterface->GetNumMetadataValues(aKeyList);
}
return numvalentries;
}
PVMFCommandId PVMFAMRFFParserNode::GetNodeMetadataKeys(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList
, uint32 aStartingKeyIndex, int32 aMaxKeyEntries, char* aQueryKeyString, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::GetNodeMetadataKeys() called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_GETNODEMETADATAKEYS, aKeyList, aStartingKeyIndex, aMaxKeyEntries, aQueryKeyString, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::GetNodeMetadataValues(PVMFSessionId aSessionId, PVMFMetadataList& aKeyList, Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList
, uint32 aStartingValueIndex, int32 aMaxValueEntries, const OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::GetNodeMetadataValue() called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_GETNODEMETADATAVALUES, aKeyList, aValueList, aStartingValueIndex, aMaxValueEntries, aContext);
return QueueCommandL(cmd);
}
PVMFStatus PVMFAMRFFParserNode::ReleaseNodeMetadataKeys(PVMFMetadataList& , uint32 , uint32)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::ReleaseNodeMetadataKeys() called"));
return PVMFSuccess;
}
PVMFStatus PVMFAMRFFParserNode::ReleaseNodeMetadataValues(Oscl_Vector<PvmiKvp, OsclMemAllocator>& aValueList, uint32 start, uint32 end)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::ReleaseNodeMetadataValues() called"));
if (start > end || aValueList.size() == 0)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFAMRFFParserNode::ReleaseNodeMetadataValues() Invalid start/end index"));
return PVMFErrArgument;
}
end = OSCL_MIN(aValueList.size(), iAMRParserNodeMetadataValueCount);
for (uint32 i = start; i < end; i++)
{
if (aValueList[i].key != NULL)
{
switch (GetValTypeFromKeyString(aValueList[i].key))
{
case PVMI_KVPVALTYPE_CHARPTR:
if (aValueList[i].value.pChar_value != NULL)
{
OSCL_ARRAY_DELETE(aValueList[i].value.pChar_value);
aValueList[i].value.pChar_value = NULL;
}
break;
case PVMI_KVPVALTYPE_UINT32:
case PVMI_KVPVALTYPE_UINT8:
// No memory to free for these valtypes
break;
default:
// Should not get a value that wasn't created from here
break;
}
OSCL_ARRAY_DELETE(aValueList[i].key);
aValueList[i].key = NULL;
}
}
return PVMFSuccess;
}
PVMFCommandId PVMFAMRFFParserNode::SetDataSourcePosition(PVMFSessionId aSessionId
, PVMFTimestamp aTargetNPT
, PVMFTimestamp& aActualNPT
, PVMFTimestamp& aActualMediaDataTS
, bool aSeekToSyncPoint
, uint32 aStreamID
, OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::SetDataSourcePosition: aTargetNPT=%d, aSeekToSyncPoint=%d, aContext=0x%x",
aTargetNPT, aSeekToSyncPoint, aContext));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_SET_DATASOURCE_POSITION, aTargetNPT, aActualNPT,
aActualMediaDataTS, aSeekToSyncPoint, aStreamID, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::QueryDataSourcePosition(PVMFSessionId aSessionId
, PVMFTimestamp aTargetNPT
, PVMFTimestamp& aActualNPT
, bool aSeekToSyncPoint
, OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::QueryDataSourcePosition: aTargetNPT=%d, aSeekToSyncPoint=%d, aContext=0x%x",
aTargetNPT, aSeekToSyncPoint, aContext));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_QUERY_DATASOURCE_POSITION, aTargetNPT, aActualNPT,
aSeekToSyncPoint, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::QueryDataSourcePosition(PVMFSessionId aSessionId
, PVMFTimestamp aTargetNPT
, PVMFTimestamp& aSeekPointBeforeTargetNPT
, PVMFTimestamp& aSeekPointAfterTargetNPT
, OsclAny* aContext
, bool aSeekToSyncPoint)
{
OSCL_UNUSED_ARG(aSeekPointAfterTargetNPT);
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
(0, "PVMFAMRFFParserNode::QueryDataSourcePosition: aTargetNPT=%d, aSeekToSyncPoint=%d, aContext=0x%x",
aTargetNPT, aSeekToSyncPoint, aContext));
PVMFAMRFFNodeCommand cmd;
// Construct not changed,aSeekPointBeforeTargetNPT has replace aActualtNPT
cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_QUERY_DATASOURCE_POSITION, aTargetNPT, aSeekPointBeforeTargetNPT,
aSeekToSyncPoint, aContext);
return QueueCommandL(cmd);
}
PVMFCommandId PVMFAMRFFParserNode::SetDataSourceRate(PVMFSessionId aSessionId
, int32 aRate
, PVMFTimebase* aTimebase
, OsclAny* aContext)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::SetDataSourceRate() called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommand::Construct(aSessionId, PVMF_AMR_PARSER_NODE_SET_DATASOURCE_RATE, aRate, aTimebase, aContext);
return QueueCommandL(cmd);
}
PVMFStatus PVMFAMRFFParserNode::CheckForAMRHeaderAvailability()
{
if (iDataStreamInterface != NULL)
{
/*
* First check if we have minimum number of bytes to recognize
* the file and determine the header size.
*/
uint32 currCapacity = 0;
iDataStreamInterface->QueryReadCapacity(iDataStreamSessionID,
currCapacity);
if (currCapacity < AMR_MIN_DATA_SIZE_FOR_RECOGNITION)
{
iRequestReadCapacityNotificationID =
iDataStreamInterface->RequestReadCapacityNotification(iDataStreamSessionID,
*this,
AMR_MIN_DATA_SIZE_FOR_RECOGNITION);
return PVMFPending;
}
uint32 headerSize32 =
Oscl_Int64_Utils::get_uint64_lower32(iAMRHeaderSize);
if (currCapacity < headerSize32)
{
iRequestReadCapacityNotificationID =
iDataStreamInterface->RequestReadCapacityNotification(iDataStreamSessionID,
*this,
headerSize32);
return PVMFPending;
}
}
return PVMFSuccess;
}
bool PVMFAMRFFParserNode::GetTrackInfo(PVMFPortInterface* aPort,
PVAMRFFNodeTrackPortInfo*& aTrackInfoPtr)
{
Oscl_Vector<PVAMRFFNodeTrackPortInfo, PVMFAMRParserNodeAllocator>::iterator it;
for (it = iSelectedTrackList.begin(); it != iSelectedTrackList.end(); it++)
{
if (it->iPort == aPort)
{
aTrackInfoPtr = it;
return true;
}
}
return false;
}
bool PVMFAMRFFParserNode::GetTrackInfo(int32 aTrackID,
PVAMRFFNodeTrackPortInfo*& aTrackInfoPtr)
{
Oscl_Vector<PVAMRFFNodeTrackPortInfo, PVMFAMRParserNodeAllocator>::iterator it;
for (it = iSelectedTrackList.begin(); it != iSelectedTrackList.end(); it++)
{
if (it->iTrackId == aTrackID)
{
aTrackInfoPtr = it;
return true;
}
}
return false;
}
bool PVMFAMRFFParserNode::ProcessPortActivity(PVAMRFFNodeTrackPortInfo* aTrackInfoPtr)
{
/*
* called by the AO to process a port activity message
*/
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::ProcessPortActivity() Called"));
PVMFStatus status;
if (aTrackInfoPtr->oQueueOutgoingMessages)
{
status = QueueMediaSample(aTrackInfoPtr);
if ((status != PVMFErrBusy) &&
(status != PVMFSuccess) &&
(status != PVMFErrInvalidState))
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::ProcessPortActivity() QueueMediaSample Failed - Err=%d", status));
return false;
}
if (iAutoPaused == true)
{
aTrackInfoPtr->oQueueOutgoingMessages = false;
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::QueueMediaSample() - Auto Paused"));
return PVMFErrBusy;
}
if (aTrackInfoPtr->iPort->IsOutgoingQueueBusy())
{
aTrackInfoPtr->oQueueOutgoingMessages = false;
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::QueueMediaSample() Port Outgoing Queue Busy"));
return PVMFErrBusy;
}
}
if (aTrackInfoPtr->oProcessOutgoingMessages)
{
if (aTrackInfoPtr->iPort->OutgoingMsgQueueSize() > 0)
{
status = ProcessOutgoingMsg(aTrackInfoPtr);
/*
* Report any unexpected failure in port processing...
* (the InvalidState error happens when port input is suspended,
* so don't report it.)
*/
if ((status != PVMFErrBusy) &&
(status != PVMFSuccess) &&
(status != PVMFErrInvalidState))
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFASFParserNode::ProcessPortActivity() ProcessOutgoingMsg Failed - Err=%d", status));
ReportErrorEvent(PVMFErrPortProcessing);
}
}
else
{
/* Nothing to send - wait for more data */
aTrackInfoPtr->oProcessOutgoingMessages = false;
}
}
return true;
}
bool PVMFAMRFFParserNode::CheckForPortRescheduling()
{
PVAMRFFNodeTrackPortInfo* trackInfoPtr = NULL;
if (!GetTrackInfo(iOutPort, trackInfoPtr))
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::CheckForPortRescheduling: Error - GetPortContainer failed"));
return false;
}
if ((trackInfoPtr->oProcessOutgoingMessages) ||
(trackInfoPtr->oQueueOutgoingMessages))
{
/*
* Found a port that has outstanding activity and
* is not busy.
*/
return true;
}
/*
* No port processing needed - either all port activity queues are empty
* or the ports are backed up due to flow control.
*/
return false;
}
PVMFStatus PVMFAMRFFParserNode::InitMetaData()
{
if (iAMRFileInfo.iFileSize > 0)
{
// Populate the metadata key vector based on info available
PushToAvailableMetadataKeysList(PVAMRMETADATA_NUMTRACKS_KEY);
if (iAMRFileInfo.iDuration > 0)
{
PushToAvailableMetadataKeysList(PVAMRMETADATA_DURATION_KEY);
}
if (iAMRFileInfo.iBitrate > 0)
{
PushToAvailableMetadataKeysList(PVAMRMETADATA_TRACKINFO_BITRATE_KEY);
}
if (iAMRFileInfo.iAmrFormat != EAMRUnrecognized)
{
PushToAvailableMetadataKeysList(PVAMRMETADATA_TRACKINFO_AUDIO_FORMAT_KEY);
}
PushToAvailableMetadataKeysList(PVAMRMETADATA_RANDOM_ACCESS_DENIED_KEY);
PushToAvailableMetadataKeysList(PVAMRMETADATA_CLIP_TYPE_KEY);
//set clip duration on download progress interface
//applicable to PDL sessions
{
if ((iDownloadProgressInterface != NULL) && (iAMRFileInfo.iDuration != 0))
{
iDownloadProgressInterface->setClipDuration(OSCL_CONST_CAST(uint32, iAMRFileInfo.iDuration));
}
}
return PVMFSuccess;
}
else
return PVMFFailure;
}
void PVMFAMRFFParserNode::PushToAvailableMetadataKeysList(const char* aKeystr, char* aOptionalParam)
{
if (aKeystr == NULL)
{
return;
}
int32 leavecode = 0;
if (aOptionalParam)
{
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_front(aKeystr);
iAvailableMetadataKeys[0] += aOptionalParam;);
}
else
{
OSCL_TRY(leavecode, iAvailableMetadataKeys.push_front(aKeystr));
}
}
void PVMFAMRFFParserNode::InitCPM()
{
iCPMInitCmdId = iCPM->Init();
}
void PVMFAMRFFParserNode::OpenCPMSession()
{
iCPMOpenSessionCmdId = iCPM->OpenSession(iCPMSessionID);
}
void PVMFAMRFFParserNode::CPMRegisterContent()
{
iCPMRegisterContentCmdId = iCPM->RegisterContent(iCPMSessionID,
iSourceURL,
iSourceFormat,
(OsclAny*) & iCPMSourceData);
}
void PVMFAMRFFParserNode::GetCPMLicenseInterface()
{
iCPMLicenseInterfacePVI = NULL;
iCPMGetLicenseInterfaceCmdId =
iCPM->QueryInterface(iCPMSessionID,
PVMFCPMPluginLicenseInterfaceUuid,
iCPMLicenseInterfacePVI);
}
bool PVMFAMRFFParserNode::GetCPMContentAccessFactory()
{
PVMFStatus status = iCPM->GetContentAccessFactory(iCPMSessionID,
iCPMContentAccessFactory);
if (status != PVMFSuccess)
{
return false;
}
return true;
}
bool PVMFAMRFFParserNode::GetCPMMetaDataExtensionInterface()
{
PVInterface* temp = NULL;
bool retVal =
iCPM->queryInterface(KPVMFMetadataExtensionUuid, temp);
iCPMMetaDataExtensionInterface = OSCL_STATIC_CAST(PVMFMetadataExtensionInterface*, temp);
return retVal;
}
void PVMFAMRFFParserNode::RequestUsage()
{
PopulateDRMInfo();
if (iDataStreamReadCapacityObserver != NULL)
{
iCPMContentAccessFactory->SetStreamReadCapacityObserver(iDataStreamReadCapacityObserver);
}
iCPMRequestUsageId = iCPM->ApproveUsage(iCPMSessionID,
iRequestedUsage,
iApprovedUsage,
iAuthorizationDataKvp,
iUsageID,
iCPMContentAccessFactory);
oSourceIsCurrent = true;
}
void PVMFAMRFFParserNode::PopulateDRMInfo()
{
if (iRequestedUsage.key)
{
OSCL_ARRAY_DELETE(iRequestedUsage.key);
iRequestedUsage.key = NULL;
}
if (iApprovedUsage.key)
{
OSCL_ARRAY_DELETE(iApprovedUsage.key);
iApprovedUsage.key = NULL;
}
if (iAuthorizationDataKvp.key)
{
OSCL_ARRAY_DELETE(iAuthorizationDataKvp.key);
iAuthorizationDataKvp.key = NULL;
}
if ((iCPMContentType == PVMF_CPM_FORMAT_OMA1) ||
(iCPMContentType == PVMF_CPM_FORMAT_AUTHORIZE_BEFORE_ACCESS))
{
int32 UseKeyLen = oscl_strlen(_STRLIT_CHAR(PVMF_CPM_REQUEST_USE_KEY_STRING));
int32 AuthKeyLen = oscl_strlen(_STRLIT_CHAR(PVMF_CPM_AUTHORIZATION_DATA_KEY_STRING));
int32 leavecode = 0;
OSCL_TRY(leavecode,
iRequestedUsage.key = OSCL_ARRAY_NEW(char, UseKeyLen + 1);
iApprovedUsage.key = OSCL_ARRAY_NEW(char, UseKeyLen + 1);
iAuthorizationDataKvp.key = OSCL_ARRAY_NEW(char, AuthKeyLen + 1);
);
if (leavecode || !iRequestedUsage.key || !iApprovedUsage.key || !iAuthorizationDataKvp.key)
{
if (iRequestedUsage.key)
{
OSCL_ARRAY_DELETE(iRequestedUsage.key);
iRequestedUsage.key = NULL;
}
if (iApprovedUsage.key)
{
OSCL_ARRAY_DELETE(iApprovedUsage.key);
iApprovedUsage.key = NULL;
}
if (iAuthorizationDataKvp.key)
{
OSCL_ARRAY_DELETE(iAuthorizationDataKvp.key);
iAuthorizationDataKvp.key = NULL;
}
return;
}
oscl_strncpy(iRequestedUsage.key,
_STRLIT_CHAR(PVMF_CPM_REQUEST_USE_KEY_STRING),
UseKeyLen);
iRequestedUsage.key[UseKeyLen] = 0;
iRequestedUsage.length = 0;
iRequestedUsage.capacity = 0;
if (iPreviewMode)
{
iRequestedUsage.value.uint32_value =
(BITMASK_PVMF_CPM_DRM_INTENT_PREVIEW |
BITMASK_PVMF_CPM_DRM_INTENT_PAUSE |
BITMASK_PVMF_CPM_DRM_INTENT_SEEK_FORWARD |
BITMASK_PVMF_CPM_DRM_INTENT_SEEK_BACK);
}
else
{
iRequestedUsage.value.uint32_value =
(BITMASK_PVMF_CPM_DRM_INTENT_PLAY |
BITMASK_PVMF_CPM_DRM_INTENT_PAUSE |
BITMASK_PVMF_CPM_DRM_INTENT_SEEK_FORWARD |
BITMASK_PVMF_CPM_DRM_INTENT_SEEK_BACK);
}
oscl_strncpy(iApprovedUsage.key,
_STRLIT_CHAR(PVMF_CPM_REQUEST_USE_KEY_STRING),
UseKeyLen);
iApprovedUsage.key[UseKeyLen] = 0;
iApprovedUsage.length = 0;
iApprovedUsage.capacity = 0;
iApprovedUsage.value.uint32_value = 0;
oscl_strncpy(iAuthorizationDataKvp.key,
_STRLIT_CHAR(PVMF_CPM_AUTHORIZATION_DATA_KEY_STRING),
AuthKeyLen);
iAuthorizationDataKvp.key[AuthKeyLen] = 0;
iAuthorizationDataKvp.length = 0;
iAuthorizationDataKvp.capacity = 0;
iAuthorizationDataKvp.value.pUint8_value = NULL;
}
else
{
//Error
OSCL_ASSERT(false);
}
}
void PVMFAMRFFParserNode::SendUsageComplete()
{
iCPMUsageCompleteCmdId = iCPM->UsageComplete(iCPMSessionID, iUsageID);
}
void PVMFAMRFFParserNode::CloseCPMSession()
{
iCPMCloseSessionCmdId = iCPM->CloseSession(iCPMSessionID);
}
void PVMFAMRFFParserNode::ResetCPM()
{
iCPMResetCmdId = iCPM->Reset();
}
void PVMFAMRFFParserNode::GetCPMMetaDataKeys()
{
if (iCPMMetaDataExtensionInterface != NULL)
{
iCPMMetadataKeys.clear();
iCPMGetMetaDataKeysCmdId =
iCPMMetaDataExtensionInterface->GetNodeMetadataKeys(iCPMSessionID,
iCPMMetadataKeys,
0,
PVMF_AMR_PARSER_NODE_MAX_CPM_METADATA_KEYS);
}
}
void PVMFAMRFFParserNode::CPMCommandCompleted(const PVMFCmdResp& aResponse)
{
PVMFCommandId id = aResponse.GetCmdId();
PVMFStatus status = aResponse.GetCmdStatus();
if (id == iCPMCancelGetLicenseCmdId)
{
/*
* if this command is CancelGetLicense, we will return success or fail here.
*/
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRFFParserNode::CPMCommandCompleted - CPM CancelGetLicense complete"));
OSCL_ASSERT(!iCancelCommand.empty());
CommandComplete(iCancelCommand,
iCancelCommand.front(),
status);
return;
}
//if CPM comes back as PVMFErrNotSupported then by pass rest of the CPM
//sequence. Fake success here so that node doesnt treat this as an error
else if (id == iCPMRegisterContentCmdId && status == PVMFErrNotSupported)
{
/* Unsupported format - Treat it like unprotected content */
PVMF_AMRPARSERNODE_LOGINFO((0, "PVMFAMRParserNode::CPMCommandCompleted - Unknown CPM Format - Ignoring CPM"));
if (CheckForAMRHeaderAvailability() == PVMFSuccess)
{
if (ParseAMRFile())
{
/* End of Node Init sequence. */
OSCL_ASSERT(!iCurrentCommand.empty());
OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_INIT);
CompleteInit();
}
}
return;
}
if (status != PVMFSuccess)
{
/*
* If any command fails, the sequence fails.
*/
CommandComplete(iCurrentCommand,
iCurrentCommand.front(),
aResponse.GetCmdStatus(),
NULL,
NULL,
NULL,
aResponse.GetEventExtensionInterface());
}
else
{
/*
* process the response, and issue the next command in
* the sequence.
*/
if (id == iCPMInitCmdId)
{
OpenCPMSession();
}
else if (id == iCPMOpenSessionCmdId)
{
CPMRegisterContent();
}
else if (id == iCPMRegisterContentCmdId)
{
GetCPMLicenseInterface();
}
else if (id == iCPMGetLicenseInterfaceCmdId)
{
iCPMLicenseInterface = OSCL_STATIC_CAST(PVMFCPMPluginLicenseInterface*, iCPMLicenseInterfacePVI);
iCPMLicenseInterfacePVI = NULL;
iCPMContentType = iCPM->GetCPMContentType(iCPMSessionID);
if ((iCPMContentType == PVMF_CPM_FORMAT_AUTHORIZE_BEFORE_ACCESS)
|| (iCPMContentType == PVMF_CPM_FORMAT_OMA1))
{
GetCPMContentAccessFactory();
GetCPMMetaDataExtensionInterface();
if (CheckForAMRHeaderAvailability() == PVMFSuccess)
{
if (ParseAMRFile())
{
RequestUsage();
}
}
}
else
{
/* Unsupported format - Treat it like unprotected content */
PVMF_AMRPARSERNODE_LOGINFO((0, "PVMFAMRParserNode::CPMCommandCompleted - Unknown CPM Format - Ignoring CPM"));
if (CheckForAMRHeaderAvailability() == PVMFSuccess)
{
if (ParseAMRFile())
{
OSCL_ASSERT(!iCurrentCommand.empty());
OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_INIT);
CompleteInit();
/*
* if there was any pending cancel, it was waiting on
* this command to complete-- so the cancel is now done.
*/
if (!iCancelCommand.empty())
{
CommandComplete(iCancelCommand,
iCancelCommand.front(),
PVMFSuccess);
}
}
}
}
}
else if (id == iCPMRequestUsageId)
{
oSourceIsCurrent = false;
if (aResponse.GetCmdStatus() == PVMFSuccess)
{
if (CheckForAMRHeaderAvailability() == PVMFSuccess)
{
if (ParseAMRFile())
{
OSCL_ASSERT(!iCurrentCommand.empty());
OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_INIT);
CompleteInit();
/*
* if there was any pending cancel, it was waiting on
* this command to complete-- so the cancel is now done.
*/
if (!iCancelCommand.empty())
{
CommandComplete(iCancelCommand,
iCancelCommand.front(),
PVMFSuccess);
}
}
}
}
else
{
CompleteInit();
}
}
else if (id == iCPMGetMetaDataKeysCmdId)
{
/* End of GetNodeMetaDataKeys */
PVMFStatus status =
CompleteGetMetadataKeys(iCurrentCommand.front());
CommandComplete(iCurrentCommand,
iCurrentCommand.front(),
status,
NULL,
NULL,
NULL,
NULL);
}
else if (id == iCPMUsageCompleteCmdId)
{
CloseCPMSession();
}
else if (id == iCPMCloseSessionCmdId)
{
ResetCPM();
}
else if (id == iCPMResetCmdId)
{
/* End of Node Reset sequence */
OSCL_ASSERT(!iCurrentCommand.empty());
OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_RESET);
CompleteReset();
}
else if (id == iCPMGetMetaDataValuesCmdId)
{
/* End of GetNodeMetaDataValues */
OSCL_ASSERT(!iCurrentCommand.empty());
OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_GETNODEMETADATAVALUES);
CompleteGetMetaDataValues();
}
else if (id == iCPMGetLicenseCmdId)
{
CompleteGetLicense();
}
else
{
/* Unknown cmd - error */
CommandComplete(iCurrentCommand,
iCurrentCommand.front(),
PVMFFailure);
}
}
/*
* if there was any pending cancel, it was waiting on
* this command to complete-- so the cancel is now done.
*/
if (!iCancelCommand.empty())
{
if (iCancelCommand.front().iCmd != PVMF_AMR_PARSER_NODE_CMD_CANCEL_GET_LICENSE)
{
CommandComplete(iCancelCommand,
iCancelCommand.front(),
PVMFSuccess);
}
}
}
void PVMFAMRFFParserNode::PassDatastreamFactory(PVMFDataStreamFactory& aFactory,
int32 aFactoryTag,
const PvmfMimeString* aFactoryConfig)
{
OSCL_UNUSED_ARG(aFactoryTag);
OSCL_UNUSED_ARG(aFactoryConfig);
iDataStreamFactory = &aFactory;
PVUuid uuid = PVMIDataStreamSyncInterfaceUuid;
PVInterface* iFace =
iDataStreamFactory->CreatePVMFCPMPluginAccessInterface(uuid);
if (iFace != NULL)
{
iDataStreamInterface = OSCL_STATIC_CAST(PVMIDataStreamSyncInterface*, iFace);
iDataStreamInterface->OpenSession(iDataStreamSessionID, PVDS_READ_ONLY);
}
}
void
PVMFAMRFFParserNode::PassDatastreamReadCapacityObserver(PVMFDataStreamReadCapacityObserver* aObserver)
{
iDataStreamReadCapacityObserver = aObserver;
}
void PVMFAMRFFParserNode::CompleteInit()
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::CompleteInit() Called"));
if (iCPM)
{
if ((iCPMContentType == PVMF_CPM_FORMAT_OMA1) ||
(iCPMContentType == PVMF_CPM_FORMAT_AUTHORIZE_BEFORE_ACCESS))
{
if (iApprovedUsage.value.uint32_value !=
iRequestedUsage.value.uint32_value)
{
CommandComplete(iCurrentCommand,
iCurrentCommand.front(),
PVMFErrAccessDenied,
NULL, NULL, NULL);
return;
}
}
}
SetState(EPVMFNodeInitialized);
CommandComplete(iCurrentCommand,
iCurrentCommand.front(),
PVMFSuccess);
return;
}
void PVMFAMRFFParserNode::CompleteGetMetaDataValues()
{
CommandComplete(iCurrentCommand,
iCurrentCommand.front(),
PVMFSuccess);
}
void PVMFAMRFFParserNode::setFileSize(const uint32 aFileSize)
{
iDownloadFileSize = aFileSize;
}
int32 PVMFAMRFFParserNode::convertSizeToTime(uint32 aFileSize, uint32& aNPTInMS)
{
OSCL_UNUSED_ARG(aFileSize);
OSCL_UNUSED_ARG(aNPTInMS);
return -1;
}
void PVMFAMRFFParserNode::setDownloadProgressInterface(PVMFDownloadProgressInterface* aInterface)
{
if (aInterface == NULL)
{
OSCL_ASSERT(false);
}
iDownloadProgressInterface = aInterface;
}
void PVMFAMRFFParserNode::DataStreamInformationalEvent(const PVMFAsyncEvent& aEvent)
{
OSCL_UNUSED_ARG(aEvent);
OSCL_LEAVE(OsclErrNotSupported);
}
void PVMFAMRFFParserNode::DataStreamErrorEvent(const PVMFAsyncEvent& aEvent)
{
OSCL_UNUSED_ARG(aEvent);
OSCL_LEAVE(OsclErrNotSupported);
}
void PVMFAMRFFParserNode::DataStreamCommandCompleted(const PVMFCmdResp& aResponse)
{
if (aResponse.GetCmdId() == iRequestReadCapacityNotificationID)
{
PVMFStatus cmdStatus = aResponse.GetCmdStatus();
if (cmdStatus == PVMFSuccess)
{
if (CheckForAMRHeaderAvailability() == PVMFSuccess)
{
if (iCPMContentType == PVMF_CPM_FORMAT_AUTHORIZE_BEFORE_ACCESS)
{
if (ParseAMRFile())
{
{
/* End of Node Init sequence. */
OSCL_ASSERT(!iCurrentCommand.empty());
OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_INIT);
CompleteInit();
}
}
}
else
{
if (ParseAMRFile())
{
/* End of Node Init sequence. */
OSCL_ASSERT(!iCurrentCommand.empty());
OSCL_ASSERT(iCurrentCommand.front().iCmd == PVMF_AMR_PARSER_NODE_INIT);
CompleteInit();
}
}
}
}
else
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::DataStreamCommandCompleted() Failed %d", cmdStatus));
CommandComplete(iCurrentCommand,
iCurrentCommand.front(),
PVMFErrResource);
}
}
else
{
OSCL_ASSERT(false);
}
}
void PVMFAMRFFParserNode::playResumeNotification(bool aDownloadComplete)
{
iAutoPaused = false;
iDownloadComplete = aDownloadComplete;
PVAMRFFNodeTrackPortInfo* trackInfoPtr = NULL;
if (!GetTrackInfo(iOutPort, trackInfoPtr))
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFASFParserNode::playResumeNotification: Error - GetPortContainer failed"));
return;
}
if (trackInfoPtr->oQueueOutgoingMessages == false)
{
trackInfoPtr->oQueueOutgoingMessages = true;
}
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::playResumeNotification() - Auto Resume Triggered - FileSize = %d, NPT = %d isDownloadComplete [%d]", iFileSizeLastConvertedToTime, iLastNPTCalcInConvertSizeToTime, iDownloadComplete));
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::playResumeNotification() - Auto Resume Triggered - FileSize = %d, NPT = %d", iFileSizeLastConvertedToTime, iLastNPTCalcInConvertSizeToTime));
RunIfNotReady();
}
void PVMFAMRFFParserNode::CompleteReset()
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::CompleteReset() Called"));
/* stop and cleanup */
ReleaseAllPorts();
CleanupFileSource();
SetState(EPVMFNodeIdle);
CommandComplete(iCurrentCommand, iCurrentCommand.front(), PVMFSuccess);
return;
}
PVMFStatus PVMFAMRFFParserNode::ThreadLogoff()
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::ThreadLogoff() Called"));
if (iInterfaceState == EPVMFNodeIdle)
{
CleanupFileSource();
iFileServer.Close();
if (IsAdded())
{
RemoveFromScheduler();
}
iLogger = NULL;
iDataPathLogger = NULL;
iClockLogger = NULL;
SetState(EPVMFNodeCreated);
return PVMFSuccess;
}
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::ThreadLogoff() - Invalid State"));
return PVMFErrInvalidState;
}
PVMFStatus PVMFAMRFFParserNode::QueueMediaSample(PVAMRFFNodeTrackPortInfo* aTrackInfoPtr)
{
if (iAutoPaused == true)
{
aTrackInfoPtr->oQueueOutgoingMessages = false;
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::QueueMediaSample() - Auto Paused"));
return PVMFErrBusy;
}
if (aTrackInfoPtr->iPort->IsOutgoingQueueBusy())
{
aTrackInfoPtr->oQueueOutgoingMessages = false;
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::QueueMediaSample() Port Outgoing Queue Busy"));
return PVMFErrBusy;
}
if (aTrackInfoPtr->oQueueOutgoingMessages)
{
PVMFStatus status;
if (aTrackInfoPtr->iSendBOS == true)
{
status = SendBeginOfMediaStreamCommand(aTrackInfoPtr);
return status;
}
if (aTrackInfoPtr->oEOSReached == false)
{
PVMFSharedMediaDataPtr mediaDataOut;
status = RetrieveMediaSample(aTrackInfoPtr, mediaDataOut);
if (status == PVMFErrBusy)
{
PVMF_AMRPARSERNODE_LOGINFO((0, "PVMFAMRParserNode::QueueMediaSample() RetrieveMediaSample - Mem Pools Busy"));
aTrackInfoPtr->oQueueOutgoingMessages = false;
if (iAutoPaused == true)
{
PauseAllMediaRetrieval();
}
return status;
}
else if (status == PVMFSuccess)
{
if (aTrackInfoPtr->oEOSReached == false)
{
mediaDataOut->setStreamID(iStreamID);
PVMFSharedMediaMsgPtr msgOut;
convertToPVMFMediaMsg(msgOut, mediaDataOut);
/* For logging purposes */
uint32 markerInfo = mediaDataOut->getMarkerInfo();
uint32 noRender = 0;
uint32 keyFrameBit = 0;
if (markerInfo & PVMF_MEDIA_DATA_MARKER_INFO_NO_RENDER_BIT)
{
noRender = 1;
}
if (markerInfo & PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT)
{
keyFrameBit = 1;
}
status = aTrackInfoPtr->iPort->QueueOutgoingMsg(msgOut);
if (status != PVMFSuccess)
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::QueueMediaSample: Error - QueueOutgoingMsg failed"));
ReportErrorEvent(PVMFErrPortProcessing);
}
/* This flag will get reset to false if the connected port is busy */
aTrackInfoPtr->oProcessOutgoingMessages = true;
return status;
}
}
else
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::QueueMediaSample() - Sample Retrieval Failed"));
ReportErrorEvent(PVMFErrCorrupt);
return PVMFFailure;
}
}
else
{
status = GenerateAndSendEOSCommand(aTrackInfoPtr);
return status;
}
}
return PVMFSuccess;
}
PVMFStatus PVMFAMRFFParserNode::RetrieveMediaSample(PVAMRFFNodeTrackPortInfo* aTrackInfoPtr,
PVMFSharedMediaDataPtr& aMediaDataOut)
{
// Create a data buffer from pool
int errcode = OsclErrNoResources;
OsclSharedPtr<PVMFMediaDataImpl> mediaDataImplOut;
mediaDataImplOut = aTrackInfoPtr->iResizableSimpleMediaMsgAlloc->allocate(MAXTRACKDATASIZE);
if (mediaDataImplOut.GetRep() != NULL)
{
errcode = OsclErrNone;
}
OsclMemPoolResizableAllocatorObserver* resizableAllocObs =
OSCL_STATIC_CAST(OsclMemPoolResizableAllocatorObserver*, aTrackInfoPtr);
// Enable flag to receive event when next deallocate() is called on pool
if (errcode != OsclErrNone)
{
aTrackInfoPtr->iResizableDataMemoryPool->notifyfreeblockavailable(*resizableAllocObs);
return PVMFErrBusy;
}
// Now create a PVMF media data from pool
errcode = OsclErrNoResources;
aMediaDataOut = PVMFMediaData::createMediaData(mediaDataImplOut, aTrackInfoPtr->iMediaDataMemPool);
if (aMediaDataOut.GetRep() != NULL)
{
errcode = OsclErrNone;
}
OsclMemPoolFixedChunkAllocatorObserver* fixedChunkObs =
OSCL_STATIC_CAST(OsclMemPoolFixedChunkAllocatorObserver*, aTrackInfoPtr);
// Enable flag to receive event when next deallocate() is called on pool
if (errcode != OsclErrNone)
{
aTrackInfoPtr->iMediaDataMemPool->notifyfreechunkavailable(*fixedChunkObs);
return PVMFErrBusy;
}
// Retrieve memory fragment to write to
OsclRefCounterMemFrag refCtrMemFragOut;
OsclMemoryFragment memFragOut;
aMediaDataOut->getMediaFragment(0, refCtrMemFragOut);
memFragOut.ptr = refCtrMemFragOut.getMemFrag().ptr;
Oscl_Vector<uint32, OsclMemAllocator> payloadSizeVec;
uint32 numsamples = NUM_AMR_FRAMES;
// Set up the GAU structure
GAU gau;
gau.numMediaSamples = numsamples;
gau.buf.num_fragments = 1;
gau.buf.buf_states[0] = NULL;
gau.buf.fragments[0].ptr = refCtrMemFragOut.getMemFrag().ptr;
gau.buf.fragments[0].len = refCtrMemFragOut.getCapacity();
int32 retval = iAMRParser->GetNextBundledAccessUnits(&numsamples, &gau);
uint32 actualdatasize = 0;
for (uint32 i = 0; i < numsamples; ++i)
{
actualdatasize += gau.info[i].len;
}
if (retval == bitstreamObject::EVERYTHING_OK)
{
memFragOut.len = actualdatasize;
// Set Actual size
aMediaDataOut->setMediaFragFilledLen(0, actualdatasize);
// Resize memory fragment
aTrackInfoPtr->iResizableSimpleMediaMsgAlloc->ResizeMemoryFragment(mediaDataImplOut);
// set current timestamp to media msg.
aTrackInfoPtr->iClockConverter->update_clock(Oscl_Int64_Utils::get_uint64_lower32(aTrackInfoPtr->iContinuousTimeStamp));
uint32 ts32 = Oscl_Int64_Utils::get_uint64_lower32(aTrackInfoPtr->iContinuousTimeStamp);
aMediaDataOut->setSeqNum(aTrackInfoPtr->iSeqNum);
aMediaDataOut->setTimestamp(ts32);
// update ts by adding the data samples
aTrackInfoPtr->iContinuousTimeStamp += numsamples * AMR_SAMPLE_DURATION; // i.e 20ms
if (aTrackInfoPtr->iSeqNum == 0)
{
aMediaDataOut->setFormatSpecificInfo(aTrackInfoPtr->iFormatSpecificConfig);
}
aTrackInfoPtr->iSeqNum += 1;
// Set M bit to 1 always - ASF FF only outputs complete frames
uint32 markerInfo = 0;
markerInfo |= PVMF_MEDIA_DATA_MARKER_INFO_M_BIT;
// Reset random access point if first frame after repositioning
if (aTrackInfoPtr->iFirstFrame)
{
markerInfo |= PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT;
aTrackInfoPtr->iFirstFrame = false;
}
mediaDataImplOut->setMarkerInfo(markerInfo);
}
else if (retval == bitstreamObject::DATA_INSUFFICIENT)
{
payloadSizeVec.clear();
if (iDownloadProgressInterface != NULL)
{
if (iDownloadComplete)
{
aTrackInfoPtr->oEOSReached = true;
return PVMFSuccess;
}
iDownloadProgressInterface->requestResumeNotification(aTrackInfoPtr->iContinuousTimeStamp,
iDownloadComplete);
iAutoPaused = true;
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::RetrieveMediaSample() - Auto Pause Triggered - TS=%d", aTrackInfoPtr->iContinuousTimeStamp));
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::RetrieveMediaSample() - Auto Pause Triggered - TS=%d", aTrackInfoPtr->iContinuousTimeStamp));
return PVMFErrBusy;
}
else
{
// if we recieve Insufficient data for local playback from parser library that means
// its end of track, so change track state to send end of track.
aTrackInfoPtr->oEOSReached = true;
}
}
else if (retval == bitstreamObject::END_OF_FILE)
{
aTrackInfoPtr->oEOSReached = true;
}
else
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::RetrieveMediaSample() - Sample Retrieval Failed"));
return PVMFFailure;
}
return PVMFSuccess;
}
void PVMFAMRFFParserNode::PauseAllMediaRetrieval()
{
PVAMRFFNodeTrackPortInfo* trackInfoPtr = NULL;
if (!GetTrackInfo(iOutPort, trackInfoPtr))
{
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::PauseAllMediaRetrieval: Error - GetPortContainer failed"));
return;
}
trackInfoPtr->oQueueOutgoingMessages = false;
return;
}
PVMFStatus PVMFAMRFFParserNode:: GenerateAndSendEOSCommand(PVAMRFFNodeTrackPortInfo* aTrackInfoPtr)
{
PVMF_AMRPARSERNODE_LOGSTACKTRACE((0, "PVMFAMRParserNode::GenerateAndSendEOSCommand Called"));
if (aTrackInfoPtr->iPort->IsOutgoingQueueBusy() == true)
{
/* come back later */
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRParserNode::GenerateAndSendEOSCommand: Waiting - Output Queue Busy"));
return PVMFErrBusy;
}
if ((aTrackInfoPtr->oEOSSent == false) && (aTrackInfoPtr->oEOSReached == true))
{
PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);
sharedMediaCmdPtr->setStreamID(iStreamID);
sharedMediaCmdPtr->setSeqNum(aTrackInfoPtr->iSeqNum++);
uint32 ts32 = Oscl_Int64_Utils::get_uint64_lower32(aTrackInfoPtr->iContinuousTimeStamp);
sharedMediaCmdPtr->setTimestamp(ts32);
PVMFSharedMediaMsgPtr msg;
convertToPVMFMediaCmdMsg(msg, sharedMediaCmdPtr);
PVMFStatus status = aTrackInfoPtr->iPort->QueueOutgoingMsg(msg);
if (status != PVMFSuccess)
{
ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aTrackInfoPtr->iPort));
PVMF_AMRPARSERNODE_LOGERROR((0, "PVMFAMRParserNode::GenerateAndSendEOSCommand: Error Sending EOS"));
return status;
}
aTrackInfoPtr->oEOSSent = true;
aTrackInfoPtr->oQueueOutgoingMessages = false;
aTrackInfoPtr->oProcessOutgoingMessages = true;
return (status);
}
aTrackInfoPtr->oQueueOutgoingMessages = false;
return PVMFFailure;
}
bool PVMFAMRFFParserNode::RetrieveTrackData(PVAMRFFNodeTrackPortInfo& aTrackPortInfo)
{
// Create a data buffer from pool
int errcode = 0;
OsclSharedPtr<PVMFMediaDataImpl> mediaDataImplOut;
OSCL_TRY(errcode, mediaDataImplOut = aTrackPortInfo.iMediaDataImplAlloc->allocate(MAXTRACKDATASIZE));
if (errcode != 0)
{
if (errcode == OsclErrNoResources)
{
aTrackPortInfo.iTrackDataMemoryPool->notifyfreechunkavailable(aTrackPortInfo); // Enable flag to receive event when next deallocate() is called on pool
return false;
}
else if (errcode == OsclErrNoMemory)
{
// Memory allocation for the pool failed
ReportErrorEvent(PVMFErrNoMemory, NULL);
return false;
}
else if (errcode == OsclErrArgument)
{
// Invalid parameters passed to mempool
ReportErrorEvent(PVMFErrArgument, NULL);
return false;
}
else
{
// General error
ReportErrorEvent(PVMFFailure, NULL);
return false;
}
}
// Now create a PVMF media data from pool
errcode = OsclErrNoResources;
PVMFSharedMediaDataPtr mediadataout;
mediadataout = PVMFMediaData::createMediaData(mediaDataImplOut, aTrackPortInfo.iMediaDataMemPool);
if (mediadataout.GetRep() != NULL)
{
errcode = OsclErrNone;
}
else
{
aTrackPortInfo.iMediaDataMemPool->notifyfreechunkavailable(aTrackPortInfo); // Enable flag to receive event when next deallocate() is called on pool
return false;
}
// Set the random access point flag if first frame
if (aTrackPortInfo.iFirstFrame == true)
{
uint32 markerInfo = 0;
markerInfo |= PVMF_MEDIA_DATA_MARKER_INFO_RANDOM_ACCESS_POINT_BIT;
mediaDataImplOut->setMarkerInfo(markerInfo);
aTrackPortInfo.iFirstFrame = false;
}
// Retrieve memory fragment to write to
OsclRefCounterMemFrag refCtrMemFragOut;
mediadataout->getMediaFragment(0, refCtrMemFragOut);
// Retrieve one bundle of samples from the file format parser
// Temporary retrieve 32 frames since AMR MDF needs 32 frames
uint32 numsamples = NUM_AMR_FRAMES;
// Set up the GAU structure
GAU gau;
gau.numMediaSamples = numsamples;
gau.buf.num_fragments = 1;
gau.buf.buf_states[0] = NULL;
gau.buf.fragments[0].ptr = refCtrMemFragOut.getMemFrag().ptr;
gau.buf.fragments[0].len = refCtrMemFragOut.getCapacity();
int32 retval = iAMRParser->GetNextBundledAccessUnits(&numsamples, &gau);
// Determine actual size of the retrieved data by summing each sample length in GAU
uint32 actualdatasize = 0;
for (uint32 i = 0; i < numsamples; ++i)
{
actualdatasize += gau.info[i].len;
}
if (retval == bitstreamObject::EVERYTHING_OK)
{
// Set buffer size
mediadataout->setMediaFragFilledLen(0, actualdatasize);
// Save the media data in the trackport info
aTrackPortInfo.iMediaData = mediadataout;
// Retrieve timestamp and convert to milliseconds
aTrackPortInfo.iClockConverter->update_clock(Oscl_Int64_Utils::get_uint64_lower32(aTrackPortInfo.iContinuousTimeStamp));
uint32 timestamp = Oscl_Int64_Utils::get_uint64_lower32(aTrackPortInfo.iContinuousTimeStamp);
// Set the media data's timestamp
aTrackPortInfo.iMediaData->setTimestamp(timestamp);
// compute "next" ts based on the duration of the samples that we obtained
aTrackPortInfo.iContinuousTimeStamp += numsamples * AMR_SAMPLE_DURATION; // i.e 20ms
// Set the sequence number
aTrackPortInfo.iMediaData->setSeqNum(aTrackPortInfo.iSeqNum++);
return true;
}
else if (retval == bitstreamObject::READ_ERROR)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::RetrieveTrackData() AMR Parser READ_ERROR"));
PVUuid erruuid = PVMFFileFormatEventTypesUUID;
int32 errcode = PVMFFFErrFileRead;
ReportErrorEvent(PVMFErrResource, NULL, &erruuid, &errcode);
return false;
}
else if (retval == bitstreamObject::END_OF_FILE)
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::RetrieveTrackData() AMR Parser End Of File!"));
if (SendEndOfTrackCommand(aTrackPortInfo))
{
// EOS message sent so change state
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFAMRFFParserNode::RetrieveTrackData() Sending EOS message succeeded"));
return false;
}
else
{
// EOS message could not be queued so keep in same state and try again later
PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_NOTICE, (0, "PVMFAMRFFParserNode::RetrieveTrackData() Sending EOS message failed"));
return true;
}
}
else
{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::RetrieveTrackData() AMR Parser Unknown Error!"));
PVUuid erruuid = PVMFFileFormatEventTypesUUID;
int32 errcode = PVMFFFErrInvalidData;
ReportErrorEvent(PVMFErrCorrupt, NULL, &erruuid, &errcode);
return false;
}
}
PVMFStatus PVMFAMRFFParserNode::SendBeginOfMediaStreamCommand(PVAMRFFNodeTrackPortInfo* aTrackPortInfoPtr)
{
PVMFSharedMediaCmdPtr sharedMediaCmdPtr = PVMFMediaCmd::createMediaCmd();
sharedMediaCmdPtr->setFormatID(PVMF_MEDIA_CMD_BOS_FORMAT_ID);
uint32 timestamp = Oscl_Int64_Utils::get_uint64_lower32(aTrackPortInfoPtr->iContinuousTimeStamp);
sharedMediaCmdPtr->setTimestamp(timestamp);
PVMFSharedMediaMsgPtr mediaMsgOut;
convertToPVMFMediaCmdMsg(mediaMsgOut, sharedMediaCmdPtr);
mediaMsgOut->setStreamID(iStreamID);
PVMFStatus status = aTrackPortInfoPtr->iPort->QueueOutgoingMsg(mediaMsgOut);
if (status != PVMFSuccess)
{
// Output queue is busy, so wait for the output queue being ready
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
(0, "PVMFAMRFFParserNode::SendBeginOfMediaStreamCommand: Outgoing queue busy. "));
return status;
}
aTrackPortInfoPtr->iSendBOS = false;
aTrackPortInfoPtr->oProcessOutgoingMessages = true;
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFAMRFFParserNode::SendBeginOfMediaStreamCommand() BOS Sent StreamId %d ", iStreamID));
return status;
}
PVMFCommandId
PVMFAMRFFParserNode::GetLicense(PVMFSessionId aSessionId,
OSCL_wString& aContentName,
OsclAny* aData,
uint32 aDataSize,
int32 aTimeoutMsec,
OsclAny* aContextData)
{
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRFFParserNode::GetLicense - Wide called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommand::Construct(aSessionId,
PVMF_AMR_PARSER_NODE_GET_LICENSE_W,
aContentName,
aData,
aDataSize,
aTimeoutMsec,
aContextData);
return QueueCommandL(cmd);
}
PVMFCommandId
PVMFAMRFFParserNode::GetLicense(PVMFSessionId aSessionId,
OSCL_String& aContentName,
OsclAny* aData,
uint32 aDataSize,
int32 aTimeoutMsec,
OsclAny* aContextData)
{
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRFFParserNode::GetLicense - Wide called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommand::Construct(aSessionId,
PVMF_AMR_PARSER_NODE_GET_LICENSE,
aContentName,
aData,
aDataSize,
aTimeoutMsec,
aContextData);
return QueueCommandL(cmd);
}
PVMFStatus PVMFAMRFFParserNode::DoGetLicense(PVMFAMRFFNodeCommand& aCmd,
bool aWideCharVersion)
{
if (iCPMLicenseInterface == NULL)
{
return PVMFErrNotSupported;
}
if (aWideCharVersion == true)
{
OSCL_wString* contentName = NULL;
OsclAny* data = NULL;
uint32 dataSize = 0;
int32 timeoutMsec = 0;
aCmd.PVMFAMRFFNodeCommand::Parse(contentName,
data,
dataSize,
timeoutMsec);
iCPMGetLicenseCmdId =
iCPMLicenseInterface->GetLicense(iCPMSessionID,
*contentName,
data,
dataSize,
timeoutMsec);
}
else
{
OSCL_String* contentName = NULL;
OsclAny* data = NULL;
uint32 dataSize = 0;
int32 timeoutMsec = 0;
aCmd.PVMFAMRFFNodeCommand::Parse(contentName,
data,
dataSize,
timeoutMsec);
iCPMGetLicenseCmdId =
iCPMLicenseInterface->GetLicense(iCPMSessionID,
*contentName,
data,
dataSize,
timeoutMsec);
}
return PVMFPending;
}
void PVMFAMRFFParserNode::CompleteGetLicense()
{
CommandComplete(iCurrentCommand,
iCurrentCommand.front(),
PVMFSuccess);
}
PVMFCommandId
PVMFAMRFFParserNode::CancelGetLicense(PVMFSessionId aSessionId, PVMFCommandId aCmdId, OsclAny* aContextData)
{
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRFFParserNode::CancelGetLicense - called"));
PVMFAMRFFNodeCommand cmd;
cmd.PVMFAMRFFNodeCommandBase::Construct(aSessionId, PVMF_AMR_PARSER_NODE_CMD_CANCEL_GET_LICENSE, aCmdId, aContextData);
return QueueCommandL(cmd);
}
PVMFStatus PVMFAMRFFParserNode::DoCancelGetLicense(PVMFAMRFFNodeCommand& aCmd)
{
PVMF_AMRPARSERNODE_LOGDATATRAFFIC((0, "PVMFAMRFFParserNode::DoCancelGetLicense() Called"));
PVMFStatus status = PVMFErrArgument;
if (iCPMLicenseInterface == NULL)
{
status = PVMFErrNotSupported;
}
else
{
/* extract the command ID from the parameters.*/
PVMFCommandId id;
aCmd.PVMFAMRFFNodeCommandBase::Parse(id);
/* first check "current" command if any */
PVMFAMRFFNodeCommand* cmd = iCurrentCommand.FindById(id);
if (cmd)
{
if (cmd->iCmd == PVMF_AMR_PARSER_NODE_GET_LICENSE_W || cmd->iCmd == PVMF_AMR_PARSER_NODE_GET_LICENSE)
{
iCPMCancelGetLicenseCmdId =
iCPMLicenseInterface->CancelGetLicense(iCPMSessionID, iCPMGetLicenseCmdId);
/*
* the queued commands are all asynchronous commands to the
* CPM module. CancelGetLicense can cancel only for GetLicense cmd.
* We need to wait CPMCommandCompleted.
*/
return PVMFPending;
}
}
/*
* next check input queue.
* start at element 1 since this cancel command is element 0.
*/
cmd = iInputCommands.FindById(id, 1);
if (cmd)
{
if (cmd->iCmd == PVMF_AMR_PARSER_NODE_GET_LICENSE_W || cmd->iCmd == PVMF_AMR_PARSER_NODE_GET_LICENSE)
{
/* cancel the queued command */
CommandComplete(iInputCommands, *cmd, PVMFErrCancelled);
/* report cancel success */
return PVMFSuccess;
}
}
}
/* if we get here the command isn't queued so the cancel fails */
return status;
}
int32 PVMFAMRFFParserNode::PushBackKeyVal(Oscl_Vector<PvmiKvp, OsclMemAllocator>*& aValueListPtr, PvmiKvp &aKeyVal)
{
int32 leavecode = 0;
OSCL_TRY(leavecode, (*aValueListPtr).push_back(aKeyVal));
return leavecode;
}
PVMFStatus PVMFAMRFFParserNode::PushValueToList(Oscl_Vector<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator> &aRefMetaDataKeys, PVMFMetadataList *&aKeyListPtr, uint32 aLcv)
{
int32 leavecode = 0;
OSCL_TRY(leavecode, aKeyListPtr->push_back(aRefMetaDataKeys[aLcv]));
OSCL_FIRST_CATCH_ANY(leavecode, PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFAMRFFParserNode::PushValueToList() Memory allocation failure when copying metadata key")); return PVMFErrNoMemory);
return PVMFSuccess;
}