1/* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18#include "pvmf_omx_videodec_node.h" 19#include "pvlogger.h" 20#include "oscl_error_codes.h" 21#include "pvmf_omx_basedec_port.h" 22#include "pv_mime_string_utils.h" 23#include "oscl_snprintf.h" 24#include "pvmf_media_cmd.h" 25#include "pvmf_media_msg_format_ids.h" 26#include "pvmi_kvp_util.h" 27// needed for capability and config 28#include "pv_omx_config_parser.h" 29 30 31#include "OMX_Core.h" 32#include "pvmf_omx_basedec_callbacks.h" //used for thin AO in Decoder's callbacks 33#include "pv_omxcore.h" 34#include "OMX_Video.h" 35 36#include "utils/Log.h" 37#undef LOG_TAG 38#define LOG_TAG "PVOMXVidDecNode" 39 40#define CONFIG_SIZE_AND_VERSION(param) \ 41 param.nSize=sizeof(param); \ 42 param.nVersion.s.nVersionMajor = SPECVERSIONMAJOR; \ 43 param.nVersion.s.nVersionMinor = SPECVERSIONMINOR; \ 44 param.nVersion.s.nRevision = SPECREVISION; \ 45 param.nVersion.s.nStep = SPECSTEP; 46 47 48#define PVOMXVIDEODEC_EXTRA_YUVBUFFER_POOLNUM 3 49#define PVOMXVIDEODEC_MEDIADATA_POOLNUM (PVOMXVIDEODECMAXNUMDPBFRAMESPLUS1 + PVOMXVIDEODEC_EXTRA_YUVBUFFER_POOLNUM) 50 51 52// Node default settings 53#define PVOMXVIDEODECNODE_CONFIG_POSTPROCENABLE_DEF false 54#define PVOMXVIDEODECNODE_CONFIG_POSTPROCTYPE_DEF 0 // 0 (nopostproc),1(deblock),3(deblock&&dering) 55#define PVOMXVIDEODECNODE_CONFIG_DROPFRAMEENABLE_DEF false 56// H263 default settings 57#define PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_DEF 40000 58#define PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MIN 20000 59#define PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MAX 120000 60#define PVOMXVIDEODECNODE_CONFIG_H263MAXWIDTH_DEF 352 61#define PVOMXVIDEODECNODE_CONFIG_H263MAXHEIGHT_DEF 288 62#define PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MIN 4 63#define PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MAX 352 64// M4v default settings 65#define PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_DEF 40000 66#define PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MIN 20000 67#define PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MAX 120000 68#define PVOMXVIDEODECNODE_CONFIG_M4VMAXWIDTH_DEF 352 69#define PVOMXVIDEODECNODE_CONFIG_M4VMAXHEIGHT_DEF 288 70#define PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MIN 4 71#define PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MAX 352 72 73// AVC default settings 74#define PVOMXVIDEODECNODE_CONFIG_AVCMAXBITSTREAMFRAMESIZE_DEF 20000 75#define PVOMXVIDEODECNODE_CONFIG_AVCMAXBITSTREAMFRAMESIZE_MIN 20000 76#define PVOMXVIDEODECNODE_CONFIG_AVCMAXBITSTREAMFRAMESIZE_MAX 120000 77#define PVOMXVIDEODECNODE_CONFIG_AVCMAXWIDTH_DEF 352 78#define PVOMXVIDEODECNODE_CONFIG_AVCMAXHEIGHT_DEF 288 79#define PVOMXVIDEODECNODE_CONFIG_AVCMAXDIMENSION_MIN 4 80#define PVOMXVIDEODECNODE_CONFIG_AVCMAXDIMENSION_MAX 352 81 82/* WMV default settings */ 83#define PVOMXVIDEODECNODE_CONFIG_WMVMAXWIDTH_DEF 352 84#define PVOMXVIDEODECNODE_CONFIG_WMVMAXHEIGHT_DEF 288 85 86 87#define PVMF_OMXVIDEODEC_NUM_METADATA_VALUES 6 88 89// Constant character strings for metadata keys 90static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY[] = "codec-info/video/format"; 91static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY[] = "codec-info/video/width"; 92static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY[] = "codec-info/video/height"; 93static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY[] = "codec-info/video/profile"; 94static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY[] = "codec-info/video/level"; 95static const char PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY[] = "codec-info/video/avgbitrate";//(bits per sec) 96 97static const char PVOMXVIDEODECMETADATA_SEMICOLON[] = ";"; 98 99///////////////////////////////////////////////////////////////////////////// 100// Class Destructor 101///////////////////////////////////////////////////////////////////////////// 102PVMFOMXVideoDecNode::~PVMFOMXVideoDecNode() 103{ 104 ReleaseAllPorts(); 105} 106 107///////////////////////////////////////////////////////////////////////////// 108// Add AO to the scheduler 109///////////////////////////////////////////////////////////////////////////// 110PVMFStatus PVMFOMXVideoDecNode::ThreadLogon() 111{ 112 PVLOGGER_LOGMSG(PVLOGMSG_INST_MLDBG, iLogger, PVLOGMSG_INFO, (0, "PVMFOMXVideoDecNode:ThreadLogon")); 113 114 switch (iInterfaceState) 115 { 116 case EPVMFNodeCreated: 117 if (!IsAdded()) 118 { 119 AddToScheduler(); 120 iIsAdded = true; 121 } 122 iLogger = PVLogger::GetLoggerObject("PVMFOMXVideoDecNode"); 123 iRunlLogger = PVLogger::GetLoggerObject("Run.PVMFOMXVideoDecNode"); 124 iDataPathLogger = PVLogger::GetLoggerObject("datapath"); 125 iClockLogger = PVLogger::GetLoggerObject("clock"); 126 iDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.decnode.OMXVideoDecnode"); 127 128 SetState(EPVMFNodeIdle); 129 return PVMFSuccess; 130 default: 131 return PVMFErrInvalidState; 132 } 133} 134 135///////////////////// 136// Private Section // 137///////////////////// 138 139///////////////////////////////////////////////////////////////////////////// 140// Class Constructor 141///////////////////////////////////////////////////////////////////////////// 142PVMFOMXVideoDecNode::PVMFOMXVideoDecNode(int32 aPriority, bool aHwAccelerated) : 143 PVMFOMXBaseDecNode(aPriority, "PVMFOMXVideoDecNode", aHwAccelerated), 144 iH263MaxBitstreamFrameSize(PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_DEF), 145 iH263MaxWidth(PVOMXVIDEODECNODE_CONFIG_H263MAXWIDTH_DEF), 146 iH263MaxHeight(PVOMXVIDEODECNODE_CONFIG_H263MAXHEIGHT_DEF), 147 iM4VMaxBitstreamFrameSize(PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_DEF), 148 iM4VMaxWidth(PVOMXVIDEODECNODE_CONFIG_M4VMAXWIDTH_DEF), 149 iM4VMaxHeight(PVOMXVIDEODECNODE_CONFIG_M4VMAXHEIGHT_DEF), 150 iNewWidth(0), 151 iNewHeight(0) 152{ 153 iInterfaceState = EPVMFNodeCreated; 154 155 iNodeConfig.iPostProcessingEnable = PVOMXVIDEODECNODE_CONFIG_POSTPROCENABLE_DEF; 156 iNodeConfig.iPostProcessingMode = PVOMXVIDEODECNODE_CONFIG_POSTPROCTYPE_DEF; 157 iNodeConfig.iDropFrame = PVOMXVIDEODECNODE_CONFIG_DROPFRAMEENABLE_DEF; 158 iNodeConfig.iMimeType = PVMF_MIME_FORMAT_UNKNOWN; 159 160 161 int32 err; 162 OSCL_TRY(err, 163 164 //Create the input command queue. Use a reserve to avoid lots of 165 //dynamic memory allocation. 166 iInputCommands.Construct(PVMF_OMXBASEDEC_NODE_COMMAND_ID_START, PVMF_OMXBASEDEC_NODE_COMMAND_VECTOR_RESERVE); 167 168 //Create the "current command" queue. It will only contain one 169 //command at a time, so use a reserve of 1. 170 iCurrentCommand.Construct(0, 1); 171 172 //Set the node capability data. 173 //This node can support an unlimited number of ports. 174 iCapability.iCanSupportMultipleInputPorts = false; 175 iCapability.iCanSupportMultipleOutputPorts = false; 176 iCapability.iHasMaxNumberOfPorts = true; 177 iCapability.iMaxNumberOfPorts = 2; 178 iCapability.iInputFormatCapability.push_back(PVMF_MIME_H264_VIDEO_MP4); 179 iCapability.iInputFormatCapability.push_back(PVMF_MIME_H264_VIDEO_RAW); 180 iCapability.iInputFormatCapability.push_back(PVMF_MIME_H264_VIDEO); 181 iCapability.iInputFormatCapability.push_back(PVMF_MIME_M4V); 182 iCapability.iInputFormatCapability.push_back(PVMF_MIME_H2631998); 183 iCapability.iInputFormatCapability.push_back(PVMF_MIME_H2632000); 184 iCapability.iInputFormatCapability.push_back(PVMF_MIME_WMV); 185 iCapability.iOutputFormatCapability.push_back(PVMF_MIME_YUV420); 186 187 iAvailableMetadataKeys.reserve(PVMF_OMXVIDEODEC_NUM_METADATA_VALUES); 188 iAvailableMetadataKeys.clear(); 189 ); 190 191 // need to init this allocator since verifyParameterSync (using the buffers) may be called through 192 // port interface before anything else happens. 193 OSCL_TRY(err, iFsiFragmentAlloc.size(PVOMXVIDEODEC_MEDIADATA_POOLNUM, sizeof(PVMFYuvFormatSpecificInfo0))); 194 195 OSCL_TRY(err, iPrivateDataFsiFragmentAlloc.size(PVOMXVIDEODEC_MEDIADATA_POOLNUM, sizeof(OsclAny *))); 196 197 iLastYUVWidth = 0; 198 iLastYUVHeight = 0; 199 iStride = 0; 200 iSliceHeight = 0; 201} 202 203///////////////////////////////////////////////////////////////////////////// 204// This routine will handle the PortReEnable state 205///////////////////////////////////////////////////////////////////////////// 206PVMFStatus PVMFOMXVideoDecNode::HandlePortReEnable() 207{ 208 // set the port index so that we get parameters for the proper port 209 iParamPort.nPortIndex = iPortIndexForDynamicReconfig; 210 211 CONFIG_SIZE_AND_VERSION(iParamPort); 212 213 // get new parameters of the port 214 OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort); 215 216 // send command for port re-enabling (for this to happen, we must first recreate the buffers) 217 OMX_SendCommand(iOMXDecoder, OMX_CommandPortEnable, iPortIndexForDynamicReconfig, NULL); 218 219 // is this output port? 220 if (iPortIndexForDynamicReconfig == iOutputPortIndex) 221 { 222 // set the new width / height 223 iYUVWidth = iParamPort.format.video.nFrameWidth; 224 iYUVHeight = iParamPort.format.video.nFrameHeight; 225 226 iOMXComponentOutputBufferSize = iParamPort.nBufferSize; 227 228 // do we need to increase the number of buffers? 229 if (iNumOutputBuffers < iParamPort.nBufferCountMin) 230 iNumOutputBuffers = iParamPort.nBufferCountMin; 231 232 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 233 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() new output buffers %d, size %d", iNumOutputBuffers, iOMXComponentOutputBufferSize)); 234 235 iStride = OSCL_ABS(iParamPort.format.video.nStride); 236 iSliceHeight = iParamPort.format.video.nSliceHeight; 237 238 // This should not happen. If it does, it is a bug in the OMX component. 239 OSCL_ASSERT( (iStride < iParamPort.format.video.nFrameWidth) || (iSliceHeight < iParamPort.format.video.nFrameHeight) ); 240 if (iStride < iParamPort.format.video.nFrameWidth) 241 { 242 iStride = iParamPort.format.video.nFrameWidth; 243 } 244 245 if (iSliceHeight < iParamPort.format.video.nFrameHeight) 246 { 247 iSliceHeight = iParamPort.format.video.nFrameHeight; 248 } 249 250 // Before allocating new set of output buffers, re-send Video FSI to 251 // media output node in case of dynamic port reconfiguration 252 253 sendFsi = true; 254 iCompactFSISettingSucceeded = false; 255 256 iLastYUVWidth = iYUVWidth ; 257 iLastYUVHeight = iYUVHeight; 258 259 // Check if Fsi configuration need to be sent 260 if (sendFsi) 261 { 262 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 263 (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Re-sending YUV FSI after Dynamic port reconfiguration")); 264 265 int fsiErrorCode = 0; 266 OsclRefCounterMemFrag yuvFsiMemfrag; 267 268 OSCL_TRY(fsiErrorCode, yuvFsiMemfrag = iFsiFragmentAlloc.get();); 269 270 OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 271 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() Failed to allocate memory for FSI"))); 272 273 if (fsiErrorCode == 0) 274 { 275 PVMFYuvFormatSpecificInfo0* fsiInfo = OSCL_PLACEMENT_NEW(yuvFsiMemfrag.getMemFragPtr(), PVMFYuvFormatSpecificInfo0()); 276 if (fsiInfo != NULL) 277 { 278 fsiInfo->uid = PVMFYuvFormatSpecificInfo0_UID; 279 fsiInfo->video_format = iYUVFormat; 280 fsiInfo->display_width = iYUVWidth; 281 fsiInfo->display_height = iYUVHeight; 282 fsiInfo->num_buffers = iNumOutputBuffers; 283 fsiInfo->buffer_size = iOMXComponentOutputBufferSize; 284 fsiInfo->width = iStride; 285 fsiInfo->height = iSliceHeight; 286 287 OsclMemAllocator alloc; 288 int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY_YUV) + 1; 289 PvmiKeyType KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength); 290 291 if (NULL == KvpKey) 292 { 293 return false; 294 } 295 296 oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY_YUV, KeyLength); 297 int32 err; 298 299 OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(yuvFsiMemfrag, KvpKey);); 300 if (err != OsclErrNone) 301 { 302 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 303 (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Problem to set FSI")); 304 305 } 306 else 307 { 308 sendFsi = false; 309 iCompactFSISettingSucceeded = true; 310 } 311 312 313 314 alloc.deallocate((OsclAny*)(KvpKey)); 315 fsiInfo->video_format.~PVMFFormatType(); 316 } 317 else 318 { 319 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 320 (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Problem allocating Output FSI")); 321 SetState(EPVMFNodeError); 322 ReportErrorEvent(PVMFErrNoMemory); 323 return false; // this is going to make everything go out of scope 324 } 325 } 326 else 327 { 328 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 329 (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Problem allocating Output FSI")); 330 return false; // this is going to make everything go out of scope 331 } 332 333 334 } 335 336 //Buffer allocation has to be done again in case we landed to port reconfiguration 337 PvmiKvp* kvp = NULL; 338 int numKvp = 0; 339 PvmiKeyType aIdentifier = (PvmiKeyType)PVMF_BUFFER_ALLOCATOR_KEY; 340 int32 err, err1; 341 ipExternalOutputBufferAllocatorInterface = NULL; 342 343 OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiGetBufferAllocatorSpecificInfoSync(aIdentifier, kvp, numKvp);); 344 345 if ((err == OsclErrNone) && (NULL != kvp)) 346 { 347 ipExternalOutputBufferAllocatorInterface = (PVInterface*) kvp->value.key_specific_value; 348 349 if (ipExternalOutputBufferAllocatorInterface) 350 { 351 PVInterface* pTempPVInterfacePtr = NULL; 352 353 OSCL_TRY(err, ipExternalOutputBufferAllocatorInterface->queryInterface(PVMFFixedSizeBufferAllocUUID, pTempPVInterfacePtr);); 354 355 OSCL_TRY(err1, ((PVMFOMXDecPort*)iOutPort)->releaseParametersSync(kvp, numKvp);); 356 357 if (err1 != OsclErrNone) 358 { 359 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 360 (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Unable to Release Parameters")); 361 } 362 363 if ((err == OsclErrNone) && (NULL != pTempPVInterfacePtr)) 364 { 365 ipFixedSizeBufferAlloc = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, pTempPVInterfacePtr); 366 367 uint32 iNumBuffers, iBufferSize; 368 369 iNumBuffers = ipFixedSizeBufferAlloc->getNumBuffers(); 370 iBufferSize = ipFixedSizeBufferAlloc->getBufferSize(); 371 372 if ((iNumBuffers < iParamPort.nBufferCountMin) || (iBufferSize < iOMXComponentOutputBufferSize)) 373 { 374 ipExternalOutputBufferAllocatorInterface->removeRef(); 375 ipExternalOutputBufferAllocatorInterface = NULL; 376 } 377 else 378 { 379 iNumOutputBuffers = iNumBuffers; 380 iOMXComponentOutputBufferSize = iBufferSize; 381 } 382 } 383 else 384 { 385 ipExternalOutputBufferAllocatorInterface->removeRef(); 386 ipExternalOutputBufferAllocatorInterface = NULL; 387 } 388 } 389 } 390 391 392 /* Allocate output buffers */ 393 if (!CreateOutMemPool(iNumOutputBuffers)) 394 { 395 396 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 397 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot allocate output buffers ")); 398 399 SetState(EPVMFNodeError); 400 ReportErrorEvent(PVMFErrNoMemory); 401 return PVMFErrNoMemory; 402 } 403 404 if (out_ctrl_struct_ptr == NULL) 405 { 406 407 out_ctrl_struct_ptr = (OsclAny **) oscl_malloc(iNumOutputBuffers * sizeof(OsclAny *)); 408 409 if (out_ctrl_struct_ptr == NULL) 410 { 411 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 412 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() out_ctrl_struct_ptr == NULL")); 413 414 SetState(EPVMFNodeError); 415 ReportErrorEvent(PVMFErrNoMemory); 416 return PVMFErrNoMemory; 417 } 418 } 419 420 if (out_buff_hdr_ptr == NULL) 421 { 422 423 out_buff_hdr_ptr = (OsclAny **) oscl_malloc(iNumOutputBuffers * sizeof(OsclAny *)); 424 425 if (out_buff_hdr_ptr == NULL) 426 { 427 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 428 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() out_buff_hdr_ptr == NULL")); 429 430 SetState(EPVMFNodeError); 431 ReportErrorEvent(PVMFErrNoMemory); 432 return PVMFErrNoMemory; 433 } 434 } 435 436 437 if (!ProvideBuffersToComponent(iOutBufMemoryPool, // allocator 438 iOutputAllocSize, // size to allocate from pool (hdr only or hdr+ buffer) 439 iNumOutputBuffers, // number of buffers 440 iOMXComponentOutputBufferSize, // actual buffer size 441 iOutputPortIndex, // port idx 442 iOMXComponentSupportsExternalOutputBufferAlloc, // can component use OMX_UseBuffer 443 false // this is not input 444 )) 445 { 446 447 448 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 449 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot provide output buffers to component")); 450 451 SetState(EPVMFNodeError); 452 ReportErrorEvent(PVMFErrNoMemory); 453 return PVMFErrNoMemory; 454 455 } 456 457 // do not drop output any more, i.e. enable output to be sent downstream 458 iDoNotSendOutputBuffersDownstreamFlag = false; 459 460 461 } 462 else 463 { 464 // this is input port 465 466 iOMXComponentInputBufferSize = iParamPort.nBufferSize; 467 // do we need to increase the number of buffers? 468 if (iNumInputBuffers < iParamPort.nBufferCountMin) 469 iNumInputBuffers = iParamPort.nBufferCountMin; 470 471 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 472 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() new buffers %d, size %d", iNumInputBuffers, iOMXComponentInputBufferSize)); 473 474 /* Allocate input buffers */ 475 if (!CreateInputMemPool(iNumInputBuffers)) 476 { 477 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 478 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot allocate new input buffers to component")); 479 480 SetState(EPVMFNodeError); 481 ReportErrorEvent(PVMFErrNoMemory); 482 return PVMFErrNoMemory; 483 } 484 485 if (in_ctrl_struct_ptr == NULL) 486 { 487 488 in_ctrl_struct_ptr = (OsclAny **) oscl_malloc(iNumInputBuffers * sizeof(OsclAny *)); 489 490 if (in_ctrl_struct_ptr == NULL) 491 { 492 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 493 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() in_ctrl_struct_ptr == NULL")); 494 495 SetState(EPVMFNodeError); 496 ReportErrorEvent(PVMFErrNoMemory); 497 return PVMFErrNoMemory; 498 } 499 } 500 501 if (in_buff_hdr_ptr == NULL) 502 { 503 504 in_buff_hdr_ptr = (OsclAny **) oscl_malloc(iNumInputBuffers * sizeof(OsclAny *)); 505 506 if (in_buff_hdr_ptr == NULL) 507 { 508 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 509 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() in_buff_hdr_ptr == NULL")); 510 511 SetState(EPVMFNodeError); 512 ReportErrorEvent(PVMFErrNoMemory); 513 return PVMFErrNoMemory; 514 } 515 } 516 517 if (!ProvideBuffersToComponent(iInBufMemoryPool, // allocator 518 iInputAllocSize, // size to allocate from pool (hdr only or hdr+ buffer) 519 iNumInputBuffers, // number of buffers 520 iOMXComponentInputBufferSize, // actual buffer size 521 iInputPortIndex, // port idx 522 iOMXComponentSupportsExternalInputBufferAlloc, // can component use OMX_UseBuffer 523 true // this is input 524 )) 525 { 526 527 528 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 529 (0, "PVMFOMXVideoDecNode::HandlePortReEnable() Port Reconfiguration -> Cannot provide new input buffers to component")); 530 531 SetState(EPVMFNodeError); 532 ReportErrorEvent(PVMFErrNoMemory); 533 return PVMFErrNoMemory; 534 535 } 536 // do not drop partially consumed input 537 iDoNotSaveInputBuffersFlag = false; 538 539 540 } 541 542 // if the callback that the port was re-enabled has not arrived yet, wait for it 543 // if it has arrived, it will set the state to either PortReconfig or to ReadyToDecode 544 if (iProcessingState != EPVMFOMXBaseDecNodeProcessingState_PortReconfig && 545 iProcessingState != EPVMFOMXBaseDecNodeProcessingState_ReadyToDecode) 546 iProcessingState = EPVMFOMXBaseDecNodeProcessingState_WaitForPortEnable; 547 548 return PVMFSuccess; // allow rescheduling of the node 549} 550//////////////////////////////////////////////////////////////////////////////// 551bool PVMFOMXVideoDecNode::NegotiateComponentParameters(OMX_PTR aOutputParameters) 552{ 553 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 554 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() In")); 555 556 OMX_ERRORTYPE Err; 557 // first get the number of ports and port indices 558 OMX_PORT_PARAM_TYPE VideoPortParameters; 559 uint32 NumPorts; 560 uint32 ii; 561 562 //set version and size; 563 CONFIG_SIZE_AND_VERSION(VideoPortParameters); 564 // get starting number 565 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamVideoInit, &VideoPortParameters); 566 NumPorts = VideoPortParameters.nPorts; // must be at least 2 of them (in&out) 567 568 if (Err != OMX_ErrorNone || NumPorts < 2) 569 { 570 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 571 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() There is insuffucient (%d) ports", NumPorts)); 572 return false; 573 } 574 575 576 // loop through video ports starting from the starting index to find index of the first input port 577 for (ii = VideoPortParameters.nStartPortNumber ; ii < VideoPortParameters.nStartPortNumber + NumPorts; ii++) 578 { 579 // get port parameters, and determine if it is input or output 580 // if there are more than 2 ports, the first one we encounter that has input direction is picked 581 582 CONFIG_SIZE_AND_VERSION(iParamPort); 583 584 //port 585 iParamPort.nPortIndex = ii; // iInputPortIndex; //OMF_MC_H264D_PORT_INDEX_OF_STREAM; 586 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort); 587 588 if (Err != OMX_ErrorNone) 589 { 590 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 591 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem negotiating with port %d ", ii)); 592 593 return false; 594 } 595 596 if (iParamPort.eDir == OMX_DirInput) 597 { 598 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 599 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Found Input port index %d ", ii)); 600 601 iInputPortIndex = ii; 602 break; 603 } 604 } 605 if (ii == VideoPortParameters.nStartPortNumber + NumPorts) 606 { 607 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 608 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Cannot find any input port ")); 609 return false; 610 } 611 612 613 // loop through video ports starting from the starting index to find index of the first output port 614 for (ii = VideoPortParameters.nStartPortNumber ; ii < VideoPortParameters.nStartPortNumber + NumPorts; ii++) 615 { 616 // get port parameters, and determine if it is input or output 617 // if there are more than 2 ports, the first one we encounter that has output direction is picked 618 619 CONFIG_SIZE_AND_VERSION(iParamPort); 620 621 //port 622 iParamPort.nPortIndex = ii; 623 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort); 624 625 if (Err != OMX_ErrorNone) 626 { 627 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 628 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem negotiating with port %d ", ii)); 629 630 return false; 631 } 632 633 if (iParamPort.eDir == OMX_DirOutput) 634 { 635 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 636 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Found Output port index %d ", ii)); 637 638 iOutputPortIndex = ii; 639 break; 640 } 641 } 642 if (ii == VideoPortParameters.nStartPortNumber + NumPorts) 643 { 644 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 645 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Cannot find any output port ")); 646 return false; 647 } 648 649 650 651 // now get input parameters 652 CONFIG_SIZE_AND_VERSION(iParamPort); 653 654 //Input port 655 iParamPort.nPortIndex = iInputPortIndex; 656 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort); 657 if (Err != OMX_ErrorNone) 658 { 659 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 660 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem negotiating with input port %d ", iInputPortIndex)); 661 return false; 662 } 663 664 // preset the number of input buffers 665 666 //iNumInputBuffers = NUMBER_INPUT_BUFFER; 667 iNumInputBuffers = iParamPort.nBufferCountActual; // use the value provided by component 668 669 // do we need to increase the number of buffers? 670 if (iNumInputBuffers < iParamPort.nBufferCountMin) 671 iNumInputBuffers = iParamPort.nBufferCountMin; 672 iOMXComponentInputBufferSize = iParamPort.nBufferSize; 673 674 iParamPort.nBufferCountActual = iNumInputBuffers; 675 676 // set the number of actual input buffers 677 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 678 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Inport buffers %d,size %d", iNumInputBuffers, iOMXComponentInputBufferSize)); 679 680 681 VideoOMXConfigParserOutputs *pOutputParameters; 682 683 pOutputParameters = (VideoOMXConfigParserOutputs *)aOutputParameters; 684 685 686 // set the width/height on INPUT port parameters (this may change during port reconfig) 687 if ((pOutputParameters->width != 0) && (pOutputParameters->height != 0)) 688 { 689 iParamPort.format.video.nFrameWidth = pOutputParameters->width; 690 iParamPort.format.video.nFrameHeight = pOutputParameters->height; 691 } 692 693 CONFIG_SIZE_AND_VERSION(iParamPort); 694 Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort); 695 if (Err != OMX_ErrorNone) 696 { 697 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 698 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting parameters in input port %d ", iInputPortIndex)); 699 return false; 700 } 701 702 //Port 1 for output port 703 iParamPort.nPortIndex = iOutputPortIndex; 704 CONFIG_SIZE_AND_VERSION(iParamPort); 705 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort); 706 if (Err != OMX_ErrorNone) 707 { 708 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 709 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem negotiating with output port %d ", iOutputPortIndex)); 710 return false; 711 } 712 713 // check if params are OK. In case of H263, width/height cannot be obtained until 714 // 1st frame is decoded, so read them from the output port. 715 // otherwise, used Width/Height from the config parser utility 716 // set the width/height based on port parameters (this may change during port reconfig) 717 if ((pOutputParameters->width != 0) && (pOutputParameters->height != 0) && iInPort && (((PVMFOMXDecPort*)iInPort)->iFormat != PVMF_MIME_H2631998 || ((PVMFOMXDecPort*)iInPort)->iFormat != PVMF_MIME_H2632000)) 718 { 719 // set width and height obtained from config parser in the output port as well 720 iParamPort.format.video.nFrameWidth = pOutputParameters->width; 721 iParamPort.format.video.nFrameHeight = pOutputParameters->height; 722 iYUVWidth = pOutputParameters->width; 723 iYUVHeight = pOutputParameters->height; 724 } 725 else 726 { 727 iYUVWidth = iParamPort.format.video.nFrameWidth; 728 iYUVHeight = iParamPort.format.video.nFrameHeight; 729 } 730 731 // Send the parameters right away to allow the OMX component to re-calculate the buffer size 732 // based on the new width and height that was just provided 733 CONFIG_SIZE_AND_VERSION(iParamPort); 734 735 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 736 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Outport buffers %d,size %d", iNumOutputBuffers, iOMXComponentOutputBufferSize)); 737 738 Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort); 739 if (Err != OMX_ErrorNone) 740 { 741 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 742 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting parameters in output port %d ", iOutputPortIndex)); 743 return false; 744 } 745 746 // Now - read the same parameters back again with potentially new buffer sizes 747 iParamPort.nPortIndex = iOutputPortIndex; 748 CONFIG_SIZE_AND_VERSION(iParamPort); 749 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort); 750 if (Err != OMX_ErrorNone) 751 { 752 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 753 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem negotiating with output port %d ", iOutputPortIndex)); 754 return false; 755 } 756 757 758 //iNumOutputBuffers = NUMBER_OUTPUT_BUFFER; 759 iNumOutputBuffers = iParamPort.nBufferCountActual; 760 if (iNumOutputBuffers > NUMBER_OUTPUT_BUFFER) 761 iNumOutputBuffers = NUMBER_OUTPUT_BUFFER; // make sure number of output buffers is not larger than port queue size 762 763 iOMXComponentOutputBufferSize = iParamPort.nBufferSize; 764 if (iNumOutputBuffers < iParamPort.nBufferCountMin) 765 iNumOutputBuffers = iParamPort.nBufferCountMin; 766 767 iStride = OSCL_ABS(iParamPort.format.video.nStride); 768 iSliceHeight = iParamPort.format.video.nSliceHeight; 769 770 // This should not happen. If it does, it is a bug in the OMX component. 771 OSCL_ASSERT( (iStride < iParamPort.format.video.nFrameWidth) || (iSliceHeight < iParamPort.format.video.nFrameHeight) ); 772 if (iStride < iParamPort.format.video.nFrameWidth) 773 { 774 iStride = iParamPort.format.video.nFrameWidth; 775 } 776 777 if(iSliceHeight < iParamPort.format.video.nFrameHeight) 778 { 779 iSliceHeight = iParamPort.format.video.nFrameHeight; 780 } 781 782 //Send the FSI information to media output node here, before setting output 783 //port parameters to the omx component 784 785 if (iLastYUVWidth != iYUVWidth || iYUVHeight != iLastYUVHeight) 786 { 787 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 788 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters - Sending YUV FSI")); 789 790 // set a flag to send Fsi configuration 791 sendFsi = true; 792 iCompactFSISettingSucceeded = false; 793 //store new values for reference 794 iLastYUVWidth = iYUVWidth ; 795 iLastYUVHeight = iYUVHeight; 796 } 797 798{ 799 // Get video color format 800 OMX_VIDEO_PARAM_PORTFORMATTYPE VideoPortFormat; 801 // init to unknown 802 iOMXVideoColorFormat = OMX_COLOR_FormatUnused; 803 CONFIG_SIZE_AND_VERSION(VideoPortFormat); 804 VideoPortFormat.nPortIndex = iOutputPortIndex; 805 806 VideoPortFormat.nIndex = 0; // read the preferred format - first 807 808// doing this in a while loop while incrementing nIndex will get all supported formats 809// until component says OMX_ErrorNoMore 810// For now, we just use the preferred one (with nIndex=0) assuming it is supported at MIO 811 812 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamVideoPortFormat, &VideoPortFormat); 813 if (Err != OMX_ErrorNone) 814 { 815 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 816 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem getting video port format")); 817 return false; 818 } 819 // check if color format is valid and set DeBlocking 820 if (VideoPortFormat.eCompressionFormat == OMX_VIDEO_CodingUnused) 821 { 822 // color format is valid, so read it 823 iOMXVideoColorFormat = VideoPortFormat.eColorFormat; 824 825 // Now set the format to confirm parameters 826 CONFIG_SIZE_AND_VERSION(VideoPortFormat); 827 828 Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamVideoPortFormat, &VideoPortFormat); 829 if (Err != OMX_ErrorNone) 830 { 831 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 832 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting video port format")); 833 return false; 834 } 835 } 836 837 // now that we have the color format, interpret it 838 if (iOMXVideoColorFormat == OMX_COLOR_Format8bitRGB332) 839 { 840 iYUVFormat = PVMF_MIME_RGB8; 841 } 842 else if (iOMXVideoColorFormat == OMX_COLOR_Format12bitRGB444) 843 { 844 iYUVFormat = PVMF_MIME_RGB12; 845 } 846 else if (iOMXVideoColorFormat >= OMX_COLOR_Format16bitARGB4444 && iOMXVideoColorFormat <= OMX_COLOR_Format16bitBGR565) 847 { 848 iYUVFormat = PVMF_MIME_RGB16; 849 } 850 else if (iOMXVideoColorFormat >= OMX_COLOR_Format24bitRGB888 && iOMXVideoColorFormat <= OMX_COLOR_Format24bitARGB1887) 851 { 852 iYUVFormat = PVMF_MIME_RGB24; 853 } 854 else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV420Planar) 855 { 856 iYUVFormat = PVMF_MIME_YUV420_PLANAR; // Y, U, V are separate - entire planes 857 } 858 else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV420PackedPlanar) 859 { 860 iYUVFormat = PVMF_MIME_YUV420_PACKEDPLANAR; // each slice contains Y,U,V separate 861 } 862 else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) 863 { 864 iYUVFormat = PVMF_MIME_YUV420_SEMIPLANAR; // Y and UV interleaved - entire planes 865 } 866 else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV420PackedSemiPlanar) 867 { 868 iYUVFormat = PVMF_MIME_YUV420_PACKEDSEMIPLANAR; // Y and UV interleaved - sliced 869 } 870 else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV422Planar) 871 { 872 iYUVFormat = PVMF_MIME_YUV422_PLANAR; // Y, U, V are separate - entire planes 873 } 874 else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV422PackedPlanar) 875 { 876 iYUVFormat = PVMF_MIME_YUV422_PACKEDPLANAR; // each slice contains Y,U,V separate 877 } 878 else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV422SemiPlanar) 879 { 880 iYUVFormat = PVMF_MIME_YUV422_SEMIPLANAR; // Y and UV interleaved - entire planes 881 } 882 else if (iOMXVideoColorFormat == OMX_COLOR_FormatYUV422PackedSemiPlanar) 883 { 884 iYUVFormat = PVMF_MIME_YUV422_PACKEDSEMIPLANAR; // Y and UV interleaved - sliced 885 } 886 else if (iOMXVideoColorFormat == OMX_COLOR_FormatCbYCrY) 887 { 888 iYUVFormat = PVMF_MIME_YUV422_INTERLEAVED_UYVY; // Y, U, V interleaved 889 } 890 else if (iOMXVideoColorFormat == 0x7FA30C00) // SPECIAL VALUE 891 { 892 iYUVFormat = PVMF_MIME_YUV420_SEMIPLANAR_YVU; // semiplanar with Y and VU interleaved 893 } 894 else 895 { 896 iYUVFormat = PVMF_MIME_FORMAT_UNKNOWN; 897 return false; 898 } 899} 900 901 // Check if Fsi configuration need to be sent 902 if (sendFsi) 903 { 904 int fsiErrorCode = 0; 905 OsclRefCounterMemFrag yuvFsiMemfrag; 906 907 OSCL_TRY(fsiErrorCode, yuvFsiMemfrag = iFsiFragmentAlloc.get();); 908 909 OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 910 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Failed to allocate memory for FSI"))); 911 912 if (fsiErrorCode == 0) 913 { 914 PVMFYuvFormatSpecificInfo0* fsiInfo = OSCL_PLACEMENT_NEW(yuvFsiMemfrag.getMemFragPtr(), PVMFYuvFormatSpecificInfo0()); 915 if (fsiInfo != NULL) 916 { 917 fsiInfo->uid = PVMFYuvFormatSpecificInfo0_UID; 918 fsiInfo->video_format = iYUVFormat; 919 fsiInfo->display_width = iYUVWidth; 920 fsiInfo->display_height = iYUVHeight; 921 fsiInfo->num_buffers = iNumOutputBuffers; 922 fsiInfo->buffer_size = iOMXComponentOutputBufferSize; 923 fsiInfo->width = iStride; 924 fsiInfo->height = iSliceHeight; 925 926 OsclMemAllocator alloc; 927 int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY_YUV) + 1; 928 PvmiKeyType KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength); 929 930 if (NULL == KvpKey) 931 { 932 return false; 933 } 934 935 oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY_YUV, KeyLength); 936 int32 err; 937 938 OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(yuvFsiMemfrag, KvpKey);); 939 940 if (err != OsclErrNone) 941 { 942 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 943 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters - Problem to set FSI")); 944 } 945 else 946 { 947 iCompactFSISettingSucceeded = true; 948 sendFsi = false; 949 } 950 951 952 alloc.deallocate((OsclAny*)(KvpKey)); 953 fsiInfo->video_format.~PVMFFormatType(); 954 } 955 else 956 { 957 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 958 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters - Problem allocating Output FSI")); 959 SetState(EPVMFNodeError); 960 ReportErrorEvent(PVMFErrNoMemory); 961 return false; // this is going to make everything go out of scope 962 } 963 } 964 else 965 { 966 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 967 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters - Problem allocating Output FSI")); 968 return false; // this is going to make everything go out of scope 969 } 970 971 972 } 973 974 //Try querying the buffer allocator KVP for output buffer allocation outside the node 975 976 PvmiKvp* kvp = NULL; 977 int numKvp = 0; 978 PvmiKeyType aIdentifier = (PvmiKeyType)PVMF_BUFFER_ALLOCATOR_KEY; 979 int32 err, err1; 980 ipExternalOutputBufferAllocatorInterface = NULL; 981 982 OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiGetBufferAllocatorSpecificInfoSync(aIdentifier, kvp, numKvp);); 983 984 if ((err == OsclErrNone) && (NULL != kvp)) 985 { 986 ipExternalOutputBufferAllocatorInterface = (PVInterface*) kvp->value.key_specific_value; 987 988 if (ipExternalOutputBufferAllocatorInterface) 989 { 990 PVInterface* pTempPVInterfacePtr = NULL; 991 992 OSCL_TRY(err, ipExternalOutputBufferAllocatorInterface->queryInterface(PVMFFixedSizeBufferAllocUUID, pTempPVInterfacePtr);); 993 994 OSCL_TRY(err1, ((PVMFOMXDecPort*)iOutPort)->releaseParametersSync(kvp, numKvp);); 995 996 if (err1 != OsclErrNone) 997 { 998 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 999 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters - Unable to Release Parameters")); 1000 } 1001 1002 1003 if ((err == OsclErrNone) && (NULL != pTempPVInterfacePtr)) 1004 { 1005 ipFixedSizeBufferAlloc = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, pTempPVInterfacePtr); 1006 1007 uint32 iNumBuffers, iBufferSize; 1008 1009 iNumBuffers = ipFixedSizeBufferAlloc->getNumBuffers(); 1010 iBufferSize = ipFixedSizeBufferAlloc->getBufferSize(); 1011 1012 if ((iNumBuffers < iParamPort.nBufferCountMin) || (iBufferSize < iOMXComponentOutputBufferSize)) 1013 { 1014 ipExternalOutputBufferAllocatorInterface->removeRef(); 1015 ipExternalOutputBufferAllocatorInterface = NULL; 1016 } 1017 else 1018 { 1019 iNumOutputBuffers = iNumBuffers; 1020 iOMXComponentOutputBufferSize = iBufferSize; 1021 } 1022 } 1023 else 1024 { 1025 ipExternalOutputBufferAllocatorInterface->removeRef(); 1026 ipExternalOutputBufferAllocatorInterface = NULL; 1027 1028 } 1029 } 1030 } 1031 1032 1033 iParamPort.nBufferCountActual = iNumOutputBuffers; 1034 CONFIG_SIZE_AND_VERSION(iParamPort); 1035 1036 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1037 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Outport buffers %d,size %d", iNumOutputBuffers, iOMXComponentOutputBufferSize)); 1038 1039 Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamPortDefinition, &iParamPort); 1040 if (Err != OMX_ErrorNone) 1041 { 1042 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1043 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting parameters in output port %d ", iOutputPortIndex)); 1044 return false; 1045 } 1046 1047 1048 //Set input video format 1049 //This is need it since a single component could handle differents roles 1050 1051 // Init to desire format 1052 PVMFFormatType Format = PVMF_MIME_FORMAT_UNKNOWN; 1053 if (iInPort != NULL) 1054 { 1055 Format = ((PVMFOMXDecPort*)iInPort)->iFormat; 1056 } 1057 if (Format == PVMF_MIME_H264_VIDEO || 1058 Format == PVMF_MIME_H264_VIDEO_MP4 || 1059 Format == PVMF_MIME_H264_VIDEO_RAW) 1060 { 1061 iOMXVideoCompressionFormat = OMX_VIDEO_CodingAVC; 1062 } 1063 else if (Format == PVMF_MIME_M4V) 1064 { 1065 iOMXVideoCompressionFormat = OMX_VIDEO_CodingMPEG4; 1066 } 1067 else if (Format == PVMF_MIME_H2631998 || 1068 Format == PVMF_MIME_H2632000) 1069 { 1070 iOMXVideoCompressionFormat = OMX_VIDEO_CodingH263; 1071 } 1072 else if (Format == PVMF_MIME_WMV) 1073 { 1074 iOMXVideoCompressionFormat = OMX_VIDEO_CodingWMV; 1075 } 1076 else 1077 { 1078 // Illegal codec specified. 1079 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1080 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting video compression format")); 1081 return false; 1082 } 1083 1084 if ((iOMXVideoCompressionFormat == OMX_VIDEO_CodingMPEG4) || 1085 (iOMXVideoCompressionFormat == OMX_VIDEO_CodingH263)) 1086 { 1087 // Enable deblocking for these two video types 1088 OMX_PARAM_DEBLOCKINGTYPE DeBlock; 1089 CONFIG_SIZE_AND_VERSION(DeBlock); 1090 1091 DeBlock.nPortIndex = iOutputPortIndex; 1092 DeBlock.bDeblocking = OMX_TRUE; 1093 1094 Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamCommonDeblocking, &DeBlock); 1095 if (Err != OMX_ErrorNone) 1096 { 1097 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1098 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting deblocking flag")); 1099 // Dont return false in this case. If enabling DeBlocking fails, just continue. 1100 } 1101 } 1102 1103 OMX_VIDEO_PARAM_PORTFORMATTYPE VideoPortFormat; 1104 CONFIG_SIZE_AND_VERSION(VideoPortFormat); 1105 VideoPortFormat.nPortIndex = iInputPortIndex; 1106 1107 // Search the proper format index and set it. 1108 // Since we already know that the component has the role we need, search until finding the proper nIndex 1109 // if component does not find the format will return OMX_ErrorNoMore 1110 1111 for (ii = 0;; ii++) 1112 { 1113 VideoPortFormat.nIndex = ii; 1114 Err = OMX_GetParameter(iOMXDecoder, OMX_IndexParamVideoPortFormat, &VideoPortFormat); 1115 if (Err != OMX_ErrorNone) 1116 { 1117 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1118 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting video compression format")); 1119 return false; 1120 } 1121 if (iOMXVideoCompressionFormat == VideoPortFormat.eCompressionFormat) 1122 { 1123 break; 1124 } 1125 } 1126 // Now set the format to confirm parameters 1127 Err = OMX_SetParameter(iOMXDecoder, OMX_IndexParamVideoPortFormat, &VideoPortFormat); 1128 if (Err != OMX_ErrorNone) 1129 { 1130 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1131 (0, "PVMFOMXVideoDecNode::NegotiateComponentParameters() Problem setting video compression format")); 1132 return false; 1133 } 1134 1135 return true; 1136} 1137 1138///////////////////////////////////////////////////////////////////////////// 1139bool PVMFOMXVideoDecNode::InitDecoder(PVMFSharedMediaDataPtr& DataIn) 1140{ 1141 OSCL_UNUSED_ARG(DataIn); 1142 1143 uint16 length = 0, size = 0; 1144 uint8 *tmp_ptr; 1145 PVMFFormatType Format = PVMF_MIME_FORMAT_UNKNOWN; 1146 1147 OsclRefCounterMemFrag DataFrag; 1148 OsclRefCounterMemFrag refCtrMemFragOut; 1149 1150 1151 1152 // NOTE: the component may not start decoding without providing the Output buffer to it, 1153 // here, we're sending input/config buffers. 1154 // Then, we'll go to ReadyToDecode state and send output as well 1155 1156 if (iInPort != NULL) 1157 { 1158 Format = ((PVMFOMXDecPort*)iInPort)->iFormat; 1159 } 1160 if (Format == PVMF_MIME_H264_VIDEO || 1161 Format == PVMF_MIME_H264_VIDEO_MP4) 1162 { 1163 uint8* initbuffer = ((PVMFOMXDecPort*)iInPort)->getTrackConfig(); 1164 int32 initbufsize = (int32)((PVMFOMXDecPort*)iInPort)->getTrackConfigSize(); 1165 1166 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::InitDecoder() for H264 Decoder. Initialization data Size %d.", initbufsize)); 1167 1168 if (initbufsize > 0) 1169 { 1170 1171 // there may be more than 1 NAL in config info in format specific data memfragment (SPS, PPS) 1172 tmp_ptr = initbuffer; 1173 do 1174 { 1175 length = (uint16)(tmp_ptr[1] << 8) | tmp_ptr[0]; 1176 size += (length + 2); 1177 if (size > initbufsize) 1178 break; 1179 tmp_ptr += 2; 1180 1181 1182 if (!SendConfigBufferToOMXComponent(tmp_ptr, length)) 1183 { 1184 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1185 (0, "PVMFOMXVideoDecNode::InitDecoder() Error in processing config buffer")); 1186 return false; 1187 1188 } 1189 1190 tmp_ptr += length; 1191 1192 } 1193 while (size < initbufsize); 1194 } 1195 } 1196 else if (Format == PVMF_MIME_M4V || 1197 Format == PVMF_MIME_H2631998 || 1198 Format == PVMF_MIME_H2632000) 1199 { 1200 uint8* initbuffer = ((PVMFOMXDecPort*)iInPort)->getTrackConfig(); 1201 int32 initbufsize = (int32)((PVMFOMXDecPort*)iInPort)->getTrackConfigSize(); 1202 1203 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::InitDecoder() for H263 Decoder. Initialization data Size %d.", initbufsize)); 1204 1205 // for H263, the initbufsize is 0, and initbuf= NULL. Config is done after 1st frame of data 1206 if (initbufsize > 0) 1207 { 1208 1209 if (!SendConfigBufferToOMXComponent(initbuffer, initbufsize)) 1210 { 1211 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1212 (0, "PVMFOMXVideoDecNode::InitDecoder() Error in processing config buffer")); 1213 return false; 1214 } 1215 } 1216 } 1217 else if (Format == PVMF_MIME_WMV) 1218 { 1219 uint8* initbuffer = ((PVMFOMXDecPort*)iInPort)->getTrackConfig(); 1220 int32 initbufsize = (int32)((PVMFOMXDecPort*)iInPort)->getTrackConfigSize(); 1221 1222 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::InitDecoder() for WMV Decoder. Initialization data Size %d.", initbufsize)); 1223 1224 if (initbufsize > 0) 1225 { 1226 1227 if (!SendConfigBufferToOMXComponent(initbuffer, initbufsize)) 1228 { 1229 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1230 (0, "PVMFOMXVideoDecNode::InitDecoder() Error in processing config buffer")); 1231 return false; 1232 } 1233 } 1234 } 1235 else 1236 { 1237 // Unknown codec type 1238 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1239 (0, "PVMFOMXVideoDecNode::InitDecoder() Unknown codec type")); 1240 return false; 1241 } 1242 1243 //Varibles initialization 1244 //sendFsi = true; 1245 1246 return true; 1247} 1248 1249 1250 1251///////////////////////////////////////////////////////////////////////////// 1252////////////////////// CALLBACK PROCESSING FOR EVENT HANDLER 1253///////////////////////////////////////////////////////////////////////////// 1254OMX_ERRORTYPE PVMFOMXVideoDecNode::EventHandlerProcessing(OMX_OUT OMX_HANDLETYPE aComponent, 1255 OMX_OUT OMX_PTR aAppData, 1256 OMX_OUT OMX_EVENTTYPE aEvent, 1257 OMX_OUT OMX_U32 aData1, 1258 OMX_OUT OMX_U32 aData2, 1259 OMX_OUT OMX_PTR aEventData) 1260{ 1261 OSCL_UNUSED_ARG(aComponent); 1262 OSCL_UNUSED_ARG(aAppData); 1263 OSCL_UNUSED_ARG(aEventData); 1264 1265 switch (aEvent) 1266 { 1267 case OMX_EventCmdComplete: 1268 { 1269 1270 switch (aData1) 1271 { 1272 case OMX_CommandStateSet: 1273 { 1274 HandleComponentStateChange(aData2); 1275 break; 1276 } 1277 case OMX_CommandFlush: 1278 { 1279 1280 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1281 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_CommandFlush - completed on port %d", aData2)); 1282 1283 if (iIsRepositioningRequestSentToComponent) 1284 { 1285 if (aData2 == iOutputPortIndex) 1286 { 1287 iIsOutputPortFlushed = true; 1288 } 1289 else if (aData2 == iInputPortIndex) 1290 { 1291 iIsInputPortFlushed = true; 1292 } 1293 1294 if (iIsOutputPortFlushed && iIsInputPortFlushed) 1295 { 1296 iIsRepositionDoneReceivedFromComponent = true; 1297 } 1298 } 1299 1300 if (IsAdded()) 1301 RunIfNotReady(); 1302 1303 } 1304 break; 1305 1306 case OMX_CommandPortDisable: 1307 { 1308 // if port disable command is done, we can re-allocate the buffers and re-enable the port 1309 1310 iProcessingState = EPVMFOMXBaseDecNodeProcessingState_PortReEnable; 1311 iPortIndexForDynamicReconfig = aData2; 1312 1313 RunIfNotReady(); 1314 break; 1315 } 1316 case OMX_CommandPortEnable: 1317 // port enable command is done. Check if the other port also reported change. 1318 // If not, we can start data flow. Otherwise, must start dynamic reconfig procedure for 1319 // the other port as well. 1320 { 1321 if (iSecondPortReportedChange) 1322 { 1323 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1324 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_CommandPortEnable - completed on port %d, dynamic reconfiguration needed on port %d", aData2, iSecondPortToReconfig)); 1325 1326 iProcessingState = EPVMFOMXBaseDecNodeProcessingState_PortReconfig; 1327 iPortIndexForDynamicReconfig = iSecondPortToReconfig; 1328 iSecondPortReportedChange = false; 1329 } 1330 else 1331 { 1332 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1333 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_CommandPortEnable - completed on port %d, resuming normal data flow", aData2)); 1334 iProcessingState = EPVMFOMXBaseDecNodeProcessingState_ReadyToDecode; 1335 iDynamicReconfigInProgress = false; 1336 // in case pause or stop command was sent to component 1337 // change processing state (because the node might otherwise 1338 // start sending buffers to component before pause/stop is processed) 1339 if (iPauseCommandWasSentToComponent) 1340 { 1341 iProcessingState = EPVMFOMXBaseDecNodeProcessingState_Pausing; 1342 } 1343 if (iStopCommandWasSentToComponent) 1344 { 1345 iProcessingState = EPVMFOMXBaseDecNodeProcessingState_Stopping; 1346 } 1347 } 1348 RunIfNotReady(); 1349 break; 1350 } 1351 1352 case OMX_CommandMarkBuffer: 1353 // nothing to do here yet; 1354 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1355 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_CommandMarkBuffer - completed - no action taken")); 1356 1357 break; 1358 1359 default: 1360 { 1361 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1362 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: Unsupported event")); 1363 break; 1364 } 1365 }//end of switch (aData1) 1366 1367 break; 1368 }//end of case OMX_EventCmdComplete 1369 1370 case OMX_EventError: 1371 { 1372 1373 LOGE("Ln %d OMX_EventError nData1 %d nData2 %d", __LINE__, aData1, aData2); 1374 if (aData1 == (OMX_U32) OMX_ErrorStreamCorrupt) 1375 { 1376 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1377 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventError - Bitstream corrupt error")); 1378 // Errors from corrupt bitstream are reported as info events 1379 ReportInfoEvent(PVMFInfoProcessingFailure, NULL); 1380 1381 } 1382 else if (aData1 == (OMX_U32) OMX_ErrorInvalidState) 1383 { 1384 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1385 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventError - OMX_ErrorInvalidState")); 1386 HandleComponentStateChange(OMX_StateInvalid); 1387 } 1388 else 1389 { 1390 1391 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1392 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventError")); 1393 // for now, any error from the component will be reported as error 1394 ReportErrorEvent(PVMFErrProcessing, NULL, NULL); 1395 SetState(EPVMFNodeError); 1396 } 1397 break; 1398 1399 } 1400 1401 case OMX_EventBufferFlag: 1402 { 1403 // the component is reporting it encountered end of stream flag 1404 // we'll send eos when we get the actual last buffer with marked eos 1405 1406 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1407 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventBufferFlag (EOS) flag returned from OMX component")); 1408 1409 RunIfNotReady(); 1410 break; 1411 }//end of case OMX_EventBufferFlag 1412 1413 case OMX_EventMark: 1414 { 1415 1416 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1417 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventMark returned from OMX component - no action taken")); 1418 1419 RunIfNotReady(); 1420 break; 1421 }//end of case OMX_EventMark 1422 1423 case OMX_EventPortSettingsChanged: 1424 { 1425 1426 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1427 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventPortSettingsChanged returned from OMX component")); 1428 1429 // first check if dynamic reconfiguration is already in progress, 1430 // if so, wait until this is completed, and then initiate the 2nd reconfiguration 1431 if (iDynamicReconfigInProgress) 1432 { 1433 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1434 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventPortSettingsChanged returned for port %d, dynamic reconfig already in progress", aData1)); 1435 1436 iSecondPortToReconfig = aData1; 1437 iSecondPortReportedChange = true; 1438 } 1439 else 1440 { 1441 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1442 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventPortSettingsChanged returned for port %d", aData1)); 1443 1444 iProcessingState = EPVMFOMXBaseDecNodeProcessingState_PortReconfig; 1445 iPortIndexForDynamicReconfig = aData1; 1446 iDynamicReconfigInProgress = true; 1447 } 1448 1449 RunIfNotReady(); 1450 break; 1451 }//end of case OMX_PortSettingsChanged 1452 1453 case OMX_EventResourcesAcquired: //not supported 1454 { 1455 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1456 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: OMX_EventResourcesAcquired returned from OMX component - no action taken")); 1457 1458 RunIfNotReady(); 1459 1460 break; 1461 } 1462 1463 default: 1464 { 1465 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1466 (0, "PVMFOMXVideoDecNode::EventHandlerProcessing: Unknown Event returned from OMX component - no action taken")); 1467 1468 break; 1469 } 1470 1471 }//end of switch (eEvent) 1472 1473 1474 1475 return OMX_ErrorNone; 1476} 1477 1478 1479 1480 1481//////////////////////////////////////////////////////////////////////////////////////////////// 1482///////////////////////////// Put output buffer in outgoing queue ////////////////////////////// 1483//////////////////////////////////////////////////////////////////////////////////////////////// 1484bool PVMFOMXVideoDecNode::QueueOutputBuffer(OsclSharedPtr<PVMFMediaDataImpl> &mediadataimplout, uint32 aDataLen) 1485{ 1486 1487 bool status = true; 1488 PVMFSharedMediaDataPtr mediaDataOut; 1489 int32 leavecode = OsclErrNone; 1490 1491 // NOTE: ASSUMPTION IS THAT OUTGOING QUEUE IS BIG ENOUGH TO QUEUE ALL THE OUTPUT BUFFERS 1492 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1493 (0, "PVMFOMXVideoDecNode::QueueOutputFrame: In")); 1494 1495 // First check if we can put outgoing msg. into the queue 1496 if (iOutPort->IsOutgoingQueueBusy()) 1497 { 1498 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 1499 (0, "PVMFOMXVideoDecNode::QueueOutputFrame() OutgoingQueue is busy")); 1500 return false; 1501 } 1502 1503 OSCL_TRY(leavecode, 1504 mediaDataOut = PVMFMediaData::createMediaData(mediadataimplout, iMediaDataMemPool);); 1505 if (OsclErrNone == leavecode) 1506 { 1507 1508 // Update the filled length of the fragment 1509 mediaDataOut->setMediaFragFilledLen(0, aDataLen); 1510 1511 // Set timestamp 1512 mediaDataOut->setTimestamp(iOutTimeStamp); 1513 1514 // Set Streamid 1515 mediaDataOut->setStreamID(iStreamID); 1516 1517 // Set sequence number 1518 mediaDataOut->setSeqNum(iSeqNum++); 1519 1520 PVLOGGER_LOGMSG(PVLOGMSG_INST_REL, iDataPathLogger, PVLOGMSG_INFO, (0, ":PVMFOMXVideoDecNode::QueueOutputFrame(): - SeqNum=%d, TS=%d", iSeqNum, iOutTimeStamp)); 1521 1522 int fsiErrorCode = 0; 1523 1524 1525 // Check if Fsi configuration need to be sent 1526 if (sendFsi && !iCompactFSISettingSucceeded) 1527 { 1528 OsclRefCounterMemFrag yuvFsiMemfrag; 1529 1530 OSCL_TRY(fsiErrorCode, yuvFsiMemfrag = iFsiFragmentAlloc.get();); 1531 1532 OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1533 (0, "PVMFOMXVideoDecNode::RemoveOutputFrame() Failed to allocate memory for FSI"))); 1534 1535 if (fsiErrorCode == 0) 1536 { 1537 PVMFYuvFormatSpecificInfo0* fsiInfo = OSCL_PLACEMENT_NEW(yuvFsiMemfrag.getMemFragPtr(), PVMFYuvFormatSpecificInfo0()); 1538 if (fsiInfo != NULL) 1539 { 1540 fsiInfo->uid = PVMFYuvFormatSpecificInfo0_UID; 1541 fsiInfo->video_format = iYUVFormat; 1542 fsiInfo->display_width = iYUVWidth; 1543 fsiInfo->display_height = iYUVHeight; 1544 fsiInfo->width = iStride; 1545 fsiInfo->height = iSliceHeight; 1546 fsiInfo->buffer_size = iOMXComponentOutputBufferSize; 1547 1548 OsclMemAllocator alloc; 1549 int32 KeyLength = oscl_strlen(PVMF_FORMAT_SPECIFIC_INFO_KEY) + 1; 1550 PvmiKeyType KvpKey = (PvmiKeyType)alloc.ALLOCATE(KeyLength); 1551 1552 if (NULL == KvpKey) 1553 { 1554 SetState(EPVMFNodeError); 1555 ReportErrorEvent(PVMFErrNoMemory); 1556 return false; 1557 } 1558 1559 oscl_strncpy(KvpKey, PVMF_FORMAT_SPECIFIC_INFO_KEY, KeyLength); 1560 int32 err; 1561 1562 OSCL_TRY(err, ((PVMFOMXDecPort*)iOutPort)->pvmiSetPortFormatSpecificInfoSync(yuvFsiMemfrag, KvpKey);); 1563 if (err != OsclErrNone) 1564 { 1565 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 1566 (0, "PVMFOMXVideoDecNode::HandlePortReEnable - Problem to set FSI")); 1567 } 1568 1569 alloc.deallocate((OsclAny*)(KvpKey)); 1570 fsiInfo->video_format.~PVMFFormatType(); 1571 } 1572 else 1573 { 1574 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 1575 (0, "PVMFOMXVideoDecNode::QueueOutputFrame - Problem allocating Output FSI")); 1576 SetState(EPVMFNodeError); 1577 ReportErrorEvent(PVMFErrNoMemory); 1578 return false; // this is going to make everything go out of scope 1579 } 1580 } 1581 else 1582 { 1583 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 1584 (0, "PVMFOMXVideoDecNode::QueueOutputFrame - Problem allocating Output FSI")); 1585 return false; // this is going to make everything go out of scope 1586 } 1587 1588 // Reset the flag 1589 sendFsi = false; 1590 } 1591 1592 1593 // in case of special YVU format, attach fsi to every outgoing message containing ptr to private data 1594 if (iYUVFormat == PVMF_MIME_YUV420_SEMIPLANAR_YVU) 1595 { 1596 OsclRefCounterMemFrag privatedataFsiMemFrag; 1597 1598 OSCL_TRY(fsiErrorCode, privatedataFsiMemFrag = iPrivateDataFsiFragmentAlloc.get();); 1599 1600 OSCL_FIRST_CATCH_ANY(fsiErrorCode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1601 (0, "PVMFOMXVideoDecNode::RemoveOutputFrame() Failed to allocate memory for FSI for private data"))); 1602 1603 if (fsiErrorCode == 0) 1604 { 1605 uint8 *fsiptr = (uint8*) privatedataFsiMemFrag.getMemFragPtr(); 1606 privatedataFsiMemFrag.getMemFrag().len = sizeof(OsclAny*); 1607 oscl_memcpy(fsiptr, &ipPrivateData, sizeof(OsclAny *)); // store ptr data into fsi 1608 mediaDataOut->setFormatSpecificInfo(privatedataFsiMemFrag); 1609 } 1610 else 1611 { 1612 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, 1613 (0, "PVMFOMXVideoDecNode::QueueOutputFrame - Problem allocating Output FSI for private data")); 1614 SetState(EPVMFNodeError); 1615 ReportErrorEvent(PVMFErrNoMemory); 1616 return false; // this is going to make everything go out of scope 1617 } 1618 } 1619 1620 1621 if (fsiErrorCode == 0) 1622 { 1623 // Send frame to downstream node 1624 PVMFSharedMediaMsgPtr mediaMsgOut; 1625 convertToPVMFMediaMsg(mediaMsgOut, mediaDataOut); 1626 1627 if (iOutPort && (iOutPort->QueueOutgoingMsg(mediaMsgOut) == PVMFSuccess)) 1628 { 1629 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_INFO, 1630 (0, "PVMFOMXVideoDecNode::QueueOutputFrame(): Queued frame OK ")); 1631 1632 } 1633 else 1634 { 1635 // we should not get here because we always check for whether queue is busy or not 1636 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, 1637 (0, "PVMFOMXVideoDecNode::QueueOutputFrame(): Send frame failed")); 1638 return false; 1639 } 1640 1641 } 1642 1643 1644 }//end of if (leavecode==0) 1645 else 1646 { 1647 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1648 (0, "PVMFOMXVideoDecNode::QueueOutputFrame() call PVMFMediaData::createMediaData is failed")); 1649 return false; 1650 } 1651 1652 return status; 1653 1654} 1655 1656///////////////////////////////////////////////////////////////////////////// 1657void PVMFOMXVideoDecNode::DoRequestPort(PVMFOMXBaseDecNodeCommand& aCmd) 1658{ 1659 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1660 (0, "PVMFOMXVideoDecNode::DoRequestPort() In")); 1661 //This node supports port request from any state 1662 1663 //retrieve port tag. 1664 int32 tag; 1665 OSCL_String* portconfig; 1666 1667 aCmd.PVMFOMXBaseDecNodeCommandBase::Parse(tag, portconfig); 1668 1669 PVMFPortInterface* port = NULL; 1670 int32 leavecode = OsclErrNone; 1671 //validate the tag... 1672 switch (tag) 1673 { 1674 case PVMF_OMX_DEC_NODE_PORT_TYPE_INPUT: 1675 if (iInPort) 1676 { 1677 CommandComplete(iInputCommands, aCmd, PVMFFailure); 1678 break; 1679 } 1680 OSCL_TRY(leavecode, iInPort = OSCL_NEW(PVMFOMXDecPort, ((int32)tag, this, PVMF_OMX_VIDEO_DEC_INPUT_PORT_NAME));); 1681 if (leavecode || iInPort == NULL) 1682 { 1683 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1684 (0, "PVMFOMXVideoDecNode::DoRequestPort: Error - Input port instantiation failed")); 1685 CommandComplete(iInputCommands, aCmd, PVMFErrArgument); 1686 return; 1687 } 1688 port = iInPort; 1689 break; 1690 1691 case PVMF_OMX_DEC_NODE_PORT_TYPE_OUTPUT: 1692 if (iOutPort) 1693 { 1694 CommandComplete(iInputCommands, aCmd, PVMFFailure); 1695 break; 1696 } 1697 OSCL_TRY(leavecode, iOutPort = OSCL_NEW(PVMFOMXDecPort, ((int32)tag, this, PVMF_OMX_VIDEO_DEC_OUTPUT_PORT_NAME))); 1698 if (leavecode || iOutPort == NULL) 1699 { 1700 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1701 (0, "PVMFOMXVideoDecNode::DoRequestPort: Error - Output port instantiation failed")); 1702 CommandComplete(iInputCommands, aCmd, PVMFErrArgument); 1703 return; 1704 } 1705 port = iOutPort; 1706 break; 1707 1708 default: 1709 //bad port tag 1710 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, 1711 (0, "PVMFOMXVideoDecNode::DoRequestPort: Error - Invalid port tag")); 1712 CommandComplete(iInputCommands, aCmd, PVMFErrArgument); 1713 return; 1714 } 1715 1716 //Return the port pointer to the caller. 1717 CommandComplete(iInputCommands, aCmd, PVMFSuccess, (OsclAny*)port); 1718} 1719 1720///////////////////////////////////////////////////////////////////////////// 1721void PVMFOMXVideoDecNode::DoReleasePort(PVMFOMXBaseDecNodeCommand& aCmd) 1722{ 1723 PVMFPortInterface* p = NULL; 1724 aCmd.PVMFOMXBaseDecNodeCommandBase::Parse(p); 1725 PVMFOMXDecPort* port = (PVMFOMXDecPort*)p; 1726 1727 if (port != NULL && (port == iInPort || port == iOutPort)) 1728 { 1729 if (port == iInPort) 1730 { 1731 OSCL_DELETE(((PVMFOMXDecPort*)iInPort)); 1732 iInPort = NULL; 1733 } 1734 else 1735 { 1736 OSCL_DELETE(((PVMFOMXDecPort*)iOutPort)); 1737 iOutPort = NULL; 1738 } 1739 //delete the port. 1740 CommandComplete(iInputCommands, aCmd, PVMFSuccess); 1741 } 1742 else 1743 { 1744 //port not found. 1745 CommandComplete(iInputCommands, aCmd, PVMFFailure); 1746 } 1747} 1748 1749///////////////////////////////////////////////////////////////////////////// 1750PVMFStatus PVMFOMXVideoDecNode::DoGetNodeMetadataKey(PVMFOMXBaseDecNodeCommand& aCmd) 1751{ 1752 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, 1753 (0, "PVMFOMXVideoDecNode::DoGetNodeMetadataKey() In")); 1754 1755 PVMFMetadataList* keylistptr = NULL; 1756 uint32 starting_index; 1757 int32 max_entries; 1758 char* query_key; 1759 1760 aCmd.PVMFOMXBaseDecNodeCommand::Parse(keylistptr, starting_index, max_entries, query_key); 1761 1762 // Check parameters 1763 if (keylistptr == NULL) 1764 { 1765 // The list pointer is invalid 1766 return PVMFErrArgument; 1767 } 1768 1769 // Update the available metadata keys 1770 iAvailableMetadataKeys.clear(); 1771 int32 leavecode = OsclErrNone; 1772 leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY, iAvailableMetadataKeys); 1773 if (OsclErrNone != leavecode) 1774 { 1775 return PVMFErrNoMemory; 1776 } 1777 1778 if (iYUVWidth > 0 && iYUVHeight > 0) 1779 { 1780 leavecode = OsclErrNone; 1781 leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY, iAvailableMetadataKeys); 1782 if (OsclErrNone != leavecode) 1783 { 1784 return PVMFErrNoMemory; 1785 } 1786 1787 leavecode = OsclErrNone; 1788 leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY, iAvailableMetadataKeys); 1789 if (OsclErrNone != leavecode) 1790 { 1791 return PVMFErrNoMemory; 1792 } 1793 } 1794 // add the profile, level and avgbitrate 1795 PVMF_MPEGVideoProfileType aProfile; 1796 PVMF_MPEGVideoLevelType aLevel; 1797 if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess) 1798 { 1799 // For H263 this metadata will be available only after first frame decoding 1800 leavecode = OsclErrNone; 1801 leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY, iAvailableMetadataKeys); 1802 if (leavecode != OsclErrNone) 1803 { 1804 return PVMFErrNoMemory; 1805 } 1806 1807 leavecode = OsclErrNone; 1808 leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY, iAvailableMetadataKeys); 1809 if (OsclErrNone != leavecode) 1810 { 1811 return PVMFErrNoMemory; 1812 } 1813 } 1814 leavecode = OsclErrNone; 1815 leavecode = PushKVPKey(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY, iAvailableMetadataKeys); 1816 if (OsclErrNone != leavecode) 1817 { 1818 return PVMFErrNoMemory; 1819 } 1820 1821 if ((starting_index > (iAvailableMetadataKeys.size() - 1)) || max_entries == 0) 1822 { 1823 // Invalid starting index and/or max entries 1824 return PVMFErrArgument; 1825 } 1826 1827 // Copy the requested keys 1828 uint32 num_entries = 0; 1829 int32 num_added = 0; 1830 for (uint32 lcv = 0; lcv < iAvailableMetadataKeys.size(); lcv++) 1831 { 1832 if (query_key == NULL) 1833 { 1834 // No query key so this key is counted 1835 ++num_entries; 1836 if (num_entries > starting_index) 1837 { 1838 // Past the starting index so copy the key 1839 leavecode = OsclErrNone; 1840 leavecode = PushKVPKey(iAvailableMetadataKeys[lcv] , keylistptr); 1841 if (OsclErrNone != leavecode) 1842 { 1843 return PVMFErrNoMemory; 1844 } 1845 num_added++; 1846 } 1847 } 1848 else 1849 { 1850 // Check if the key matche the query key 1851 if (pv_mime_strcmp(iAvailableMetadataKeys[lcv].get_cstr(), query_key) >= 0) 1852 { 1853 // This key is counted 1854 ++num_entries; 1855 if (num_entries > starting_index) 1856 { 1857 // Past the starting index so copy the key 1858 leavecode = OsclErrNone; 1859 leavecode = PushKVPKey(iAvailableMetadataKeys[lcv] , keylistptr); 1860 if (OsclErrNone != leavecode) 1861 { 1862 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetNodeMetadataKey() Memory allocation failure when copying metadata key")); 1863 return PVMFErrNoMemory; 1864 } 1865 num_added++; 1866 } 1867 } 1868 } 1869 1870 // Check if max number of entries have been copied 1871 if (max_entries > 0 && num_added >= max_entries) 1872 { 1873 break; 1874 } 1875 } 1876 1877 return PVMFSuccess; 1878} 1879 1880///////////////////////////////////////////////////////////////////////////// 1881PVMFStatus PVMFOMXVideoDecNode::DoGetNodeMetadataValue(PVMFOMXBaseDecNodeCommand& aCmd) 1882{ 1883 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetNodeMetadataValue() In")); 1884 1885 PVMFMetadataList* keylistptr = NULL; 1886 Oscl_Vector<PvmiKvp, OsclMemAllocator>* valuelistptr = NULL; 1887 uint32 starting_index; 1888 int32 max_entries; 1889 1890 aCmd.PVMFOMXBaseDecNodeCommand::Parse(keylistptr, valuelistptr, starting_index, max_entries); 1891 1892 // Check the parameters 1893 if (keylistptr == NULL || valuelistptr == NULL) 1894 { 1895 return PVMFErrArgument; 1896 } 1897 1898 uint32 numkeys = keylistptr->size(); 1899 1900 if (starting_index > (numkeys - 1) || numkeys <= 0 || max_entries == 0) 1901 { 1902 // Don't do anything 1903 return PVMFErrArgument; 1904 } 1905 1906 uint32 numvalentries = 0; 1907 int32 numentriesadded = 0; 1908 for (uint32 lcv = 0; lcv < numkeys; lcv++) 1909 { 1910 int32 leavecode = OsclErrNone; 1911 int32 leavecode1 = OsclErrNone; 1912 PvmiKvp KeyVal; 1913 KeyVal.key = NULL; 1914 uint32 KeyLen = 0; 1915 1916 if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY) == 0) && 1917 iYUVWidth > 0) 1918 { 1919 // Video width 1920 // Increment the counter for the number of values found so far 1921 ++numvalentries; 1922 1923 // Create a value entry if past the starting index 1924 if (numvalentries > starting_index) 1925 { 1926 KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY) + 1; // for "codec-info/video/width;" 1927 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" 1928 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator 1929 1930 // Allocate memory for the string 1931 leavecode = OsclErrNone; 1932 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen); 1933 if (OsclErrNone == leavecode) 1934 { 1935 // Copy the key string 1936 oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY) + 1); 1937 oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON)); 1938 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); 1939 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR)); 1940 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; 1941 // Copy the value 1942 KeyVal.value.uint32_value = iYUVWidth; 1943 // Set the length and capacity 1944 KeyVal.length = 1; 1945 KeyVal.capacity = 1; 1946 } 1947 else 1948 { 1949 // Memory allocation failed 1950 KeyVal.key = NULL; 1951 break; 1952 } 1953 } 1954 } 1955 else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) == 0) && 1956 iYUVHeight > 0) 1957 { 1958 // Video height 1959 // Increment the counter for the number of values found so far 1960 ++numvalentries; 1961 1962 // Create a value entry if past the starting index 1963 if (numvalentries > starting_index) 1964 { 1965 KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) + 1; // for "codec-info/video/height;" 1966 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" 1967 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator 1968 1969 // Allocate memory for the string 1970 leavecode = OsclErrNone; 1971 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen); 1972 if (OsclErrNone == leavecode) 1973 { 1974 // Copy the key string 1975 oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) + 1); 1976 oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON)); 1977 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); 1978 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR)); 1979 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; 1980 // Copy the value 1981 KeyVal.value.uint32_value = iYUVHeight; 1982 // Set the length and capacity 1983 KeyVal.length = 1; 1984 KeyVal.capacity = 1; 1985 } 1986 else 1987 { 1988 // Memory allocation failed 1989 KeyVal.key = NULL; 1990 break; 1991 } 1992 } 1993 } 1994 else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY) == 0)) 1995 { 1996 // Video profile 1997 // Increment the counter for the number of values found so far 1998 ++numvalentries; 1999 2000 // Create a value entry if past the starting index 2001 if (numvalentries > starting_index) 2002 { 2003 KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY) + 1; // for "codec-info/video/profile;" 2004 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" 2005 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator 2006 2007 // Allocate memory for the string 2008 leavecode = OsclErrNone; 2009 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen); 2010 2011 if (OsclErrNone == leavecode) 2012 { 2013 PVMF_MPEGVideoProfileType aProfile; 2014 PVMF_MPEGVideoLevelType aLevel; 2015 if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess) 2016 { 2017 // Copy the key string 2018 oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY) + 1); 2019 oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON)); 2020 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); 2021 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR)); 2022 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; 2023 // Copy the value 2024 KeyVal.value.uint32_value = (uint32)aProfile; // This is to be decided, who will interpret these value 2025 // Set the length and capacity 2026 KeyVal.length = 1; 2027 KeyVal.capacity = 1; 2028 } 2029 else 2030 { 2031 // Memory allocation failed 2032 KeyVal.key = NULL; 2033 break; 2034 } 2035 } 2036 else 2037 { 2038 // Memory allocation failed 2039 KeyVal.key = NULL; 2040 break; 2041 } 2042 } 2043 } 2044 else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY) == 0)) 2045 { 2046 // Video level 2047 // Increment the counter for the number of values found so far 2048 ++numvalentries; 2049 2050 // Create a value entry if past the starting index 2051 if (numvalentries > starting_index) 2052 { 2053 KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY) + 1; // for "codec-info/video/level;" 2054 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" 2055 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator 2056 2057 // Allocate memory for the string 2058 leavecode = OsclErrNone; 2059 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen); 2060 2061 if (OsclErrNone == leavecode) 2062 { 2063 PVMF_MPEGVideoProfileType aProfile; 2064 PVMF_MPEGVideoLevelType aLevel; 2065 if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess) 2066 { 2067 // Copy the key string 2068 oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY) + 1); 2069 oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON)); 2070 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); 2071 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR)); 2072 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; 2073 // Copy the value 2074 KeyVal.value.uint32_value = (uint32)aLevel; // This is to be decided, who will interpret these value 2075 // Set the length and capacity 2076 KeyVal.length = 1; 2077 KeyVal.capacity = 1; 2078 } 2079 else 2080 { 2081 // Memory allocation failed 2082 KeyVal.key = NULL; 2083 break; 2084 } 2085 } 2086 else 2087 { 2088 // Memory allocation failed 2089 KeyVal.key = NULL; 2090 break; 2091 } 2092 } 2093 } 2094 else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) == 0) && 2095 (iAvgBitrateValue > 0)) 2096 { 2097 // Video average bitrate 2098 // Increment the counter for the number of values found so far 2099 ++numvalentries; 2100 2101 // Create a value entry if past the starting index 2102 if (numvalentries > starting_index) 2103 { 2104 KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) + 1; // for "codec-info/video/avgbitrate;" 2105 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" 2106 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR) + 1; // for "uint32" and NULL terminator 2107 2108 // Allocate memory for the string 2109 leavecode = OsclErrNone; 2110 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen); 2111 2112 if (OsclErrNone == leavecode) 2113 { 2114 // Copy the key string 2115 oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) + 1); 2116 oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON)); 2117 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); 2118 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING_CONSTCHAR)); 2119 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; 2120 // Copy the value 2121 KeyVal.value.uint32_value = iAvgBitrateValue; 2122 // Set the length and capacity 2123 KeyVal.length = 1; 2124 KeyVal.capacity = 1; 2125 2126 } 2127 else 2128 { 2129 // Memory allocation failed 2130 KeyVal.key = NULL; 2131 break; 2132 } 2133 } 2134 } 2135 else if ((oscl_strcmp((*keylistptr)[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY) == 0) && 2136 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2631998 || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2632000 || 2137 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_M4V || 2138 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4 || 2139 ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMV)) 2140 { 2141 // Format 2142 // Increment the counter for the number of values found so far 2143 ++numvalentries; 2144 2145 // Create a value entry if past the starting index 2146 if (numvalentries > starting_index) 2147 { 2148 KeyLen = oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY) + 1; // for "codec-info/video/format;" 2149 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR); // for "valtype=" 2150 KeyLen += oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR) + 1; // for "char*" and NULL terminator 2151 2152 uint32 valuelen = 0; 2153 2154 if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO) 2155 { 2156 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO)) + 1; // Value string plus one for NULL terminator 2157 } 2158 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4) 2159 { 2160 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO_MP4)) + 1; // Value string plus one for NULL terminator 2161 } 2162 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW) 2163 { 2164 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H264_VIDEO_RAW)) + 1; // Value string plus one for NULL terminator 2165 } 2166 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_M4V) 2167 { 2168 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_M4V)) + 1; // Value string plus one for NULL terminator 2169 } 2170 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2631998) 2171 { 2172 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H2631998)) + 1; // Value string plus one for NULL terminator 2173 } 2174 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2632000) 2175 { 2176 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_H2632000)) + 1; // Value string plus one for NULL terminator 2177 } 2178 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMV) 2179 { 2180 valuelen = oscl_strlen(_STRLIT_CHAR(PVMF_MIME_WMV)) + 1; // Value string plus one for NULL terminator 2181 } 2182 else 2183 { 2184 // Should not enter here 2185 OSCL_ASSERT(false); 2186 valuelen = 1; 2187 } 2188 2189 // Allocate memory for the strings 2190 leavecode = OsclErrNone; 2191 KeyVal.key = (char*) AllocateKVPKeyArray(leavecode, PVMI_KVPVALTYPE_CHARPTR, KeyLen); 2192 if (OsclErrNone == leavecode) 2193 { 2194 KeyVal.value.pChar_value = (char*) AllocateKVPKeyArray(leavecode1, PVMI_KVPVALTYPE_CHARPTR, valuelen); 2195 } 2196 2197 if (OsclErrNone == leavecode && OsclErrNone == leavecode1) 2198 { 2199 // Copy the key string 2200 oscl_strncpy(KeyVal.key, PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY, oscl_strlen(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY) + 1); 2201 oscl_strncat(KeyVal.key, PVOMXVIDEODECMETADATA_SEMICOLON, oscl_strlen(PVOMXVIDEODECMETADATA_SEMICOLON)); 2202 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_STRING_CONSTCHAR)); 2203 oscl_strncat(KeyVal.key, PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR, oscl_strlen(PVMI_KVPVALTYPE_CHARPTR_STRING_CONSTCHAR)); 2204 KeyVal.key[KeyLen-1] = NULL_TERM_CHAR; 2205 // Copy the value 2206 if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO) 2207 { 2208 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO), valuelen); 2209 } 2210 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4) 2211 { 2212 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO_MP4), valuelen); 2213 } 2214 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW) 2215 { 2216 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H264_VIDEO_RAW), valuelen); 2217 } 2218 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_M4V) 2219 { 2220 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_M4V), valuelen); 2221 } 2222 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2631998) 2223 { 2224 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H2631998), valuelen); 2225 } 2226 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2632000) 2227 { 2228 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_H2632000), valuelen); 2229 } 2230 else if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMV) 2231 { 2232 oscl_strncpy(KeyVal.value.pChar_value, _STRLIT_CHAR(PVMF_MIME_WMV), valuelen); 2233 } 2234 else 2235 { 2236 // Should not enter here 2237 OSCL_ASSERT(false); 2238 } 2239 KeyVal.value.pChar_value[valuelen-1] = NULL_TERM_CHAR; 2240 // Set the length and capacity 2241 KeyVal.length = valuelen; 2242 KeyVal.capacity = valuelen; 2243 } 2244 else 2245 { 2246 // Memory allocation failed so clean up 2247 if (KeyVal.key) 2248 { 2249 OSCL_ARRAY_DELETE(KeyVal.key); 2250 KeyVal.key = NULL; 2251 } 2252 if (KeyVal.value.pChar_value) 2253 { 2254 OSCL_ARRAY_DELETE(KeyVal.value.pChar_value); 2255 } 2256 break; 2257 } 2258 } 2259 } 2260 2261 if (KeyVal.key != NULL) 2262 { 2263 leavecode = OsclErrNone; 2264 leavecode = PushKVP(KeyVal, *valuelistptr); 2265 if (OsclErrNone != leavecode) 2266 { 2267 switch (GetValTypeFromKeyString(KeyVal.key)) 2268 { 2269 case PVMI_KVPVALTYPE_CHARPTR: 2270 if (KeyVal.value.pChar_value != NULL) 2271 { 2272 OSCL_ARRAY_DELETE(KeyVal.value.pChar_value); 2273 KeyVal.value.pChar_value = NULL; 2274 } 2275 break; 2276 2277 default: 2278 // Add more case statements if other value types are returned 2279 break; 2280 } 2281 2282 OSCL_ARRAY_DELETE(KeyVal.key); 2283 KeyVal.key = NULL; 2284 } 2285 else 2286 { 2287 // Increment the counter for number of value entries added to the list 2288 ++numentriesadded; 2289 } 2290 2291 // Check if the max number of value entries were added 2292 if (max_entries > 0 && numentriesadded >= max_entries) 2293 { 2294 break; 2295 } 2296 } 2297 } 2298 2299 return PVMFSuccess; 2300} 2301 2302///////////////////////////////////////////////////////////////////////////// 2303bool PVMFOMXVideoDecNode::ReleaseAllPorts() 2304{ 2305 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::ReleaseAllPorts() In")); 2306 2307 if (iInPort) 2308 { 2309 iInPort->ClearMsgQueues(); 2310 iInPort->Disconnect(); 2311 OSCL_DELETE(((PVMFOMXDecPort*)iInPort)); 2312 iInPort = NULL; 2313 } 2314 2315 if (iOutPort) 2316 { 2317 iOutPort->ClearMsgQueues(); 2318 iOutPort->Disconnect(); 2319 OSCL_DELETE(((PVMFOMXDecPort*)iOutPort)); 2320 iOutPort = NULL; 2321 } 2322 2323 return true; 2324} 2325 2326///////////////////////////////////////////////////////////////////////////// 2327void PVMFOMXVideoDecNode::DoQueryUuid(PVMFOMXBaseDecNodeCommand& aCmd) 2328{ 2329 //This node supports Query UUID from any state 2330 2331 OSCL_String* mimetype; 2332 Oscl_Vector<PVUuid, OsclMemAllocator> *uuidvec; 2333 bool exactmatch; 2334 aCmd.PVMFOMXBaseDecNodeCommandBase::Parse(mimetype, uuidvec, exactmatch); 2335 2336 //Try to match the input mimetype against any of 2337 //the custom interfaces for this node 2338 2339 //Match against custom interface1... 2340 if (*mimetype == PVMF_OMX_BASE_DEC_NODE_CUSTOM1_MIMETYPE 2341 //also match against base mimetypes for custom interface1, 2342 //unless exactmatch is set. 2343 || (!exactmatch && *mimetype == PVMF_OMX_VIDEO_DEC_NODE_MIMETYPE) 2344 || (!exactmatch && *mimetype == PVMF_BASEMIMETYPE)) 2345 { 2346 2347 PVUuid uuid(PVMF_OMX_BASE_DEC_NODE_CUSTOM1_UUID); 2348 uuidvec->push_back(uuid); 2349 } 2350 CommandComplete(iInputCommands, aCmd, PVMFSuccess); 2351} 2352 2353///////////////////////////////////////////////////////////////////////////// 2354uint32 PVMFOMXVideoDecNode::GetNumMetadataKeys(char* aQueryKeyString) 2355{ 2356 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::GetNumMetadataKeys() called")); 2357 2358 // Update the available metadata keys 2359 iAvailableMetadataKeys.clear(); 2360 int32 errcode = OsclErrNone; 2361 OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY)); 2362 2363 if (iYUVWidth > 0 && iYUVHeight > 0) 2364 { 2365 errcode = OsclErrNone; 2366 OSCL_TRY(errcode, 2367 iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY); 2368 iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY)); 2369 } 2370 // add the profile, level and avgbitrate 2371 PVMF_MPEGVideoProfileType aProfile; 2372 PVMF_MPEGVideoLevelType aLevel; 2373 if (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess) 2374 { 2375 // For H263 this metadata will be available only after first frame decoding 2376 errcode = OsclErrNone; 2377 OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY)); 2378 errcode = OsclErrNone; 2379 OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY)); 2380 } 2381 errcode = OsclErrNone; 2382 OSCL_TRY(errcode, iAvailableMetadataKeys.push_back(PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY)); 2383 2384 2385 2386 uint32 num_entries = 0; 2387 2388 if (aQueryKeyString == NULL) 2389 { 2390 num_entries = iAvailableMetadataKeys.size(); 2391 } 2392 else 2393 { 2394 for (uint32 i = 0; i < iAvailableMetadataKeys.size(); i++) 2395 { 2396 if (pv_mime_strcmp(iAvailableMetadataKeys[i].get_cstr(), aQueryKeyString) >= 0) 2397 { 2398 num_entries++; 2399 } 2400 } 2401 } 2402 return num_entries; // Number of elements 2403} 2404 2405///////////////////////////////////////////////////////////////////////////// 2406uint32 PVMFOMXVideoDecNode::GetNumMetadataValues(PVMFMetadataList& aKeyList) 2407{ 2408 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::GetNumMetadataValues() called")); 2409 2410 uint32 numkeys = aKeyList.size(); 2411 2412 if (numkeys <= 0) 2413 { 2414 // Don't do anything 2415 return 0; 2416 } 2417 2418 // Count the number of value entries for the provided key list 2419 uint32 numvalentries = 0; 2420 PVMF_MPEGVideoProfileType aProfile; 2421 PVMF_MPEGVideoLevelType aLevel; 2422 for (uint32 lcv = 0; lcv < numkeys; lcv++) 2423 { 2424 if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_WIDTH_KEY) == 0) && 2425 iYUVWidth > 0) 2426 { 2427 // Video width 2428 ++numvalentries; 2429 } 2430 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_HEIGHT_KEY) == 0) && 2431 iYUVHeight > 0) 2432 { 2433 // Video height 2434 ++numvalentries; 2435 } 2436 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_PROFILE_KEY) == 0) && 2437 (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)) 2438 2439 { 2440 // Video profile 2441 ++numvalentries; 2442 } 2443 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_LEVEL_KEY) == 0) && 2444 (GetProfileAndLevel(aProfile, aLevel) == PVMFSuccess)) 2445 { 2446 // Video level 2447 ++numvalentries; 2448 } 2449 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_AVGBITRATE_KEY) == 0) && 2450 (iAvgBitrateValue > 0)) 2451 2452 { 2453 // Video average bitrate 2454 if (iAvgBitrateValue > 0) 2455 ++numvalentries; 2456 } 2457 else if ((oscl_strcmp(aKeyList[lcv].get_cstr(), PVOMXVIDEODECMETADATA_CODECINFO_VIDEO_FORMAT_KEY) == 0) && 2458 (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMV || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_M4V || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2631998 || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H2632000 || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_MP4 || ((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_H264_VIDEO_RAW)) 2459 { 2460 // Format 2461 ++numvalentries; 2462 } 2463 } 2464 2465 return numvalentries; 2466} 2467 2468//////////////////////////////////////////////////////////////////////////////////////////////// 2469// CAPABILITY CONFIG PRIVATE 2470PVMFStatus PVMFOMXVideoDecNode::DoCapConfigGetParametersSync(PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements, PvmiCapabilityContext aContext) 2471{ 2472 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() In")); 2473 OSCL_UNUSED_ARG(aContext); 2474 2475 // Initialize the output parameters 2476 aNumParamElements = 0; 2477 aParameters = NULL; 2478 2479 // Count the number of components and parameters in the key 2480 int compcount = pv_mime_string_compcnt(aIdentifier); 2481 // Retrieve the first component from the key string 2482 char* compstr = NULL; 2483 pv_mime_string_extract_type(0, aIdentifier, compstr); 2484 2485 if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/decoder")) < 0) || compcount < 3) 2486 { 2487 if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/render")) < 0) || compcount != 3) 2488 { 2489 // First 3 component should be "x-pvmf/video/decoder" and there must 2490 // be at least three components 2491 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() Unsupported key")); 2492 return PVMFErrArgument; 2493 } 2494 } 2495 2496 if (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/render")) >= 0) 2497 { 2498 aParameters = (PvmiKvp*)oscl_malloc(PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS * sizeof(PvmiKvp)); 2499 if (aParameters == NULL) 2500 { 2501 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for KVP failed")); 2502 return PVMFErrNoMemory; 2503 } 2504 oscl_memset(aParameters, 0, PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS*sizeof(PvmiKvp)); 2505 // Allocate memory for the key strings in each KVP 2506 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char)); 2507 if (memblock == NULL) 2508 { 2509 oscl_free(aParameters); 2510 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for key string failed")); 2511 return PVMFErrNoMemory; 2512 } 2513 oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS*PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char)); 2514 // Assign the key string buffer to each KVP 2515 int32 j; 2516 for (j = 0; j < PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS; ++j) 2517 { 2518 aParameters[j].key = memblock + (j * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE); 2519 } 2520 // Copy the requested info 2521 for (j = 0; j < PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS; ++j) 2522 { 2523 oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/video/render/"), 20); 2524 oscl_strncat(aParameters[j].key, PVOMXVideoDecNodeConfigRenderKeys[j].iString, oscl_strlen(PVOMXVideoDecNodeConfigRenderKeys[j].iString)); 2525 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";valtype=uint32_value"), 21); 2526 aParameters[j].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0; 2527 2528 // Copy the requested info 2529 switch (j) 2530 { 2531 case 0: // "width" 2532 // Return current value 2533 aParameters[j].value.uint32_value = iNewWidth; 2534 break; 2535 case 1: // "height" 2536 aParameters[j].value.uint32_value = iNewHeight; 2537 break; 2538 default: 2539 break; 2540 } 2541 } 2542 2543 aNumParamElements = PVOMXVIDEODECNODECONFIG_RENDER_NUMKEYS; 2544 } 2545 else if (compcount == 3) 2546 { 2547 // Since key is "x-pvmf/video/decoder" return all 2548 // nodes available at this level. Ignore attribute 2549 // since capability is only allowed 2550 2551 // Allocate memory for the KVP list 2552 aParameters = (PvmiKvp*)oscl_malloc(PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS * sizeof(PvmiKvp)); 2553 if (aParameters == NULL) 2554 { 2555 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for KVP failed")); 2556 return PVMFErrNoMemory; 2557 } 2558 oscl_memset(aParameters, 0, PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS*sizeof(PvmiKvp)); 2559 // Allocate memory for the key strings in each KVP 2560 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char)); 2561 if (memblock == NULL) 2562 { 2563 oscl_free(aParameters); 2564 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for key string failed")); 2565 return PVMFErrNoMemory; 2566 } 2567 oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS*PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char)); 2568 // Assign the key string buffer to each KVP 2569 int32 j; 2570 for (j = 0; j < PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS; ++j) 2571 { 2572 aParameters[j].key = memblock + (j * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE); 2573 } 2574 // Copy the requested info 2575 for (j = 0; j < PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS; ++j) 2576 { 2577 oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/video/decoder/"), 21); 2578 oscl_strncat(aParameters[j].key, PVOMXVideoDecNodeConfigBaseKeys[j].iString, oscl_strlen(PVOMXVideoDecNodeConfigBaseKeys[j].iString)); 2579 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type="), 6); 2580 switch (PVOMXVideoDecNodeConfigBaseKeys[j].iType) 2581 { 2582 case PVMI_KVPTYPE_AGGREGATE: 2583 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_AGGREGATE_STRING), oscl_strlen(PVMI_KVPTYPE_AGGREGATE_STRING)); 2584 break; 2585 2586 case PVMI_KVPTYPE_POINTER: 2587 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_POINTER_STRING), oscl_strlen(PVMI_KVPTYPE_POINTER_STRING)); 2588 break; 2589 2590 case PVMI_KVPTYPE_VALUE: 2591 default: 2592 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPTYPE_VALUE_STRING), oscl_strlen(PVMI_KVPTYPE_VALUE_STRING)); 2593 // Now append the valtype param 2594 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";valtype="), 9); 2595 switch (PVOMXVideoDecNodeConfigBaseKeys[j].iValueType) 2596 { 2597 case PVMI_KVPVALTYPE_BITARRAY32: 2598 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BITARRAY32_STRING), oscl_strlen(PVMI_KVPVALTYPE_BITARRAY32_STRING)); 2599 break; 2600 2601 case PVMI_KVPVALTYPE_UINT32: 2602 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING)); 2603 break; 2604 2605 case PVMI_KVPVALTYPE_BOOL: 2606 default: 2607 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING)); 2608 break; 2609 } 2610 break; 2611 } 2612 2613 aParameters[j].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0; 2614 } 2615 2616 aNumParamElements = PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS; 2617 } 2618 else 2619 { 2620 // Retrieve the fourth component from the key string 2621 pv_mime_string_extract_type(3, aIdentifier, compstr); 2622 2623 for (int32 vdeccomp4ind = 0; vdeccomp4ind < PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS; ++vdeccomp4ind) 2624 { 2625 // Go through each video dec component string at 4th level 2626 if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigBaseKeys[vdeccomp4ind].iString)) >= 0) 2627 { 2628 if (vdeccomp4ind == 3) 2629 { 2630 // "x-pvmf/video/decoder/h263" 2631 if (compcount == 4) 2632 { 2633 // Return list of H263 settings. Ignore the 2634 // attribute since capability is only allowed 2635 2636 // Allocate memory for the KVP list 2637 aParameters = (PvmiKvp*)oscl_malloc(PVOMXVIDEODECNODECONFIG_H263_NUMKEYS * sizeof(PvmiKvp)); 2638 if (aParameters == NULL) 2639 { 2640 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for KVP failed")); 2641 return PVMFErrNoMemory; 2642 } 2643 oscl_memset(aParameters, 0, PVOMXVIDEODECNODECONFIG_H263_NUMKEYS*sizeof(PvmiKvp)); 2644 // Allocate memory for the key strings in each KVP 2645 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_H263_NUMKEYS * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char)); 2646 if (memblock == NULL) 2647 { 2648 oscl_free(aParameters); 2649 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for key string failed")); 2650 return PVMFErrNoMemory; 2651 } 2652 oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_H263_NUMKEYS*PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char)); 2653 // Assign the key string buffer to each KVP 2654 int32 j; 2655 for (j = 0; j < PVOMXVIDEODECNODECONFIG_H263_NUMKEYS; ++j) 2656 { 2657 aParameters[j].key = memblock + (j * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE); 2658 } 2659 // Copy the requested info 2660 for (j = 0; j < PVOMXVIDEODECNODECONFIG_H263_NUMKEYS; ++j) 2661 { 2662 oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/video/decoder/h263/"), 26); 2663 oscl_strncat(aParameters[j].key, PVOMXVideoDecNodeConfigH263Keys[j].iString, oscl_strlen(PVOMXVideoDecNodeConfigH263Keys[j].iString)); 2664 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type=value;valtype="), 20); 2665 switch (PVOMXVideoDecNodeConfigH263Keys[j].iValueType) 2666 { 2667 case PVMI_KVPVALTYPE_RANGE_UINT32: 2668 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING)); 2669 break; 2670 2671 case PVMI_KVPVALTYPE_UINT32: 2672 default: 2673 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING)); 2674 break; 2675 } 2676 2677 aParameters[j].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0; 2678 } 2679 2680 aNumParamElements = PVOMXVIDEODECNODECONFIG_H263_NUMKEYS; 2681 } 2682 else if (compcount > 4) 2683 { 2684 // Retrieve the fifth component from the key string 2685 pv_mime_string_extract_type(4, aIdentifier, compstr); 2686 2687 for (int32 vdeccomp5ind = 0; vdeccomp5ind < PVOMXVIDEODECNODECONFIG_H263_NUMKEYS; ++vdeccomp5ind) 2688 { 2689 if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigH263Keys[vdeccomp5ind].iString)) >= 0) 2690 { 2691 // Determine what is requested 2692 PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier); 2693 if (reqattr == PVMI_KVPATTR_UNKNOWN) 2694 { 2695 // Default is current setting 2696 reqattr = PVMI_KVPATTR_CUR; 2697 } 2698 2699 // Return the requested info 2700 PVMFStatus retval = DoGetH263DecoderParameter(aParameters, aNumParamElements, vdeccomp5ind, reqattr); 2701 if (retval != PVMFSuccess) 2702 { 2703 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Retrieving H.263 parameter failed")); 2704 return retval; 2705 } 2706 2707 // Break out of the for(vdeccomp5ind) loop 2708 break; 2709 } 2710 } 2711 } 2712 else 2713 { 2714 // Right now video dec node doesn't support more than 5 components 2715 // for the key sub-string so error out 2716 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Unsupported key")); 2717 return PVMFErrArgument; 2718 } 2719 } 2720 else if (vdeccomp4ind == 4) 2721 { 2722 // "x-pvmf/video/decoder/m4v" 2723 if (compcount == 4) 2724 { 2725 // Return list of M4v settings. Ignore the 2726 // attribute since capability is only allowed 2727 2728 // Allocate memory for the KVP list 2729 aParameters = (PvmiKvp*)oscl_malloc(PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS * sizeof(PvmiKvp)); 2730 if (aParameters == NULL) 2731 { 2732 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for KVP failed")); 2733 return PVMFErrNoMemory; 2734 } 2735 oscl_memset(aParameters, 0, PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS*sizeof(PvmiKvp)); 2736 // Allocate memory for the key strings in each KVP 2737 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char)); 2738 if (memblock == NULL) 2739 { 2740 oscl_free(aParameters); 2741 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Memory allocation for key string failed")); 2742 return PVMFErrNoMemory; 2743 } 2744 oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS*PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char)); 2745 // Assign the key string buffer to each KVP 2746 int32 j; 2747 for (j = 0; j < PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS; ++j) 2748 { 2749 aParameters[j].key = memblock + (j * PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE); 2750 } 2751 // Copy the requested info 2752 for (j = 0; j < PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS; ++j) 2753 { 2754 oscl_strncat(aParameters[j].key, _STRLIT_CHAR("x-pvmf/video/decoder/m4v/"), 25); 2755 oscl_strncat(aParameters[j].key, PVOMXVideoDecNodeConfigM4VKeys[j].iString, oscl_strlen(PVOMXVideoDecNodeConfigM4VKeys[j].iString)); 2756 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(";type=value;valtype="), 20); 2757 switch (PVOMXVideoDecNodeConfigM4VKeys[j].iValueType) 2758 { 2759 case PVMI_KVPVALTYPE_RANGE_UINT32: 2760 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING)); 2761 break; 2762 2763 case PVMI_KVPVALTYPE_UINT32: 2764 default: 2765 oscl_strncat(aParameters[j].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING)); 2766 break; 2767 } 2768 2769 aParameters[j].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0; 2770 } 2771 2772 aNumParamElements = PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS; 2773 } 2774 else if (compcount > 4) 2775 { 2776 // Retrieve the fifth component from the key string 2777 pv_mime_string_extract_type(4, aIdentifier, compstr); 2778 2779 for (int32 vdeccomp5ind = 0; vdeccomp5ind < PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS; ++vdeccomp5ind) 2780 { 2781 if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigM4VKeys[vdeccomp5ind].iString)) >= 0) 2782 { 2783 // Determine what is requested 2784 PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier); 2785 if (reqattr == PVMI_KVPATTR_UNKNOWN) 2786 { 2787 // Default is current setting 2788 reqattr = PVMI_KVPATTR_CUR; 2789 } 2790 2791 // Return the requested info 2792 PVMFStatus retval = DoGetM4VDecoderParameter(aParameters, aNumParamElements, vdeccomp5ind, reqattr); 2793 if (retval != PVMFSuccess) 2794 { 2795 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Retrieving M4v parameter failed")); 2796 return retval; 2797 } 2798 2799 // Break out of the for(vdeccomp5ind) loop 2800 break; 2801 } 2802 } 2803 } 2804 else 2805 { 2806 // Right now video dec node doesn't support more than 5 components 2807 // for the key sub-string so error out 2808 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Unsupported key")); 2809 return PVMFErrArgument; 2810 } 2811 } 2812 else if ((vdeccomp4ind == 0) || // "postproc_enable", 2813 (vdeccomp4ind == 1) || // "postproc_type" 2814 (vdeccomp4ind == 2) || // "dropframe_enable" 2815 (vdeccomp4ind == 5) // "format_type" 2816 ) 2817 { 2818 if (compcount == 4) 2819 { 2820 // Determine what is requested 2821 PvmiKvpAttr reqattr = GetAttrTypeFromKeyString(aIdentifier); 2822 if (reqattr == PVMI_KVPATTR_UNKNOWN) 2823 { 2824 reqattr = PVMI_KVPATTR_CUR; 2825 } 2826 2827 // Return the requested info 2828 PVMFStatus retval = DoGetVideoDecNodeParameter(aParameters, aNumParamElements, vdeccomp4ind, reqattr); 2829 if (retval != PVMFSuccess) 2830 { 2831 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Retrieving video dec node parameter failed")); 2832 return retval; 2833 } 2834 } 2835 else 2836 { 2837 // Right now videodec node doesn't support more than 4 components 2838 // for this sub-key string so error out 2839 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Unsupported key")); 2840 return PVMFErrArgument; 2841 } 2842 } 2843 2844 // Breakout of the for(vdeccomp4ind) loop 2845 break; 2846 } 2847 } 2848 } 2849 2850 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Out")); 2851 if (aNumParamElements == 0) 2852 { 2853 // If no one could get the parameter, return error 2854 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigGetParametersSync() Unsupported key")); 2855 return PVMFFailure; 2856 } 2857 else 2858 { 2859 return PVMFSuccess; 2860 } 2861} 2862 2863 2864PVMFStatus PVMFOMXVideoDecNode::DoCapConfigReleaseParameters(PvmiKvp* aParameters, int aNumElements) 2865{ 2866 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() In")); 2867 2868 if (aParameters == NULL || aNumElements < 1) 2869 { 2870 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() KVP list is NULL or number of elements is 0")); 2871 return PVMFErrArgument; 2872 } 2873 2874 // Count the number of components and parameters in the key 2875 int compcount = pv_mime_string_compcnt(aParameters[0].key); 2876 // Retrieve the first component from the key string 2877 char* compstr = NULL; 2878 pv_mime_string_extract_type(0, aParameters[0].key, compstr); 2879 2880 if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/decoder")) < 0) || compcount < 3) 2881 { 2882 if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/render")) < 0) || compcount != 4) 2883 { 2884 // First 3 component should be "x-pvmf/video/decoder" and there must 2885 // be at least three components 2886 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() Unsupported key")); 2887 return PVMFErrArgument; 2888 } 2889 } 2890 2891 if (pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/decoder")) >= 0) 2892 { 2893 // Retrieve the third component from the key string 2894 pv_mime_string_extract_type(2, aParameters[0].key, compstr); 2895 2896 // Go through each KVP and release memory for value if allocated from heap 2897 for (int32 i = 0; i < aNumElements; ++i) 2898 { 2899 // Next check if it is a value type that allocated memory 2900 PvmiKvpType kvptype = GetTypeFromKeyString(aParameters[i].key); 2901 if (kvptype == PVMI_KVPTYPE_VALUE || kvptype == PVMI_KVPTYPE_UNKNOWN) 2902 { 2903 PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameters[i].key); 2904 if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN) 2905 { 2906 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() Valtype not specified in key string")); 2907 return PVMFErrArgument; 2908 } 2909 2910 if (keyvaltype == PVMI_KVPVALTYPE_CHARPTR && aParameters[i].value.pChar_value != NULL) 2911 { 2912 oscl_free(aParameters[i].value.pChar_value); 2913 aParameters[i].value.pChar_value = NULL; 2914 } 2915 else if (keyvaltype == PVMI_KVPVALTYPE_KSV && aParameters[i].value.key_specific_value != NULL) 2916 { 2917 oscl_free(aParameters[i].value.key_specific_value); 2918 aParameters[i].value.key_specific_value = NULL; 2919 } 2920 else if (keyvaltype == PVMI_KVPVALTYPE_RANGE_UINT32 && aParameters[i].value.key_specific_value != NULL) 2921 { 2922 range_uint32* rui32 = (range_uint32*)aParameters[i].value.key_specific_value; 2923 aParameters[i].value.key_specific_value = NULL; 2924 oscl_free(rui32); 2925 } 2926 2927 } 2928 } 2929 } 2930 // Video dec node allocated its key strings in one chunk so just free the first key string ptr 2931 oscl_free(aParameters[0].key); 2932 2933 // Free memory for the parameter list 2934 oscl_free(aParameters); 2935 aParameters = NULL; 2936 2937 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigReleaseParameters() Out")); 2938 return PVMFSuccess; 2939} 2940 2941 2942void PVMFOMXVideoDecNode::DoCapConfigSetParameters(PvmiKvp* aParameters, int aNumElements, PvmiKvp* &aRetKVP) 2943{ 2944 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() In")); 2945 2946 if (aParameters == NULL || aNumElements < 1) 2947 { 2948 if (aParameters) 2949 { 2950 aRetKVP = aParameters; 2951 } 2952 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Passed in parameter invalid")); 2953 return; 2954 } 2955 2956 // Go through each parameter 2957 for (int32 paramind = 0; paramind < aNumElements; ++paramind) 2958 { 2959 // Count the number of components and parameters in the key 2960 int compcount = pv_mime_string_compcnt(aParameters[paramind].key); 2961 // Retrieve the first component from the key string 2962 char* compstr = NULL; 2963 pv_mime_string_extract_type(0, aParameters[paramind].key, compstr); 2964 2965 if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/decoder")) < 0) || compcount < 4) 2966 { 2967 // First 3 components should be "x-pvmf/video/decoder" and there must 2968 // be at least four components 2969 aRetKVP = &aParameters[paramind]; 2970 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Unsupported key")); 2971 return; 2972 } 2973 2974 if (compcount == 4) 2975 { 2976 // Verify and set the passed-in video dec node setting 2977 PVMFStatus retval = DoVerifyAndSetVideoDecNodeParameter(aParameters[paramind], true); 2978 if (retval != PVMFSuccess) 2979 { 2980 aRetKVP = &aParameters[paramind]; 2981 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Setting parameter %d failed", paramind)); 2982 return; 2983 } 2984 } 2985 else if (compcount == 5) 2986 { 2987 // Determine the 4th level component 2988 pv_mime_string_extract_type(3, aParameters[paramind].key, compstr); 2989 if (pv_mime_strcmp(compstr, _STRLIT_CHAR("h263")) >= 0) 2990 { 2991 // Verify and set the passed-in H.263 decoder setting 2992 PVMFStatus retval = DoVerifyAndSetH263DecoderParameter(aParameters[paramind], true); 2993 if (retval != PVMFSuccess) 2994 { 2995 aRetKVP = &aParameters[paramind]; 2996 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Setting parameter %d failed", paramind)); 2997 return; 2998 } 2999 } 3000 else if (pv_mime_strcmp(compstr, _STRLIT_CHAR("m4v")) >= 0) 3001 { 3002 // Verify and set the passed-in M4v decoder setting 3003 PVMFStatus retval = DoVerifyAndSetM4VDecoderParameter(aParameters[paramind], true); 3004 if (retval != PVMFSuccess) 3005 { 3006 aRetKVP = &aParameters[paramind]; 3007 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Setting parameter %d failed", paramind)); 3008 return; 3009 } 3010 } 3011 else 3012 { 3013 // Unknown key sub-string 3014 aRetKVP = &aParameters[paramind]; 3015 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Unsupported key")); 3016 return; 3017 } 3018 } 3019 else 3020 { 3021 // Do not support more than 5 components right now 3022 aRetKVP = &aParameters[paramind]; 3023 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Unsupported key")); 3024 return; 3025 } 3026 } 3027 3028 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigSetParameters() Out")); 3029} 3030 3031/* This function finds a nal from the SC's, moves the bitstream pointer to the beginning of the NAL unit, returns the 3032 size of the NAL, and at the same time, updates the remaining size in the bitstream buffer that is passed in */ 3033int32 PVMFOMXVideoDecNode::GetNAL_OMXNode(uint8** bitstream, int* size) 3034{ 3035 int i = 0; 3036 int j; 3037 uint8* nal_unit = *bitstream; 3038 int count = 0; 3039 3040 /* find SC at the beginning of the NAL */ 3041 while (nal_unit[i++] == 0 && i < *size) 3042 { 3043 } 3044 3045 if (nal_unit[i-1] == 1) 3046 { 3047 *bitstream = nal_unit + i; 3048 } 3049 else 3050 { 3051 j = *size; 3052 *size = 0; 3053 return j; // no SC at the beginning, not supposed to happen 3054 } 3055 3056 j = i; 3057 3058 /* found the SC at the beginning of the NAL, now find the SC at the beginning of the next NAL */ 3059 while (i < *size) 3060 { 3061 if (count == 2 && nal_unit[i] == 0x01) 3062 { 3063 i -= 2; 3064 break; 3065 } 3066 3067 if (nal_unit[i]) 3068 count = 0; 3069 else 3070 count++; 3071 i++; 3072 } 3073 3074 *size -= i; 3075 return (i - j); 3076} 3077 3078 3079PVMFStatus PVMFOMXVideoDecNode::DoCapConfigVerifyParameters(PvmiKvp* aParameters, int aNumElements) 3080{ 3081 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() In")); 3082 3083 if (aParameters == NULL || aNumElements < 1) 3084 { 3085 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Passed in parameter invalid")); 3086 return PVMFErrArgument; 3087 } 3088 3089 // Go through each parameter 3090 for (int32 paramind = 0; paramind < aNumElements; ++paramind) 3091 { 3092 // Count the number of components and parameters in the key 3093 int compcount = pv_mime_string_compcnt(aParameters[paramind].key); 3094 // Retrieve the first component from the key string 3095 char* compstr = NULL; 3096 pv_mime_string_extract_type(0, aParameters[paramind].key, compstr); 3097 3098 if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/video/decoder")) < 0) || compcount < 4) 3099 { 3100 if ((pv_mime_strcmp(compstr, _STRLIT_CHAR("x-pvmf/media/format_specific_info")) < 0) || compcount < 3) 3101 { 3102 // First 3 components should be "x-pvmf/media/format_specific_info" and there must 3103 // be at least three components 3104 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Unsupported key")); 3105 return PVMFErrArgument; 3106 } 3107 else 3108 { 3109 pvVideoConfigParserInputs aInputs; 3110 OMXConfigParserInputs aInputParameters; 3111 VideoOMXConfigParserOutputs aOutputParameters; 3112 3113 aInputs.inPtr = (uint8*)(aParameters->value.key_specific_value); 3114 aInputs.inBytes = (int32)aParameters->capacity; 3115 aInputs.iMimeType = iNodeConfig.iMimeType; 3116 aInputParameters.inBytes = aInputs.inBytes; 3117 aInputParameters.inPtr = aInputs.inPtr; 3118 3119 if (aInputs.iMimeType == PVMF_MIME_H264_VIDEO || 3120 aInputs.iMimeType == PVMF_MIME_H264_VIDEO_MP4 || 3121 aInputs.iMimeType == PVMF_MIME_H264_VIDEO_RAW) 3122 { 3123 aInputParameters.cComponentRole = (OMX_STRING)"video_decoder.avc"; 3124 } 3125 else if (aInputs.iMimeType == PVMF_MIME_M4V) 3126 { 3127 aInputParameters.cComponentRole = (OMX_STRING)"video_decoder.mpeg4"; 3128 } 3129 else if (aInputs.iMimeType == PVMF_MIME_H2631998 || 3130 aInputs.iMimeType == PVMF_MIME_H2632000) 3131 { 3132 aInputParameters.cComponentRole = (OMX_STRING)"video_decoder.h263"; 3133 } 3134 else if (aInputs.iMimeType == PVMF_MIME_WMV) 3135 { 3136 aInputParameters.cComponentRole = (OMX_STRING)"video_decoder.wmv"; 3137 } 3138 else 3139 { 3140 // Illegal codec specified. 3141 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "%s::PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Input port format other then codec type", iName.Str())); 3142 3143 } 3144 3145 3146 OMX_BOOL status = OMX_FALSE; 3147 OMX_U32 num_comps = 0; 3148 OMX_STRING *CompOfRole; 3149 OMX_U32 ii; 3150 3151 // call once to find out the number of components that can fit the role 3152 3153 OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, NULL); 3154 3155 if (num_comps > 0) 3156 { 3157 CompOfRole = (OMX_STRING *)oscl_malloc(num_comps * sizeof(OMX_STRING)); 3158 for (ii = 0; ii < num_comps; ii++) 3159 CompOfRole[ii] = (OMX_STRING) oscl_malloc(PV_OMX_MAX_COMPONENT_NAME_LENGTH * sizeof(OMX_U8)); 3160 3161 // call 2nd time to get the component names 3162 OMX_MasterGetComponentsOfRole(aInputParameters.cComponentRole, &num_comps, (OMX_U8 **)CompOfRole); 3163 for (ii = 0; ii < num_comps; ii++) 3164 { 3165 aInputParameters.cComponentName = CompOfRole[ii]; 3166 status = OMX_MasterConfigParser(&aInputParameters, &aOutputParameters); 3167 if (status == OMX_TRUE) 3168 { 3169 break; 3170 } 3171 else 3172 { 3173 status = OMX_FALSE; 3174 } 3175 } 3176 3177 // whether successful or not, need to free CompOfRoles 3178 for (ii = 0; ii < num_comps; ii++) 3179 { 3180 oscl_free(CompOfRole[ii]); 3181 CompOfRole[ii] = NULL; 3182 } 3183 oscl_free(CompOfRole); 3184 } 3185 else 3186 { 3187 // if no component supports the role, nothing else to do 3188 return PVMFErrNotSupported; 3189 } 3190 3191 if (status == OMX_FALSE) 3192 { 3193 return PVMFErrNotSupported; 3194 } 3195 3196 iNewWidth = aOutputParameters.width; 3197 iNewHeight = aOutputParameters.height; 3198 3199 return PVMFSuccess; 3200 } 3201 } 3202 else 3203 { 3204 if (compcount == 4) 3205 { 3206 // Verify and set the passed-in video dec node setting 3207 PVMFStatus retval = DoVerifyAndSetVideoDecNodeParameter(aParameters[paramind], false); 3208 if (retval != PVMFSuccess) 3209 { 3210 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Setting parameter %d failed", paramind)); 3211 return retval; 3212 } 3213 } 3214 else if (compcount == 5) 3215 { 3216 // Determine the 4th level component 3217 pv_mime_string_extract_type(3, aParameters[paramind].key, compstr); 3218 if (pv_mime_strcmp(compstr, _STRLIT_CHAR("h263")) >= 0) 3219 { 3220 // Verify and set the passed-in H.263 decoder setting 3221 PVMFStatus retval = DoVerifyAndSetH263DecoderParameter(aParameters[paramind], false); 3222 if (retval != PVMFSuccess) 3223 { 3224 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Setting parameter %d failed", paramind)); 3225 return retval; 3226 } 3227 } 3228 else if (pv_mime_strcmp(compstr, _STRLIT_CHAR("m4v")) >= 0) 3229 { 3230 // Verify and set the passed-in M4v decoder setting 3231 PVMFStatus retval = DoVerifyAndSetM4VDecoderParameter(aParameters[paramind], false); 3232 if (retval != PVMFSuccess) 3233 { 3234 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Setting parameter %d failed", paramind)); 3235 return retval; 3236 } 3237 } 3238 else 3239 { 3240 // Unknown key sub-string 3241 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Unsupported key")); 3242 return PVMFErrArgument; 3243 } 3244 } 3245 else 3246 { 3247 // Do not support more than 5 components right now 3248 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Unsupported key")); 3249 return PVMFErrArgument; 3250 } 3251 } 3252 } 3253 3254 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoCapConfigVerifyParameters() Out")); 3255 return PVMFSuccess; 3256} 3257 3258 3259 3260PVMFStatus PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr) 3261{ 3262 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter() In")); 3263 3264 aNumParamElements = 0; 3265 3266 // Allocate memory for the KVP 3267 aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp)); 3268 if (aParameters == NULL) 3269 { 3270 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter() Memory allocation for KVP failed")); 3271 return PVMFErrNoMemory; 3272 } 3273 oscl_memset(aParameters, 0, sizeof(PvmiKvp)); 3274 // Allocate memory for the key string in KVP 3275 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char)); 3276 if (memblock == NULL) 3277 { 3278 oscl_free(aParameters); 3279 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter() Memory allocation for key string failed")); 3280 return PVMFErrNoMemory; 3281 } 3282 oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char)); 3283 // Assign the key string buffer to KVP 3284 aParameters[0].key = memblock; 3285 3286 // Copy the key string 3287 oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/video/decoder/"), 21); 3288 oscl_strncat(aParameters[0].key, PVOMXVideoDecNodeConfigBaseKeys[aIndex].iString, oscl_strlen(PVOMXVideoDecNodeConfigBaseKeys[aIndex].iString)); 3289 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20); 3290 switch (PVOMXVideoDecNodeConfigBaseKeys[aIndex].iValueType) 3291 { 3292 case PVMI_KVPVALTYPE_BITARRAY32: 3293 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BITARRAY32_STRING), oscl_strlen(PVMI_KVPVALTYPE_BITARRAY32_STRING)); 3294 break; 3295 3296 case PVMI_KVPVALTYPE_KSV: 3297 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_KSV_STRING), oscl_strlen(PVMI_KVPVALTYPE_KSV_STRING)); 3298 break; 3299 3300 case PVMI_KVPVALTYPE_BOOL: 3301 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_BOOL_STRING), oscl_strlen(PVMI_KVPVALTYPE_BOOL_STRING)); 3302 break; 3303 3304 case PVMI_KVPVALTYPE_UINT32: 3305 default: 3306 if (reqattr == PVMI_KVPATTR_CAP) 3307 { 3308 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING)); 3309 } 3310 else 3311 { 3312 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING)); 3313 } 3314 break; 3315 } 3316 aParameters[0].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0; 3317 3318 // Copy the requested info 3319 switch (aIndex) 3320 { 3321 case 0: // "postproc_enable" 3322 if (reqattr == PVMI_KVPATTR_CUR) 3323 { 3324 // Return current value 3325 aParameters[0].value.bool_value = iNodeConfig.iPostProcessingEnable; 3326 } 3327 else if (reqattr == PVMI_KVPATTR_DEF) 3328 { 3329 // Return default 3330 aParameters[0].value.bool_value = PVOMXVIDEODECNODE_CONFIG_POSTPROCENABLE_DEF; 3331 } 3332 3333 break; 3334 3335 case 1: // "postproc_type" 3336 if (reqattr == PVMI_KVPATTR_CUR) 3337 { 3338 // Return current value 3339 aParameters[0].value.uint32_value = iNodeConfig.iPostProcessingMode; 3340 } 3341 else if (reqattr == PVMI_KVPATTR_DEF) 3342 { 3343 // Return default 3344 aParameters[0].value.uint32_value = PVOMXVIDEODECNODE_CONFIG_POSTPROCTYPE_DEF; 3345 } 3346 3347 break; 3348 3349 case 2: // "dropframe_enable" 3350 if (reqattr == PVMI_KVPATTR_CUR) 3351 { 3352 // Return current value 3353 aParameters[0].value.bool_value = iNodeConfig.iDropFrame; 3354 } 3355 else if (reqattr == PVMI_KVPATTR_DEF) 3356 { 3357 // Return default 3358 aParameters[0].value.bool_value = PVOMXVIDEODECNODE_CONFIG_DROPFRAMEENABLE_DEF; 3359 } 3360 3361 break; 3362 3363 case 5: //"format-type" 3364 if (reqattr == PVMI_KVPATTR_CUR) 3365 { 3366 // Return current value 3367 aParameters[0].value.pChar_value = (char*)iNodeConfig.iMimeType.getMIMEStrPtr(); 3368 } 3369 else if (reqattr == PVMI_KVPATTR_DEF) 3370 { 3371 // Return default 3372 aParameters[0].value.pChar_value = (char*)PVMF_MIME_FORMAT_UNKNOWN; 3373 } 3374 3375 break; 3376 3377 default: 3378 // Invalid index 3379 oscl_free(aParameters[0].key); 3380 oscl_free(aParameters); 3381 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter() Invalid index to video dec node parameter")); 3382 return PVMFErrArgument; 3383 } 3384 3385 aNumParamElements = 1; 3386 3387 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetVideoDecNodeParameter() Out")); 3388 return PVMFSuccess; 3389} 3390 3391 3392PVMFStatus PVMFOMXVideoDecNode::DoGetH263DecoderParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr) 3393{ 3394 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() In")); 3395 3396 aNumParamElements = 0; 3397 3398 // Allocate memory for the KVP 3399 aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp)); 3400 if (aParameters == NULL) 3401 { 3402 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Memory allocation for KVP failed")); 3403 return PVMFErrNoMemory; 3404 } 3405 oscl_memset(aParameters, 0, sizeof(PvmiKvp)); 3406 // Allocate memory for the key string in KVP 3407 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char)); 3408 if (memblock == NULL) 3409 { 3410 oscl_free(aParameters); 3411 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Memory allocation for key string failed")); 3412 return PVMFErrNoMemory; 3413 } 3414 oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char)); 3415 // Assign the key string buffer to KVP 3416 aParameters[0].key = memblock; 3417 3418 // Copy the key string 3419 oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/video/decoder/h263/"), 26); 3420 oscl_strncat(aParameters[0].key, PVOMXVideoDecNodeConfigH263Keys[aIndex].iString, oscl_strlen(PVOMXVideoDecNodeConfigH263Keys[aIndex].iString)); 3421 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20); 3422 switch (PVOMXVideoDecNodeConfigH263Keys[aIndex].iValueType) 3423 { 3424 case PVMI_KVPVALTYPE_RANGE_UINT32: 3425 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING)); 3426 break; 3427 3428 case PVMI_KVPVALTYPE_UINT32: 3429 default: 3430 if (reqattr == PVMI_KVPATTR_CAP) 3431 { 3432 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING)); 3433 } 3434 else 3435 { 3436 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING)); 3437 } 3438 break; 3439 } 3440 aParameters[0].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0; 3441 3442 // Copy the requested info 3443 switch (aIndex) 3444 { 3445 case 0: // "maxbitstreamframesize" 3446 if (reqattr == PVMI_KVPATTR_CUR) 3447 { 3448 // Return current value 3449 aParameters[0].value.uint32_value = iH263MaxBitstreamFrameSize; 3450 } 3451 else if (reqattr == PVMI_KVPATTR_DEF) 3452 { 3453 // Return default 3454 aParameters[0].value.uint32_value = PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_DEF; 3455 } 3456 else 3457 { 3458 // Return capability 3459 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32)); 3460 if (rui32 == NULL) 3461 { 3462 oscl_free(aParameters[0].key); 3463 oscl_free(aParameters); 3464 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Memory allocation for range uint32 failed")); 3465 return PVMFErrNoMemory; 3466 } 3467 rui32->min = PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MIN; 3468 rui32->max = PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MAX; 3469 aParameters[0].value.key_specific_value = (void*)rui32; 3470 } 3471 break; 3472 3473 case 1: // "maxdimension" 3474 { 3475 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32)); 3476 if (rui32 == NULL) 3477 { 3478 oscl_free(aParameters[0].key); 3479 oscl_free(aParameters); 3480 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Memory allocation for range uint32 failed")); 3481 return PVMFErrNoMemory; 3482 } 3483 3484 if (reqattr == PVMI_KVPATTR_CUR) 3485 { 3486 // Return current value 3487 rui32->min = iH263MaxWidth; 3488 rui32->max = iH263MaxHeight; 3489 aParameters[0].value.key_specific_value = (void*)rui32; 3490 } 3491 else if (reqattr == PVMI_KVPATTR_DEF) 3492 { 3493 // Return default 3494 rui32->min = PVOMXVIDEODECNODE_CONFIG_H263MAXWIDTH_DEF; 3495 rui32->max = PVOMXVIDEODECNODE_CONFIG_H263MAXHEIGHT_DEF; 3496 aParameters[0].value.key_specific_value = (void*)rui32; 3497 } 3498 else 3499 { 3500 // Return capability 3501 rui32->min = PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MIN; 3502 rui32->max = PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MAX; 3503 aParameters[0].value.key_specific_value = (void*)rui32; 3504 } 3505 } 3506 break; 3507 3508 default: 3509 // Invalid index 3510 oscl_free(aParameters[0].key); 3511 oscl_free(aParameters); 3512 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Invalid index to H.263 decoder parameter")); 3513 return PVMFErrArgument; 3514 } 3515 3516 aNumParamElements = 1; 3517 3518 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetH263DecoderParameter() Out")); 3519 return PVMFSuccess; 3520} 3521 3522 3523PVMFStatus PVMFOMXVideoDecNode::DoGetM4VDecoderParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr) 3524{ 3525 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() In")); 3526 3527 aNumParamElements = 0; 3528 3529 // Allocate memory for the KVP 3530 aParameters = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp)); 3531 if (aParameters == NULL) 3532 { 3533 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Memory allocation for KVP failed")); 3534 return PVMFErrNoMemory; 3535 } 3536 oscl_memset(aParameters, 0, sizeof(PvmiKvp)); 3537 // Allocate memory for the key string in KVP 3538 PvmiKeyType memblock = (PvmiKeyType)oscl_malloc(PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE * sizeof(char)); 3539 if (memblock == NULL) 3540 { 3541 oscl_free(aParameters); 3542 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Memory allocation for key string failed")); 3543 return PVMFErrNoMemory; 3544 } 3545 oscl_strset(memblock, 0, PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE*sizeof(char)); 3546 // Assign the key string buffer to KVP 3547 aParameters[0].key = memblock; 3548 3549 // Copy the key string 3550 oscl_strncat(aParameters[0].key, _STRLIT_CHAR("x-pvmf/video/decoder/m4v/"), 25); 3551 oscl_strncat(aParameters[0].key, PVOMXVideoDecNodeConfigM4VKeys[aIndex].iString, oscl_strlen(PVOMXVideoDecNodeConfigM4VKeys[aIndex].iString)); 3552 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(";type=value;valtype="), 20); 3553 switch (PVOMXVideoDecNodeConfigM4VKeys[aIndex].iValueType) 3554 { 3555 case PVMI_KVPVALTYPE_RANGE_UINT32: 3556 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING)); 3557 break; 3558 3559 case PVMI_KVPVALTYPE_UINT32: 3560 default: 3561 if (reqattr == PVMI_KVPATTR_CAP) 3562 { 3563 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_RANGE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_RANGE_UINT32_STRING)); 3564 } 3565 else 3566 { 3567 oscl_strncat(aParameters[0].key, _STRLIT_CHAR(PVMI_KVPVALTYPE_UINT32_STRING), oscl_strlen(PVMI_KVPVALTYPE_UINT32_STRING)); 3568 } 3569 break; 3570 } 3571 aParameters[0].key[PVOMXVIDEODECNODECONFIG_KEYSTRING_SIZE-1] = 0; 3572 3573 // Copy the requested info 3574 switch (aIndex) 3575 { 3576 case 0: // "maxbitstreamframesize" 3577 if (reqattr == PVMI_KVPATTR_CUR) 3578 { 3579 // Return current value 3580 aParameters[0].value.uint32_value = iM4VMaxBitstreamFrameSize; 3581 } 3582 else if (reqattr == PVMI_KVPATTR_DEF) 3583 { 3584 // Return default 3585 aParameters[0].value.uint32_value = PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_DEF; 3586 } 3587 else 3588 { 3589 // Return capability 3590 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32)); 3591 if (rui32 == NULL) 3592 { 3593 oscl_free(aParameters[0].key); 3594 oscl_free(aParameters); 3595 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Memory allocation for range uint32 failed")); 3596 return PVMFErrNoMemory; 3597 } 3598 rui32->min = PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MIN; 3599 rui32->max = PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MAX; 3600 aParameters[0].value.key_specific_value = (void*)rui32; 3601 } 3602 break; 3603 3604 case 1: // "maxdimension" 3605 { 3606 range_uint32* rui32 = (range_uint32*)oscl_malloc(sizeof(range_uint32)); 3607 if (rui32 == NULL) 3608 { 3609 oscl_free(aParameters[0].key); 3610 oscl_free(aParameters); 3611 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Memory allocation for range uint32 failed")); 3612 return PVMFErrNoMemory; 3613 } 3614 3615 if (reqattr == PVMI_KVPATTR_CUR) 3616 { 3617 // Return current value 3618 rui32->min = iM4VMaxWidth; 3619 rui32->max = iM4VMaxHeight; 3620 aParameters[0].value.key_specific_value = (void*)rui32; 3621 } 3622 else if (reqattr == PVMI_KVPATTR_DEF) 3623 { 3624 // Return default 3625 rui32->min = PVOMXVIDEODECNODE_CONFIG_M4VMAXWIDTH_DEF; 3626 rui32->max = PVOMXVIDEODECNODE_CONFIG_M4VMAXHEIGHT_DEF; 3627 aParameters[0].value.key_specific_value = (void*)rui32; 3628 } 3629 else 3630 { 3631 // Return capability 3632 rui32->min = PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MIN; 3633 rui32->max = PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MAX; 3634 aParameters[0].value.key_specific_value = (void*)rui32; 3635 } 3636 } 3637 break; 3638 3639 default: 3640 // Invalid index 3641 oscl_free(aParameters[0].key); 3642 oscl_free(aParameters); 3643 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Invalid index to H.263 decoder parameter")); 3644 return PVMFErrArgument; 3645 } 3646 3647 aNumParamElements = 1; 3648 3649 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoGetM4VDecoderParameter() Out")); 3650 return PVMFSuccess; 3651} 3652 3653 3654PVMFStatus PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter(PvmiKvp& aParameter, bool aSetParam) 3655{ 3656 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() In")); 3657 3658 // Determine the valtype 3659 PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key); 3660 if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN) 3661 { 3662 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Valtype in key string unknown")); 3663 return PVMFErrArgument; 3664 } 3665 // Retrieve the fourth component from the key string 3666 char* compstr = NULL; 3667 pv_mime_string_extract_type(3, aParameter.key, compstr); 3668 3669 int32 vdeccomp4ind = 0; 3670 for (vdeccomp4ind = 0; vdeccomp4ind < PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS; ++vdeccomp4ind) 3671 { 3672 // Go through each component string at 4th level 3673 if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigBaseKeys[vdeccomp4ind].iString)) >= 0) 3674 { 3675 // Break out of the for loop 3676 break; 3677 } 3678 } 3679 3680 if (vdeccomp4ind == PVOMXVIDEODECNODECONFIG_BASE_NUMKEYS || vdeccomp4ind == 3 || vdeccomp4ind == 4) 3681 { 3682 // Match couldn't be found or non-leaf node specified 3683 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Unsupported key or non-leaf node")); 3684 return PVMFErrArgument; 3685 } 3686 3687 // Verify the valtype 3688 if (keyvaltype != PVOMXVideoDecNodeConfigBaseKeys[vdeccomp4ind].iValueType) 3689 { 3690 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Valtype does not match for key")); 3691 return PVMFErrArgument; 3692 } 3693 3694 switch (vdeccomp4ind) 3695 { 3696 case 0: // "postproc_enable" 3697 // Nothing to validate since it is boolean 3698 // Change the config if to set 3699 if (aSetParam) 3700 { 3701 iNodeConfig.iPostProcessingEnable = aParameter.value.bool_value; 3702 } 3703 break; 3704 3705 case 1: // "postproc_type" 3706 // Nothing to validate since it is bitarray32 3707 // Change the config if to set 3708 if (aSetParam) 3709 { 3710 iNodeConfig.iPostProcessingMode = aParameter.value.uint32_value; 3711 if (iNodeConfig.iPostProcessingEnable && iOMXDecoder) 3712 { 3713 // Don't do anything yet: Need to communicate post-processing to decoder 3714 //iVideoDecoder->SetPostProcType(iNodeConfig.iPostProcessingMode); 3715 } 3716 } 3717 break; 3718 3719 case 2: // "dropframe_enable" 3720 // Nothing to validate since it is boolean 3721 // Change the config if to set 3722 if (aSetParam) 3723 { 3724 if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused) 3725 { 3726 // This setting cannot be changed when decoder has been initialized 3727 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused")); 3728 return PVMFErrInvalidState; 3729 } 3730 3731 iNodeConfig.iDropFrame = aParameter.value.bool_value; 3732 } 3733 break; 3734 3735 case 5: // "format-type" 3736 // Nothing to validate since it is boolean 3737 // Change the config if to set 3738 if (aSetParam) 3739 { 3740 if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused) 3741 { 3742 // This setting cannot be changed when decoder has been initialized 3743 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused")); 3744 return PVMFErrInvalidState; 3745 } 3746 3747 iNodeConfig.iMimeType = aParameter.value.pChar_value; 3748 } 3749 break; 3750 3751 default: 3752 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Invalid index for video dec node parameter")); 3753 return PVMFErrArgument; 3754 } 3755 3756 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Out")); 3757 return PVMFSuccess; 3758} 3759 3760 3761PVMFStatus PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter(PvmiKvp& aParameter, bool aSetParam) 3762{ 3763 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() In")); 3764 3765 // Determine the valtype 3766 PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key); 3767 if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN) 3768 { 3769 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Valtype in key string unknown")); 3770 return PVMFErrArgument; 3771 } 3772 // Retrieve the fifth component from the key string 3773 char* compstr = NULL; 3774 pv_mime_string_extract_type(4, aParameter.key, compstr); 3775 3776 int32 vdeccomp5ind = 0; 3777 for (vdeccomp5ind = 0; vdeccomp5ind < PVOMXVIDEODECNODECONFIG_H263_NUMKEYS; ++vdeccomp5ind) 3778 { 3779 // Go through each component string at 5th level 3780 if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigH263Keys[vdeccomp5ind].iString)) >= 0) 3781 { 3782 // Break out of the for loop 3783 break; 3784 } 3785 } 3786 3787 if (vdeccomp5ind == PVOMXVIDEODECNODECONFIG_H263_NUMKEYS) 3788 { 3789 // Match couldn't be found or non-leaf node specified 3790 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Unsupported key or non-leaf node")); 3791 return PVMFErrArgument; 3792 } 3793 3794 // Verify the valtype 3795 if (keyvaltype != PVOMXVideoDecNodeConfigH263Keys[vdeccomp5ind].iValueType) 3796 { 3797 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Valtype does not match for key")); 3798 return PVMFErrArgument; 3799 } 3800 3801 switch (vdeccomp5ind) 3802 { 3803 case 0: // "maxbitstreamframesize" 3804 // Check if within range 3805 if (aParameter.value.uint32_value < PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MIN || 3806 aParameter.value.uint32_value > PVOMXVIDEODECNODE_CONFIG_H263MAXBITSTREAMFRAMESIZE_MAX) 3807 { 3808 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Invalid value for maxbitstreamframesize")); 3809 return PVMFErrArgument; 3810 } 3811 // Change the config if to set 3812 if (aSetParam) 3813 { 3814 if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused) 3815 { 3816 // This setting cannot be changed when decoder has been initialized 3817 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused")); 3818 return PVMFErrInvalidState; 3819 } 3820 3821 iH263MaxBitstreamFrameSize = aParameter.value.uint32_value; 3822 } 3823 break; 3824 3825 case 1: // "maxdimension" 3826 { 3827 range_uint32* rui32 = (range_uint32*)aParameter.value.key_specific_value; 3828 if (rui32 == NULL) 3829 { 3830 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() ksv for maxdimension is NULL")); 3831 return PVMFErrArgument; 3832 } 3833 3834 // Check if within range 3835 if (rui32->min < PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MIN || 3836 rui32->min > PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MAX || 3837 rui32->max < PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MIN || 3838 rui32->max > PVOMXVIDEODECNODE_CONFIG_H263MAXDIMENSION_MAX) 3839 { 3840 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Invalid range for maxdimension")); 3841 return PVMFErrArgument; 3842 } 3843 3844 // Change the config if to set 3845 if (aSetParam) 3846 { 3847 if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused) 3848 { 3849 // This setting cannot be changed when decoder has been initialized 3850 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused")); 3851 return PVMFErrInvalidState; 3852 } 3853 3854 iH263MaxWidth = rui32->min; 3855 iH263MaxHeight = rui32->max; 3856 } 3857 } 3858 break; 3859 3860 default: 3861 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Invalid index for H.263 decoder parameter")); 3862 return PVMFErrArgument; 3863 } 3864 3865 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetH263DecoderParameter() Out")); 3866 return PVMFSuccess; 3867} 3868 3869 3870PVMFStatus PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter(PvmiKvp& aParameter, bool aSetParam) 3871{ 3872 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() In")); 3873 3874 // Determine the valtype 3875 PvmiKvpValueType keyvaltype = GetValTypeFromKeyString(aParameter.key); 3876 if (keyvaltype == PVMI_KVPVALTYPE_UNKNOWN) 3877 { 3878 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Valtype in key string unknown")); 3879 return PVMFErrArgument; 3880 } 3881 // Retrieve the fifth component from the key string 3882 char* compstr = NULL; 3883 pv_mime_string_extract_type(4, aParameter.key, compstr); 3884 3885 int32 vdeccomp5ind = 0; 3886 for (vdeccomp5ind = 0; vdeccomp5ind < PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS; ++vdeccomp5ind) 3887 { 3888 // Go through each component string at 5th level 3889 if (pv_mime_strcmp(compstr, (char*)(PVOMXVideoDecNodeConfigM4VKeys[vdeccomp5ind].iString)) >= 0) 3890 { 3891 // Break out of the for loop 3892 break; 3893 } 3894 } 3895 3896 if (vdeccomp5ind == PVOMXVIDEODECNODECONFIG_M4V_NUMKEYS) 3897 { 3898 // Match couldn't be found or non-leaf node specified 3899 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Unsupported key or non-leaf node")); 3900 return PVMFErrArgument; 3901 } 3902 3903 // Verify the valtype 3904 if (keyvaltype != PVOMXVideoDecNodeConfigM4VKeys[vdeccomp5ind].iValueType) 3905 { 3906 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Valtype does not match for key")); 3907 return PVMFErrArgument; 3908 } 3909 3910 switch (vdeccomp5ind) 3911 { 3912 case 0: // "maxbitstreamframesize" 3913 // Check if within range 3914 if (aParameter.value.uint32_value < PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MIN || 3915 aParameter.value.uint32_value > PVOMXVIDEODECNODE_CONFIG_M4VMAXBITSTREAMFRAMESIZE_MAX) 3916 { 3917 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Invalid value for maxbitstreamframesize")); 3918 return PVMFErrArgument; 3919 } 3920 // Change the config if to set 3921 if (aSetParam) 3922 { 3923 if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused) 3924 { 3925 // This setting cannot be changed when decoder has been initialized 3926 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused")); 3927 return PVMFErrInvalidState; 3928 } 3929 3930 iM4VMaxBitstreamFrameSize = aParameter.value.uint32_value; 3931 } 3932 break; 3933 3934 case 1: // "maxdimension" 3935 { 3936 range_uint32* rui32 = (range_uint32*)aParameter.value.key_specific_value; 3937 if (rui32 == NULL) 3938 { 3939 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() ksv for maxdimension is NULL")); 3940 return PVMFErrArgument; 3941 } 3942 3943 // Check if within range 3944 if (rui32->min < PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MIN || 3945 rui32->min > PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MAX || 3946 rui32->max < PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MIN || 3947 rui32->max > PVOMXVIDEODECNODE_CONFIG_M4VMAXDIMENSION_MAX) 3948 { 3949 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Invalid range for maxdimension")); 3950 return PVMFErrArgument; 3951 } 3952 3953 // Change the config if to set 3954 if (aSetParam) 3955 { 3956 if (iInterfaceState == EPVMFNodeStarted || iInterfaceState == EPVMFNodePaused) 3957 { 3958 // This setting cannot be changed when decoder has been initialized 3959 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetVideoDecNodeParameter() Setting cannot be changed while started or paused")); 3960 return PVMFErrInvalidState; 3961 } 3962 3963 iM4VMaxWidth = rui32->min; 3964 iM4VMaxHeight = rui32->max; 3965 } 3966 } 3967 break; 3968 3969 default: 3970 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Invalid index for M4v decoder parameter")); 3971 return PVMFErrArgument; 3972 } 3973 3974 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::DoVerifyAndSetM4VDecoderParameter() Out")); 3975 return PVMFSuccess; 3976} 3977 3978 3979 3980PVMFStatus PVMFOMXVideoDecNode::GetProfileAndLevel(PVMF_MPEGVideoProfileType& aProfile, PVMF_MPEGVideoLevelType& aLevel) 3981{ 3982 3983 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVMFOMXVideoDecNode::GetProfileAndLevel() In")); 3984 3985 if (NULL == iOMXDecoder) 3986 { 3987 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::GetProfileAndLevel() iVideoDecoder is Null")); 3988 aProfile = PV_MPEG_VIDEO_RESERVED_PROFILE; 3989 aLevel = PV_MPEG_VIDEO_LEVEL_UNKNOWN; 3990 return PVMFFailure; 3991 } 3992 3993 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::GetProfileAndLevel() iVideoDecoder is Null")); 3994 aProfile = PV_MPEG_VIDEO_RESERVED_PROFILE; 3995 aLevel = PV_MPEG_VIDEO_LEVEL_UNKNOWN; 3996 // FOR NOW, JUST RETURN FAILURE, WE DON'T SUPPORT THIS FEATURE YET 3997 return PVMFFailure; 3998 3999 4000} 4001 4002 4003// DEFINITIONS for parsing the config information & sequence header for WMV 4004 4005#define GetUnalignedDword( pb, dw ) \ 4006 (dw) = ((uint32) *(pb + 3) << 24) + \ 4007 ((uint32) *(pb + 2) << 16) + \ 4008 ((uint16) *(pb + 1) << 8) + *pb; 4009 4010#define GetUnalignedDwordEx( pb, dw ) GetUnalignedDword( pb, dw ); (pb) += sizeof(uint32); 4011#define LoadDWORD( dw, p ) GetUnalignedDwordEx( p, dw ) 4012#ifndef MAKEFOURCC_WMC 4013#define MAKEFOURCC_WMC(ch0, ch1, ch2, ch3) \ 4014 ((uint32)(uint8)(ch0) | ((uint32)(uint8)(ch1) << 8) | \ 4015 ((uint32)(uint8)(ch2) << 16) | ((uint32)(uint8)(ch3) << 24 )) 4016 4017#define mmioFOURCC_WMC(ch0, ch1, ch2, ch3) MAKEFOURCC_WMC(ch0, ch1, ch2, ch3) 4018#endif 4019 4020#define FOURCC_WMV3 mmioFOURCC_WMC('W','M','V','3') 4021#define FOURCC_WMV2 mmioFOURCC_WMC('W','M','V','2') 4022#define FOURCC_WMVA mmioFOURCC_WMC('W','M','V','A') 4023 4024//For WMV3 4025enum { NOT_WMV3 = -1, WMV3_SIMPLE_PROFILE, WMV3_MAIN_PROFILE, WMV3_PC_PROFILE, WMV3_SCREEN }; 4026 4027//For WMVA 4028#define ASFBINDING_SIZE 1 // size of ASFBINDING is 1 byte 4029#define SC_SEQ 0x0F 4030#define SC_ENTRY 0x0E 4031 4032 4033bool PVMFOMXVideoDecNode::VerifyParametersSync(PvmiMIOSession aSession, PvmiKvp* aParameters, int num_elements) 4034{ 4035 // unused parameters 4036 OSCL_UNUSED_ARG(aSession); 4037 OSCL_UNUSED_ARG(num_elements); 4038 4039 // call this in case of WMV format 4040 if (((PVMFOMXDecPort*)iInPort)->iFormat == PVMF_MIME_WMV) 4041 { 4042 4043 //verify bitrate 4044 if (pv_mime_strcmp(aParameters->key, PVMF_BITRATE_VALUE_KEY) == 0) 4045 { 4046 if (((PVMFOMXDecPort*)iOutPort)->verifyConnectedPortParametersSync(PVMF_BITRATE_VALUE_KEY, &(aParameters->value.uint32_value)) != PVMFSuccess) 4047 { 4048 return false; 4049 } 4050 return true; 4051 } 4052 else if (pv_mime_strcmp(aParameters->key, PVMF_FRAMERATE_VALUE_KEY) == 0) 4053 { 4054 if (((PVMFOMXDecPort*)iOutPort)->verifyConnectedPortParametersSync(PVMF_FRAMERATE_VALUE_KEY, &(aParameters->value.uint32_value)) != PVMFSuccess) 4055 { 4056 return false; 4057 } 4058 return true; 4059 } 4060 else if (pv_mime_strcmp(aParameters->key, PVMF_FORMAT_SPECIFIC_INFO_KEY) < 0) 4061 { 4062 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::VerifyParametersSync() - Unsupported Key")); 4063 return true; 4064 } 4065 4066 // pConfig points to format specific info and sequence header. 4067 uint8 *pConfig = (uint8*)(aParameters->value.key_specific_value); 4068 uint8 *pData; 4069 uint32 dwdat; 4070 uint32 NewCompression; 4071 uint32 NewSeqHeader; 4072 uint32 NewProfile, NewFrameRate, NewBitRate; 4073 4074 // We are interested in the following (and will extract it) 4075 // 1. Version (WMV9 or WMV8 etc.) (from format specific info) 4076 // 2. picture dimensions // from format specific info 4077 // 3. interlaced YUV411 /sprite content is not supported (from sequence header) 4078 // 4. framerate / bitrate information (from sequence header) 4079 4080 pData = pConfig + 15; // position ptr to Width & Height 4081 4082 LoadDWORD(dwdat, pData); 4083 iNewWidth = dwdat; 4084 LoadDWORD(dwdat, pData); 4085 iNewHeight = dwdat; 4086 4087 if (((iNewWidth != (uint32)iYUVWidth) || (iNewHeight != (uint32)iYUVHeight)) && iOutPort != NULL) 4088 { 4089 // see if downstream node can handle the re-sizing 4090 int32 errcode = OsclErrNone; 4091 OsclRefCounterMemFrag yuvFsiMemfrag; 4092 OSCL_TRY(errcode, yuvFsiMemfrag = iFsiFragmentAlloc.get()); 4093 4094 4095 OSCL_FIRST_CATCH_ANY(errcode, PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVMFOMXVideoDecNode::VerifyParametersSync() Failed to allocate memory for verifyParametersSync FSI"))); 4096 if (OsclErrNone == errcode) 4097 { 4098 PVMFYuvFormatSpecificInfo0* fsiInfo = OSCL_PLACEMENT_NEW(yuvFsiMemfrag.getMemFragPtr(), PVMFYuvFormatSpecificInfo0()); 4099 if (fsiInfo != NULL) 4100 { 4101 fsiInfo->video_format = PVMF_MIME_YUV420; 4102 fsiInfo->uid = PVMFYuvFormatSpecificInfo0_UID; 4103 fsiInfo->display_width = iNewWidth; 4104 fsiInfo->display_height = iNewHeight; 4105 fsiInfo->width = (iNewWidth + 3) & -4; 4106 fsiInfo->height = iNewHeight; 4107 4108 if (((PVMFOMXDecPort*)iOutPort)->verifyConnectedPortParametersSync(PVMF_FORMAT_SPECIFIC_INFO_KEY, &yuvFsiMemfrag) != PVMFSuccess) 4109 { 4110 fsiInfo->video_format.~PVMFFormatType(); 4111 return false; 4112 } 4113 fsiInfo->video_format.~PVMFFormatType(); 4114 } 4115 else 4116 { 4117 return false; 4118 } 4119 } 4120 else 4121 { 4122 return false; 4123 } 4124 } 4125 4126 pData += 4; //position ptr to Compression type 4127 4128 LoadDWORD(dwdat, pData); 4129 NewCompression = dwdat; 4130 4131 if (NewCompression != FOURCC_WMV2 && 4132 NewCompression != FOURCC_WMV3 && 4133 NewCompression != FOURCC_WMVA) 4134 return false; 4135 4136 4137 // Check sequence header 4138 switch (NewCompression) 4139 { 4140 case FOURCC_WMV3: 4141 { 4142 pData = pConfig + 11 + 40; //sizeof(BITMAPINFOHEADER); // position to sequence header 4143 4144 LoadDWORD(dwdat, pData); 4145 NewSeqHeader = dwdat; // this is little endian read sequence header 4146 4147 uint32 YUV411flag, Spriteflag; 4148 4149 // For FOURCC_WMV3 4150 uint32 YUV411; 4151 uint32 SpriteMode; 4152 uint32 LoopFilter; 4153 uint32 Xintra8Switch; 4154 uint32 MultiresEnabled; 4155 uint32 X16bitXform; 4156 uint32 UVHpelBilinear; 4157 uint32 ExtendedMvMode; 4158 uint32 DQuantCodingOn; 4159 uint32 XformSwitch; 4160 uint32 DCTTable_MB_ENABLED; 4161 uint32 SequenceOverlap; 4162 uint32 StartCode; 4163 uint32 PreProcRange; 4164 uint32 NumBFrames; 4165 uint32 ExplicitSeqQuantizer; 4166 uint32 Use3QPDZQuantizer = 0; 4167 uint32 ExplicitFrameQuantizer = 0; 4168 4169 4170 bool bValidProfile = true; 4171 4172 NewProfile = (NewSeqHeader & 0xC0) >> 6; // 0 - simple , 1- main, 3 - complex, 2-forbidden 4173 4174 if (NewProfile == WMV3_PC_PROFILE) 4175 return false; 4176 4177 YUV411flag = (NewSeqHeader & 0x20) >> 5; 4178 Spriteflag = (NewSeqHeader & 0x10) >> 4; 4179 if ((YUV411flag != 0) || (Spriteflag != 0)) 4180 return false; 4181 4182 YUV411 = (uint32)YUV411flag; 4183 SpriteMode = (uint32)Spriteflag; 4184 LoopFilter = (NewSeqHeader & 0x800) >> 11; 4185 Xintra8Switch = (NewSeqHeader & 0x400) >> 10; 4186 MultiresEnabled = (NewSeqHeader & 0x200) >> 9; 4187 X16bitXform = (NewSeqHeader & 0x100) >> 8; 4188 UVHpelBilinear = (NewSeqHeader & 0x800000) >> 23; 4189 ExtendedMvMode = (NewSeqHeader & 0x400000) >> 22; 4190 DQuantCodingOn = (NewSeqHeader & 0x300000) >> 20; 4191 XformSwitch = (NewSeqHeader & 0x80000) >> 19; 4192 DCTTable_MB_ENABLED = (NewSeqHeader & 0x40000) >> 18; 4193 SequenceOverlap = (NewSeqHeader & 0x20000) >> 17; 4194 StartCode = (NewSeqHeader & 0x10000) >> 16; 4195 PreProcRange = (NewSeqHeader & 0x80000000) >> 31; 4196 NumBFrames = (NewSeqHeader & 0x70000000) >> 28; 4197 ExplicitSeqQuantizer = (NewSeqHeader & 0x8000000) >> 27; 4198 if (ExplicitSeqQuantizer) 4199 Use3QPDZQuantizer = (NewSeqHeader & 0x4000000) >> 26; 4200 else 4201 ExplicitFrameQuantizer = (NewSeqHeader & 0x4000000) >> 26; 4202 4203 NewFrameRate = (NewSeqHeader & 0x0E) >> 1 ; // from 2 to 30 fps (in steps of 4) 4204 NewFrameRate = 4 * NewFrameRate + 2; // (in fps) 4205 4206 NewBitRate = (((NewSeqHeader & 0xF000) >> 24) | ((NewSeqHeader & 0x01) << 8)); // from 32 to 2016 kbps in steps of 64kbps 4207 NewBitRate = 64 * NewBitRate + 32; // (in kbps) 4208 4209 // Verify Profile 4210 if (!SpriteMode) 4211 { 4212 if (NewProfile == WMV3_SIMPLE_PROFILE) 4213 { 4214 bValidProfile = (Xintra8Switch == 0) && 4215 (X16bitXform == 1) && 4216 (UVHpelBilinear == 1) && 4217 (StartCode == 0) && 4218 (LoopFilter == 0) && 4219 (YUV411 == 0) && 4220 (MultiresEnabled == 0) && 4221 (DQuantCodingOn == 0) && 4222 (NumBFrames == 0) && 4223 (PreProcRange == 0); 4224 4225 } 4226 else if (NewProfile == WMV3_MAIN_PROFILE) 4227 { 4228 bValidProfile = (Xintra8Switch == 0) && 4229 (X16bitXform == 1); 4230 } 4231 else if (NewProfile == WMV3_PC_PROFILE) 4232 { 4233 // no feature restrictions for complex profile. 4234 } 4235 4236 if (!bValidProfile) 4237 { 4238 return false; 4239 } 4240 } 4241 else 4242 { 4243 if (!Xintra8Switch && 4244 !DCTTable_MB_ENABLED && 4245 !YUV411 && 4246 !LoopFilter && 4247 !ExtendedMvMode && 4248 !MultiresEnabled && 4249 !UVHpelBilinear && 4250 !DQuantCodingOn && 4251 !XformSwitch && 4252 !StartCode && 4253 !PreProcRange && 4254 !ExplicitSeqQuantizer && 4255 !Use3QPDZQuantizer && 4256 !ExplicitFrameQuantizer) 4257 return true; 4258 else 4259 return false; 4260 } 4261 } 4262 break; 4263 case FOURCC_WMVA: 4264 { 4265 pData = pConfig + 11 + 40 + ASFBINDING_SIZE; //sizeof(BITMAPINFOHEADER); // position to sequence header 4266 4267 LoadDWORD(dwdat, pData); 4268 NewSeqHeader = dwdat; // this is little endian read sequence header 4269 4270 int32 iPrefix; 4271 //ignore start code prefix 4272 iPrefix = NewSeqHeader & 0xFF; 4273 if (iPrefix != 0) return false; 4274 iPrefix = (NewSeqHeader & 0xFF00) >> 8; 4275 if (iPrefix != 0) return false; 4276 iPrefix = (NewSeqHeader & 0xFF0000) >> 16; 4277 if (iPrefix != 1) return false; 4278 iPrefix = (NewSeqHeader & 0xFF000000) >> 24; 4279 if (iPrefix != SC_SEQ) return false; 4280 4281 LoadDWORD(dwdat, pData); 4282 NewSeqHeader = dwdat; 4283 4284 NewProfile = (NewSeqHeader & 0xC0) >> 6; 4285 if (NewProfile != 3) 4286 return false; 4287 pData += 3; 4288 LoadDWORD(dwdat, pData); 4289 NewSeqHeader = dwdat; 4290 //ignore start code prefix 4291 iPrefix = NewSeqHeader & 0xFF; 4292 if (iPrefix != 0) return false; 4293 iPrefix = (NewSeqHeader & 0xFF00) >> 8; 4294 if (iPrefix != 0) return false; 4295 iPrefix = (NewSeqHeader & 0xFF0000) >> 16; 4296 if (iPrefix != 1) return false; 4297 iPrefix = (NewSeqHeader & 0xFF000000) >> 24; 4298 if (iPrefix != SC_ENTRY) return false; 4299 } 4300 break; 4301 4302 case FOURCC_WMV2: 4303 break; 4304 4305 default: 4306 return false; 4307 } 4308 4309 } // end of if(format == PVMF_MIME_WMV) 4310 return true; 4311} 4312 4313