1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2010 PacketVideo
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
18 #include "pvmf_omx_audiodec_node.h"
19 #include "oscl_string_utils.h"
21 #define CONFIG_SIZE_AND_VERSION(param) \
22 param.nSize=sizeof(param); \
23 param.nVersion.s.nVersionMajor = SPECVERSIONMAJOR; \
24 param.nVersion.s.nVersionMinor = SPECVERSIONMINOR; \
25 param.nVersion.s.nRevision = SPECREVISION; \
26 param.nVersion.s.nStep = SPECSTEP;
30 #define PVOMXAUDIODEC_MEDIADATA_POOLNUM 2*NUMBER_OUTPUT_BUFFER
31 #define PVOMXAUDIODEC_MEDIADATA_CHUNKSIZE 128
34 // Node default settings
36 #define PVOMXAUDIODECNODE_CONFIG_MIMETYPE_DEF 0
38 #define PVMF_OMXAUDIODEC_NUM_METADATA_VALUES 6
42 // Constant character strings for metadata keys
43 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY[] = "codec-info/audio/format";
44 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY[] = "codec-info/audio/channels";
45 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY[] = "codec-info/audio/sample-rate";
46 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_AVGBITRATE_KEY[] = "codec-info/audio/avgbitrate";
47 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_AACOBJECTTYPE_KEY[] = "codec-info/audio/aac-objecttype";
48 static const char PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_AACSTREAMTYPE_KEY[] = "codec-info/audio/aac-streamtype";
51 static const char PVOMXAUDIODECMETADATA_SEMICOLON[] = ";";
53 /////////////////////////////////////////////////////////////////////////////
55 /////////////////////////////////////////////////////////////////////////////
56 PVMFOMXAudioDecNode::~PVMFOMXAudioDecNode()
60 iGaplessLogger = NULL;
64 PVMFOMXAudioDecNode::PVMFOMXAudioDecNode(int32 aPriority) :
65 PVMFOMXBaseDecNode(aPriority, "PVMFOMXAudioDecNode")
67 iInterfaceState = EPVMFNodeCreated;
69 iNodeConfig.iMimeType = PVOMXAUDIODECNODE_CONFIG_MIMETYPE_DEF;
75 //Create the input command queue. Use a reserve to avoid lots of
76 //dynamic memory allocation.
77 iInputCommands.Construct(PVMF_OMXBASEDEC_NODE_COMMAND_ID_START, PVMF_OMXBASEDEC_NODE_COMMAND_VECTOR_RESERVE);
79 //Set the node capability data.
80 //This node can support an unlimited number of ports.
81 iCapability.iCanSupportMultipleInputPorts = false;
82 iCapability.iCanSupportMultipleOutputPorts = false;
83 iCapability.iHasMaxNumberOfPorts = true;
84 iCapability.iMaxNumberOfPorts = 2;
85 iCapability.iInputFormatCapability.push_back(PVMF_MIME_MPEG4_AUDIO);
86 iCapability.iInputFormatCapability.push_back(PVMF_MIME_3640);
87 iCapability.iInputFormatCapability.push_back(PVMF_MIME_ADIF);
88 iCapability.iInputFormatCapability.push_back(PVMF_MIME_LATM);
89 iCapability.iInputFormatCapability.push_back(PVMF_MIME_ASF_MPEG4_AUDIO);
90 iCapability.iInputFormatCapability.push_back(PVMF_MIME_AAC_SIZEHDR);
92 iCapability.iInputFormatCapability.push_back(PVMF_MIME_AMR_IF2);
93 iCapability.iInputFormatCapability.push_back(PVMF_MIME_AMR_IETF);
94 iCapability.iInputFormatCapability.push_back(PVMF_MIME_AMR);
95 iCapability.iInputFormatCapability.push_back(PVMF_MIME_AMRWB_IETF);
96 iCapability.iInputFormatCapability.push_back(PVMF_MIME_AMRWB);
98 iCapability.iInputFormatCapability.push_back(PVMF_MIME_MP3);
100 iCapability.iInputFormatCapability.push_back(PVMF_MIME_WMA);
102 iCapability.iInputFormatCapability.push_back(PVMF_MIME_REAL_AUDIO);
104 iCapability.iOutputFormatCapability.push_back(PVMF_MIME_PCM16);
106 iAvailableMetadataKeys.reserve(PVMF_OMXAUDIODEC_NUM_METADATA_VALUES);
107 iAvailableMetadataKeys.clear();
111 iLATMConfigBuffer = NULL;
112 iLATMConfigBufferSize = 0;
114 iCountSamplesInBuffer = false;
115 iBufferContainsIntFrames = true;
117 iComputeSamplesPerFrame = true;
119 // This default value can be changed using cap-config
120 iOutputBufferPCMDuration = PVOMXAUDIODEC_DEFAULT_OUTPUTPCM_TIME; // set PCM buffer duration to default (200ms)
123 //Try Allocate FSI buffer
125 // Do This first in case of Query
126 OSCL_TRY(err, iFsiFragmentAlloc.size(PVOMXAUDIODEC_MEDIADATA_POOLNUM, sizeof(channelSampleInfo)));
129 OSCL_TRY(err, iPrivateDataFsiFragmentAlloc.size(PVOMXAUDIODEC_MEDIADATA_POOLNUM, sizeof(OsclAny *)));
131 iLogger = PVLogger::GetLoggerObject("PVMFOMXAudioDecNode");
132 iRunlLogger = PVLogger::GetLoggerObject("Run.PVMFOMXAudioDecNode");
133 iDataPathLogger = PVLogger::GetLoggerObject("datapath");
134 iClockLogger = PVLogger::GetLoggerObject("clock");
135 iDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.decnode.OMXAudioDecnode");
136 iGaplessLogger = PVLogger::GetLoggerObject("gapless.decnode");
140 // this is a utility possibly called multiple times by ProcessIncomingMsg method
141 // it returns PVMFSuccess if the msg is a cmd msg and is processed
142 // PVMFFailure if the msg is a cmd msg, but cannot be processed correctly
143 // PVMFPending if the msg is a data msg
144 PVMFStatus PVMFOMXAudioDecNode::CheckIfIncomingMsgIsCmd(PVMFSharedMediaMsgPtr msg)
147 PVMFStatus status = PVMFPending; // assume this is a data message
149 if (msg->getFormatID() == PVMF_MEDIA_CMD_BOS_FORMAT_ID)
151 //store the stream id and time stamp of bos message
152 iStreamID = msg->getStreamID();
153 iCurrentClipId = msg->getClipID();
155 iClipSampleCount = 0;
159 // if new BOS arrives, and
160 //if we're in the middle of a partial frame assembly
161 // abandon it and start fresh
162 if (iObtainNewInputBuffer == false)
164 if (iInputBufferUnderConstruction != NULL)
166 if (iInBufMemoryPool != NULL)
168 iInBufMemoryPool->deallocate((OsclAny *)(iInputBufferUnderConstruction->pMemPoolEntry));
170 iInputBufferUnderConstruction = NULL;
172 iObtainNewInputBuffer = true;
176 // needed to init the sequence numbers and timestamp for partial frame assembly
177 iFirstDataMsgAfterBOS = true;
178 iKeepDroppingMsgsUntilMarkerBit = false;
180 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
181 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: Received BOS stream %d, clipId %d", iStreamID, iCurrentClipId));
183 status = PVMFSuccess;
185 else if (msg->getFormatID() == PVMF_MEDIA_CMD_EOS_FORMAT_ID)
188 iEndOfDataReached = true;
189 // Save the timestamp for the EOS cmd
190 iEndOfDataTimestamp = msg->getTimestamp();
191 iCurrentClipId = msg->getClipID();
193 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
194 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: Received EOS clipId %d", iCurrentClipId));
197 status = PVMFSuccess;
199 else if (msg->getFormatID() == PVMF_MEDIA_CMD_BOC_FORMAT_ID)
201 // get pointer to the data fragment
202 OsclRefCounterMemFrag DataFrag;
203 msg->getFormatSpecificInfo(DataFrag);
205 // get format specific info
206 BOCInfo* bocInfoPtr = (BOCInfo*)DataFrag.getMemFragPtr();
207 int32 bocInfoSize = (int32)DataFrag.getMemFragSize();
208 OSCL_UNUSED_ARG(bocInfoSize); // bocInfoSize is used only for logging
209 if (bocInfoPtr == NULL)
211 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
212 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: Received BOC, memFragPtr %x, memFragSize %d, but memFragPtr is NULL",
213 bocInfoPtr, bocInfoSize));
218 iBOCSamplesToSkip = bocInfoPtr->samplesToSkip;
219 iBOCTimeStamp = msg->getTimestamp();
222 if (iNodeConfig.iMimeType == PVMF_MIME_MP3)
224 iBOCSamplesToSkip += MP3_DECODER_DELAY;
227 CalculateBOCParameters();
229 // only count samples if there is gapless metadata (i.e. BOC is sent)
230 iCountSamplesInBuffer = true;
231 iClipSampleCount = 0;
233 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
234 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: Received BOC, memFragPtr %x, memFragSize %d, samplesToSkipBOC %d",
235 bocInfoPtr, bocInfoSize, bocInfoPtr->samplesToSkip));
237 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iGaplessLogger, PVLOGMSG_INFO,
238 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg() Gapless BOC, bocInfoPtr->samplesToSkip %d, iBOCSamplesToSkip %d",
239 bocInfoPtr->samplesToSkip, iBOCSamplesToSkip));
241 status = PVMFSuccess;
243 else if (msg->getFormatID() == PVMF_MEDIA_CMD_EOC_FORMAT_ID)
245 // get pointer to the data fragment
246 OsclRefCounterMemFrag DataFrag;
247 msg->getFormatSpecificInfo(DataFrag);
249 // get format specific info
250 EOCInfo* eocInfoPtr = (EOCInfo*)DataFrag.getMemFragPtr();
251 int32 eocInfoSize = (int32)DataFrag.getMemFragSize();
252 OSCL_UNUSED_ARG(eocInfoSize); // eocInfoSize is used only for logging
254 if (eocInfoPtr == NULL)
256 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
257 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: Received EOC, memFragPtr %x, memFragSize %d, but memFragPtr is NULL",
258 eocInfoPtr, eocInfoSize));
263 iEOCSamplesToSkip = eocInfoPtr->samplesToSkip;
264 iEOCFramesToFollow = eocInfoPtr->framesToFollow;
265 iEOCTimeStamp = msg->getTimestamp();
268 if (iNodeConfig.iMimeType == PVMF_MIME_MP3)
270 iEOCSamplesToSkip -= OSCL_MIN(MP3_DECODER_DELAY, iEOCSamplesToSkip);
273 CalculateEOCParameters();
275 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
276 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: Received EOC, memFragPtr %x, memFragSize %d, framesToFollowEOC % d, samplesToSkipEOC %d",
277 eocInfoPtr, eocInfoSize, eocInfoPtr->samplesToSkip, eocInfoPtr->framesToFollow));
279 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iGaplessLogger, PVLOGMSG_INFO,
280 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg() Gapless EOC, framesToFollowEOC %d, eocInfoPtr->samplesToSkip %d, iEOCSamplesToSkip %d",
281 iEOCFramesToFollow, eocInfoPtr->samplesToSkip, iEOCSamplesToSkip));
284 status = PVMFSuccess;
290 /////////////////////////////////////////////////////////////////////////////
291 // This routine will process incomming message from the port
292 /////////////////////////////////////////////////////////////////////////////
293 bool PVMFOMXAudioDecNode::ProcessIncomingMsg(PVMFPortInterface* aPort)
295 //Called by the AO to process one buffer off the port's
296 //incoming data queue. This routine will dequeue and
299 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
300 (0, "0x%x PVMFOMXAudioDecNode::ProcessIncomingMsg: aPort=0x%x", this, aPort));
302 PVMFStatus status = PVMFFailure;
303 #ifdef SIMULATE_DROP_MSGS
304 if ((((PVMFOMXDecPort*)aPort)->iNumFramesConsumed % 300 == 299)) // && (((PVMFOMXDecPort*)aPort)->iNumFramesConsumed < 30) )
308 PVMFSharedMediaMsgPtr msg;
310 status = aPort->DequeueIncomingMsg(msg);
311 ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
312 status = aPort->DequeueIncomingMsg(msg);
313 ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
314 status = aPort->DequeueIncomingMsg(msg);
315 ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
318 printf("PVMFOMXAudioDecNode::ProcessIncomingMsg() SIMULATED DROP 3 MSGS\n");
327 if ((((PVMFOMXDecPort*)aPort)->iNumFramesConsumed == 6))
330 PVMFSharedMediaCmdPtr BOSCmdPtr = PVMFMediaCmd::createMediaCmd();
332 // Set the format ID to BOS
333 BOSCmdPtr->setFormatID(PVMF_MEDIA_CMD_BOS_FORMAT_ID);
336 BOSCmdPtr->setTimestamp(201);
337 BOSCmdPtr->setStreamID(0);
339 // Convert to media message and send it out
340 PVMFSharedMediaMsgPtr mediaMsgOut;
341 convertToPVMFMediaCmdMsg(mediaMsgOut, BOSCmdPtr);
343 //store the stream id bos message
344 iStreamID = mediaMsgOut->getStreamID();
349 printf("PVMFOMXAudioDecNode::ProcessIncomingMsg() SIMULATED BOS\n");
351 ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
357 #ifdef SIMULATE_PREMATURE_EOS
358 if (((PVMFOMXDecPort*)aPort)->iNumFramesConsumed == 5)
360 PVMFSharedMediaCmdPtr EOSCmdPtr = PVMFMediaCmd::createMediaCmd();
362 // Set the format ID to EOS
363 EOSCmdPtr->setFormatID(PVMF_MEDIA_CMD_EOS_FORMAT_ID);
366 EOSCmdPtr->setTimestamp(200);
368 // Convert to media message and send it out
369 PVMFSharedMediaMsgPtr mediaMsgOut;
370 convertToPVMFMediaCmdMsg(mediaMsgOut, EOSCmdPtr);
372 ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
374 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
375 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: SIMULATED EOS"));
377 printf("PVMFOMXAudioDecNode::ProcessIncomingMsg() SIMULATED EOS\n");
380 iEndOfDataReached = true;
381 // Save the timestamp for the EOS cmd
382 iEndOfDataTimestamp = mediaMsgOut->getTimestamp();
391 PVMFSharedMediaMsgPtr msg;
393 status = aPort->DequeueIncomingMsg(msg);
394 if (status != PVMFSuccess)
396 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
397 (0, "0x%x PVMFOMXAudioDecNode::ProcessIncomingMsg: Error - DequeueIncomingMsg failed", this));
402 // check if incoming msg is a cmd msg
403 status = CheckIfIncomingMsgIsCmd(msg);
404 if (PVMFSuccess == status)
406 // if a cmd msg, it was processed inside a helper method above
407 ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
410 else if (PVMFFailure == status)
412 // something went wrong when processing the msg
416 // if we end up here, the msg is a data message
420 ///////////////////////////////////////////////////////////////////////////////////////
421 ///////////////////////////////////////////////////////////////////////
422 // For LATM data, need to convert to raw bitstream
423 if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM)
425 // Keep looping and parsing LATM data until frame complete or data queue runs out
426 uint8 retval; //=FRAME_INCOMPLETE;
427 // if LATM parser does not exist (very first frame), create it:
428 if (iLATMParser == NULL)
430 // Create and configure the LATM parser based on the stream MUX config
431 // which should be sent as the format specific config in the first media data
432 if (CreateLATMParser() != PVMFSuccess)
435 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
436 (0, "PVMFOMXAudioDecNode::Process Incoming Msg - LATM parser cannot be created"));
438 ReportErrorEvent(PVMFErrResourceConfiguration);
439 ChangeNodeState(EPVMFNodeError);
444 OsclRefCounterMemFrag DataFrag;
445 msg->getFormatSpecificInfo(DataFrag);
447 //get pointer to the data fragment
448 uint8* initbuffer = (uint8 *) DataFrag.getMemFragPtr();
449 uint32 initbufsize = (int32) DataFrag.getMemFragSize();
451 iLATMConfigBufferSize = initbufsize;
452 iLATMConfigBuffer = iLATMParser->ParseStreamMuxConfig(initbuffer, (int32 *) & iLATMConfigBufferSize);
453 if (iLATMConfigBuffer == NULL)
455 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
456 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg() LATM Stream MUX config parsing failed"));
458 ReportErrorEvent(PVMFErrResourceConfiguration);
459 ChangeNodeState(EPVMFNodeError);
468 // if we end up here, the msg is a data message
470 // Convert the next input media msg to media data
471 PVMFSharedMediaDataPtr mediaData;
472 convertToPVMFMediaData(mediaData, msg);
475 ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
477 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iDataPathLogger, PVLOGMSG_INFO,
478 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: TS=%d, SEQNUM= %d", msg->getTimestamp(), msg->getSeqNum()));
481 // Convert the LATM data to raw bitstream
482 retval = iLATMParser->compose(mediaData);
484 // if frame is complete, break out of the loop
485 if (retval != FRAME_INCOMPLETE && retval != FRAME_ERROR)
489 if (retval == FRAME_ERROR)
491 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
492 (0, "PVMFAACDecNode::GetInputMediaData() LATM parser error"));
495 // frame is not complete, keep looping
496 if (aPort->IncomingMsgQueueSize() == 0)
498 // no more data in the input port queue, unbind current msg, and return
500 // enable reading more data from port
506 aPort->DequeueIncomingMsg(msg); // dequeue the message directly from input port
510 // check if incoming msg is a cmd msg
511 status = CheckIfIncomingMsgIsCmd(msg);
512 if (PVMFSuccess == status)
514 // if a cmd msg, it was processed inside a helper method above
515 ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
518 else if (PVMFFailure == status)
520 // something went wrong when processing the msg
525 while ((retval == FRAME_INCOMPLETE || retval == FRAME_ERROR));
527 if (retval == FRAME_COMPLETE)
529 // Save the media data containing the parser data as the input media data
530 iDataIn = iLATMParser->GetOutputBuffer();
531 // set the MARKER bit on the data msg, since this is a complete frame produced by LATM parser
532 iDataIn->setMarkerInfo(PVMF_MEDIA_DATA_MARKER_INFO_M_BIT);
533 PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO,
534 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: - LATM frame assembled"));
537 else if ((retval == FRAME_INCOMPLETE) || (retval == FRAME_ERROR))
539 // Do nothing and wait for more data to come in
540 PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO,
541 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: - incomplete LATM"));
542 // return immediately (i.e. don't assign anything to iDataIn, which will prevent
546 else if (retval == FRAME_OUTPUTNOTAVAILABLE)
548 // This should not happen since this node processes one parsed media data at a time
549 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
550 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: LATM parser OUTPUT NOT AVAILABLE"));
555 ReportErrorEvent(PVMFErrResourceConfiguration);
556 ChangeNodeState(EPVMFNodeError);
561 /////////////////////////////////////////////////////////
562 //////////////////////////
565 // regular (i.e. Non-LATM case)
566 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iDataPathLogger, PVLOGMSG_INFO,
567 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: TS=%d, SEQNUM= %d", msg->getTimestamp(), msg->getSeqNum()));
569 if (iFirstDataMsgAfterBOS)
571 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iDataPathLogger, PVLOGMSG_INFO,
572 (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg: iTSOfFirstDataMsgAfterBOS = %d", msg->getTimestamp()));
573 iTSOfFirstDataMsgAfterBOS = msg->getTimestamp();
574 iInputTimestampClock.set_clock(iTSOfFirstDataMsgAfterBOS, 0);
576 convertToPVMFMediaData(iDataIn, msg);
577 ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed++;
580 iCurrFragNum = 0; // for new message, reset the fragment counter
581 iIsNewDataFragment = true;
584 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::ProcessIncomingMsg() Received %d frames", ((PVMFOMXDecPort*)aPort)->iNumFramesConsumed));
586 //return true if we processed an activity...
590 /////////////////////////////////////////////////////////////////////////////
591 // This routine will handle the PortReEnable state
592 /////////////////////////////////////////////////////////////////////////////
593 PVMFStatus PVMFOMXAudioDecNode::HandlePortReEnable()
596 // set the port index so that we get parameters for the proper port
597 iParamPort.nPortIndex = iPortIndexForDynamicReconfig;
599 CONFIG_SIZE_AND_VERSION(iParamPort);
601 // get new parameters of the port
602 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
603 if (Err != OMX_ErrorNone)
605 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
606 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Problem getting parameters at port %d", iPortIndexForDynamicReconfig));
608 SetState(EPVMFNodeError);
609 ReportErrorEvent(PVMFErrResource);
610 return PVMFErrResource;
613 // send command for port re-enabling (for this to happen, we must first recreate the buffers)
614 Err = OMX_SendCommand(iOMXDecoder, OMX_CommandPortEnable, iPortIndexForDynamicReconfig, NULL);
615 if (Err != OMX_ErrorNone)
617 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
618 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> problem sending Port Enable command at port %d", iPortIndexForDynamicReconfig));
620 SetState(EPVMFNodeError);
621 ReportErrorEvent(PVMFErrResource);
622 return PVMFErrResource;
626 // get also input info (for frame duration if necessary)
627 OMX_PTR CodecProfilePtr;
628 OMX_INDEXTYPE CodecProfileIndx;
629 OMX_AUDIO_PARAM_AACPROFILETYPE Audio_Aac_Param;
630 OMX_AUDIO_PARAM_RATYPE Audio_Ra_Param;
632 // determine the proper index and structure (based on codec type)
636 if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MPEG4_AUDIO ||
637 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640 ||
638 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM ||
639 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF ||
640 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ASF_MPEG4_AUDIO ||
641 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AAC_SIZEHDR) // for testing
643 CodecProfilePtr = (OMX_PTR) & Audio_Aac_Param;
644 CodecProfileIndx = OMX_IndexParamAudioAac;
645 Audio_Aac_Param.nPortIndex = iInputPortIndex;
647 CONFIG_SIZE_AND_VERSION(Audio_Aac_Param);
651 Err = OMX_GetParameter(iOMXDecoder, CodecProfileIndx, CodecProfilePtr);
652 if (Err != OMX_ErrorNone)
654 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
655 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Input port parameters problem"));
657 SetState(EPVMFNodeError);
658 ReportErrorEvent(PVMFErrResource);
659 return PVMFErrResource;
662 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_REAL_AUDIO)
664 CodecProfilePtr = (OMX_PTR) & Audio_Ra_Param;
665 CodecProfileIndx = OMX_IndexParamAudioRa;
666 Audio_Ra_Param.nPortIndex = iInputPortIndex;
668 CONFIG_SIZE_AND_VERSION(Audio_Ra_Param);
672 Err = OMX_GetParameter(iOMXDecoder, CodecProfileIndx, CodecProfilePtr);
673 if (Err != OMX_ErrorNone)
675 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
676 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Input port parameters problem"));
678 SetState(EPVMFNodeError);
679 ReportErrorEvent(PVMFErrResource);
680 return PVMFErrResource;
683 // for AMR, frame sizes are known, no need to get the parameters
684 // for MP3, frame sizes cannot be obtained through OMX params
685 // for WMA, frame sizes cannot be obtained through OMX params
690 PVMFFormatType Format = PVMF_MIME_FORMAT_UNKNOWN;
693 Format = ((PVMFOMXDecPort*)iInPort)->iFormat;
695 if (Format == PVMF_MIME_MPEG4_AUDIO ||
696 Format == PVMF_MIME_3640 ||
697 Format == PVMF_MIME_LATM ||
698 Format == PVMF_MIME_ADIF ||
699 Format == PVMF_MIME_ASF_MPEG4_AUDIO ||
700 Format == PVMF_MIME_AAC_SIZEHDR) // for testing
702 iSamplesPerFrame = Audio_Aac_Param.nFrameLength;
705 else if (Format == PVMF_MIME_AMR_IF2 ||
706 Format == PVMF_MIME_AMR_IETF ||
707 Format == PVMF_MIME_AMR)
709 // AMR NB has fs=8khz Mono and the frame is 20ms long, i.e. there is 160 samples per frame
710 iSamplesPerFrame = PVOMXAUDIODEC_AMRNB_SAMPLES_PER_FRAME;
712 else if (Format == PVMF_MIME_AMRWB_IETF ||
713 Format == PVMF_MIME_AMRWB)
715 // AMR WB has fs=16khz Mono and the frame is 20ms long, i.e. there is 320 samples per frame
716 iSamplesPerFrame = PVOMXAUDIODEC_AMRWB_SAMPLES_PER_FRAME;
718 else if (Format == PVMF_MIME_MP3)
720 // frame size is either 576 or 1152 samples per frame. However, this information cannot be
721 // obtained through OMX MP3 Params. Assume that it's 1152
722 iSamplesPerFrame = PVOMXAUDIODEC_MP3_DEFAULT_SAMPLES_PER_FRAME;
724 else if (Format == PVMF_MIME_WMA)
726 // output frame size is unknown in WMA. However, the PV-WMA decoder can control the number
727 // of samples it places in an output buffer, so we can create an output buffer of arbitrary size
728 // and let the decoder control how it is filled
729 iSamplesPerFrame = 0; // unknown
731 else if (Format == PVMF_MIME_REAL_AUDIO)
733 iSamplesPerFrame = Audio_Ra_Param.nSamplePerFrame;
737 // is this output port?
738 if (iPortIndexForDynamicReconfig == iOutputPortIndex)
741 // GET the output buffer params and sizes
742 OMX_AUDIO_PARAM_PCMMODETYPE Audio_Pcm_Param;
743 Audio_Pcm_Param.nPortIndex = iOutputPortIndex; // we're looking for output port params
745 CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
749 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
750 if (Err != OMX_ErrorNone)
752 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
753 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot get component output parameters"));
755 SetState(EPVMFNodeError);
756 ReportErrorEvent(PVMFErrResource);
757 return PVMFErrResource;
760 iPCMSamplingRate = Audio_Pcm_Param.nSamplingRate; // can be set to 0 (if unknown)
762 if (iPCMSamplingRate == 0) // use default sampling rate (i.e. 48000)
763 iPCMSamplingRate = PVOMXAUDIODEC_DEFAULT_SAMPLINGRATE;
765 iNumberOfAudioChannels = Audio_Pcm_Param.nChannels; // should be 1 or 2
766 if (iNumberOfAudioChannels != 1 && iNumberOfAudioChannels != 2)
768 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
769 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Output parameters num channels = %d", iNumberOfAudioChannels));
771 SetState(EPVMFNodeError);
772 ReportErrorEvent(PVMFErrResource);
773 return PVMFErrResource;
776 if ((iSamplesPerFrame != 0) && ((iSamplesPerFrame * 1000) > iPCMSamplingRate))
777 // if this iSamplesPerFrame is known and is large enough to ensure that the iMilliSecPerFrame calculation
778 // below won't be set to 0.
780 // CALCULATE NumBytes per frame, Msec per frame, etc.
781 iNumBytesPerFrame = 2 * iSamplesPerFrame * iNumberOfAudioChannels;
782 iMilliSecPerFrame = (iSamplesPerFrame * 1000) / iPCMSamplingRate;
783 // Determine the size of each PCM output buffer. Size would be big enough to hold certain time amount of PCM data
784 uint32 numframes = iOutputBufferPCMDuration / iMilliSecPerFrame;
786 if (iOutputBufferPCMDuration % iMilliSecPerFrame)
788 // If there is a remainder, include one more frame
792 // set the output buffer size accordingly:
793 iOMXComponentOutputBufferSize = numframes * iNumBytesPerFrame;
796 iOMXComponentOutputBufferSize = (2 * iNumberOfAudioChannels * iOutputBufferPCMDuration * iPCMSamplingRate) / 1000; // assuming 16 bits per sample
798 if (iOMXComponentOutputBufferSize < iParamPort.nBufferSize)
800 // the OMX spec says that nBuffersize is a read only field, but the client is allowed to allocate
801 // a buffer size larger than nBufferSize.
802 iOMXComponentOutputBufferSize = iParamPort.nBufferSize;
806 CalculateBOCParameters();
809 CalculateEOCParameters();
811 // read the alignment again - just in case
812 iOutputBufferAlignment = iParamPort.nBufferAlignment;
814 iNumOutputBuffers = iParamPort.nBufferCountActual;
816 if (iNumOutputBuffers > NUMBER_OUTPUT_BUFFER)
817 iNumOutputBuffers = NUMBER_OUTPUT_BUFFER; // make sure number of output buffers is not larger than port queue size
819 // do we need to increase the number of buffers?
820 if (iNumOutputBuffers < iParamPort.nBufferCountMin)
821 iNumOutputBuffers = iParamPort.nBufferCountMin;
823 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
824 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() new output buffers %d, size %d", iNumOutputBuffers, iOMXComponentOutputBufferSize));
826 // assume that the following will fail (it's a special type of buffer allocator). If so - we'd need to
827 // send the FSI at a later time.
829 iCompactFSISettingSucceeded = false;
831 //Try querying the buffer allocator KVP for output buffer allocation outside of the node
832 PvmiKvp* pkvp = NULL;
834 PvmiKeyType aKvpIdentifier = (PvmiKeyType)PVMF_SUPPORT_FOR_BUFFER_ALLOCATOR_IN_MIO_KEY;
835 // Check if Fsi configuration need to be sent
836 // Send it only if the MIO supports the buffer allocator
837 if (((PVMFOMXDecPort*)iOutPort)->pvmiGetBufferAllocatorSpecificInfoSync(aKvpIdentifier, pkvp, NumKvp) == PVMFSuccess)
839 //Send the FSI information to media output node here, before setting output
840 //port parameters to the omx component
841 int fsiErrorCode = 0;
842 OsclRefCounterMemFrag FsiMemfrag;
844 OSCL_TRY(fsiErrorCode, FsiMemfrag = iFsiFragmentAlloc.get(););
846 OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
847 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Failed to allocate memory for FSI")));
849 if (fsiErrorCode == 0)
851 channelSampleInfo* pcminfo = (channelSampleInfo*) FsiMemfrag.getMemFragPtr();
855 OSCL_ASSERT(pcminfo != NULL);
857 pcminfo->samplingRate = iPCMSamplingRate;
858 pcminfo->desiredChannels = iNumberOfAudioChannels;
859 pcminfo->bitsPerSample = 16;
860 pcminfo->num_buffers = iNumOutputBuffers;
861 pcminfo->buffer_size = iOMXComponentOutputBufferSize;
863 OsclMemAllocator alloc;
864 int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY_PCM) + 1;
865 PvmiKeyType KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength);
872 oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY_PCM, KeyLength);
875 OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(FsiMemfrag, KvpKey););
877 if (err != OsclErrNone)
879 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
880 (0, "PVMFOMXAudioDecNode::HandlePortReEnable - Problem to set FSI"));
884 // FSI setting succeeded. No need to repeat it later
886 iCompactFSISettingSucceeded = true;
889 alloc.deallocate((OsclAny*)(KvpKey));
893 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
894 (0, "PVMFOMXAudioDecNode::HandlePortReEnable - Problem allocating Output FSI"));
895 SetState(EPVMFNodeError);
896 ReportErrorEvent(PVMFErrNoMemory);
897 return false; // this is going to make everything go out of scope
902 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
903 (0, "PVMFOMXAudioDecNode::HandlePortReEnable - Problem allocating Output FSI"));
904 return false; // this is going to make everything go out of scope
910 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_WARNING,
911 (0, "PVMFOMXAudioDecNode::HandlePortReEnable Warning- It is OK for this KVP to fail"
912 "Do NOT attempt to fix the failure in the MIO unless you absolutely want to implement"
913 "the MIO BUFFER ALLOCATOR - see documentation"));
916 ReportInfoEvent(PVMFPvmiBufferAllocatorNotAcquired);
919 //Buffer allocator kvp query and allocation has to be done again if we landed into handle port reconfiguration
923 PvmiKeyType aIdentifier = (PvmiKeyType)PVMF_BUFFER_ALLOCATOR_KEY;
925 if (ipExternalOutputBufferAllocatorInterface)
927 ipExternalOutputBufferAllocatorInterface->removeRef();
928 ipExternalOutputBufferAllocatorInterface = NULL;
931 OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiGetBufferAllocatorSpecificInfoSync(aIdentifier, kvp, numKvp););
933 if ((err == OsclErrNone) && (NULL != kvp))
935 ipExternalOutputBufferAllocatorInterface = (PVInterface *)kvp->value.key_specific_value;
937 if (ipExternalOutputBufferAllocatorInterface)
939 PVInterface* pTempPVInterfacePtr = NULL;
940 OSCL_TRY(err, ipExternalOutputBufferAllocatorInterface->queryInterface(PVMFFixedSizeBufferAllocUUID, pTempPVInterfacePtr););
942 OSCL_TRY(err1, ((PVMFOMXDecPort*)iOutPort)->releaseParametersSync(kvp, numKvp););
944 if (err1 != OsclErrNone)
946 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
947 (0, "PVMFOMXAudioDecNode::HandlePortReEnable - Unable to Release Parameters"));
950 if ((err == OsclErrNone) && (NULL != pTempPVInterfacePtr))
952 ipFixedSizeBufferAlloc = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, pTempPVInterfacePtr);
954 uint32 iNumBuffers, iBufferSize;
956 iNumBuffers = ipFixedSizeBufferAlloc->getNumBuffers();
957 iBufferSize = ipFixedSizeBufferAlloc->getBufferSize();
959 if ((iNumBuffers < iParamPort.nBufferCountMin) || (iBufferSize < iOMXComponentOutputBufferSize))
961 ipExternalOutputBufferAllocatorInterface->removeRef();
962 ipExternalOutputBufferAllocatorInterface = NULL;
966 iNumOutputBuffers = iNumBuffers;
967 iOMXComponentOutputBufferSize = iBufferSize;
968 ReportInfoEvent(PVMFPvmiBufferAlloctorAcquired);
974 ipExternalOutputBufferAllocatorInterface->removeRef();
975 ipExternalOutputBufferAllocatorInterface = NULL;
981 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_WARNING,
982 (0, "PVMFOMXAudioDecNode::HandlePortReEnable Warning- It is OK for this KVP to fail"
983 "Do NOT attempt to fix the failure in the MIO unless you absolutely want to implement"
984 "the MIO BUFFER ALLOCATOR -see documentation"));
986 ReportInfoEvent(PVMFPvmiBufferAllocatorNotAcquired);
989 /* Allocate output buffers */
990 if (!CreateOutMemPool(iNumOutputBuffers))
993 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
994 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot allocate output buffers "));
996 SetState(EPVMFNodeError);
997 ReportErrorEvent(PVMFErrNoMemory);
998 return PVMFErrNoMemory;
1004 if (!ProvideBuffersToComponent(iOutBufMemoryPool, // allocator
1005 iOutputAllocSize, // size to allocate from pool (hdr only or hdr+ buffer)
1006 iNumOutputBuffers, // number of buffers
1007 iOMXComponentOutputBufferSize, // actual buffer size
1008 iOutputPortIndex, // port idx
1009 iOMXComponentSupportsExternalOutputBufferAlloc, // can component use OMX_UseBuffer
1010 false // this is not input
1015 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1016 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot provide output buffers to component"));
1018 SetState(EPVMFNodeError);
1019 ReportErrorEvent(PVMFErrNoMemory);
1020 return PVMFErrNoMemory;
1024 // do not drop output any more, i.e. enable output to be sent downstream
1025 iDoNotSendOutputBuffersDownstreamFlag = false;
1031 // this is input port
1033 // read the alignment again - just in case
1034 iInputBufferAlignment = iParamPort.nBufferAlignment;
1036 iNumInputBuffers = iParamPort.nBufferCountActual;
1037 if (iNumInputBuffers > NUMBER_INPUT_BUFFER)
1038 iNumInputBuffers = NUMBER_INPUT_BUFFER; // make sure number of output buffers is not larger than port queue size
1040 iOMXComponentInputBufferSize = iParamPort.nBufferSize;
1041 // do we need to increase the number of buffers?
1042 if (iNumInputBuffers < iParamPort.nBufferCountMin)
1043 iNumInputBuffers = iParamPort.nBufferCountMin;
1045 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1046 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() new buffers %d, size %d", iNumInputBuffers, iOMXComponentInputBufferSize));
1048 /* Allocate input buffers */
1049 if (!CreateInputMemPool(iNumInputBuffers))
1051 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1052 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot allocate new input buffers to component"));
1054 SetState(EPVMFNodeError);
1055 ReportErrorEvent(PVMFErrNoMemory);
1056 return PVMFErrNoMemory;
1059 if (!ProvideBuffersToComponent(iInBufMemoryPool, // allocator
1060 iInputAllocSize, // size to allocate from pool (hdr only or hdr+ buffer)
1061 iNumInputBuffers, // number of buffers
1062 iOMXComponentInputBufferSize, // actual buffer size
1063 iInputPortIndex, // port idx
1064 iOMXComponentSupportsExternalInputBufferAlloc, // can component use OMX_UseBuffer
1065 true // this is input
1070 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1071 (0, "PVMFOMXAudioDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot provide new input buffers to component"));
1073 SetState(EPVMFNodeError);
1074 ReportErrorEvent(PVMFErrNoMemory);
1075 return PVMFErrNoMemory;
1080 // if the callback that the port was re-enabled has not arrived yet, wait for it
1081 // if it has arrived, it will set the state to either PortReconfig or to ReadyToDecode or InitDecoder (if more init buffers need to be sent)
1082 if (iProcessingState != EPVMFOMXBaseDecNodeProcessingState_PortReconfig &&
1083 iProcessingState != EPVMFOMXBaseDecNodeProcessingState_ReadyToDecode &&
1084 iProcessingState != EPVMFOMXBaseDecNodeProcessingState_InitDecoder)
1085 iProcessingState = EPVMFOMXBaseDecNodeProcessingState_WaitForPortEnable;
1087 return PVMFSuccess; // allow rescheduling of the node
1089 ////////////////////////////////////////////////////////////////////////////////
1090 bool PVMFOMXAudioDecNode::NegotiateComponentParameters(OMX_PTR aOutputParameters)
1092 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1093 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() In"));
1096 // first get the number of ports and port indices
1097 OMX_PORT_PARAM_TYPE AudioPortParameters;
1102 pvAudioConfigParserInputs aInputs;
1103 AudioOMXConfigParserOutputs *pOutputParameters;
1105 aInputs.inPtr = (uint8*)((PVMFOMXDecPort*)iInPort)->iTrackConfig;
1106 aInputs.inBytes = (int32)((PVMFOMXDecPort*)iInPort)->iTrackConfigSize;
1107 aInputs.iMimeType = ((PVMFOMXDecPort*)iInPort)->iFormat;
1108 pOutputParameters = (AudioOMXConfigParserOutputs *)aOutputParameters;
1110 // config parser was called prior to calling NegotiateComponentParameters method - the results are available here
1111 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1112 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Audio config parser parameters - TrackConfig = %p, TrackConfigSize = %d, mimetype = %s", aInputs.inPtr, aInputs.inBytes, aInputs.iMimeType.getMIMEStrPtr()));
1115 //Initialize the timestamp delta to 0 for all other formats except AAC
1116 iTimestampDeltaForMemFragment = 0;
1118 if (aInputs.iMimeType == PVMF_MIME_WMA)
1120 iNumberOfAudioChannels = pOutputParameters->Channels;
1121 iPCMSamplingRate = pOutputParameters->SamplesPerSec;
1123 else if (aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
1124 aInputs.iMimeType == PVMF_MIME_3640 ||
1125 aInputs.iMimeType == PVMF_MIME_LATM ||
1126 aInputs.iMimeType == PVMF_MIME_ADIF ||
1127 aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
1128 aInputs.iMimeType == PVMF_MIME_AAC_SIZEHDR)
1131 iNumberOfAudioChannels = pOutputParameters->Channels;
1132 iPCMSamplingRate = pOutputParameters->SamplesPerSec;
1133 iSamplesPerFrame = pOutputParameters->SamplesPerFrame;
1135 if (aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
1136 aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO)
1138 // Get the duration of one AAC frame in millisec
1139 MediaClockConverter mcc(iPCMSamplingRate, iSamplesPerFrame);
1140 // calculate the timestamp update in OMX_TICKS (microseconds). This value
1141 // will be added directly to the OMX_TICKS timestamp
1142 iTimestampDeltaForMemFragment = mcc.get_converted_ts(iTimeScale); // this is 1000000 microsecond timescale
1147 CONFIG_SIZE_AND_VERSION(AudioPortParameters);
1148 // get starting number
1149 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioInit, &AudioPortParameters);
1150 NumPorts = AudioPortParameters.nPorts; // must be at least 2 of them (in&out)
1152 if (Err != OMX_ErrorNone || NumPorts < 2)
1154 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1155 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() There is insuffucient (%d) ports", NumPorts));
1160 // loop through ports starting from the starting index to find index of the first input port
1161 for (ii = AudioPortParameters.nStartPortNumber ; ii < AudioPortParameters.nStartPortNumber + NumPorts; ii++)
1163 // get port parameters, and determine if it is input or output
1164 // if there are more than 2 ports, the first one we encounter that has input direction is picked
1166 iParamPort.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
1169 iParamPort.nPortIndex = ii;
1171 CONFIG_SIZE_AND_VERSION(iParamPort);
1173 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
1175 if (Err != OMX_ErrorNone)
1177 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1178 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating with port %d ", ii));
1183 if (iParamPort.eDir == OMX_DirInput)
1185 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1186 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Found Input port index %d ", ii));
1188 iInputPortIndex = ii;
1192 if (ii == AudioPortParameters.nStartPortNumber + NumPorts)
1194 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1195 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Cannot find any input port "));
1200 // loop through ports starting from the starting index to find index of the first output port
1201 for (ii = AudioPortParameters.nStartPortNumber ; ii < AudioPortParameters.nStartPortNumber + NumPorts; ii++)
1203 // get port parameters, and determine if it is input or output
1204 // if there are more than 2 ports, the first one we encounter that has output direction is picked
1208 iParamPort.nPortIndex = ii;
1210 CONFIG_SIZE_AND_VERSION(iParamPort);
1212 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
1214 if (Err != OMX_ErrorNone)
1216 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1217 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating with port %d ", ii));
1222 if (iParamPort.eDir == OMX_DirOutput)
1224 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1225 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Found Output port index %d ", ii));
1227 iOutputPortIndex = ii;
1231 if (ii == AudioPortParameters.nStartPortNumber + NumPorts)
1233 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1234 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Cannot find any output port "));
1240 // now get input parameters
1242 CONFIG_SIZE_AND_VERSION(iParamPort);
1245 iParamPort.nPortIndex = iInputPortIndex;
1246 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
1247 if (Err != OMX_ErrorNone)
1249 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1250 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating with input port %d ", iInputPortIndex));
1254 // preset the number of input buffers
1255 //iNumInputBuffers = NUMBER_INPUT_BUFFER;
1256 iInputBufferAlignment = iParamPort.nBufferAlignment;
1257 iNumInputBuffers = iParamPort.nBufferCountActual; // use the value provided by component
1259 // do we need to increase the number of buffers?
1260 if (iNumInputBuffers < iParamPort.nBufferCountMin)
1261 iNumInputBuffers = iParamPort.nBufferCountMin;
1263 iOMXComponentInputBufferSize = iParamPort.nBufferSize;
1265 iParamPort.nBufferCountActual = iNumInputBuffers;
1267 // set the number of actual input buffers
1268 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1269 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Inport buffers %d,size %d", iNumInputBuffers, iOMXComponentInputBufferSize));
1274 CONFIG_SIZE_AND_VERSION(iParamPort);
1275 iParamPort.nPortIndex = iInputPortIndex;
1276 iParamPort.format.audio.bFlagErrorConcealment = (OMX_BOOL) iSilenceInsertionFlag;
1278 // finalize setting input port parameters
1279 Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
1280 if (Err != OMX_ErrorNone)
1282 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1283 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting parameters in input port %d ", iInputPortIndex));
1288 // in case of WMA - config parser decodes config info and produces reliable numchannels and sampling rate
1289 // set these values now to prevent unnecessary port reconfig
1290 // in case of AAC formats - config parser produces a potentially correct numchannels and sampling rate
1291 // however in case of implicit AAC+ signaling, the sampling rate may change and cause a port reconfig
1292 if (aInputs.iMimeType == PVMF_MIME_WMA ||
1293 aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
1294 aInputs.iMimeType == PVMF_MIME_3640 ||
1295 aInputs.iMimeType == PVMF_MIME_LATM ||
1296 aInputs.iMimeType == PVMF_MIME_ADIF ||
1297 aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
1298 aInputs.iMimeType == PVMF_MIME_AAC_SIZEHDR)
1300 // First get the structure
1301 OMX_AUDIO_PARAM_PCMMODETYPE Audio_Pcm_Param;
1302 Audio_Pcm_Param.nPortIndex = iOutputPortIndex; // we're looking for output port params
1303 CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
1305 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
1306 if (Err != OMX_ErrorNone)
1308 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1309 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating PCM parameters with output port %d ", iOutputPortIndex));
1313 // set the sampling rate obtained from config parser
1314 Audio_Pcm_Param.nSamplingRate = iPCMSamplingRate; // can be set to 0 (if unknown)
1316 // set number of channels obtained from config parser
1317 Audio_Pcm_Param.nChannels = iNumberOfAudioChannels; // should be 1 or 2
1319 // Now, set the parameters
1320 Audio_Pcm_Param.nPortIndex = iOutputPortIndex; // we're looking for output port params
1321 CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
1323 Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
1324 if (Err != OMX_ErrorNone)
1326 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1327 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem Setting PCM parameters with output port %d ", iOutputPortIndex));
1334 // Codec specific info set/get: SamplingRate, formats etc.
1335 // NOTE: iParamPort is modified in the routine below - it is loaded from the component output port values
1336 // Based on sampling rate - we also determine the desired output buffer size
1337 if (!GetSetCodecSpecificInfo())
1340 //Port 1 for output port
1341 iParamPort.nPortIndex = iOutputPortIndex;
1343 CONFIG_SIZE_AND_VERSION(iParamPort);
1345 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
1346 if (Err != OMX_ErrorNone)
1348 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1349 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating with output port %d ", iOutputPortIndex));
1353 // set number of output buffers and the size
1354 iOutputBufferAlignment = iParamPort.nBufferAlignment;
1356 iNumOutputBuffers = iParamPort.nBufferCountActual;
1358 if (iNumOutputBuffers > NUMBER_OUTPUT_BUFFER)
1359 iNumOutputBuffers = NUMBER_OUTPUT_BUFFER; // make sure to limit this number to what the port can hold
1362 if (iNumOutputBuffers < iParamPort.nBufferCountMin)
1363 iNumOutputBuffers = iParamPort.nBufferCountMin;
1367 //Try querying the buffer allocator KVP for output buffer allocation outside of the node
1369 // assume that this is going to fail and set the flags accordingly (so that FSI can be sent later on)
1371 iCompactFSISettingSucceeded = false;
1373 PvmiKvp* pkvp = NULL;
1375 PvmiKeyType aKvpIdentifier = (PvmiKeyType)PVMF_SUPPORT_FOR_BUFFER_ALLOCATOR_IN_MIO_KEY;
1376 // Check if Fsi configuration need to be sent
1377 // Send it only if the MIO supports the buffer allocator
1378 if (((PVMFOMXDecPort*)iOutPort)->pvmiGetBufferAllocatorSpecificInfoSync(aKvpIdentifier, pkvp, NumKvp) == PVMFSuccess)
1380 //Send the FSI information to media output node here, before setting output
1381 //port parameters to the omx component
1382 int fsiErrorCode = 0;
1384 OsclRefCounterMemFrag FsiMemfrag;
1386 OSCL_TRY(fsiErrorCode, FsiMemfrag = iFsiFragmentAlloc.get(););
1388 OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
1389 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Failed to allocate memory for FSI")));
1391 if (fsiErrorCode == 0)
1393 channelSampleInfo* pcminfo = (channelSampleInfo*) FsiMemfrag.getMemFragPtr();
1394 if (pcminfo != NULL)
1396 OSCL_ASSERT(pcminfo != NULL);
1397 pcminfo->samplingRate = iPCMSamplingRate;
1398 pcminfo->desiredChannels = iNumberOfAudioChannels;
1399 pcminfo->bitsPerSample = 16;
1400 pcminfo->num_buffers = iNumOutputBuffers;
1401 pcminfo->buffer_size = iOMXComponentOutputBufferSize;
1403 OsclMemAllocator alloc;
1404 int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY_PCM) + 1;
1405 PvmiKeyType KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength);
1412 oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY_PCM, KeyLength);
1415 bool success = false;
1417 OSCL_TRY(err, success = ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(FsiMemfrag, KvpKey););
1418 if (err != OsclErrNone || !success)
1420 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
1421 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters - Problem to set FSI"));
1426 iCompactFSISettingSucceeded = true;
1428 alloc.deallocate((OsclAny*)(KvpKey));
1434 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
1435 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters - Problem allocating Output FSI"));
1436 SetState(EPVMFNodeError);
1437 ReportErrorEvent(PVMFErrNoMemory);
1438 return false; // this is going to make everything go out of scope
1443 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
1444 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters - Problem allocating Output FSI"));
1445 return false; // this is going to make everything go out of scope
1452 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_WARNING,
1453 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters Warning- It is OK for this KVP to fail"
1454 "Do NOT attempt to fix the failure in the MIO unless you absolutely want to implement"
1455 "the MIO BUFFER ALLOCATOR -see documentation"));
1457 ReportInfoEvent(PVMFPvmiBufferAllocatorNotAcquired);
1459 //Try querying the buffer allocator KVP for output buffer allocation outside of the node
1460 PvmiKvp* kvp = NULL;
1462 PvmiKeyType aIdentifier = (PvmiKeyType)PVMF_BUFFER_ALLOCATOR_KEY;
1464 if (ipExternalOutputBufferAllocatorInterface)
1466 ipExternalOutputBufferAllocatorInterface->removeRef();
1467 ipExternalOutputBufferAllocatorInterface = NULL;
1470 OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiGetBufferAllocatorSpecificInfoSync(aIdentifier, kvp, numKvp););
1472 if ((err == OsclErrNone) && (NULL != kvp))
1474 ipExternalOutputBufferAllocatorInterface = (PVInterface*) kvp->value.key_specific_value;
1476 if (ipExternalOutputBufferAllocatorInterface)
1478 PVInterface* pTempPVInterfacePtr = NULL;
1480 OSCL_TRY(err, ipExternalOutputBufferAllocatorInterface->queryInterface(PVMFFixedSizeBufferAllocUUID, pTempPVInterfacePtr););
1482 OSCL_TRY(err1, ((PVMFOMXDecPort*)iOutPort)->releaseParametersSync(kvp, numKvp););
1483 if (err1 != OsclErrNone)
1485 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
1486 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters - Unable to Release Parameters"));
1489 if ((err == OsclErrNone) && (NULL != pTempPVInterfacePtr))
1491 ipFixedSizeBufferAlloc = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, pTempPVInterfacePtr);
1493 uint32 iNumBuffers, iBufferSize;
1495 iNumBuffers = ipFixedSizeBufferAlloc->getNumBuffers();
1496 iBufferSize = ipFixedSizeBufferAlloc->getBufferSize();
1498 if ((iNumBuffers < iParamPort.nBufferCountMin) || (iBufferSize < iOMXComponentOutputBufferSize))
1500 ipExternalOutputBufferAllocatorInterface->removeRef();
1501 ipExternalOutputBufferAllocatorInterface = NULL;
1505 iNumOutputBuffers = iNumBuffers;
1506 iOMXComponentOutputBufferSize = iBufferSize;
1507 ReportInfoEvent(PVMFPvmiBufferAlloctorAcquired);
1513 ipExternalOutputBufferAllocatorInterface->removeRef();
1514 ipExternalOutputBufferAllocatorInterface = NULL;
1521 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_WARNING,
1522 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters Warning- It is OK for this KVP to fail"
1523 "Do NOT attempt to fix the failure in the MIO unless you absolutely want to implement"
1524 "the MIO BUFFER ALLOCATOR -see documentation"));
1526 ReportInfoEvent(PVMFPvmiBufferAllocatorNotAcquired);
1529 iParamPort.nBufferCountActual = iNumOutputBuffers;
1531 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1532 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Outport buffers %d,size %d", iNumOutputBuffers, iOMXComponentOutputBufferSize));
1534 CONFIG_SIZE_AND_VERSION(iParamPort);
1535 iParamPort.nPortIndex = iOutputPortIndex;
1536 // finalize setting output port parameters
1537 Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
1538 if (Err != OMX_ErrorNone)
1540 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1541 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting parameters in output port %d ", iOutputPortIndex));
1545 //Set input audio format
1546 //This is need it since a single component could handle differents roles
1548 // Init to desire format
1549 PVMFFormatType Format = PVMF_MIME_FORMAT_UNKNOWN;
1550 if (iInPort != NULL)
1552 Format = ((PVMFOMXDecPort*)iInPort)->iFormat;
1554 if (Format == PVMF_MIME_MPEG4_AUDIO ||
1555 Format == PVMF_MIME_3640 ||
1556 Format == PVMF_MIME_LATM ||
1557 Format == PVMF_MIME_ADIF ||
1558 Format == PVMF_MIME_ASF_MPEG4_AUDIO ||
1559 Format == PVMF_MIME_AAC_SIZEHDR)
1561 iOMXAudioCompressionFormat = OMX_AUDIO_CodingAAC;
1563 else if (Format == PVMF_MIME_AMR_IF2 ||
1564 Format == PVMF_MIME_AMR_IETF ||
1565 Format == PVMF_MIME_AMR ||
1566 Format == PVMF_MIME_AMRWB_IETF ||
1567 Format == PVMF_MIME_AMRWB)
1569 iOMXAudioCompressionFormat = OMX_AUDIO_CodingAMR;
1571 else if (Format == PVMF_MIME_MP3)
1573 iOMXAudioCompressionFormat = OMX_AUDIO_CodingMP3;
1575 else if (Format == PVMF_MIME_WMA)
1577 iOMXAudioCompressionFormat = OMX_AUDIO_CodingWMA;
1579 else if (Format == PVMF_MIME_REAL_AUDIO)
1581 iOMXAudioCompressionFormat = OMX_AUDIO_CodingRA;
1585 // Illegal codec specified.
1586 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1587 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting audio compression format"));
1592 OMX_AUDIO_PARAM_PORTFORMATTYPE AudioPortFormat;
1593 CONFIG_SIZE_AND_VERSION(AudioPortFormat);
1594 AudioPortFormat.nPortIndex = iInputPortIndex;
1596 // Search the proper format index and set it.
1597 // Since we already know that the component has the role we need, search until finding the proper nIndex
1598 // if component does not find the format will return OMX_ErrorNoMore
1601 for (ii = 0; ii < PVOMXAUDIO_MAX_SUPPORTED_FORMAT; ii++)
1603 AudioPortFormat.nIndex = ii;
1604 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioPortFormat, &AudioPortFormat);
1605 if (Err != OMX_ErrorNone)
1607 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1608 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting audio compression format"));
1611 if (iOMXAudioCompressionFormat == AudioPortFormat.eEncoding)
1617 if (ii == PVOMXAUDIO_MAX_SUPPORTED_FORMAT)
1619 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1620 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() No audio compression format found"));
1624 // Now set the format to confirm parameters
1625 Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamAudioPortFormat, &AudioPortFormat);
1626 if (Err != OMX_ErrorNone)
1628 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1629 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting audio compression format"));
1637 bool PVMFOMXAudioDecNode::GetSetCodecSpecificInfo()
1640 // for AAC, need to let the decoder know about the type of AAC format. Need to get the frame length
1641 // need to get the parameters
1642 OMX_PTR CodecProfilePtr = NULL;
1643 OMX_INDEXTYPE CodecProfileIndx = OMX_IndexAudioStartUnused;
1644 OMX_AUDIO_PARAM_AACPROFILETYPE Audio_Aac_Param;
1645 OMX_AUDIO_PARAM_AMRTYPE Audio_Amr_Param;
1646 OMX_AUDIO_PARAM_MP3TYPE Audio_Mp3_Param;
1647 OMX_AUDIO_PARAM_WMATYPE Audio_Wma_Param;
1648 OMX_AUDIO_PARAM_RATYPE Audio_Ra_Param;
1649 OMX_ERRORTYPE Err = OMX_ErrorNone;
1650 PVMFFormatType Format = PVMF_MIME_FORMAT_UNKNOWN;
1652 // determine the proper index and structure (based on codec type)
1654 if (iInPort != NULL)
1656 Format = ((PVMFOMXDecPort*)iInPort)->iFormat;
1658 if (Format == PVMF_MIME_MPEG4_AUDIO ||
1659 Format == PVMF_MIME_3640 ||
1660 Format == PVMF_MIME_LATM ||
1661 Format == PVMF_MIME_ADIF ||
1662 Format == PVMF_MIME_ASF_MPEG4_AUDIO ||
1663 Format == PVMF_MIME_AAC_SIZEHDR) // for testing
1667 CodecProfilePtr = (OMX_PTR) & Audio_Aac_Param;
1668 CodecProfileIndx = OMX_IndexParamAudioAac;
1669 Audio_Aac_Param.nPortIndex = iInputPortIndex;
1671 CONFIG_SIZE_AND_VERSION(Audio_Aac_Param);
1674 else if (Format == PVMF_MIME_AMR_IF2 ||
1675 Format == PVMF_MIME_AMR_IETF ||
1676 Format == PVMF_MIME_AMR ||
1677 Format == PVMF_MIME_AMRWB_IETF ||
1678 Format == PVMF_MIME_AMRWB)
1680 CodecProfilePtr = (OMX_PTR) & Audio_Amr_Param;
1681 CodecProfileIndx = OMX_IndexParamAudioAmr;
1682 Audio_Amr_Param.nPortIndex = iInputPortIndex;
1684 CONFIG_SIZE_AND_VERSION(Audio_Amr_Param);
1686 else if (Format == PVMF_MIME_MP3)
1688 CodecProfilePtr = (OMX_PTR) & Audio_Mp3_Param;
1689 CodecProfileIndx = OMX_IndexParamAudioMp3;
1690 Audio_Mp3_Param.nPortIndex = iInputPortIndex;
1692 CONFIG_SIZE_AND_VERSION(Audio_Mp3_Param);
1694 else if (Format == PVMF_MIME_WMA)
1696 CodecProfilePtr = (OMX_PTR) & Audio_Wma_Param;
1697 CodecProfileIndx = OMX_IndexParamAudioWma;
1698 Audio_Wma_Param.nPortIndex = iInputPortIndex;
1700 CONFIG_SIZE_AND_VERSION(Audio_Wma_Param);
1702 else if (Format == PVMF_MIME_REAL_AUDIO)
1704 CodecProfilePtr = (OMX_PTR) & Audio_Ra_Param;
1705 CodecProfileIndx = OMX_IndexParamAudioRa;
1706 Audio_Ra_Param.nPortIndex = iInputPortIndex;
1708 CONFIG_SIZE_AND_VERSION(Audio_Ra_Param);
1711 // first get parameters:
1712 Err = OMX_GetParameter(iOMXDecoder, CodecProfileIndx, CodecProfilePtr);
1713 if (Err != OMX_ErrorNone)
1715 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1716 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem getting codec profile parameter on input port %d ", iInputPortIndex));
1719 // Set the stream format
1723 if (Format == PVMF_MIME_MPEG4_AUDIO)
1725 Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
1727 else if (Format == PVMF_MIME_3640)
1729 Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
1731 else if (Format == PVMF_MIME_LATM)
1733 Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4LATM;
1735 else if (Format == PVMF_MIME_ADIF)
1737 Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatADIF;
1739 else if (Format == PVMF_MIME_ASF_MPEG4_AUDIO)
1741 Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
1743 else if (Format == PVMF_MIME_AAC_SIZEHDR) // for testing
1745 Audio_Aac_Param.eAACStreamFormat = OMX_AUDIO_AACStreamFormatMP4ADTS;
1748 else if (Format == PVMF_MIME_AMR_IF2)
1750 Audio_Amr_Param.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatIF2;
1751 Audio_Amr_Param.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0; // we don't know the bitrate yet, but for init
1752 // purposes, we'll set this to any NarrowBand bitrate
1753 // to indicate NB vs WB
1757 else if (Format == PVMF_MIME_AMR_IETF)
1759 Audio_Amr_Param.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
1760 Audio_Amr_Param.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0; // we don't know the bitrate yet, but for init
1761 // purposes, we'll set this to any NarrowBand bitrate
1762 // to indicate NB vs WB
1765 else if (Format == PVMF_MIME_AMRWB_IETF)
1767 Audio_Amr_Param.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
1768 Audio_Amr_Param.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0; // we don't know the bitrate yet, but for init
1769 // purposes, we'll set this to any WideBand bitrate
1770 // to indicate NB vs WB
1772 // streaming with Table of Contents
1773 else if (Format == PVMF_MIME_AMR)
1775 Audio_Amr_Param.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatRTPPayload;
1776 Audio_Amr_Param.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0; // we don't know the bitrate yet, but for init
1777 // purposes, we'll set this to any WideBand bitrate
1778 // to indicate NB vs WB
1780 else if (Format == PVMF_MIME_AMRWB)
1782 Audio_Amr_Param.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatRTPPayload;
1783 Audio_Amr_Param.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0; // we don't know the bitrate yet, but for init
1784 // purposes, we'll set this to any WideBand bitrate
1785 // to indicate NB vs WB
1787 else if (Format == PVMF_MIME_MP3)
1789 // nothing to do here
1791 else if (Format == PVMF_MIME_WMA)
1793 Audio_Wma_Param.eFormat = OMX_AUDIO_WMAFormatUnused; // set this initially
1795 else if (Format == PVMF_MIME_REAL_AUDIO)
1797 Audio_Ra_Param.eFormat = OMX_AUDIO_RA8; // set this initially
1801 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1802 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Unknown format in input port negotiation "));
1806 // set parameters to inform teh component of the stream type
1807 Err = OMX_SetParameter(iOMXDecoder, CodecProfileIndx, CodecProfilePtr);
1808 if (Err != OMX_ErrorNone)
1810 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1811 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem setting codec profile parameter on input port %d ", iInputPortIndex));
1816 // read the output frame size
1818 if (Format == PVMF_MIME_MPEG4_AUDIO ||
1819 Format == PVMF_MIME_3640 ||
1820 Format == PVMF_MIME_LATM ||
1821 Format == PVMF_MIME_ADIF ||
1822 Format == PVMF_MIME_ASF_MPEG4_AUDIO ||
1823 Format == PVMF_MIME_AAC_SIZEHDR) // for testing
1825 // AAC frame size is 1024 samples or 2048 samples for AAC-HE
1826 iSamplesPerFrame = Audio_Aac_Param.nFrameLength;
1829 else if (Format == PVMF_MIME_AMR_IF2 ||
1830 Format == PVMF_MIME_AMR_IETF ||
1831 Format == PVMF_MIME_AMR)
1833 // AMR NB has fs=8khz Mono and the frame is 20ms long, i.e. there is 160 samples per frame
1834 iSamplesPerFrame = PVOMXAUDIODEC_AMRNB_SAMPLES_PER_FRAME;
1836 else if (Format == PVMF_MIME_AMRWB_IETF ||
1837 Format == PVMF_MIME_AMRWB)
1839 // AMR WB has fs=16khz Mono and the frame is 20ms long, i.e. there is 320 samples per frame
1840 iSamplesPerFrame = PVOMXAUDIODEC_AMRWB_SAMPLES_PER_FRAME;
1842 else if (Format == PVMF_MIME_MP3)
1844 // frame size is either 576 or 1152 samples per frame. However, this information cannot be
1845 // obtained through OMX MP3 Params. Assume that it's 1152
1846 iSamplesPerFrame = PVOMXAUDIODEC_MP3_DEFAULT_SAMPLES_PER_FRAME;
1848 else if (Format == PVMF_MIME_WMA)
1850 // output frame size is unknown in WMA. However, the PV-WMA decoder can control the number
1851 // of samples it places in an output buffer, so we can create an output buffer of arbitrary size
1852 // and let the decoder control how it is filled
1853 iSamplesPerFrame = 0; // unknown
1855 else if (Format == PVMF_MIME_REAL_AUDIO)
1857 // samples per frame is unknown in RA as of now, keep it to 0
1858 // and let the decoder control how it is filled
1859 iSamplesPerFrame = 0; // unknown
1863 // iSamplesPerFrame depends on the codec.
1864 // for AAC: iSamplesPerFrame = 1024
1865 // for AAC+: iSamplesPerFrame = 2048
1866 // for AMRNB: iSamplesPerFrame = 160
1867 // for AMRWB: iSamplesPerFrame = 320
1868 // for MP3: iSamplesPerFrame = unknown, but either 1152 or 576 (we pick 1152 as default)
1869 // for WMA: unknown (iSamplesPerFrame is set to 0)
1870 // for RA: unknown (iSamplesPerFrame is set to 0)
1872 // GET the output buffer params and sizes
1873 OMX_AUDIO_PARAM_PCMMODETYPE Audio_Pcm_Param;
1874 Audio_Pcm_Param.nPortIndex = iOutputPortIndex; // we're looking for output port params
1876 CONFIG_SIZE_AND_VERSION(Audio_Pcm_Param);
1879 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamAudioPcm, &Audio_Pcm_Param);
1880 if (Err != OMX_ErrorNone)
1882 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1883 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating PCM parameters with output port %d ", iOutputPortIndex));
1888 // these are some initial default values that may change
1889 iPCMSamplingRate = Audio_Pcm_Param.nSamplingRate; // can be set to 0 (if unknown)
1891 if (iPCMSamplingRate == 0) // use default sampling rate (i.e. 48000)
1892 iPCMSamplingRate = PVOMXAUDIODEC_DEFAULT_SAMPLINGRATE;
1894 iNumberOfAudioChannels = Audio_Pcm_Param.nChannels; // should be 1 or 2
1895 if (iNumberOfAudioChannels != 1 && iNumberOfAudioChannels != 2)
1899 if ((iSamplesPerFrame != 0) && ((iSamplesPerFrame * 1000) > iPCMSamplingRate))
1900 // if this iSamplesPerFrame is known and is large enough to ensure that the iMilliSecPerFrame calculation
1901 // below won't be set to 0.
1903 // CALCULATE NumBytes per frame, Msec per frame, etc.
1905 iNumBytesPerFrame = 2 * iSamplesPerFrame * iNumberOfAudioChannels;
1906 iMilliSecPerFrame = (iSamplesPerFrame * 1000) / iPCMSamplingRate;
1907 // Determine the size of each PCM output buffer. Size would be big enough to hold certain time amount of PCM data
1908 uint32 numframes = iOutputBufferPCMDuration / iMilliSecPerFrame;
1910 if (iOutputBufferPCMDuration % iMilliSecPerFrame)
1912 // If there is a remainder, include one more frame
1915 // set the output buffer size accordingly:
1916 iOMXComponentOutputBufferSize = numframes * iNumBytesPerFrame;
1919 iOMXComponentOutputBufferSize = (2 * iNumberOfAudioChannels * iOutputBufferPCMDuration * iPCMSamplingRate) / 1000; // assuming 16 bits per sample
1922 CalculateBOCParameters();
1925 CalculateEOCParameters();
1927 //Port 1 for output port
1928 iParamPort.nPortIndex = iOutputPortIndex;
1929 CONFIG_SIZE_AND_VERSION(iParamPort);
1930 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort);
1931 if (Err != OMX_ErrorNone)
1933 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1934 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters() Problem negotiating with output port %d ", iOutputPortIndex));
1938 if (iOMXComponentOutputBufferSize < iParamPort.nBufferSize)
1940 // the OMX spec says that nBuffersize is a read only field, but the client is allowed to allocate
1941 // a buffer size larger than nBufferSize.
1942 iOMXComponentOutputBufferSize = iParamPort.nBufferSize;
1949 /////////////////////////////////////////////////////////////////////////////
1950 PVMFStatus PVMFOMXAudioDecNode::InitDecoder(PVMFSharedMediaDataPtr& DataIn)
1953 OsclRefCounterMemFrag DataFrag;
1954 OsclRefCounterMemFrag refCtrMemFragOut;
1955 uint8* initbuffer = NULL;
1956 uint32 initbufsize = 0;
1957 PVMFStatus status = PVMFSuccess;
1959 // NOTE: the component may not start decoding without providing the Output buffer to it,
1960 // here, we're sending input/config buffers.
1961 // Then, we'll go to ReadyToDecode state and send output as well
1963 if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM)
1965 // must have the LATM config buffer and size already present
1966 if (iLATMConfigBuffer != NULL)
1968 initbuffer = iLATMConfigBuffer;
1969 initbufsize = iLATMConfigBufferSize;
1973 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
1974 (0, "PVMFOMXAudioDecNode::InitDecoder() Error - LATM config buffer not present"));
1978 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MPEG4_AUDIO ||
1979 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640 ||
1980 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF ||
1981 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ASF_MPEG4_AUDIO ||
1982 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AAC_SIZEHDR) // for testing
1984 // get format specific info and send it as config data:
1985 DataIn->getFormatSpecificInfo(DataFrag);
1986 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
1987 (0, "PVMFOMXAudioDecNode::InitDecoder() VOL header (Size=%d)", DataFrag.getMemFragSize()));
1989 //get pointer to the data fragment
1990 initbuffer = (uint8 *) DataFrag.getMemFragPtr();
1991 initbufsize = (int32) DataFrag.getMemFragSize();
1993 // in case of ASF_MPEG4 audio need to create aac config header
1994 if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ASF_MPEG4_AUDIO)
1998 if (!CreateAACConfigDataFromASF(initbuffer, initbufsize, &iAACConfigData[0], iAACConfigDataLength))
2000 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
2001 (0, "PVMFOMXAudioDecNode::InitDecoder() Error in creating AAC Codec Config data"));
2006 initbuffer = &iAACConfigData[0];
2007 initbufsize = iAACConfigDataLength;
2011 } // in some cases, initbufsize may be 0, and initbuf= NULL. Config is done after 1st frame of data
2012 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IF2 ||
2013 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IETF ||
2014 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR ||
2015 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB_IETF ||
2016 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB ||
2017 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MP3)
2019 initbuffer = NULL; // no special config header. Need to decode 1 frame
2023 else if ((((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMA) ||
2024 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_REAL_AUDIO))
2026 // in case of WMA, get config parameters from the port
2027 initbuffer = ((PVMFOMXDecPort*)iInPort)->getTrackConfig();
2028 initbufsize = (int32)((PVMFOMXDecPort*)iInPort)->getTrackConfigSize();
2030 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2031 (0, "PVMFOMXAudioDecNode::InitDecoder() for WMA Decoder. Initialization data Size %d.", initbufsize));
2034 if (initbufsize > 0)
2038 status = SendConfigBufferToOMXComponent(initbuffer, initbufsize);
2039 if (status != PVMFSuccess)
2041 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
2042 (0, "PVMFOMXAudioDecNode::InitDecoder() Error in processing config buffer"));
2043 iIsThereMoreConfigDataToBeSent = true; // this means that we may not have buffers available to send,
2047 // set the flag requiring config data processing by the component
2048 iIsConfigDataProcessingCompletionNeeded = true;
2049 iConfigDataBuffersOutstanding++;
2050 iIsThereMoreConfigDataToBeSent = false;
2054 iIsThereMoreConfigDataToBeSent = false;
2061 /////////////////////////////////////////////////////////////////////////////
2062 ////////////////////// CALLBACK PROCESSING FOR FILL BUFFER DONE - output buffer is ready
2063 /////////////////////////////////////////////////////////////////////////////
2064 OMX_ERRORTYPE PVMFOMXAudioDecNode::FillBufferDoneProcessing(OMX_OUT OMX_HANDLETYPE aComponent,
2065 OMX_OUT OMX_PTR aAppData,
2066 OMX_OUT OMX_BUFFERHEADERTYPE* aBuffer)
2068 OSCL_UNUSED_ARG(aComponent);
2069 OSCL_UNUSED_ARG(aAppData);
2071 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2072 (0, "PVMFOMXAudioDecNode::FillBufferDoneProcessing: In"));
2074 OSCL_ASSERT((void*) aComponent == (void*) iOMXDecoder); // component should match the component
2075 OSCL_ASSERT(aAppData == (OMX_PTR)(this)); // AppData should represent this node ptr
2077 // first, get the buffer "context", i.e. pointer to application private data that contains the
2078 // address of the mempool buffer (so that it can be released)
2079 OutputBufCtrlStruct *pContext = (OutputBufCtrlStruct*) aBuffer->pAppPrivate;
2081 // check for EOS flag
2082 if ((aBuffer->nFlags & OMX_BUFFERFLAG_EOS))
2084 // EOS received - enable sending EOS msg
2085 iIsEOSReceivedFromComponent = true;
2087 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2088 (0, "PVMFOMXAudioDecNode::FillBufferDoneProcessing: Output buffer has EOS set"));
2091 if (iCountSamplesInBuffer)
2093 CountSamplesInBuffer(aBuffer);
2099 HandleBOCProcessing(aBuffer);
2105 HandleEOCProcessing(aBuffer);
2108 // if a buffer is empty, or if it should not be sent downstream (say, due to state change)
2109 // release the buffer back to the pool
2110 if ((aBuffer->nFilledLen == 0) || (iDoNotSendOutputBuffersDownstreamFlag == true))
2112 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2113 (0, "PVMFOMXAudioDecNode::FillBufferDoneProcessing: Release output buffer %x pointing to buffer %x back to mempool - buffer empty or not to be sent downstream", pContext, pContext->pMemPoolEntry));
2115 iOutBufMemoryPool->deallocate(pContext->pMemPoolEntry);
2120 // get pointer to actual buffer data
2121 uint8 *pBufdata = ((uint8*) aBuffer->pBuffer);
2122 // move the data pointer based on offset info
2123 pBufdata += aBuffer->nOffset;
2125 iOutTimeStamp = ConvertOMXTicksIntoTimestamp(aBuffer->nTimeStamp);
2127 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2128 (0, "PVMFOMXAudioDecNode::FillBufferDoneProcessing: Output frame %d with timestamp %d received", iFrameCounter++, iOutTimeStamp));
2131 ipPrivateData = (OsclAny *) aBuffer->pPlatformPrivate; // record the pointer
2133 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2134 (0, "PVMFOMXAudioDecNode::FillBufferDoneProcessing: Wrapping buffer %x of size %d", pBufdata, aBuffer->nFilledLen));
2135 // wrap the buffer into the MediaDataImpl wrapper, and queue it for sending downstream
2136 // wrapping will create a refcounter. When refcounter goes to 0 i.e. when media data
2137 // is released in downstream components, the custom deallocator will automatically release the buffer back to the
2138 // mempool. To do that, the deallocator needs to have info about Context
2139 // NOTE: we had to wait until now to wrap the buffer data because we only know
2140 // now where the actual data is located (based on buffer offset)
2141 OsclSharedPtr<PVMFMediaDataImpl> MediaDataOut = WrapOutputBuffer(pBufdata, (uint32)(aBuffer->nFilledLen), pContext->pMemPoolEntry);
2143 // if you can't get the MediaDataOut, release the buffer back to the pool
2144 if (MediaDataOut.GetRep() == NULL)
2146 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2147 (0, "PVMFOMXAudioDecNode::FillBufferDoneProcessing: Problem wrapping buffer %x of size %d - releasing the buffer", pBufdata, aBuffer->nFilledLen));
2149 iOutBufMemoryPool->deallocate(pContext->pMemPoolEntry);
2154 // if there's a problem queuing output buffer, MediaDataOut will expire at end of scope and
2155 // release buffer back to the pool, (this should not be the case)
2156 if (QueueOutputBuffer(MediaDataOut, aBuffer->nFilledLen))
2158 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2159 (0, "PVMFOMXAudioDecNode::FillBufferDoneProcessing: Buffer %x of size %d queued - reschedule the node to send out", pBufdata, aBuffer->nFilledLen));
2161 // if queing went OK,
2162 // re-schedule the node so that outgoing queue can be emptied (unless the outgoing port is busy)
2163 if ((iOutPort) && !(iOutPort->IsConnectedPortBusy()))
2168 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2169 (0, "PVMFOMXAudioDecNode::FillBufferDoneProcessing: Problem queing buffer %x of size %d - releasing the buffer", pBufdata, aBuffer->nFilledLen));
2176 // the OMX spec says that no error is to be returned
2177 return OMX_ErrorNone;
2181 ////////////////////////////////////////////////////////////////////////////////////////////////
2182 ///////////////////////////// Put output buffer in outgoing queue //////////////////////////////
2183 ////////////////////////////////////////////////////////////////////////////////////////////////
2184 bool PVMFOMXAudioDecNode::QueueOutputBuffer(OsclSharedPtr<PVMFMediaDataImpl> &mediadataimplout, uint32 aDataLen)
2188 PVMFSharedMediaDataPtr mediaDataOut;
2189 int32 leavecode = OsclErrNone;
2191 // NOTE: ASSUMPTION IS THAT OUTGOING QUEUE IS BIG ENOUGH TO QUEUE ALL THE OUTPUT BUFFERS
2192 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2193 (0, "PVMFOMXAudioDecNode::QueueOutputFrame: In"));
2197 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
2198 (0, "PVMFOMXAudioDecNode::QueueOutputFrame() Output Port doesn't exist!!!!!!!!!!"));
2201 // First check if we can put outgoing msg. into the queue
2202 if (iOutPort->IsOutgoingQueueBusy())
2204 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
2205 (0, "PVMFOMXAudioDecNode::QueueOutputFrame() OutgoingQueue is busy"));
2210 mediaDataOut = PVMFMediaData::createMediaData(mediadataimplout, iOutputMediaDataMemPool););
2211 if (OsclErrNone == leavecode)
2213 // Update the filled length of the fragment
2214 mediaDataOut->setMediaFragFilledLen(0, aDataLen);
2217 mediaDataOut->setTimestamp(iOutTimeStamp);
2220 // Duration = (OutputBufferSize * 1000)/(SamplingRate * NumChannels * BitsPerSample/8)
2221 uint32 duration = (iOMXComponentOutputBufferSize * 1000) / (iPCMSamplingRate * iNumberOfAudioChannels * 16 / 8);
2222 mediaDataOut->setDuration(duration);
2224 // Get the markerinfo and set the Duration Bit
2225 uint32 markerInfo = mediaDataOut->getMarkerInfo();
2226 markerInfo |= PVMF_MEDIA_DATA_MARKER_INFO_DURATION_AVAILABLE_BIT;
2227 mediaDataOut->setMarkerInfo(markerInfo);
2229 // Set sequence number
2230 mediaDataOut->setSeqNum(iSeqNum++);
2232 mediaDataOut->setStreamID(iStreamID);
2234 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iDataPathLogger, PVLOGMSG_INFO, (0, ":PVMFOMXAudioDecNode::QueueOutputFrame(): - SeqNum=%d, TS=%d", iSeqNum, iOutTimeStamp));
2235 int fsiErrorCode = 0;
2237 // Check if Fsi configuration need to be sent
2238 if (sendFsi && !iCompactFSISettingSucceeded)
2241 OsclRefCounterMemFrag FsiMemfrag;
2243 OSCL_TRY(fsiErrorCode, FsiMemfrag = iFsiFragmentAlloc.get(););
2245 OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
2246 (0, "PVMFOMXAudioDecNode::RemoveOutputFrame() Failed to allocate memory for FSI")));
2248 if (fsiErrorCode == 0)
2251 channelSampleInfo* pcminfo = (channelSampleInfo*) FsiMemfrag.getMemFragPtr();
2252 if (pcminfo != NULL)
2254 OSCL_ASSERT(pcminfo != NULL);
2256 pcminfo->samplingRate = iPCMSamplingRate;
2257 pcminfo->desiredChannels = iNumberOfAudioChannels;
2258 pcminfo->bitsPerSample = 16;
2259 pcminfo->num_buffers = 0;
2260 pcminfo->buffer_size = 0;
2262 mediaDataOut->setFormatSpecificInfo(FsiMemfrag);
2265 OsclMemAllocator alloc;
2266 int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY_PCM) + 1;
2268 PvmiKeyType KvpKey = NULL;
2269 AllocatePvmiKey(&KvpKey, &alloc, KeyLength);
2273 SetState(EPVMFNodeError);
2274 ReportErrorEvent(PVMFErrNoMemory);
2278 oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY_PCM, KeyLength);
2281 OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(FsiMemfrag, KvpKey););
2282 if (err != OsclErrNone)
2284 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
2285 (0, "PVMFOMXAudioDecNode::NegotiateComponentParameters - Problem to set FSI_PCM key, will try to send ordinary FSI"));
2287 alloc.deallocate((OsclAny*)(KvpKey));
2290 // try to send the ordinary FSI
2291 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY) + 1;
2292 KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength);
2295 SetState(EPVMFNodeError);
2296 ReportErrorEvent(PVMFErrNoMemory);
2300 oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY, KeyLength);
2303 OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(FsiMemfrag, KvpKey););
2304 if (err != OsclErrNone)
2306 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
2307 (0, "PVMFOMXAudioDecNode::QueueOutputFrame - Problem to set ordinary FSI as well"));
2309 alloc.deallocate((OsclAny*)(KvpKey));
2311 SetState(EPVMFNodeError);
2312 ReportErrorEvent(PVMFErrNoMemory);
2313 return false; // this is going to make everything go out of scope
2317 alloc.deallocate((OsclAny*)(KvpKey));
2321 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
2322 (0, "PVMFOMXAudioDecNode::QueueOutputFrame - Problem allocating Output FSI"));
2323 SetState(EPVMFNodeError);
2324 ReportErrorEvent(PVMFErrNoMemory);
2325 return false; // this is going to make everything go out of scope
2330 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
2331 (0, "PVMFOMXAudioDecNode::QueueOutputFrame - Problem allocating Output FSI"));
2332 return false; // this is going to make everything go out of scope
2339 if (fsiErrorCode == 0)
2341 // Send frame to downstream node
2342 PVMFSharedMediaMsgPtr mediaMsgOut;
2343 convertToPVMFMediaMsg(mediaMsgOut, mediaDataOut);
2345 if (iOutPort && (iOutPort->QueueOutgoingMsg(mediaMsgOut) == PVMFSuccess))
2347 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_DEBUG,
2348 (0, "PVMFOMXAudioDecNode::QueueOutputFrame(): Queued frame OK "));
2353 // we should not get here because we always check for whether queue is busy or not
2354 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
2355 (0, "PVMFOMXAudioDecNode::QueueOutputFrame(): Send frame failed"));
2360 }//end of if (OsclErrNone == leavecode)
2363 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
2364 (0, "PVMFOMXAudioDecNode::QueueOutputFrame() call PVMFMediaData::createMediaData is failed"));
2371 /////////////////////////////////////////////////////////////////////////////
2372 PVMFStatus PVMFOMXAudioDecNode::DoRequestPort(PVMFPortInterface*& aPort)
2374 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2375 (0, "PVMFOMXAudioDecNode::DoRequestPort() In"));
2376 //This node supports port request from any state
2378 //retrieve port tag.
2380 OSCL_String* portconfig;
2382 iCurrentCommand.PVMFNodeCommandBase::Parse(tag, portconfig);
2384 int32 leavecode = OsclErrNone;
2385 //validate the tag...
2388 case PVMF_OMX_DEC_NODE_PORT_TYPE_INPUT:
2394 OSCL_TRY(leavecode, iInPort = OSCL_NEW(PVMFOMXDecPort, ((int32)tag, this, (OMX_STRING)PVMF_OMX_AUDIO_DEC_INPUT_PORT_NAME)););
2395 if (leavecode || iInPort == NULL)
2397 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
2398 (0, "PVMFOMXAudioDecNode::DoRequestPort: Error - Input port instantiation failed"));
2399 return PVMFErrArgument;
2404 case PVMF_OMX_DEC_NODE_PORT_TYPE_OUTPUT:
2410 OSCL_TRY(leavecode, iOutPort = OSCL_NEW(PVMFOMXDecPort, ((int32)tag, this, (OMX_STRING)PVMF_OMX_AUDIO_DEC_OUTPUT_PORT_NAME)));
2411 if (leavecode || iOutPort == NULL)
2413 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
2414 (0, "PVMFOMXAudioDecNode::DoRequestPort: Error - Output port instantiation failed"));
2415 return PVMFErrArgument;
2422 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
2423 (0, "PVMFOMXAudioDecNode::DoRequestPort: Error - Invalid port tag"));
2424 return PVMFErrArgument;
2430 /////////////////////////////////////////////////////////////////////////////
2431 PVMFStatus PVMFOMXAudioDecNode::DoGetNodeMetadataKey()
2433 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
2434 (0, "PVMFOMXAudioDecNode::DoGetNodeMetadataKey() In"));
2436 PVMFMetadataList* keylistptr = NULL;
2437 uint32 starting_index;
2441 iCurrentCommand.PVMFNodeCommand::Parse(keylistptr, starting_index, max_entries, query_key);
2444 if (keylistptr == NULL)
2446 // The list pointer is invalid
2447 return PVMFErrArgument;
2450 // Update the available metadata keys
2451 iAvailableMetadataKeys.clear();
2452 int32 leavecode = OsclErrNone;
2453 leavecode = PushKVPKey(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY, iAvailableMetadataKeys);
2454 if (OsclErrNone != leavecode)
2456 return PVMFErrNoMemory;
2459 if (iNumberOfAudioChannels > 0)
2461 leavecode = OsclErrNone;
2462 leavecode = PushKVPKey(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY, iAvailableMetadataKeys);
2463 if (OsclErrNone != leavecode)
2465 return PVMFErrNoMemory;
2469 if (iPCMSamplingRate > 0)
2471 leavecode = OsclErrNone;
2472 leavecode = PushKVPKey(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY, iAvailableMetadataKeys);
2473 if (OsclErrNone != leavecode)
2475 return PVMFErrNoMemory;
2479 if ((starting_index > (iAvailableMetadataKeys.size() - 1)) || max_entries == 0)
2481 // Invalid starting index and/or max entries
2482 return PVMFErrArgument;
2485 // Copy the requested keys
2486 uint32 num_entries = 0;
2487 int32 num_added = 0;
2488 for (uint32 lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++)
2490 if (query_key == NULL)
2492 // No query key so this key is counted
2494 if (num_entries > starting_index)
2496 // Past the starting index so copy the key
2497 leavecode = OsclErrNone;
2498 leavecode = PushKVPKey(iAvailableMetadataKeys[lcv], keylistptr);
2499 if (OsclErrNone != leavecode)
2501 return PVMFErrNoMemory;
2509 // Check if the key matche the query key
2510 if (pv_mime_strcmp(iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0)
2512 // This key is counted
2514 if (num_entries > starting_index)
2516 // Past the starting index so copy the key
2517 leavecode = OsclErrNone;
2518 leavecode = PushKVPKey(iAvailableMetadataKeys[lcv], keylistptr);
2519 if (OsclErrNone != leavecode)
2521 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::DoGetNodeMetadataKey() Memory allocation failure when copying metadata key"));
2522 return PVMFErrNoMemory;
2530 // Check if max number of entries have been copied
2531 if (max_entries > 0 && num_added >= max_entries)
2540 /////////////////////////////////////////////////////////////////////////////
2541 PVMFStatus PVMFOMXAudioDecNode::DoGetNodeMetadataValue()
2543 PVMFMetadataList* keylistptr = NULL;
2544 Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL;
2545 uint32 starting_index;
2548 iCurrentCommand.PVMFNodeCommand::Parse(keylistptr, valuelistptr, starting_index, max_entries);
2550 // Check the parameters
2551 if (keylistptr == NULL || valuelistptr == NULL)
2553 return PVMFErrArgument;
2556 uint32 numkeys = keylistptr->size();
2558 if (starting_index > (numkeys - 1) || numkeys <= 0 || max_entries == 0)
2560 // Don't do anything
2561 return PVMFErrArgument;
2564 uint32 numvalentries = 0;
2565 int32 numentriesadded = 0;
2566 for (uint32 lcv = 0; lcv < numkeys; lcv++)
2568 int32 leavecode = OsclErrNone;
2569 int32 leavecode1 = OsclErrNone;
2574 if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY) == 0))
2576 // PCM output channels
2577 if (iNumberOfAudioChannels > 0)
2579 // Increment the counter for the number of values found so far
2582 // Create a value entry if past the starting index
2583 if (numvalentries > starting_index)
2585 KeyLen = oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY) + 1; // for "codec-info/audio/channels;"
2586 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
2587 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
2589 // Allocate memory for the string
2590 leavecode = OsclErrNone;
2591 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
2592 if (OsclErrNone == leavecode)
2594 // Copy the key string
2595 oscl_strncpy(KeyVal.key, PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY, oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY) + 1);
2596 oscl_strncat(KeyVal.key, PVOMXAUDIODECMETADATA_SEMICOLON, oscl_strlen(PVOMXAUDIODECMETADATA_SEMICOLON));
2597 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
2598 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
2599 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
2601 KeyVal.value.uint32_value = iNumberOfAudioChannels;
2602 // Set the length and capacity
2604 KeyVal.capacity = 1;
2608 // Memory allocation failed
2615 else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY) == 0) &&
2616 (iPCMSamplingRate > 0))
2618 // PCM output sampling rate
2619 // Increment the counter for the number of values found so far
2622 // Create a value entry if past the starting index
2623 if (numvalentries > starting_index)
2625 KeyLen = oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY) + 1; // for "codec-info/audio/sample-rate;"
2626 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
2627 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator
2629 // Allocate memory for the string
2630 leavecode = OsclErrNone;
2631 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
2632 if (OsclErrNone == leavecode)
2634 // Copy the key string
2635 oscl_strncpy(KeyVal.key, PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY, oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY) + 1);
2636 oscl_strncat(KeyVal.key, PVOMXAUDIODECMETADATA_SEMICOLON, oscl_strlen(PVOMXAUDIODECMETADATA_SEMICOLON));
2637 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
2638 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR));
2639 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
2641 KeyVal.value.uint32_value = iPCMSamplingRate;
2642 // Set the length and capacity
2644 KeyVal.capacity = 1;
2648 // Memory allocation failed
2654 else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY) == 0) &&
2658 if ((((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM) ||
2659 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MPEG4_AUDIO) ||
2660 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640) ||
2661 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF) ||
2662 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ASF_MPEG4_AUDIO) ||
2663 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AAC_SIZEHDR) ||
2664 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IF2) ||
2665 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IETF) ||
2666 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR) ||
2667 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB_IETF) ||
2668 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB) ||
2669 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MP3) ||
2670 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMA) ||
2671 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_REAL_AUDIO)
2675 // Increment the counter for the number of values found so far
2678 // Create a value entry if past the starting index
2679 if (numvalentries > starting_index)
2681 KeyLen = oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY) + 1; // for "codec-info/audio/format;"
2682 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype="
2683 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*" and NULL terminator
2685 uint32 valuelen = 0;
2686 if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM)
2688 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_LATM)) + 1; // Value string plus one for NULL terminator
2690 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MPEG4_AUDIO)
2692 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_MPEG4_AUDIO)) + 1; // Value string plus one for NULL terminator
2694 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640)
2696 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_3640)) + 1; // Value string plus one for NULL terminator
2698 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF)
2700 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_ADIF)) + 1;
2702 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ASF_MPEG4_AUDIO)
2704 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_ASF_MPEG4_AUDIO)) + 1;
2706 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IF2)
2708 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_AMR_IF2)) + 1;
2710 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IETF)
2712 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_AMR_IETF)) + 1;
2714 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR)
2716 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_AMR)) + 1;
2718 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB_IETF)
2720 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_AMRWB_IETF)) + 1;
2722 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB)
2724 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_AMRWB)) + 1;
2726 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MP3)
2728 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_MP3)) + 1;
2730 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMA)
2732 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_WMA)) + 1;
2734 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_REAL_AUDIO)
2736 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_REAL_AUDIO)) + 1;
2740 // Should not enter here
2745 // Allocate memory for the strings
2746 leavecode = OsclErrNone;
2747 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen);
2748 if (OsclErrNone == leavecode)
2750 KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode1, PVMI_KVPVALTYPE_CHARPTR, valuelen);
2753 if (OsclErrNone == leavecode && OsclErrNone == leavecode1)
2755 // Copy the key string
2756 oscl_strncpy(KeyVal.key, PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY, oscl_strlen(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY) + 1);
2757 oscl_strncat(KeyVal.key, PVOMXAUDIODECMETADATA_SEMICOLON, oscl_strlen(PVOMXAUDIODECMETADATA_SEMICOLON));
2758 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR));
2759 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR));
2760 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR;
2762 if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM)
2764 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_LATM), valuelen);
2766 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MPEG4_AUDIO)
2768 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_MPEG4_AUDIO), valuelen);
2770 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640)
2772 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_3640), valuelen);
2774 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF)
2776 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_ADIF), valuelen);
2778 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ASF_MPEG4_AUDIO)
2780 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_ASF_MPEG4_AUDIO), valuelen);
2782 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IF2)
2784 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_AMR_IF2), valuelen);
2786 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IETF)
2788 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_AMR_IETF), valuelen);
2790 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR)
2792 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_AMR), valuelen);
2794 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB_IETF)
2796 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_AMRWB_IETF), valuelen);
2798 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB)
2800 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_AMRWB), valuelen);
2802 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MP3)
2804 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_MP3), valuelen);
2806 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMA)
2808 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_WMA), valuelen);
2810 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_REAL_AUDIO)
2812 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_REAL_AUDIO), valuelen);
2816 // Should not enter here
2819 KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR;
2820 // Set the length and capacity
2821 KeyVal.length = valuelen;
2822 KeyVal.capacity = valuelen;
2826 // Memory allocation failed so clean up
2829 OSCL_ARRAY_DELETE(KeyVal.key);
2832 if (KeyVal.value.pChar_value)
2834 OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
2842 if (KeyVal.key != NULL)
2844 leavecode = OsclErrNone;
2845 leavecode = PushKVP(KeyVal, *valuelistptr);
2846 if (OsclErrNone != leavecode)
2848 switch (GetValTypeFromKeyString(KeyVal.key))
2850 case PVMI_KVPVALTYPE_CHARPTR:
2851 if (KeyVal.value.pChar_value != NULL)
2853 OSCL_ARRAY_DELETE(KeyVal.value.pChar_value);
2854 KeyVal.value.pChar_value = NULL;
2859 // Add more case statements if other value types are returned
2863 OSCL_ARRAY_DELETE(KeyVal.key);
2868 // Increment the counter for number of value entries added to the list
2872 // Check if the max number of value entries were added
2873 if (max_entries > 0 && numentriesadded >= max_entries)
2886 /////////////////////////////////////////////////////////////////////////////
2887 bool PVMFOMXAudioDecNode::ReleaseAllPorts()
2889 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::ReleaseAllPorts() In"));
2893 iInPort->ClearMsgQueues();
2894 iInPort->Disconnect();
2895 OSCL_DELETE(((PVMFOMXDecPort*)iInPort));
2901 iOutPort->ClearMsgQueues();
2902 iOutPort->Disconnect();
2903 OSCL_DELETE(((PVMFOMXDecPort*)iOutPort));
2910 /////////////////////////////////////////////////////////////////////////////
2911 PVMFStatus PVMFOMXAudioDecNode::CreateLATMParser()
2913 PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXAudioDecNode::CreateLATMParser() In"));
2915 // First clean up if necessary
2918 // Instantiate the LATM parser
2919 iLATMParser = OSCL_NEW(PV_LATM_Parser, ());
2922 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::CreateLATMParser() LATM parser instantiation failed"));
2923 return PVMFErrNoMemory;
2926 PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXAudioDecNode::CreateLATMParser() Out"));
2930 PVMFStatus PVMFOMXAudioDecNode::DeleteLATMParser()
2932 PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXAudioDecNode::DeleteLATMParser() In"));
2934 // Delete LATM parser if there is one
2937 OSCL_DELETE(iLATMParser);
2941 if (iLATMConfigBuffer)
2943 oscl_free(iLATMConfigBuffer);
2944 iLATMConfigBuffer = NULL;
2945 iLATMConfigBufferSize = 0;
2948 PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXAudioDecNode::DeleteLATMParser() Out"));
2957 /////////////////////////////////////////////////////////////////////////////
2958 uint32 PVMFOMXAudioDecNode::GetNumMetadataKeys(char* aQueryKeyString)
2960 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::GetNumMetadataKeys() called"));
2962 // Update the available metadata keys
2963 iAvailableMetadataKeys.clear();
2964 int32 errcode = OsclErrNone;
2965 OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY));
2967 if (iNumberOfAudioChannels > 0)
2969 errcode = OsclErrNone;
2970 OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY));
2973 if (iPCMSamplingRate > 0)
2975 errcode = OsclErrNone;
2976 OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY));
2979 uint32 num_entries = 0;
2981 if (aQueryKeyString == NULL)
2983 num_entries = iAvailableMetadataKeys.size();
2987 for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++)
2989 if (pv_mime_strcmp(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) >= 0)
2995 return num_entries; // Number of elements
2999 /////////////////////////////////////////////////////////////////////////////
3000 uint32 PVMFOMXAudioDecNode::GetNumMetadataValues(PVMFMetadataList& aKeyList)
3002 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::GetNumMetadataValues() called"));
3004 uint32 numkeys = aKeyList.size();
3008 // Don't do anything
3012 // Count the number of value entries for the provided key list
3013 uint32 numvalentries = 0;
3014 for (uint32 lcv = 0; lcv < numkeys; lcv++)
3016 if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_CHANNELS_KEY) == 0))
3019 if (iNumberOfAudioChannels > 0)
3024 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_SAMPLERATE_KEY) == 0) && (iPCMSamplingRate > 0))
3029 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXAUDIODECMETADATA_CODECINFO_AUDIO_FORMAT_KEY) == 0) &&
3033 if ((((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_LATM) ||
3034 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MPEG4_AUDIO) ||
3035 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_3640) ||
3036 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ADIF) ||
3037 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_ASF_MPEG4_AUDIO) ||
3038 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IF2) ||
3039 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR_IETF) ||
3040 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMR) ||
3041 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB_IETF) ||
3042 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_AMRWB) ||
3043 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_MP3) ||
3044 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMA) ||
3045 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_REAL_AUDIO)
3055 return numvalentries;
3059 // needed for WMA parameter verification
3060 bool PVMFOMXAudioDecNode::VerifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements)
3062 OSCL_UNUSED_ARG(aSession);
3063 OSCL_UNUSED_ARG(num_elements);
3064 if (pv_mime_strcmp(aParameters->key, PVMF_BITRATE_VALUE_KEY) == 0)
3066 if (((PVMFOMXDecPort*)iOutPort)->verifyConnectedPortParametersSync(PVMF_BITRATE_VALUE_KEY, &(aParameters->value.uint32_value)) != PVMFSuccess)
3072 else if (pv_mime_strcmp(aParameters->key, PVMF_FORMAT_SPECIFIC_INFO_KEY) < 0)
3074 PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::VerifyParametersSync() - Unsupported Key"));
3078 bool cap_exchange_status = false;
3080 pvAudioConfigParserInputs aInputs;
3081 OMXConfigParserInputs aInputParameters;
3082 AudioOMXConfigParserOutputs aOutputParameters;
3084 aInputs.inPtr = (uint8*)(aParameters->value.key_specific_value);
3085 aInputs.inBytes = (int32)aParameters->capacity;
3086 aInputs.iMimeType = PVMF_MIME_WMA;
3087 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.wma";
3088 aInputParameters.inBytes = aInputs.inBytes;
3089 aInputParameters.inPtr = aInputs.inPtr;
3092 if (aInputs.inBytes == 0 || aInputs.inPtr == NULL)
3094 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::VerifyParametersSync() Codec Config data is not present"));
3095 return cap_exchange_status;
3099 OMX_BOOL status = OMX_FALSE;
3100 OMX_U32 num_comps = 0, ii;
3101 OMX_STRING *CompOfRole;
3102 OMX_ERRORTYPE Err = OMX_ErrorNone;
3104 // call once to find out the number of components that can fit the role
3105 Err = OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, NULL);
3107 if ((num_comps > 0) && (OMX_ErrorNone == Err))
3109 CompOfRole = (OMX_STRING *)oscl_malloc(num_comps * sizeof(OMX_STRING));
3110 for (ii = 0; ii < num_comps; ii++)
3111 CompOfRole[ii] = (OMX_STRING) oscl_malloc(PV_OMX_MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8));
3113 // call 2nd time to get the component names
3114 Err = OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, (OMX_U8 **)CompOfRole);
3116 if (OMX_ErrorNone == Err)
3118 for (ii = 0; ii < num_comps; ii++)
3120 aInputParameters.cComponentName = CompOfRole[ii];
3121 status = OMX_MasterConfigParser(&aInputParameters, &aOutputParameters);
3122 if (status == OMX_TRUE)
3133 // whether successful or not, need to free CompOfRoles
3134 for (ii = 0; ii < num_comps; ii++)
3136 oscl_free(CompOfRole[ii]);
3137 CompOfRole[ii] = NULL;
3140 oscl_free(CompOfRole);
3145 // if no components support the role, nothing else to do
3149 if (OMX_FALSE != status)
3151 cap_exchange_status = true;
3153 iPCMSamplingRate = aOutputParameters.SamplesPerSec;
3154 iNumberOfAudioChannels = aOutputParameters.Channels;
3156 if ((iNumberOfAudioChannels != 1 && iNumberOfAudioChannels != 2) ||
3157 (iPCMSamplingRate <= 0))
3159 cap_exchange_status = false;
3163 return cap_exchange_status;
3168 PVMFStatus PVMFOMXAudioDecNode::DoCapConfigVerifyParameters(PvmiKvp* aParameters, int aNumElements)
3170 OSCL_UNUSED_ARG(aNumElements);
3172 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3173 (0, "PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() In"));
3175 pvAudioConfigParserInputs aInputs;
3176 OMXConfigParserInputs aInputParameters;
3177 AudioOMXConfigParserOutputs aOutputParameters;
3179 aInputs.inPtr = (uint8*)(aParameters->value.key_specific_value);
3180 aInputs.inBytes = (int32)aParameters->capacity;
3181 aInputs.iMimeType = iNodeConfig.iMimeType;
3182 aInputParameters.inBytes = aInputs.inBytes;
3183 aInputParameters.inPtr = aInputs.inPtr;
3185 if (aInputs.inBytes == 0 || aInputs.inPtr == NULL)
3187 // in case of following formats - config codec data is expected to
3188 // be present in the query. If not, config parser cannot be called
3190 if (aInputs.iMimeType == PVMF_MIME_WMA ||
3191 aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
3192 aInputs.iMimeType == PVMF_MIME_3640 ||
3193 aInputs.iMimeType == PVMF_MIME_LATM ||
3194 aInputs.iMimeType == PVMF_MIME_ADIF ||
3195 aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
3196 aInputs.iMimeType == PVMF_MIME_AAC_SIZEHDR ||
3197 aInputs.iMimeType == PVMF_MIME_REAL_AUDIO)
3199 if (aInputs.iMimeType == PVMF_MIME_LATM)
3201 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() Codec Config data is not present"));
3202 return PVMFErrNotSupported;
3206 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() Codec Config data is not present"));
3208 // DV TO_DO: remove this
3209 OSCL_LEAVE(OsclErrNotSupported);
3214 // in case of ASF_MPEG4 audio need to create aac config header
3215 if (aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO)
3217 if (!CreateAACConfigDataFromASF(aInputParameters.inPtr, aInputParameters.inBytes, &iAACConfigData[0], iAACConfigDataLength))
3219 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
3220 (0, "PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() - Error in creating AAC Codec Config data"));
3223 return PVMFErrNotSupported;
3226 aInputParameters.inPtr = &iAACConfigData[0];
3227 aInputParameters.inBytes = iAACConfigDataLength;
3231 if (aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
3232 aInputs.iMimeType == PVMF_MIME_3640 ||
3233 aInputs.iMimeType == PVMF_MIME_LATM ||
3234 aInputs.iMimeType == PVMF_MIME_ADIF ||
3235 aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
3236 aInputs.iMimeType == PVMF_MIME_AAC_SIZEHDR)
3238 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.aac";
3241 else if (aInputs.iMimeType == PVMF_MIME_AMR_IF2 ||
3242 aInputs.iMimeType == PVMF_MIME_AMR_IETF ||
3243 aInputs.iMimeType == PVMF_MIME_AMR)
3245 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.amrnb";
3247 else if (aInputs.iMimeType == PVMF_MIME_AMRWB_IETF ||
3248 aInputs.iMimeType == PVMF_MIME_AMRWB)
3250 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.amrwb";
3252 else if (aInputs.iMimeType == PVMF_MIME_MP3)
3254 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.mp3";
3256 else if (aInputs.iMimeType == PVMF_MIME_WMA)
3258 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.wma";
3260 else if (aInputs.iMimeType == PVMF_MIME_REAL_AUDIO)
3262 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.ra";
3266 // Illegal codec specified.
3267 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "%s::PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() Input port format other then codec type", iName.Str()));
3270 OMX_BOOL status = OMX_FALSE;
3271 OMX_U32 num_comps = 0, ii;
3272 OMX_STRING *CompOfRole;
3273 OMX_ERRORTYPE Err = OMX_ErrorNone;
3275 // call once to find out the number of components that can fit the role
3276 Err = OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, NULL);
3278 if ((num_comps > 0) && (OMX_ErrorNone == Err))
3280 CompOfRole = (OMX_STRING *)oscl_malloc(num_comps * sizeof(OMX_STRING));
3281 for (ii = 0; ii < num_comps; ii++)
3282 CompOfRole[ii] = (OMX_STRING) oscl_malloc(PV_OMX_MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8));
3284 // call 2nd time to get the component names
3285 Err = OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, (OMX_U8 **)CompOfRole);
3287 if (OMX_ErrorNone == Err)
3289 for (ii = 0; ii < num_comps; ii++)
3291 aInputParameters.cComponentName = CompOfRole[ii];
3292 status = OMX_MasterConfigParser(&aInputParameters, &aOutputParameters);
3293 if (status == OMX_TRUE)
3304 // whether successful or not, need to free CompOfRoles
3305 for (ii = 0; ii < num_comps; ii++)
3307 oscl_free(CompOfRole[ii]);
3308 CompOfRole[ii] = NULL;
3311 oscl_free(CompOfRole);
3316 // if no component supports the role, nothing else to do
3317 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3318 (0, "PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() No omx component supports this role PVMFErrNotSupported"));
3319 return PVMFErrNotSupported;
3322 if (status == OMX_FALSE)
3324 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3325 (0, "PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() ->OMXConfigParser() PVMFErrNotSupported"));
3326 return PVMFErrNotSupported;
3329 if (aInputs.iMimeType == PVMF_MIME_WMA)
3331 iNumberOfAudioChannels = aOutputParameters.Channels;
3332 iPCMSamplingRate = aOutputParameters.SamplesPerSec;
3334 else if (aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
3335 aInputs.iMimeType == PVMF_MIME_3640 ||
3336 aInputs.iMimeType == PVMF_MIME_LATM ||
3337 aInputs.iMimeType == PVMF_MIME_ADIF ||
3338 aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
3339 aInputs.iMimeType == PVMF_MIME_AAC_SIZEHDR)
3341 iNumberOfAudioChannels = aOutputParameters.Channels;
3342 iPCMSamplingRate = aOutputParameters.SamplesPerSec;
3345 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3346 (0, "PVMFOMXAudioDecNode::DoCapConfigVerifyParameters() Out"));
3350 void PVMFOMXAudioDecNode::DoCapConfigSetParameters(PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP)
3352 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3353 (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() In"));
3355 if (aParameters == NULL || aNumElements < 1)
3357 aRetKVP = aParameters;
3358 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() Passed in parameter invalid"));
3364 for (ii = 0; ii < aNumElements; ii ++)
3367 // find out if the audio dec format key is used for the query
3368 if (pv_mime_strcmp(aParameters[ii].key, PVMF_FORMAT_SPECIFIC_INFO_KEY) == 0)
3371 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3372 (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() set audio format specific info"));
3374 if (iTrackUnderVerificationConfig)
3376 oscl_free(iTrackUnderVerificationConfig);
3377 iTrackUnderVerificationConfig = NULL;
3378 iTrackUnderVerificationConfigSize = 0;
3381 iTrackUnderVerificationConfigSize = aParameters[ii].capacity;
3383 if (iTrackUnderVerificationConfigSize > 0)
3385 iTrackUnderVerificationConfig = (uint8*)(oscl_malloc(sizeof(uint8) * iTrackUnderVerificationConfigSize));
3386 oscl_memcpy(iTrackUnderVerificationConfig, aParameters[ii].value.key_specific_value, iTrackUnderVerificationConfigSize);
3390 else if (pv_mime_strcmp(aParameters[ii].key, _STRLIT_CHAR(PVMF_DEC_AVAILABLE_OMX_COMPONENTS_KEY)) == 0)
3392 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3393 (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() set preferred omx component list"));
3396 // each kvp paramater corresponds to one omx component - a new item in the vector is created
3398 iOMXPreferredComponentOrderVec.push_back((OMX_STRING)(aParameters[ii].value.pChar_value));
3402 else if (pv_mime_strcmp(aParameters[ii].key, PVMF_AUDIO_DEC_FORMAT_TYPE_VALUE_KEY) == 0)
3404 // set the mime type if audio format is being used
3405 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3406 (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() set audio dec format type to %s", aParameters->value.pChar_value));
3408 iNodeConfig.iMimeType = aParameters[ii].value.pChar_value;
3410 else if (pv_mime_strcmp(aParameters[ii].key, PVMF_AUDIO_DEC_PCM_BUFFER_DURATION_KEY) == 0)
3412 // set the mime type if audio format is being used
3413 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3414 (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() set audio dec pcm buffer size to %d milliseconds", aParameters->value.uint32_value));
3416 iOutputBufferPCMDuration = aParameters[ii].value.uint32_value;
3417 if (iOutputBufferPCMDuration == 0)
3420 aRetKVP = aParameters; // indicate "error" by setting return KVP to original
3421 iOutputBufferPCMDuration = PVOMXAUDIODEC_DEFAULT_OUTPUTPCM_TIME;
3423 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3424 (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() set audio dec pcm buffer size to 0 milliseconds not allowed, reveting to default of %d", iOutputBufferPCMDuration));
3429 else if (pv_mime_strcmp(aParameters[ii].key, PVMF_AUDIO_SILENCE_INSERTION_KEY) == 0)
3431 // Enable or Disable silence insertion in audio tracks
3432 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3433 (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() Silence insertion key \n"));
3435 iSilenceInsertionFlag = aParameters[ii].value.bool_value;
3439 // For now, ignore other queries
3440 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3441 (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() Key not used"));
3443 // indicate "error" by setting return KVP to the original
3444 aRetKVP = aParameters;
3451 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3452 (0, "PVMFOMXAudioDecNode::DoCapConfigSetParameters() Out"));
3455 void PVMFOMXAudioDecNode::CalculateBOCParameters()
3457 OSCL_ASSERT(iBOCReceived);
3459 iBOCBytesToSkip = iBOCSamplesToSkip * iNumberOfAudioChannels * 2; // assuming 16-bit data
3460 iBOCBeginningOfContentTS = iBOCTimeStamp + ((iBOCSamplesToSkip * iInTimeScale + iPCMSamplingRate - 1) / iPCMSamplingRate);
3463 void PVMFOMXAudioDecNode::HandleBOCProcessing(OMX_BUFFERHEADERTYPE* aBuffer)
3465 if (aBuffer->nTimeStamp > (((int64)iBOCBeginningOfContentTS *(int64)iTimeScale) / (int64)iInTimeScale))
3467 // buffer time stamp is passed the beginning of content time stamp before dropping all BOC samples
3468 // this is most likely due to a reposition during the BOC silence dropping
3469 iBOCReceived = false;
3474 if (iBOCBytesToSkip < aBuffer->nFilledLen)
3476 aBuffer->nOffset += iBOCBytesToSkip;
3477 aBuffer->nFilledLen -= iBOCBytesToSkip;
3479 iBOCBytesToSkip = 0;
3480 iBOCReceived = false;
3482 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3483 (0, "PVMFOMXAudioDecNode::HandleBOCProcessing: Dropping %d samples from buffer %x due to BOC", iBOCSamplesToSkip, (OsclAny*) aBuffer->pAppPrivate));
3487 iBOCBytesToSkip -= aBuffer->nFilledLen;
3488 aBuffer->nFilledLen = 0;
3490 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3491 (0, "PVMFOMXAudioDecNode::HandleBOCProcessing: Dropping %d samples (the entire buffer) from buffer %x due to BOC. There are %d samples more to drop.", aBuffer->nFilledLen, (OsclAny*) aBuffer->pAppPrivate, iBOCSamplesToSkip));
3495 void PVMFOMXAudioDecNode::CalculateEOCParameters()
3497 OSCL_ASSERT(iEOCReceived);
3499 // calculate the total number of frames
3500 // timestamp is from media msg, therefore in milliseconds
3501 uint32 totalFrames = (uint32)(((int64)(iEOCTimeStamp - iTSOfFirstDataMsgAfterBOS) * (int64)iPCMSamplingRate + (((int64)iInTimeScale * (int64)iSamplesPerFrame) >> 1)) / ((int64)iInTimeScale * (int64)iSamplesPerFrame) + iEOCFramesToFollow); // round to frame boundaries
3503 // calculate the frame at which silence removal should begin
3504 iEOCSilenceRemovalStartFrame = totalFrames - ((iEOCSamplesToSkip + iSamplesPerFrame - 1) / iSamplesPerFrame);
3506 // calculate the offset in samples within the frame at which silence removal should begin
3507 iEOCSilenceRemovalSampleOffset = iSamplesPerFrame - (iEOCSamplesToSkip % iSamplesPerFrame);
3510 void PVMFOMXAudioDecNode::HandleEOCProcessing(OMX_BUFFERHEADERTYPE* aBuffer)
3512 uint32 bytesPerSample = 2; // assuming 16-bit data
3513 uint32 bufferLengthSamples = aBuffer->nFilledLen / (bytesPerSample * iNumberOfAudioChannels);
3515 if (iBufferContainsIntFrames)
3517 uint32 outputBufferStartFrame;
3518 uint32 outputBufferEndFrame;
3519 uint32 framesInBuffer;
3521 // calculate everything in frames, since timestamps won't be sample accurate.
3522 // also assume that there is always an integer number of frames per buffer.
3523 // note: timestamp is from OMX buffer, therefore in microseconds
3524 // note: frames are 0-indexed here
3525 int64 normTS = aBuffer->nTimeStamp - (((int64)iTSOfFirstDataMsgAfterBOS * (int64)iTimeScale) / (int64)iInTimeScale);
3526 outputBufferStartFrame = (uint32)((normTS * (int64)iPCMSamplingRate + (((int64)iTimeScale * (int64)iSamplesPerFrame) >> 1)) / ((int64)iTimeScale * (int64)iSamplesPerFrame)); // round to frame boundaries
3527 framesInBuffer = bufferLengthSamples / iSamplesPerFrame; // no rounding needed since length should be an integer number of frames
3529 OSCL_ASSERT((bufferLengthSamples % iSamplesPerFrame) == 0); // double check
3531 outputBufferEndFrame = outputBufferStartFrame + framesInBuffer - 1;
3533 // check to see if silence removal begins within this buffer
3534 if (outputBufferEndFrame >= iEOCSilenceRemovalStartFrame)
3536 uint32 validSamples;
3537 uint32 newFilledLen;
3538 uint32 skippedSamples;
3540 validSamples = OSCL_MAX((int32) iEOCSilenceRemovalStartFrame - (int32)outputBufferStartFrame, 0) * iSamplesPerFrame + iEOCSilenceRemovalSampleOffset;
3541 newFilledLen = validSamples * bytesPerSample * iNumberOfAudioChannels;
3542 skippedSamples = bufferLengthSamples - validSamples;
3544 iEOCSamplesToSkip = OSCL_MAX((int32) iEOCSamplesToSkip - (int32) skippedSamples, 0);
3546 if (iEOCSamplesToSkip == 0)
3548 iEOCReceived = false;
3552 // update start point information
3553 iEOCSilenceRemovalSampleOffset += skippedSamples;
3555 iEOCSilenceRemovalStartFrame += iEOCSilenceRemovalSampleOffset / iSamplesPerFrame;
3556 iEOCSilenceRemovalSampleOffset = iEOCSilenceRemovalSampleOffset % iSamplesPerFrame;
3559 OSCL_ASSERT(newFilledLen <= aBuffer->nFilledLen);
3561 aBuffer->nFilledLen = newFilledLen;
3563 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3564 (0, "PVMFOMXAudioDecNode::HandleEOCProcessing: Dropping %d samples from buffer %x due to EOC", skippedSamples, (OsclAny*) aBuffer->pAppPrivate));
3569 // the method for gapless silence removal without int frames per buffer isn't guaranteed to be sample accurate
3571 uint32 outputBufferStartSample;
3572 uint32 outputBufferEndSample;
3573 uint32 EOCSilenceRemovalStartSample = (iEOCSilenceRemovalStartFrame * iSamplesPerFrame) + iEOCSilenceRemovalSampleOffset;
3575 // find the difference between the time based off of timestamps and that based off of accumulated samples
3576 // the timestamps have a max error dependent on their resolution (timescale) equivalent to: ceil(sampling_rate / timescale)
3577 // if the accumulated sample count is within this max error then most likely no data has been dropped, and the accumulated sample
3578 // count is more accurate than the timestamps. however, if it is outside of that error window then we should use the
3579 // calculation based off of the timestamps; since while the ts calculation may not be sample accurate, it will be more accurate
3580 // than the accumulated sample count in the case of dropped data
3581 int64 normTS = aBuffer->nTimeStamp - (((int64)iTSOfFirstDataMsgAfterBOS * (int64)iTimeScale) / (int64)iInTimeScale);
3583 int32 sampleDelta = (int32)(((normTS * (int64)iPCMSamplingRate) / (int64)iTimeScale) - (iClipSampleCount - bufferLengthSamples));
3584 int32 tsMaxError = (iPCMSamplingRate + (iInTimeScale - 1)) / iInTimeScale;
3586 if (oscl_abs(sampleDelta) < tsMaxError)
3588 // use accumulated sample count based calculation
3590 outputBufferStartSample = iClipSampleCount - bufferLengthSamples;
3591 outputBufferEndSample = iClipSampleCount;
3595 // some data must have been dropped, use the timestamp based calculation
3597 outputBufferStartSample = (uint32)((normTS * (int64)iPCMSamplingRate) / (int64)iTimeScale);
3598 outputBufferEndSample = outputBufferStartSample + bufferLengthSamples;
3602 // check to see if silence removal begins within this buffer
3603 if (outputBufferEndSample >= EOCSilenceRemovalStartSample)
3605 uint32 validSamples;
3606 uint32 newFilledLen;
3607 uint32 skippedSamples;
3609 validSamples = OSCL_MAX((int32)EOCSilenceRemovalStartSample - (int32) outputBufferStartSample, 0);
3610 newFilledLen = validSamples * bytesPerSample * iNumberOfAudioChannels;
3611 skippedSamples = bufferLengthSamples - validSamples;
3613 iEOCSamplesToSkip = OSCL_MAX((int32) iEOCSamplesToSkip - (int32) skippedSamples, 0);
3615 if (iEOCSamplesToSkip == 0)
3617 iEOCReceived = false;
3621 // update start point information
3622 iEOCSilenceRemovalSampleOffset += skippedSamples;
3624 iEOCSilenceRemovalStartFrame += iEOCSilenceRemovalSampleOffset / iSamplesPerFrame;
3625 iEOCSilenceRemovalSampleOffset = iEOCSilenceRemovalSampleOffset % iSamplesPerFrame;
3628 OSCL_ASSERT(newFilledLen <= aBuffer->nFilledLen);
3630 aBuffer->nFilledLen = newFilledLen;
3632 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3633 (0, "PVMFOMXAudioDecNode::HandleEOCProcessing: Dropping %d samples from buffer %x due to EOC", skippedSamples, (OsclAny*) aBuffer->pAppPrivate));
3639 PVMFStatus PVMFOMXAudioDecNode::RetrieveMP3FrameLength(uint8 *pBuffer)
3642 PVMFStatus err = PVMFSuccess;
3651 * MPEG Audio Version ID
3654 tmp2 = *(pBuffer + 1);
3655 tmp3 = *(pBuffer + 2);
3656 tmp4 = *(pBuffer + 3);
3658 temp = ((((uint32)(tmp1)) << 24) |
3659 (((uint32)(tmp2)) << 16) |
3660 (((uint32)(tmp3)) << 8) |
3661 (((uint32)(tmp4))));
3663 if (((temp >> 21) & MP3_SYNC_WORD) != MP3_SYNC_WORD)
3665 return PVMFErrCorrupt;
3668 temp = (temp << 11) >> 11;
3671 switch (temp >> 19) /* 2 */
3683 version = INVALID_VERSION;
3684 err = PVMFErrNotSupported;
3690 iSamplesPerFrame = (version == MPEG_1) ?
3691 2 * MP3_SUBBANDS_NUMBER * MP3_FILTERBANK_BANDS :
3692 MP3_SUBBANDS_NUMBER * MP3_FILTERBANK_BANDS;
3697 PVMFStatus PVMFOMXAudioDecNode::CountSamplesInBuffer(OMX_BUFFERHEADERTYPE* aBuffer)
3699 if (aBuffer->nTimeStamp < (((int64)iTSOfFirstDataMsgAfterBOS *(int64)iTimeScale) / (int64)iInTimeScale))
3701 // time stamp is before BOS (i.e. the buffer could be from the port flush)
3702 // therefore don't count this buffer
3706 uint32 bytesPerSample = 2; // assuming 16-bit data
3708 if ((0 == iNumberOfAudioChannels) ||
3709 (0 == iSamplesPerFrame))
3714 uint32 samplesInBuffer = aBuffer->nFilledLen / (bytesPerSample * iNumberOfAudioChannels);
3717 if ((0 != (samplesInBuffer % iSamplesPerFrame)) && (iBufferContainsIntFrames == true))
3719 iBufferContainsIntFrames = false;
3722 iClipSampleCount += samplesInBuffer;
3727 // needed for AAC in ASF
3730 AAC_LC = 1, // should map to 2
3731 AAC_LTP = 3 // should map to 4
3736 AAC_LC_SBR = 5 // should map to 5
3737 , ENHANCED_AAC_LC_SBR_PS // should map to 29
3738 , INVALID_OBJ_TYPE = 0xffffffff
3739 } EXTERNAL_OBJECT_TYPES;
3743 AOT_NULL_OBJECT = 0,
3744 AOT_AAC_LC = 2, // LC
3745 AOT_AAC_LTP = 4, // LTP
3749 } eAUDIO_OBJECT_TYPE;
3751 static const uint32 srIndexTable[16] = {96000, 88200, 64000, 48000, 44100,
3752 32000, 24000, 22050, 16000, 12000,
3753 11025, 8000, 7350, 0, 0, 0
3757 bool PVMFOMXAudioDecNode::CreateAACConfigDataFromASF(uint8 *inptr, uint32 inlen, uint8 *outptr, uint32 &outlen)
3760 if (NULL == inptr || inlen < 20)
3762 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3763 (0, "PVMFOMXAudioDecNode::CreateAACConfigDataFromASF() Error - insufficient config data"));
3770 uint32 *valPtr = OSCL_STATIC_CAST(uint32 *, inptr);
3771 EXTERNAL_OBJECT_TYPES ExternlObjType = INVALID_OBJ_TYPE;
3772 eAUDIO_OBJECT_TYPE objType = AOT_NULL_OBJECT;
3774 uint32 OutSampRate = 0;
3775 uint32 SamplingRate = 0;
3776 uint32 NumChannels = 0; /* checks below assume unsigned type
3777 * (i.e., less than 0 not explicitly
3778 * checked, so don't change to signed.
3780 uint32 SamplesPerFrame = 0;
3782 valPtr++; // this field represents frame length in bytes (we're not interested right now)
3783 // e.g. if there's 1024 samples per frame stereo, frame length is 4096 (2x2x1024)
3784 SamplesPerFrame = *valPtr++; // read number of samples per frame (1024 or 2048)
3785 SamplingRate = *valPtr++;
3786 NumChannels = *valPtr++;
3788 PROFILE_TYPES profile = OSCL_STATIC_CAST(PROFILE_TYPES, *valPtr++);
3792 OutSampRate = *valPtr++;
3793 ExternlObjType = OSCL_STATIC_CAST(EXTERNAL_OBJECT_TYPES, *valPtr++);
3794 // the next field is the Down sampling mode - which we dont care about here
3795 //iDownSampMode = *valPtr++;
3799 // Now - need to convert the ASF External obj type into proper AAC decoder audio obj type
3801 if (INVALID_OBJ_TYPE == ExternlObjType)
3803 objType = OSCL_STATIC_CAST(eAUDIO_OBJECT_TYPE, profile + 1);
3804 OutSampRate = SamplingRate;
3806 else if (AAC_LC_SBR == ExternlObjType)
3810 else if (ENHANCED_AAC_LC_SBR_PS == ExternlObjType)
3816 objType = OSCL_STATIC_CAST(eAUDIO_OBJECT_TYPE, profile + 1);
3817 OutSampRate = SamplingRate;
3820 uint32 framelength = 1024; // hardcode to fit plain AAC case - since we use plain aac sampling rate as well
3824 uint8 *aConfigHeader = outptr;
3827 if (objType > AOT_PS)
3832 aConfigHeader[0] = (uint8)(objType << 3); /* AudioObjectType 5 bits */
3834 /* Write Sampling frequency */
3835 for (i = 0; i < 15; i++)
3837 if (srIndexTable[i] == SamplingRate)
3845 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3846 (0, "PVMFOMXAudioDecNode::CreateAACConfigDataFromASF() Error - unsupported sampling rate"));
3851 aConfigHeader[0] |= (uint8)(i >> 1); /* SamplingRate 3 of 4 bits */
3852 aConfigHeader[1] = (uint8)(i << 7); /* SamplingRate 1 of 4 bits */
3854 /* Write Number of Channels */
3855 // NumChannels is unsigned so can't be less than 0
3856 // only need to check if the value is too large.
3857 if ((NumChannels > 2))
3859 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3860 (0, "PVMFOMXAudioDecNode::CreateAACConfigDataFromASF() Error - unsupported number of channels"));
3866 aConfigHeader[1] |= (uint8)(NumChannels << 3); /* NumChannels 4 of 4 bits */
3869 /* detect extension AOT */
3870 if ((objType == AOT_SBR) || (objType == AOT_PS))
3872 /* Write Final Sampling frequency */
3874 for (i = 0; i < 15; i++)
3876 if (srIndexTable[i] == OutSampRate)
3884 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
3885 (0, "PVMFOMXAudioDecNode::CreateAACConfigDataFromASF() Error - unsupported sampling rate"));
3890 aConfigHeader[1] |= (uint8)(i >> 1); /* SamplingRate 1 of 4 bits */
3891 aConfigHeader[2] = (uint8)(i << 7); /* SamplingRate 3 of 4 bits */
3893 aConfigHeader[2] |= (uint8)((AOT_AAC_LC) << 2); /* external AudioObjectType 5 bits */
3895 aConfigHeader[3] = (framelength == 960) ? 4 : 0; /* framelength 1 of 1 bits (shifted) */
3896 aConfigHeader[3] |= 0; /* dependsOnCoreCoder 1 bits, 0, see ISO/IEC 14496-3 Subpart 4, 4.4.1 */
3897 aConfigHeader[3] |= 0; /* Extension Flag: Shall be 0 for supported aot */
3904 aConfigHeader[1] |= (framelength == 960) ? 4 : 0; /* framelength 1 of 1 bits (shifted) */
3906 aConfigHeader[1] |= 0; /* dependsOnCoreCoder 1 bits, 0, see ISO/IEC 14496-3 Subpart 4, 4.4.1 */
3907 aConfigHeader[1] |= 0; /* Extension Flag: Shall be 0 for supported aot */
3917 PVMFStatus PVMFOMXAudioDecNode::DoCapConfigReleaseParameters(PvmiKvp* aParameters, int aNumElements)
3919 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::DoCapConfigReleaseParameters() In"));
3921 if (aParameters == NULL || aNumElements < 1)
3923 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::DoCapConfigReleaseParameters() KVP list is NULL or number of elements is 0"));
3924 return PVMFErrArgument;
3928 if (pv_mime_strcmp(aParameters[0].key, _STRLIT_CHAR(PVMF_DEC_AVAILABLE_OMX_COMPONENTS_KEY)) == 0)
3930 // everything was allocated in blocks, so it's enough to release the beginning
3931 oscl_free(aParameters[0].key);
3932 oscl_free(aParameters[0].value.pChar_value);
3933 // Free memory for the parameter list
3934 oscl_free(aParameters);
3937 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::DoCapConfigReleaseParameters() Out"));
3940 else if (pv_mime_strcmp(aParameters[0].key, _STRLIT_CHAR(PVMF_AUDIO_DEC_PCM_BUFFER_DURATION_KEY)) == 0)
3942 oscl_free(aParameters[0].key);
3943 oscl_free(aParameters);
3944 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::DoCapConfigReleaseParameters() Out"));
3949 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::DoCapConfigReleaseParameters() KVP list is NULL or number of elements is 0"));
3950 return PVMFErrArgument;
3953 PVMFStatus PVMFOMXAudioDecNode::DoCapConfigGetParametersSync(PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext)
3955 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXAudioDecNode::DoCapConfigGetParametersSync() In"));
3956 OSCL_UNUSED_ARG(aContext);
3958 // Initialize the output parameters
3959 aNumParamElements = 0;
3962 if (pv_mime_strcmp(aIdentifier, _STRLIT_CHAR(PVMF_DEC_AVAILABLE_OMX_COMPONENTS_KEY)) == 0)
3964 // get the list of omx components that support the track.
3965 // Track config info and mime type was previously set through capconfig - setparametersync
3967 pvAudioConfigParserInputs aInputs;
3968 OMXConfigParserInputs aInputParameters;
3969 AudioOMXConfigParserOutputs aOutputParameters;
3971 aInputs.inPtr = (uint8*) iTrackUnderVerificationConfig;
3972 aInputs.inBytes = (int32) iTrackUnderVerificationConfigSize;
3973 aInputs.iMimeType = iNodeConfig.iMimeType;
3975 aInputParameters.inBytes = aInputs.inBytes;
3976 aInputParameters.inPtr = aInputs.inPtr;
3978 if (aInputs.inBytes == 0 || aInputs.inPtr == NULL)
3980 // in case of following formats - config codec data is expected to
3981 // be present in the query. If not, config parser cannot be called
3983 if (aInputs.iMimeType == PVMF_MIME_WMA ||
3984 aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
3985 aInputs.iMimeType == PVMF_MIME_3640 ||
3986 aInputs.iMimeType == PVMF_MIME_LATM ||
3987 aInputs.iMimeType == PVMF_MIME_ADIF ||
3988 aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
3989 aInputs.iMimeType == PVMF_MIME_AAC_SIZEHDR)
3992 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXAudioDecNode::DoCapConfigGetParameters() Codec Config data is not present"));
3993 return PVMFErrNotSupported;
3999 // in case of ASF_MPEG4 audio need to create aac config header
4000 if (aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO)
4002 if (!CreateAACConfigDataFromASF(aInputParameters.inPtr, aInputParameters.inBytes, &iAACConfigData[0], iAACConfigDataLength))
4004 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR,
4005 (0, "PVMFOMXAudioDecNode::DoCapConfigGetParameters() - Error in creating AAC Codec Config data"));
4008 return PVMFErrNotSupported;
4011 aInputParameters.inPtr = &iAACConfigData[0];
4012 aInputParameters.inBytes = iAACConfigDataLength;
4016 if (aInputs.iMimeType == PVMF_MIME_MPEG4_AUDIO ||
4017 aInputs.iMimeType == PVMF_MIME_3640 ||
4018 aInputs.iMimeType == PVMF_MIME_LATM ||
4019 aInputs.iMimeType == PVMF_MIME_ADIF ||
4020 aInputs.iMimeType == PVMF_MIME_ASF_MPEG4_AUDIO ||
4021 aInputs.iMimeType == PVMF_MIME_AAC_SIZEHDR)
4023 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.aac";
4026 else if (aInputs.iMimeType == PVMF_MIME_AMR_IF2 ||
4027 aInputs.iMimeType == PVMF_MIME_AMR_IETF ||
4028 aInputs.iMimeType == PVMF_MIME_AMR)
4030 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.amrnb";
4032 else if (aInputs.iMimeType == PVMF_MIME_AMRWB_IETF ||
4033 aInputs.iMimeType == PVMF_MIME_AMRWB)
4035 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.amrwb";
4037 else if (aInputs.iMimeType == PVMF_MIME_MP3)
4039 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.mp3";
4041 else if (aInputs.iMimeType == PVMF_MIME_WMA)
4043 aInputParameters.cComponentRole = (OMX_STRING)"audio_decoder.wma";
4047 // Illegal codec specified.
4048 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "%s::PVMFOMXAudioDecNode::DoCapConfigGetParameters() Input port format other then codec type", iName.Str()));
4049 return PVMFErrNotSupported;
4055 OMX_BOOL status = OMX_FALSE;
4056 OMX_U32 num_comps = 0;
4057 OMX_STRING *CompOfRole;
4059 OMX_ERRORTYPE Err = OMX_ErrorNone;
4061 // call once to find out the number of components that can fit the role
4062 Err = OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, NULL);
4067 if ((num_comps > 0) && (OMX_ErrorNone == Err))
4069 // allocate num_comps kvps and keys all in one block
4071 aParameters = (PvmiKvp*)oscl_malloc(num_comps * sizeof(PvmiKvp));
4072 if (aParameters == NULL)
4074 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for KVP failed"));
4075 return PVMFErrNoMemory;
4078 oscl_memset(aParameters, 0, num_comps*sizeof(PvmiKvp));
4080 // Allocate memory for the key strings in each KVP
4081 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(num_comps * (sizeof(_STRLIT_CHAR(PVMF_DEC_AVAILABLE_OMX_COMPONENTS_KEY)) + 1) * sizeof(char));
4082 if (memblock == NULL)
4084 oscl_free(aParameters);
4085 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for key string failed"));
4086 return PVMFErrNoMemory;
4088 oscl_strset(memblock, 0, num_comps *(sizeof(_STRLIT_CHAR(PVMF_DEC_AVAILABLE_OMX_COMPONENTS_KEY)) + 1) * sizeof(char));
4091 // allocate a block of memory for component names
4092 OMX_U8 *memblockomx = (OMX_U8 *) oscl_malloc(num_comps * PV_OMX_MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8));
4093 if (memblockomx == NULL)
4095 oscl_free(aParameters);
4096 oscl_free(memblock);
4097 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for omx component strings failed"));
4098 return PVMFErrNoMemory;
4101 oscl_memset(memblockomx, 0, num_comps * PV_OMX_MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8));
4103 // allocate a placeholder
4104 CompOfRole = (OMX_STRING *)oscl_malloc(num_comps * sizeof(OMX_STRING));
4106 for (ii = 0; ii < num_comps; ii++)
4108 CompOfRole[ii] = (OMX_STRING)(memblockomx + (ii * PV_OMX_MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8)));
4111 // call 2nd time to get the component names
4112 Err = OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, (OMX_U8 **)CompOfRole);
4113 if (OMX_ErrorNone == Err)
4115 for (ii = 0; ii < num_comps; ii++)
4117 aInputParameters.cComponentName = CompOfRole[ii];
4118 status = OMX_MasterConfigParser(&aInputParameters, &aOutputParameters);
4119 if (status == OMX_TRUE)
4121 // component passes the test - write the component name into kvp list
4123 aParameters[ii].key = memblock + (aNumParamElements * (sizeof(_STRLIT_CHAR(PVMF_DEC_AVAILABLE_OMX_COMPONENTS_KEY)) + 1) * sizeof(char)) ;
4124 oscl_strncat(aParameters[ii].key, _STRLIT_CHAR(PVMF_DEC_AVAILABLE_OMX_COMPONENTS_KEY), sizeof(_STRLIT_CHAR(PVMF_DEC_AVAILABLE_OMX_COMPONENTS_KEY)));
4125 aParameters[ii].key[sizeof(_STRLIT_CHAR(PVMF_DEC_AVAILABLE_OMX_COMPONENTS_KEY))] = 0; // null terminate
4128 aParameters[ii].length = PV_OMX_MAX_COMPONENT_NAME_LENGTH;
4130 aParameters[ii].value.pChar_value = CompOfRole[ii];
4131 aNumParamElements++;
4138 // free memory for CompOfRole placeholder.
4139 // The other blocks of memory will be freed during release parameter sync
4140 oscl_free(CompOfRole);
4144 // if no component supports the role, nothing else to do
4145 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "%s::PVMFOMXVideoDecNode::DoCapConfigGetParameters() No OMX components support the role", iName.Str()));
4146 return PVMFErrNotSupported;
4154 else if (pv_mime_strcmp(aIdentifier, PVMF_AUDIO_DEC_PCM_BUFFER_DURATION_KEY) == 0)
4156 // set the mime type if audio format is being used
4157 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
4158 (0, "PVMFOMXAudioDecNode::DoCapConfigGetParameters() audio dec pcm buffer size is %d milliseconds", iOutputBufferPCMDuration));
4161 aNumParamElements = 1;
4162 aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
4163 if (aParameters == NULL)
4165 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for KVP failed"));
4166 return PVMFErrNoMemory;
4168 oscl_memset(aParameters, 0, sizeof(PvmiKvp));
4170 // Allocate memory for the key strings in each KVP
4171 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc((sizeof(_STRLIT_CHAR(PVMF_AUDIO_DEC_PCM_BUFFER_DURATION_KEY)) + 1) * sizeof(char));
4172 if (memblock == NULL)
4174 oscl_free(aParameters);
4175 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for key string failed"));
4176 return PVMFErrNoMemory;
4178 oscl_strset(memblock, 0, (sizeof(_STRLIT_CHAR(PVMF_AUDIO_DEC_PCM_BUFFER_DURATION_KEY)) + 1) * sizeof(char));
4180 aParameters->key = memblock;
4182 oscl_strncat(aParameters->key, _STRLIT_CHAR(PVMF_AUDIO_DEC_PCM_BUFFER_DURATION_KEY), sizeof(_STRLIT_CHAR(PVMF_AUDIO_DEC_PCM_BUFFER_DURATION_KEY)));
4183 aParameters->key[sizeof(_STRLIT_CHAR(PVMF_AUDIO_DEC_PCM_BUFFER_DURATION_KEY))] = 0; // null terminate
4186 aParameters->value.uint32_value = iOutputBufferPCMDuration;
4191 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Out"));
4192 if (aNumParamElements == 0)
4194 // If no one could get the parameter, return error
4195 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Unsupported key"));