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 "h324utils.h" 19 #include "oscl_dll.h" 20 #include "oscl_map.h" 21 22 OSCL_DLL_ENTRY_POINT_DEFAULT() 23 static const uint32 g_num_ones[] = 24 { 25 /* 0 - 0000 0000 */0, 1, 1, 2, 1, 2, 2, 3, 26 /* 8 - 0000 1000 */1, 2, 2, 3, 2, 3, 3, 4, 27 /*16 - 0001 0000 */1, 2, 2, 3, 2, 3, 3, 4, 28 /*24 - 0001 1000 */2, 3, 3, 4, 3, 4, 4, 5, 29 /*32 - 0010 0000 */1, 2, 2, 3, 2, 3, 3, 4, 30 /*40 - 0010 1000 */2, 3, 3, 4, 3, 4, 4, 5, 31 /*48 - 0011 0000 */2, 3, 3, 4, 3, 4, 4, 5, 32 /*56 - 0011 1000 */3, 4, 4, 5, 4, 5, 5, 6, 33 /*64 - 0100 0000 */1, 2, 2, 3, 2, 3, 3, 4, 34 /*72 - 0100 1000 */2, 3, 3, 4, 3, 4, 4, 5, 35 /*80 - 0101 0000 */2, 3, 3, 4, 3, 4, 4, 5, 36 /*88 - 0101 1000 */3, 4, 4, 5, 4, 5, 5, 6, 37 /*96 - 0110 0000 */2, 3, 3, 4, 3, 4, 4, 5, 38 /*104 - 0110 1000 */3, 4, 4, 5, 4, 5, 5, 6, 39 /*112 - 0111 0000 */3, 4, 4, 5, 4, 5, 5, 6, 40 /*120 - 0111 1000 */4, 5, 5, 6, 5, 6, 6, 7, 41 /*128 - 1000 0000 */1, 2, 2, 3, 2, 3, 3, 4, 42 /*136 - 1000 1000 */2, 3, 3, 4, 3, 4, 4, 5, 43 /*144 - 1001 0000 */2, 3, 3, 4, 3, 4, 4, 5, 44 /*152 - 1001 1000 */3, 4, 4, 5, 4, 5, 5, 6, 45 /*160 - 1010 0000 */2, 3, 3, 4, 3, 4, 4, 5, 46 /*168 - 1010 1000 */3, 4, 4, 5, 4, 5, 5, 6, 47 /*176 - 1011 0000 */3, 4, 4, 5, 4, 5, 5, 6, 48 /*184 - 1011 1000 */4, 5, 5, 6, 5, 6, 6, 7, 49 /*192 - 1100 0000 */2, 3, 3, 4, 3, 4, 4, 5, 50 /*200 - 1100 1000 */3, 4, 4, 5, 4, 5, 5, 6, 51 /*208 - 1101 0000 */3, 4, 4, 5, 4, 5, 5, 6, 52 /*216 - 1101 1000 */4, 5, 5, 6, 5, 6, 6, 7, 53 /*224 - 1110 0000 */3, 4, 4, 5, 4, 5, 5, 6, 54 /*232 - 1110 1000 */4, 5, 5, 6, 5, 6, 6, 7, 55 /*240 - 1111 0000 */4, 5, 5, 6, 5, 6, 6, 7, 56 /*248 - 1111 1000 */5, 6, 6, 7, 6, 7, 7, 8 57 }; 58 59 PVCodecType_t GetVidCodecTypeFromVideoCapability(PS_VideoCapability capability) 60 { 61 switch (capability->index) 62 { 63 case 3: 64 return PV_VID_TYPE_H263; 65 case 5: 66 { 67 if (capability->genericVideoCapability->capabilityIdentifier.index == 0) 68 { 69 S_CapabilityIdentifierStandard capabilityIdentifierStandardInfo; 70 ParseCapabilityIdentifierStandard( 71 capability->genericVideoCapability->capabilityIdentifier.standard->data, 72 capability->genericVideoCapability->capabilityIdentifier.standard->size, 73 capabilityIdentifierStandardInfo); 74 return GetVidCodecTypeFromCapabilityIdentifier( 75 capabilityIdentifierStandardInfo); 76 } 77 } 78 default: 79 break; 80 } 81 return PV_CODEC_TYPE_NONE; 82 } 83 84 PVCodecType_t GetVidCodecTypeFromCapabilityIdentifier(S_CapabilityIdentifierStandard& identifier) 85 { 86 if (identifier.itu != 0 || 87 identifier.spec_type != 0 || 88 identifier.series_letter != 8) 89 return PV_CODEC_TYPE_NONE; 90 if (identifier.spec_number == 245) 91 { 92 if (identifier.data[0] == 1 && // generic capabilty 93 identifier.data[1] == 0 && // video 94 identifier.data[2] == 0) // 14496-2 95 { 96 return PV_VID_TYPE_MPEG4; 97 } 98 } 99 return PV_CODEC_TYPE_NONE; 100 } 101 102 PVCodecType_t GetAudCodecTypeFrom245Index(int32 index) 103 { 104 switch (index) 105 { 106 case 8: 107 return PV_AUD_TYPE_G723; 108 default: 109 break; 110 } 111 return PV_CODEC_TYPE_NONE; 112 }; 113 114 PVCodecType_t GetAudCodecType(PS_GenericCapability audio_capability) 115 { 116 S_CapabilityIdentifierStandard capabilityIdentifierStandardInfo; 117 ParseCapabilityIdentifierStandard( 118 audio_capability->capabilityIdentifier.standard->data, 119 audio_capability->capabilityIdentifier.standard->size, 120 capabilityIdentifierStandardInfo); 121 if (capabilityIdentifierStandardInfo.itu != 0 || 122 capabilityIdentifierStandardInfo.spec_type != 0 || 123 capabilityIdentifierStandardInfo.series_letter != 8) 124 { 125 return PV_CODEC_TYPE_NONE; 126 } 127 if (capabilityIdentifierStandardInfo.spec_number != 245 || 128 capabilityIdentifierStandardInfo.data[0] != 1 || // generic capability 129 capabilityIdentifierStandardInfo.data[1] != 1 || // AUDIO capability 130 capabilityIdentifierStandardInfo.data[2] != 1) // AMR capability 131 { 132 return PV_CODEC_TYPE_NONE; 133 } 134 return PV_AUD_TYPE_GSM; 135 }; 136 137 PVCodecType_t GetAudCodecType(PS_AudioCapability audio_capability) 138 { 139 if (audio_capability->index == 20) 140 { 141 return GetAudCodecType(audio_capability->genericAudioCapability); 142 } 143 return GetAudCodecTypeFrom245Index(audio_capability->index); 144 } 145 146 PVCodecType_t GetUiCodecTypeFrom245Index(int32 index) 147 { 148 switch (index) 149 { 150 case 1: 151 return PV_UI_BASIC_STRING; 152 case 2: 153 return PV_UI_IA5_STRING; 154 case 3: 155 return PV_UI_GENERAL_STRING; 156 case 4: 157 return PV_UI_DTMF; 158 default: 159 break; 160 } 161 return PV_CODEC_TYPE_NONE; 162 } 163 164 void GetCodecInfo(PS_Capability capability, CodecCapabilityInfo& info) 165 { 166 info.codec = PV_CODEC_TYPE_NONE; 167 switch (capability->index) 168 { 169 case 1: 170 info.dir = INCOMING; 171 info.codec = GetVidCodecTypeFromVideoCapability( 172 capability->receiveVideoCapability); 173 break; 174 case 2: 175 info.dir = OUTGOING; 176 info.codec = GetVidCodecTypeFromVideoCapability( 177 capability->transmitVideoCapability); 178 break; 179 case 3: 180 info.dir = PV_DIRECTION_BOTH; 181 info.codec = GetVidCodecTypeFromVideoCapability( 182 capability->receiveAndTransmitVideoCapability); 183 break; 184 case 4: 185 info.dir = INCOMING; 186 info.codec = GetAudCodecType(capability->receiveAudioCapability); 187 break; 188 case 5: 189 info.dir = OUTGOING; 190 info.codec = GetAudCodecType(capability->transmitAudioCapability); 191 break; 192 case 6: 193 info.dir = PV_DIRECTION_BOTH; 194 info.codec = GetAudCodecType( 195 capability->receiveAndTransmitAudioCapability); 196 break; 197 case 15: 198 info.dir = INCOMING; 199 info.codec = GetUiCodecTypeFrom245Index( 200 capability->receiveUserInputCapability->index); 201 break; 202 case 16: 203 info.dir = OUTGOING; 204 info.codec = GetUiCodecTypeFrom245Index( 205 capability->transmitUserInputCapability->index); 206 break; 207 case 17: 208 info.dir = PV_DIRECTION_BOTH; 209 info.codec = GetUiCodecTypeFrom245Index( 210 capability->receiveAndTransmitUserInputCapability->index); 211 break; 212 default: 213 break; 214 } 215 } 216 217 void FillCapability(CodecCapabilityInfo& codec_info, 218 PS_Capability capability) 219 { 220 PV2WayMediaType media_type = GetMediaType(codec_info.codec); 221 switch (media_type) 222 { 223 case PV_VIDEO: 224 { 225 PS_VideoCapability video_capability = 226 (PS_VideoCapability)OSCL_DEFAULT_MALLOC(sizeof(S_VideoCapability)); 227 oscl_memset(video_capability, 0, sizeof(S_VideoCapability)); 228 229 if (codec_info.dir == INCOMING) 230 { 231 capability->index = 1; 232 capability->receiveVideoCapability = video_capability; 233 } 234 else if (codec_info.dir == OUTGOING) 235 { 236 capability->index = 2; 237 capability->transmitVideoCapability = video_capability; 238 } 239 else 240 { 241 capability->index = 3; 242 capability->receiveAndTransmitVideoCapability = 243 video_capability; 244 } 245 FillVideoCapability((VideoCodecCapabilityInfo&)codec_info, 246 video_capability); 247 } 248 break; 249 case PV_AUDIO: 250 { 251 PS_AudioCapability audio_capability = 252 (PS_AudioCapability)OSCL_DEFAULT_MALLOC(sizeof(S_AudioCapability)); 253 oscl_memset(audio_capability, 0, sizeof(S_AudioCapability)); 254 255 if (codec_info.dir == INCOMING) 256 { 257 capability->index = 4; 258 capability->receiveAudioCapability = audio_capability; 259 } 260 else if (codec_info.dir == OUTGOING) 261 { 262 capability->index = 5; 263 capability->transmitAudioCapability = audio_capability; 264 } 265 else 266 { 267 capability->index = 6; 268 capability->receiveAndTransmitAudioCapability = audio_capability; 269 } 270 FillAudioCapability(codec_info, audio_capability); 271 } 272 break; 273 case PV_USER_INPUT: 274 { 275 PS_UserInputCapability userinput_capability = 276 (PS_UserInputCapability)OSCL_DEFAULT_MALLOC(sizeof(S_UserInputCapability)); 277 oscl_memset(userinput_capability, 0, sizeof(S_UserInputCapability)); 278 if (codec_info.dir == INCOMING) 279 { 280 capability->index = 15; 281 capability->receiveUserInputCapability = userinput_capability; 282 } 283 else if (codec_info.dir == OUTGOING) 284 { 285 capability->index = 16; 286 capability->transmitUserInputCapability = userinput_capability; 287 } 288 else 289 { 290 capability->index = 15; 291 capability->receiveAndTransmitUserInputCapability = userinput_capability; 292 } 293 FillUserInputCapability(codec_info, userinput_capability); 294 } 295 break; 296 default: 297 break; 298 } 299 } 300 301 CodecCapabilityInfo* GetCodecCapabilityInfo(PS_Capability capability) 302 { 303 CodecCapabilityInfo* ret = NULL; 304 TPVDirection dir = PV_DIRECTION_BOTH; 305 switch (capability->index) 306 { 307 case 1: 308 ret = GetCodecCapabilityInfo(capability->receiveVideoCapability); 309 dir = INCOMING; 310 break; 311 case 2: 312 ret = GetCodecCapabilityInfo(capability->transmitVideoCapability); 313 dir = OUTGOING; 314 break; 315 case 3: 316 ret = GetCodecCapabilityInfo( 317 capability->receiveAndTransmitVideoCapability); 318 dir = PV_DIRECTION_BOTH; 319 break; 320 case 4: 321 ret = GetCodecCapabilityInfo(capability->receiveAudioCapability); 322 dir = INCOMING; 323 break; 324 case 5: 325 ret = GetCodecCapabilityInfo(capability->transmitAudioCapability); 326 dir = OUTGOING; 327 break; 328 case 6: 329 ret = GetCodecCapabilityInfo( 330 capability->receiveAndTransmitAudioCapability); 331 dir = PV_DIRECTION_BOTH; 332 break; 333 case 15: 334 ret = GetCodecCapabilityInfo(capability->receiveUserInputCapability); 335 dir = INCOMING; 336 break; 337 case 16: 338 ret = GetCodecCapabilityInfo( 339 capability->transmitUserInputCapability); 340 dir = OUTGOING; 341 break; 342 case 17: 343 ret = GetCodecCapabilityInfo( 344 capability->receiveAndTransmitUserInputCapability); 345 dir = PV_DIRECTION_BOTH; 346 break; 347 default: 348 break; 349 } 350 if (ret) 351 { 352 ret->dir = dir; 353 } 354 return ret; 355 } 356 357 358 void FillVideoCapability(VideoCodecCapabilityInfo& video_codec_info, 359 PS_VideoCapability video_capability) 360 { 361 switch (video_codec_info.codec) 362 { 363 case PV_VID_TYPE_H263: 364 video_capability->index = 3; 365 video_capability->h263VideoCapability = 366 (PS_H263VideoCapability)OSCL_DEFAULT_MALLOC( 367 sizeof(S_H263VideoCapability)); 368 oscl_memset(video_capability->h263VideoCapability, 369 0, sizeof(S_H263VideoCapability)); 370 FillH263Capability(video_codec_info, 371 video_capability->h263VideoCapability); 372 break; 373 case PV_VID_TYPE_MPEG4: 374 video_capability->index = 5; 375 video_capability->genericVideoCapability = 376 (PS_GenericCapability)OSCL_DEFAULT_MALLOC( 377 sizeof(S_GenericCapability)); 378 oscl_memset(video_capability->genericVideoCapability, 379 0, sizeof(S_GenericCapability)); 380 FillM4vCapability(video_codec_info, 381 video_capability->genericVideoCapability); 382 break; 383 default: 384 break; 385 } 386 } 387 388 CodecCapabilityInfo* GetCodecCapabilityInfo(PS_VideoCapability capability) 389 { 390 switch (capability->index) 391 { 392 case 3: 393 return GetCodecCapabilityInfo(capability->h263VideoCapability); 394 case 5: 395 return GetCodecCapabilityInfo(capability->genericVideoCapability); 396 default: 397 break; 398 } 399 return NULL; 400 } 401 402 CodecCapabilityInfo* GetCodecCapabilityInfo(PS_GenericCapability capability) 403 { 404 if (capability->capabilityIdentifier.index != 0) 405 return NULL; 406 S_CapabilityIdentifierStandard capabilityIdentifierStandardInfo; 407 ParseCapabilityIdentifierStandard( 408 capability->capabilityIdentifier.standard->data, 409 capability->capabilityIdentifier.standard->size, 410 capabilityIdentifierStandardInfo); 411 PVCodecType_t codec_type 412 = GetVidCodecTypeFromCapabilityIdentifier(capabilityIdentifierStandardInfo); 413 switch (codec_type) 414 { 415 case PV_VID_TYPE_MPEG4: 416 return GetCodecCapabilityInfoMpeg4(capability); 417 default: 418 break; 419 } 420 return NULL; 421 } 422 423 void FillM4vCapability(VideoCodecCapabilityInfo& video_codec_info, 424 PS_GenericCapability m4vcaps) 425 { 426 OSCL_UNUSED_ARG(video_codec_info); 427 // x15 is a set of 1 GenericParameter(s) 428 unsigned num_generic_parameters = 1; 429 PS_GenericParameter x15 = (PS_GenericParameter)OSCL_DEFAULT_MALLOC(num_generic_parameters * 430 sizeof(S_GenericParameter)); 431 oscl_memset(x15, 0, num_generic_parameters * sizeof(S_GenericParameter)); 432 433 // x13 is a GenericCapability (SEQUENCE) 434 PS_CapabilityIdentifier x14 = &m4vcaps->capabilityIdentifier; 435 m4vcaps->option_of_maxBitRate = ON; 436 m4vcaps->maxBitRate = 521; 437 m4vcaps->option_of_collapsing = OFF; 438 m4vcaps->option_of_nonCollapsing = ON; 439 m4vcaps->size_of_nonCollapsing = 1; 440 m4vcaps->nonCollapsing = x15; 441 m4vcaps->option_of_nonCollapsingRaw = OFF; 442 m4vcaps->option_of_transport = OFF; 443 444 // x14 is a CapabilityIdentifier (CHOICE) 445 x14->index = 0; 446 447 PS_OBJECTIDENT objident = (PS_OBJECTIDENT)OSCL_DEFAULT_MALLOC(sizeof(S_OBJECTIDENT)); 448 oscl_memset(objident, 0, sizeof(S_OBJECTIDENT)); 449 x14->standard = objident; 450 x14->standard->size = 7; 451 x14->standard->data = (uint8*)OSCL_DEFAULT_MALLOC(x14->standard->size); 452 x14->standard->data[0] = 0x00; 453 x14->standard->data[1] = 0x08; 454 x14->standard->data[2] = 0x81; 455 x14->standard->data[3] = 0x75; 456 x14->standard->data[4] = 0x01; 457 x14->standard->data[5] = 0x00; 458 x14->standard->data[6] = 0x00; 459 460 // x15[0] is a GenericParameter (SEQUENCE) 461 PS_ParameterIdentifier x16 = &x15[0].parameterIdentifier; 462 PS_ParameterValue x17 = &x15[0].parameterValue; 463 x15[0].option_of_supersedes = OFF; 464 465 // x16 is a ParameterIdentifier (CHOICE) 466 x16->index = 0; 467 x16->standard = 0; 468 469 // x17 is a ParameterValue (CHOICE) 470 x17->index = 3; 471 x17->unsignedMax = 8; // Value changed from 3 to 8. (RAN - PandL) 472 } 473 474 CodecCapabilityInfo* GetCodecCapabilityInfoMpeg4(PS_GenericCapability mpeg4caps) 475 { 476 VideoCodecCapabilityInfo* cci = new VideoCodecCapabilityInfo(); 477 cci->codec = PV_VID_TYPE_MPEG4; 478 cci->max_bitrate = mpeg4caps->maxBitRate; 479 return cci; 480 } 481 482 void FillH263Capability(VideoCodecCapabilityInfo& video_codec_info, 483 PS_H263VideoCapability h263caps) 484 { 485 if (IsResolutionSupported(PVMF_RESOLUTION_SQCIF, 486 video_codec_info.resolutions)) 487 { 488 h263caps->option_of_sqcifMPI = ON; 489 h263caps->sqcifMPI = 2; 490 } 491 if (IsResolutionSupported(PVMF_RESOLUTION_QCIF, 492 video_codec_info.resolutions)) 493 { 494 h263caps->option_of_qcifMPI = ON; 495 h263caps->qcifMPI = 2; 496 } 497 if (IsResolutionSupported(PVMF_RESOLUTION_CIF, 498 video_codec_info.resolutions)) 499 { 500 h263caps->option_of_cifMPI = ON; 501 h263caps->cifMPI = 2; 502 } 503 if (IsResolutionSupported(PVMF_RESOLUTION_4CIF, 504 video_codec_info.resolutions)) 505 { 506 h263caps->option_of_cif4MPI = ON; 507 h263caps->cif4MPI = 2; 508 } 509 if (IsResolutionSupported(PVMF_RESOLUTION_16CIF, 510 video_codec_info.resolutions)) 511 { 512 h263caps->option_of_cif16MPI = ON; 513 h263caps->cif16MPI = 2; 514 } 515 h263caps->maxBitRate = 521; 516 h263caps->unrestrictedVector = OFF; 517 h263caps->arithmeticCoding = OFF; 518 h263caps->advancedPrediction = OFF; 519 h263caps->pbFrames = OFF; 520 h263caps->temporalSpatialTradeOffCapability = ON; 521 h263caps->option_of_hrd_B = OFF; 522 h263caps->option_of_bppMaxKb = OFF; 523 h263caps->option_of_slowSqcifMPI = OFF; 524 h263caps->option_of_slowQcifMPI = OFF; 525 h263caps->option_of_slowCifMPI = OFF; 526 h263caps->option_of_slowCif4MPI = OFF; 527 h263caps->option_of_slowCif16MPI = OFF; 528 h263caps->option_of_errorCompensation = ON; 529 h263caps->errorCompensation = OFF; 530 h263caps->option_of_enhancementLayerInfo = OFF; 531 h263caps->option_of_h263Options = OFF; 532 } 533 534 CodecCapabilityInfo* GetCodecCapabilityInfo(PS_H263VideoCapability h263caps) 535 { 536 VideoCodecCapabilityInfo* cci = new VideoCodecCapabilityInfo(); 537 cci->codec = PV_VID_TYPE_H263; 538 cci->max_bitrate = h263caps->maxBitRate; 539 540 if (h263caps->option_of_sqcifMPI == ON && h263caps->sqcifMPI) 541 { 542 PVMFVideoResolutionRange range_sqcif(PVMF_RESOLUTION_SQCIF, 543 PVMF_RESOLUTION_SQCIF); 544 cci->resolutions.push_back(range_sqcif); 545 } 546 if (h263caps->option_of_qcifMPI == ON && h263caps->qcifMPI) 547 { 548 PVMFVideoResolutionRange range_qcif(PVMF_RESOLUTION_QCIF, 549 PVMF_RESOLUTION_QCIF); 550 cci->resolutions.push_back(range_qcif); 551 } 552 if (h263caps->option_of_cifMPI == ON && h263caps->cifMPI) 553 { 554 PVMFVideoResolutionRange range_cif(PVMF_RESOLUTION_CIF, 555 PVMF_RESOLUTION_CIF); 556 cci->resolutions.push_back(range_cif); 557 } 558 if (h263caps->option_of_cif4MPI == ON && h263caps->cif4MPI) 559 { 560 PVMFVideoResolutionRange range_4cif(PVMF_RESOLUTION_4CIF, 561 PVMF_RESOLUTION_4CIF); 562 cci->resolutions.push_back(range_4cif); 563 } 564 if (h263caps->option_of_cif16MPI == ON && h263caps->cif16MPI) 565 { 566 PVMFVideoResolutionRange range_16cif(PVMF_RESOLUTION_16CIF, 567 PVMF_RESOLUTION_16CIF); 568 cci->resolutions.push_back(range_16cif); 569 } 570 return cci; 571 } 572 573 void FillAudioCapability(CodecCapabilityInfo& codec_info, 574 PS_AudioCapability audio_capability) 575 { 576 switch (codec_info.codec) 577 { 578 case PV_AUD_TYPE_GSM: 579 audio_capability->index = 20; 580 audio_capability->genericAudioCapability = 581 (PS_GenericCapability)OSCL_DEFAULT_MALLOC( 582 sizeof(S_GenericCapability)); 583 FillAmrCapability(audio_capability->genericAudioCapability); 584 break; 585 case PV_AUD_TYPE_G723: 586 audio_capability->index = 8; 587 audio_capability->g7231 = (PS_G7231)OSCL_DEFAULT_MALLOC( 588 sizeof(S_G7231)); 589 FillG723Capability(audio_capability->g7231); 590 break; 591 default: 592 break; 593 } 594 } 595 596 CodecCapabilityInfo* GetCodecCapabilityInfo(PS_AudioCapability audio_capability) 597 { 598 switch (audio_capability->index) 599 { 600 case 8: 601 return GetCodecCapabilityInfo(audio_capability->g7231); 602 case 20: 603 return GetCodecCapabilityInfoAmr( 604 audio_capability->genericAudioCapability); 605 default: 606 break; 607 } 608 return NULL; 609 } 610 611 void FillG723Capability(PS_G7231 g723caps) 612 { 613 g723caps->maxAl_sduAudioFrames = 1; 614 g723caps->silenceSuppression = OFF; 615 } 616 617 CodecCapabilityInfo* GetCodecCapabilityInfo(PS_G7231 g723caps) 618 { 619 OSCL_UNUSED_ARG(g723caps); 620 CodecCapabilityInfo* cci = new CodecCapabilityInfo(); 621 cci->codec = PV_AUD_TYPE_G723; 622 cci->max_bitrate = 6300; 623 return cci; 624 } 625 626 void FillAmrCapability(PS_GenericCapability amrCaps) 627 { 628 unsigned sizeof_generic_params = 1; 629 PS_GenericParameter x25 = 630 (PS_GenericParameter)OSCL_DEFAULT_MALLOC(sizeof_generic_params * 631 sizeof(S_GenericParameter)); 632 oscl_memset(x25, 0, sizeof_generic_params * sizeof(S_GenericParameter)); 633 634 // x23 is a GenericCapability (SEQUENCE) 635 PS_CapabilityIdentifier x24 = &amrCaps->capabilityIdentifier; 636 amrCaps->option_of_maxBitRate = ON; 637 amrCaps->maxBitRate = 122; 638 amrCaps->option_of_collapsing = ON; 639 amrCaps->size_of_collapsing = 1; 640 amrCaps->collapsing = x25; 641 amrCaps->option_of_nonCollapsing = OFF; 642 amrCaps->option_of_nonCollapsingRaw = OFF; 643 amrCaps->option_of_transport = OFF; 644 645 // x24 is a CapabilityIdentifier (CHOICE) 646 x24->index = 0; 647 // ----------- Define protocolID -------------- 648 PS_OBJECTIDENT objident2 = (PS_OBJECTIDENT)OSCL_DEFAULT_MALLOC(sizeof(S_OBJECTIDENT)); 649 oscl_memset(objident2, 0, sizeof(S_OBJECTIDENT)); 650 651 x24->standard = objident2; 652 x24->standard->size = 7; 653 x24->standard->data = (uint8*)OSCL_DEFAULT_MALLOC(x24->standard->size); 654 x24->standard->data[0] = 0x00; 655 x24->standard->data[1] = 0x08; 656 x24->standard->data[2] = 0x81; 657 x24->standard->data[3] = 0x75; 658 x24->standard->data[4] = 0x01; 659 x24->standard->data[5] = 0x01; 660 x24->standard->data[6] = 0x01; 661 // ----------- End protocolID ----------------- 662 663 // x25 is a set of 1 GenericParameter(s) 664 665 // x25[0] is a GenericParameter (SEQUENCE) 666 PS_ParameterIdentifier x26 = &x25[0].parameterIdentifier; 667 PS_ParameterValue x27 = &x25[0].parameterValue; 668 x25[0].option_of_supersedes = OFF; 669 670 // x26 is a ParameterIdentifier (CHOICE) 671 x26->index = 0; 672 x26->standard = 0; 673 674 /* x27 is a ParameterValue (CHOICE) */ 675 x27->index = 2; 676 x27->unsignedMin = 1; 677 } 678 679 CodecCapabilityInfo* GetCodecCapabilityInfoAmr(PS_GenericCapability amrCaps) 680 { 681 CodecCapabilityInfo* cci = new CodecCapabilityInfo(); 682 cci->codec = PV_AUD_TYPE_GSM; 683 cci->max_bitrate = amrCaps->maxBitRate; 684 return cci; 685 } 686 687 void FillUserInputCapability(CodecCapabilityInfo& codec_info, 688 PS_UserInputCapability userinputCaps) 689 { 690 switch (codec_info.codec) 691 { 692 case PV_UI_BASIC_STRING: 693 userinputCaps->index = 1; 694 break; 695 case PV_UI_IA5_STRING: 696 userinputCaps->index = 2; 697 break; 698 case PV_UI_GENERAL_STRING: 699 userinputCaps->index = 3; 700 break; 701 case PV_UI_DTMF: 702 userinputCaps->index = 4; 703 break; 704 default: 705 break; 706 } 707 } 708 709 CodecCapabilityInfo* GetCodecCapabilityInfo(PS_UserInputCapability uiCaps) 710 { 711 CodecCapabilityInfo* cci = new CodecCapabilityInfo(); 712 switch (uiCaps->index) 713 { 714 case 1: 715 cci->codec = PV_UI_BASIC_STRING; 716 break; 717 case 2: 718 cci->codec = PV_UI_IA5_STRING; 719 break; 720 case 3: 721 cci->codec = PV_UI_GENERAL_STRING; 722 break; 723 case 4: 724 cci->codec = PV_UI_DTMF; 725 break; 726 } 727 cci->max_bitrate = 0; 728 return cci; 729 } 730 731 void ParseCapabilityIdentifierStandard(uint8* octet_string, 732 uint16 octet_string_len, 733 S_CapabilityIdentifierStandard& capabilityIdentifier) 734 { 735 oscl_memset(&capabilityIdentifier, 0, 736 sizeof(S_CapabilityIdentifierStandard)); 737 if (octet_string_len < 6) 738 return; 739 capabilityIdentifier.spec_type = (uint8)(octet_string[0] % 10); 740 capabilityIdentifier.itu = (uint8)((octet_string[0] - 741 capabilityIdentifier.spec_type) / 40); 742 capabilityIdentifier.series_letter = octet_string[1]; 743 capabilityIdentifier.spec_number = 0; 744 unsigned pos = 2; 745 do 746 { 747 capabilityIdentifier.spec_number = 748 capabilityIdentifier.spec_number << 7 | (octet_string[pos] & 0x7F); 749 } 750 while ((octet_string[pos++]&0x80) && (pos < octet_string_len)); 751 unsigned tmp_pos = 0; 752 while (pos < octet_string_len) 753 { 754 capabilityIdentifier.data[tmp_pos++] = octet_string[pos++]; 755 } 756 } 757 758 bool PVCheckSH(uint8 *ptr, int32 size) 759 { 760 int count = 0; 761 int32 i = size - 4; 762 763 if (size < 0) 764 { 765 return false; 766 } 767 while (i--) 768 { 769 if ((count > 1) && (ptr[0] == 0x01) && (ptr[1] & 0xF0) == 0x20) 770 { 771 return false; 772 } 773 774 if (*ptr++) 775 count = 0; 776 else 777 count++; 778 } 779 return true; // SH switch to h263 780 } 781 782 PVCodecType_t GetCodecType(PS_DataType pDataType) 783 { 784 PVCodecType_t codecIndex = PV_INVALID_CODEC_TYPE; 785 if (!pDataType) 786 return PV_CODEC_TYPE_NONE; 787 788 if (pDataType->index == 1) 789 { // null data 790 codecIndex = PV_CODEC_TYPE_NONE; // No codec 791 } 792 else if (pDataType->index == 2) 793 { // videoData 794 if (pDataType->videoData->index == 3) 795 { // H263VideoCapability 796 codecIndex = PV_VID_TYPE_H263; 797 } 798 else if (pDataType->videoData->index == 5) 799 { // GenericVideoCapability 800 codecIndex = GetVidCodecTypeFromVideoCapability(pDataType->videoData); 801 } 802 } 803 else if (pDataType->index == 3) 804 { // audioData 805 if (pDataType->audioData->index == 8) 806 { // G.723 807 codecIndex = PV_AUD_TYPE_G723; 808 } 809 else if (pDataType->audioData->index == 20) 810 { // GenericAudioCapability 811 S_CapabilityIdentifierStandard capabilityIdentifierStandardInfo; 812 ParseCapabilityIdentifierStandard( 813 pDataType->audioData->genericAudioCapability->capabilityIdentifier.standard->data, 814 pDataType->audioData->genericAudioCapability->capabilityIdentifier.standard->size, 815 capabilityIdentifierStandardInfo); 816 if (capabilityIdentifierStandardInfo.itu != 0 || 817 capabilityIdentifierStandardInfo.spec_type != 0 || 818 capabilityIdentifierStandardInfo.series_letter != 8) 819 { 820 return PV_CODEC_TYPE_NONE; 821 } 822 if (capabilityIdentifierStandardInfo.spec_number != 245 || 823 capabilityIdentifierStandardInfo.data[0] != 1 || // generic capability 824 capabilityIdentifierStandardInfo.data[1] != 1 || // AUDIO capability 825 capabilityIdentifierStandardInfo.data[2] != 1) // AMR capability 826 { 827 return PV_CODEC_TYPE_NONE; 828 } 829 codecIndex = PV_AUD_TYPE_GSM; 830 } 831 } 832 return codecIndex; 833 } 834 835 PV2WayMediaType GetMediaType(PS_DataType pDataType) 836 { 837 PV2WayMediaType mediaType = PV_MEDIA_NONE; 838 if (!pDataType) 839 return mediaType; 840 841 if (pDataType->index == 2) 842 { // videoData 843 mediaType = PV_VIDEO; 844 } 845 else if (pDataType->index == 3) 846 { // audioData 847 mediaType = PV_AUDIO; 848 } 849 return mediaType; 850 } 851 852 // ======================================================= 853 // GetSimpleAudioType() (RAN-32K) 854 // 855 // This routine takes the value from p324->GetAudioType() 856 // (an H324AudType_t enum) and maps it onto a 857 // simpler, reduced codec type space (an H324AudTypeSimple_t 858 // enum). This is a convenience for the H.245 routines 859 // which don't need to know the audio rate. 860 // ======================================================= 861 PVAudTypeSimple_t GetSimpleAudioType(PVAudType_t audio) 862 { 863 if ((audio >= PV_AUD_TYPE_GSM_475) && 864 (audio <= PV_AUD_TYPE_GSM_122)) 865 { 866 return PV_AUD_TYPE_GSM; 867 } 868 else if (audio == PV_AUD_TYPE_G723_53 || 869 audio == PV_AUD_TYPE_G723_63) 870 { 871 return PV_AUD_TYPE_G723; 872 } 873 else 874 return PV_SIMPLE_AUD_TYPE_NONE; 875 } 876 877 ErrorProtectionLevel_t GetEpl(uint16 al_index) 878 { 879 switch (al_index) 880 { 881 case 1: 882 case 2: 883 return E_EP_LOW; 884 case 3: 885 case 4: 886 return E_EP_MEDIUM; 887 case 5: 888 return E_EP_HIGH; 889 default: 890 return E_EP_LOW; 891 } 892 } 893 894 void printBuffer(PVLogger* logger, 895 const uint8* buffer, 896 uint16 len) 897 { 898 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_STACK_TRACE, 899 (0, "printBuffer(%d)", len)); 900 901 const uint16 roundto = 10; 902 int32 cpylen = len + roundto - (len + roundto) % roundto; 903 uint8* cpy = (uint8*)OSCL_DEFAULT_MALLOC(cpylen); 904 uint8* cpysave = cpy; 905 oscl_memset(cpy, 0, cpylen); 906 oscl_memcpy(cpy, buffer, len); 907 int loops = cpylen / roundto; 908 for (uint16 num = 0; num < loops; ++num) 909 { 910 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_STACK_TRACE, 911 (0, 912 "bytes(%d) %x %x %x %x %x %x %x %x %x %x", 913 num, cpy[0], cpy[1], cpy[2], cpy[3], cpy[4], cpy[5], 914 cpy[6], cpy[7], cpy[8], cpy[9])); 915 cpy += roundto; 916 } 917 OSCL_DEFAULT_FREE(cpysave); 918 } 919 920 unsigned GetFormatSpecificInfo(PS_DataType dataType, 921 uint8*& fsi) 922 { 923 uint32 size = 0; 924 PS_GenericParameter parameter_list = NULL, parameter = NULL; 925 PS_OCTETSTRING config = NULL; 926 unsigned ret = 0; 927 fsi = NULL; 928 929 if (!dataType || 930 (dataType->index != 2) || // videoData 931 (dataType->videoData->index != 5)) // genericVideoCapability 932 return ret; 933 934 if (dataType->videoData->genericVideoCapability->option_of_nonCollapsing) 935 { 936 size = 937 dataType->videoData->genericVideoCapability->size_of_nonCollapsing; 938 parameter_list = 939 dataType->videoData->genericVideoCapability->nonCollapsing; 940 } 941 else if (dataType->videoData->genericVideoCapability->option_of_collapsing) 942 { 943 size = 944 dataType->videoData->genericVideoCapability->size_of_collapsing; 945 parameter_list = 946 dataType->videoData->genericVideoCapability->collapsing; 947 } 948 if (size == 0 || parameter_list == NULL) 949 return ret; 950 951 for (uint32 ii = 0; ii < size; ++ii) 952 { 953 parameter = parameter_list + ii; 954 if ((parameter->parameterIdentifier.index == 0) && // standard 955 (parameter->parameterValue.index == 6)) // OctetString 956 { 957 config = parameter->parameterValue.octetString; 958 } 959 } 960 961 bool is_filler_fsi = IsFillerFsi(config->data, config->size); 962 if (config != NULL && !is_filler_fsi) 963 { // Found valid decoderConfig 964 ret = config->size; 965 fsi = config->data; 966 } 967 return ret; 968 } 969 970 PS_Capability LookupCapability(PS_TerminalCapabilitySet pTcs, 971 uint16 cap_entry_num) 972 { 973 if (!(pTcs->option_of_capabilityTable && 974 pTcs->option_of_capabilityDescriptors)) 975 { 976 return NULL; 977 } 978 for (unsigned cap_entry = 0; 979 cap_entry < pTcs->size_of_capabilityTable; 980 ++cap_entry) 981 { 982 PS_CapabilityTableEntry pCapEntry = pTcs->capabilityTable + cap_entry; 983 if (pCapEntry->option_of_capability && 984 pCapEntry->capabilityTableEntryNumber == cap_entry_num) 985 { 986 return &pCapEntry->capability; 987 } 988 } 989 return NULL; 990 } 991 992 bool IsTransmitOnlyAltCapSet(PS_TerminalCapabilitySet pTcs, 993 PS_AlternativeCapabilitySet pAltCapSet) 994 { 995 for (uint32 ii = 0; ii < pAltCapSet->size; ++ii) 996 { 997 uint32 entry = pAltCapSet->item[ii]; 998 PS_Capability pCapability = LookupCapability(pTcs, 999 OSCL_STATIC_CAST(uint16, entry)); 1000 if (pCapability != NULL && 1001 pCapability->index != 2 && 1002 pCapability->index != 5) 1003 { 1004 return false; 1005 } 1006 } 1007 return true; 1008 } 1009 1010 // ======================================================= 1011 // VerifyCodecs() (RAN-32K) 1012 // 1013 // This routine checks an outgoing audio/video combination 1014 // against the capabilities of the remote terminal. 1015 // Note: 1016 // audio, video are 'Simple' tags for outgoing codecs. 1017 // pTcs = Pointer to received TerminalCapabilitySet 1018 // The routine returns nonzero if the codec combo is OK. 1019 // ======================================================= 1020 PVMFStatus VerifyCodecs(PS_TerminalCapabilitySet pTcs, 1021 Oscl_Vector<OlcFormatInfo, OsclMemAllocator> codecs, 1022 PVLogger *logger) 1023 { 1024 PS_CapabilityTableEntry pCapEntry = NULL; 1025 PS_CapabilityDescriptor pCapDesc = NULL; 1026 PS_AlternativeCapabilitySet pAltCapSet = NULL; 1027 unsigned num_codecs = codecs.size(); 1028 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_STACK_TRACE, 1029 (0, "VerifyCodecs(%d)", num_codecs)); 1030 1031 if (!(pTcs->option_of_capabilityTable && 1032 pTcs->option_of_capabilityDescriptors)) 1033 { 1034 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_WARNING, 1035 (0, 1036 "VerifyCodecs - No capabilities option_of_capabilityTable=%d,option_of_capabilityDescriptors=%d", 1037 pTcs->option_of_capabilityTable, 1038 pTcs->option_of_capabilityDescriptors)); 1039 return PVMFErrNotSupported; 1040 } 1041 1042 Oscl_Map<PVCodecType_t, uint32, OsclMemAllocator> codec_capentry_map; 1043 1044 // verify if all the codecs are supported individually 1045 for (unsigned codec_num = 0; codec_num < codecs.size(); ++codec_num) 1046 { 1047 bool codec_verified = false; 1048 OlcFormatInfo& codec_info = codecs[codec_num]; 1049 bool is_symmetric = codec_info.isSymmetric; 1050 if (codec_info.iCodec == PV_CODEC_TYPE_NONE) 1051 { 1052 num_codecs--; 1053 continue; 1054 } 1055 for (unsigned cap_entry = 0; 1056 cap_entry < pTcs->size_of_capabilityTable; 1057 ++cap_entry) 1058 { 1059 pCapEntry = pTcs->capabilityTable + cap_entry; 1060 if (pCapEntry->option_of_capability) 1061 { 1062 CodecCapabilityInfo cap_info; 1063 GetCodecInfo(&pCapEntry->capability, cap_info); 1064 if (((cap_info.dir == INCOMING) || 1065 (cap_info.dir == PV_DIRECTION_BOTH && is_symmetric)) && 1066 (codec_info.iCodec == cap_info.codec)) 1067 { 1068 codec_verified = true; 1069 codec_capentry_map.insert( 1070 Oscl_Map<PVCodecType_t, uint32, OsclMemAllocator>::value_type( 1071 codec_info.iCodec, pCapEntry->capabilityTableEntryNumber)); 1072 break; 1073 } 1074 } 1075 } 1076 if (!codec_verified) 1077 { 1078 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_WARNING, 1079 (0, "VerifyCodecs Codec not present in cap table(%d)", 1080 codec_info.iCodec)); 1081 return PVMFErrNotSupported; 1082 } 1083 } 1084 1085 if (num_codecs == 1) 1086 { 1087 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_STACK_TRACE, 1088 (0, "VerifyCodecs - single codec ok. No combo check reqd")); 1089 return PVMFSuccess; 1090 } 1091 1092 for (uint32 ii = 0; ii < pTcs->size_of_capabilityDescriptors; ++ii) 1093 { 1094 pCapDesc = pTcs->capabilityDescriptors + ii; 1095 OSCL_ASSERT(pCapDesc->size_of_simultaneousCapabilities <= 1096 MAX_NUM_SIMULTANEOUS_CAPABILITIES); 1097 // For each codec, create a bitwise OR of all 1098 // the simultaneous cap entries that include it 1099 Oscl_Map<PVCodecType_t, uint32, OsclMemAllocator> sim_caps_for_codec; 1100 uint32 numValidAltCapSets = 0; 1101 for (uint32 jj = 0; jj < pCapDesc->size_of_simultaneousCapabilities; ++jj) 1102 { 1103 // Does codec exist in this altCapSet? 1104 pAltCapSet = pCapDesc->simultaneousCapabilities + jj; 1105 1106 if (IsTransmitOnlyAltCapSet(pTcs, pAltCapSet)) continue; 1107 1108 for (unsigned codec_num = 0; codec_num < codecs.size(); codec_num++) 1109 { 1110 OlcFormatInfo& codec_info = codecs[codec_num]; 1111 if (codec_info.iCodec != PV_CODEC_TYPE_NONE && 1112 CheckAltCapSet(pAltCapSet, 1113 codec_capentry_map[codec_info.iCodec])) 1114 { 1115 uint32 mask = 1 << numValidAltCapSets; 1116 uint32 val = 0; 1117 Oscl_Map<PVCodecType_t, uint32, OsclMemAllocator>::iterator iter = 1118 sim_caps_for_codec.find(codec_info.iCodec); 1119 if (iter != sim_caps_for_codec.end()) 1120 val = (*iter).second; 1121 val |= mask; 1122 sim_caps_for_codec[codec_info.iCodec] = val; 1123 } 1124 } 1125 numValidAltCapSets++; 1126 } 1127 int32 sum = 0; 1128 Oscl_Map<PVCodecType_t, uint32, OsclMemAllocator>::iterator iter = 1129 sim_caps_for_codec.begin(); 1130 if (sim_caps_for_codec.size() < num_codecs) 1131 continue; 1132 uint16 num_unsupported_codecs = 0; 1133 while (iter != sim_caps_for_codec.end()) 1134 { 1135 if ((*iter).second == 0) 1136 num_unsupported_codecs++; 1137 sum |= (*iter++).second; 1138 } 1139 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_STACK_TRACE, 1140 (0, 1141 "VerifyCodecs TSC verified vs codecs sum(%d) num_codecs(%d),num_unsupported_codecs(%d)", 1142 sum, num_codecs, num_unsupported_codecs)); 1143 if (num_unsupported_codecs == 0 && (g_num_ones[sum] >= num_codecs)) 1144 { 1145 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_STACK_TRACE, 1146 (0, "VerifyCodecs TSC verified vs codecs successfully")); 1147 // Found match 1148 return PVMFSuccess; 1149 } 1150 } 1151 1152 // COMBINATION failed 1153 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_WARNING, 1154 (0, "VerifyCodecs Failed to find a single matching descriptor")); 1155 1156 return PVMFErrNotSupported; 1157 } 1158 1159 PVMFStatus GetCodecCapInfo(PVCodecType_t codec, 1160 PS_TerminalCapabilitySet pTcs, 1161 CodecCapabilityInfo& codec_info, 1162 PVLogger *logger) 1163 { 1164 OSCL_UNUSED_ARG(codec); 1165 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_STACK_TRACE, 1166 (0, "GetCodecCapInfo(%d)", codec)); 1167 PS_CapabilityTableEntry pCapEntry = NULL; 1168 1169 if (!(pTcs->option_of_capabilityTable && pTcs->option_of_capabilityDescriptors)) 1170 { 1171 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_WARNING, 1172 (0, "GetCodecCapInfo - Terminal is incapable of anything")); 1173 return PVMFErrNotSupported; 1174 } 1175 1176 for (unsigned cap_entry = 0; cap_entry < pTcs->size_of_capabilityTable; ++cap_entry) 1177 { 1178 pCapEntry = pTcs->capabilityTable + cap_entry; 1179 if (pCapEntry->option_of_capability) 1180 { 1181 CodecCapabilityInfo cap_info; 1182 GetCodecInfo(&pCapEntry->capability, cap_info); 1183 if (cap_info.codec == codec) 1184 { 1185 codec_info = cap_info; 1186 return PVMFSuccess; 1187 } 1188 } 1189 } 1190 1191 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, logger, PVLOGMSG_WARNING, 1192 (0, "GetCodecInfo - codec not suppported")); 1193 return PVMFErrNotSupported; 1194 } 1195 1196 uint32 CheckAltCapSet(PS_AlternativeCapabilitySet pAltCapSet, uint32 entry) 1197 { 1198 for (uint ii = 0; ii < pAltCapSet->size; ++ii) 1199 { 1200 if (pAltCapSet->item[ii] == entry) 1201 return true; 1202 } 1203 1204 return false; 1205 } 1206 1207 1208 PS_TerminalCapabilitySet GenerateTcs(MultiplexCapabilityInfo& mux_cap_info, 1209 Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator>& outgoing_codecs, 1210 Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator>& incoming_codecs) 1211 { 1212 // === Auto Codeword Generation === 1213 PS_TerminalCapabilitySet ret = 1214 (PS_TerminalCapabilitySet)OSCL_DEFAULT_MALLOC(sizeof(S_TerminalCapabilitySet)); 1215 oscl_memset(ret, 0, sizeof(S_TerminalCapabilitySet)); 1216 1217 PS_MultiplexCapability x3 = NULL; 1218 PS_H223Capability x4 = 1219 (PS_H223Capability)OSCL_DEFAULT_MALLOC(sizeof(S_H223Capability)); 1220 oscl_memset(x4, 0, sizeof(S_H223Capability)); 1221 1222 PS_H223MultiplexTableCapability x5 = NULL; 1223 PS_MobileOperationTransmitCapability x6 = NULL; 1224 1225 unsigned sizeof_cap_table = outgoing_codecs.size() + incoming_codecs.size(); 1226 PS_CapabilityTableEntry x7 = 1227 (PS_CapabilityTableEntry)OSCL_DEFAULT_MALLOC(sizeof(S_CapabilityTableEntry) * 1228 sizeof_cap_table); 1229 oscl_memset(x7, 0, sizeof(S_CapabilityTableEntry) * sizeof_cap_table); 1230 1231 unsigned sizeof_cap_descriptors = 1; 1232 PS_CapabilityDescriptor x28 = 1233 (PS_CapabilityDescriptor)OSCL_DEFAULT_MALLOC(sizeof(S_CapabilityDescriptor) * 1234 sizeof_cap_descriptors); 1235 oscl_memset(x28, 0, sizeof(S_CapabilityDescriptor) * sizeof_cap_descriptors); 1236 1237 // ================== // 1238 // Build the Codeword // 1239 // ================== // 1240 1241 // (Top two levels deleted -- RAN) // 1242 1243 // ret is a TerminalCapabilitySet (SEQUENCE) // 1244 ret->sequenceNumber = 0; 1245 // ----------- Define protocolID -------------- // 1246 ret->protocolIdentifier.size = 6; 1247 uint8* x2ProtocolIdentifierData = (uint8*)OSCL_DEFAULT_MALLOC(ret->protocolIdentifier.size); 1248 x2ProtocolIdentifierData[0] = 0x00; 1249 x2ProtocolIdentifierData[1] = 0x08; 1250 x2ProtocolIdentifierData[2] = 0x81; 1251 x2ProtocolIdentifierData[3] = 0x75; 1252 x2ProtocolIdentifierData[4] = 0x00; 1253 x2ProtocolIdentifierData[5] = 0x06; 1254 ret->protocolIdentifier.data = x2ProtocolIdentifierData; 1255 1256 ret->option_of_multiplexCapability = ON; 1257 ret->option_of_capabilityTable = ON; 1258 ret->size_of_capabilityTable = (uint16)sizeof_cap_table; 1259 ret->capabilityTable = x7; 1260 ret->option_of_capabilityDescriptors = ON; 1261 ret->size_of_capabilityDescriptors = (uint16)sizeof_cap_descriptors; 1262 ret->capabilityDescriptors = x28; 1263 1264 // x3 is a MultiplexCapability (CHOICE) // 1265 x3 = &ret->multiplexCapability; 1266 x3->index = 2; 1267 x3->h223Capability = x4; 1268 1269 // x4 is an H223Capability (SEQUENCE) // 1270 x4->transportWithI_frames = OFF; // transmitting contro msgs within LAPM I-frames // 1271 x4->videoWithAL1 = (mux_cap_info.iAllowAl1Video ? ON : OFF); 1272 x4->videoWithAL2 = (mux_cap_info.iAllowAl2Video ? ON : OFF); 1273 x4->videoWithAL3 = (mux_cap_info.iAllowAl3Video ? ON : OFF); 1274 x4->audioWithAL1 = (mux_cap_info.iAllowAl1Audio ? ON : OFF); 1275 x4->audioWithAL2 = (mux_cap_info.iAllowAl2Audio ? ON : OFF); 1276 x4->audioWithAL3 = (mux_cap_info.iAllowAl3Audio ? ON : OFF); 1277 x4->dataWithAL1 = OFF; 1278 x4->dataWithAL2 = OFF; 1279 x4->dataWithAL3 = OFF; 1280 x4->maximumAl2SDUSize = (uint16)mux_cap_info.iMaximumAl2SDUSize; 1281 x4->maximumAl3SDUSize = (uint16)mux_cap_info.iMaximumAl3SDUSize; 1282 x4->maximumDelayJitter = 10; 1283 x5 = &x4->h223MultiplexTableCapability; 1284 x4->option_of_maxMUXPDUSizeCapability = ON; 1285 x4->maxMUXPDUSizeCapability = ON; 1286 x4->option_of_nsrpSupport = ON; 1287 x4->nsrpSupport = ON; 1288 x4->option_of_mobileOperationTransmitCapability = ON; 1289 x6 = &x4->mobileOperationTransmitCapability; 1290 x4->option_of_h223AnnexCCapability = OFF; 1291 1292 // x5 is an H223MultiplexTableCapability (CHOICE) // 1293 x5->index = 0; 1294 1295 // x6 is a MobileOperationTransmitCapability (SEQUENCE) // 1296 x6->modeChangeCapability = OFF; 1297 x6->h223AnnexA = OFF; 1298 x6->h223AnnexADoubleFlag = OFF; 1299 x6->h223AnnexB = ON; 1300 x6->h223AnnexBwithHeader = OFF; 1301 1302 // x7 is a set of CapabilityTableEntry(s) // 1303 unsigned entry_num = 1, codec_num = 0; 1304 1305 Oscl_Map<PV2WayMediaType, Oscl_Vector<unsigned, OsclMemAllocator>*, OsclMemAllocator> 1306 cap_entries_for_media_type; 1307 for (codec_num = 0; codec_num < incoming_codecs.size(); ++codec_num) 1308 { 1309 FillCapabilityTableEntry(x7 + entry_num - 1, *incoming_codecs[codec_num], entry_num); 1310 PV2WayMediaType media_type = GetMediaType(incoming_codecs[codec_num]->codec); 1311 Oscl_Vector<unsigned, OsclMemAllocator>* list = NULL; 1312 Oscl_Map<PV2WayMediaType, Oscl_Vector<unsigned, OsclMemAllocator>*, OsclMemAllocator>::iterator iter = 1313 cap_entries_for_media_type.find(media_type); 1314 if (iter == cap_entries_for_media_type.end()) 1315 { 1316 list = new Oscl_Vector<unsigned, OsclMemAllocator>(); 1317 cap_entries_for_media_type.insert( 1318 Oscl_Map < PV2WayMediaType, 1319 Oscl_Vector<unsigned, OsclMemAllocator>*, 1320 OsclMemAllocator >::value_type(media_type, list)); 1321 } 1322 else 1323 { 1324 list = (*iter).second; 1325 } 1326 list->push_back(entry_num++); 1327 } 1328 1329 for (codec_num = 0; codec_num < outgoing_codecs.size(); ++codec_num) 1330 { 1331 FillCapabilityTableEntry(x7 + entry_num - 1, *outgoing_codecs[codec_num], entry_num); 1332 entry_num++; 1333 } 1334 1335 1336 // x28 is a set of 1 CapabilityDescriptor(s) // 1337 // x29 is a set of num_alt_cap_sets AlternativeCapabilitySet(s) // 1338 unsigned num_alt_cap_sets = cap_entries_for_media_type.size(); 1339 PS_AlternativeCapabilitySet x29 = 1340 (PS_AlternativeCapabilitySet)OSCL_DEFAULT_MALLOC(num_alt_cap_sets * 1341 sizeof(S_AlternativeCapabilitySet)); 1342 oscl_memset(x29, 0, num_alt_cap_sets * sizeof(S_AlternativeCapabilitySet)); 1343 Oscl_Map < PV2WayMediaType, 1344 Oscl_Vector<unsigned, OsclMemAllocator>*, OsclMemAllocator >::iterator iter = 1345 cap_entries_for_media_type.begin(); 1346 1347 // x28[0] is a CapabilityDescriptor (SEQUENCE) // 1348 x28[0].capabilityDescriptorNumber = 0; 1349 x28[0].option_of_simultaneousCapabilities = true; 1350 x28[0].size_of_simultaneousCapabilities = (uint16)num_alt_cap_sets; 1351 x28[0].simultaneousCapabilities = x29; 1352 1353 for (unsigned acsnum = 0; acsnum < num_alt_cap_sets; ++acsnum) 1354 { 1355 Oscl_Vector<unsigned, OsclMemAllocator>* alternatives = (*iter++).second; 1356 x29[acsnum].item = (uint32*)OSCL_DEFAULT_MALLOC(sizeof(uint32) * alternatives->size()); 1357 x29[acsnum].size = (uint16)alternatives->size(); 1358 for (unsigned altnum = 0; altnum < alternatives->size(); ++altnum) 1359 { 1360 x29[acsnum].item[altnum] = (*alternatives)[altnum]; 1361 } 1362 delete alternatives; 1363 } 1364 1365 return ret; 1366 } 1367 1368 void FillCapabilityTableEntry(PS_CapabilityTableEntry pCapEntry, 1369 CodecCapabilityInfo& codec_info, 1370 uint32 entry_num) 1371 { 1372 pCapEntry->option_of_capability = 1; 1373 pCapEntry->capabilityTableEntryNumber = (uint16)entry_num; 1374 PS_Capability capability = &pCapEntry->capability; 1375 FillCapability(codec_info, capability); 1376 } 1377 1378 unsigned GetMaxFrameRate(PS_DataType pDataType) 1379 { 1380 if (!pDataType) 1381 return 0; 1382 switch (GetCodecType(pDataType)) 1383 { 1384 case PV_VID_TYPE_H263: 1385 return GetMaxFrameRate_H263(pDataType->videoData->h263VideoCapability); 1386 case PV_VID_TYPE_MPEG4: 1387 return GetMaxFrameRate_M4V( 1388 pDataType->videoData->genericVideoCapability); 1389 case PV_AUD_TYPE_GSM: 1390 return 50; 1391 case PV_AUD_TYPE_G723: 1392 return 34; 1393 default: 1394 break; 1395 } 1396 return 0; 1397 } 1398 1399 unsigned GetVideoFrameSize(PS_DataType pDataType, bool width) 1400 { 1401 if (!pDataType) 1402 return 0; 1403 switch (GetCodecType(pDataType)) 1404 { 1405 case PV_VID_TYPE_H263: 1406 return GetVideoFrameSize_H263(pDataType->videoData->h263VideoCapability, width); 1407 case PV_VID_TYPE_MPEG4: 1408 return GetVideoFrameSize_M4V( 1409 pDataType->videoData->genericVideoCapability, width); 1410 case PV_AUD_TYPE_GSM: 1411 return 0; 1412 case PV_AUD_TYPE_G723: 1413 return 0; 1414 default: 1415 break; 1416 } 1417 return 0; 1418 } 1419 1420 1421 unsigned GetMaxBitrate(PS_DataType pDataType) 1422 { 1423 if (!pDataType) 1424 return 0; 1425 switch (GetCodecType(pDataType)) 1426 { 1427 case PV_VID_TYPE_H263: 1428 return pDataType->videoData->h263VideoCapability->maxBitRate * 100; 1429 case PV_VID_TYPE_MPEG4: 1430 return pDataType->videoData->genericVideoCapability->maxBitRate * 100; 1431 case PV_VID_TYPE_H264: 1432 return pDataType->videoData->genericVideoCapability->maxBitRate * 100; 1433 case PV_AUD_TYPE_GSM: 1434 return pDataType->audioData->genericAudioCapability->maxBitRate * 100; 1435 case PV_AUD_TYPE_G723: 1436 return 6300; 1437 default: 1438 break; 1439 } 1440 return 0; 1441 } 1442 1443 unsigned GetSampleInterval(PS_DataType pDataType) 1444 { 1445 if (!pDataType) 1446 return 0; 1447 switch (GetCodecType(pDataType)) 1448 { 1449 case PV_AUD_TYPE_GSM: 1450 return 20; 1451 case PV_AUD_TYPE_G723: 1452 return 30; 1453 default: 1454 break; 1455 } 1456 return 0; 1457 } 1458 1459 unsigned GetMaxFrameRate_H263(PS_H263VideoCapability h263caps) 1460 { 1461 const int MPIMAX = 31; 1462 unsigned mpi = MPIMAX; 1463 if (h263caps->option_of_cif16MPI && h263caps->cif16MPI) 1464 { 1465 mpi = h263caps->cif16MPI; 1466 } 1467 if (h263caps->option_of_cif4MPI && h263caps->cif4MPI) 1468 { 1469 mpi = (h263caps->cif4MPI < mpi) ? h263caps->cif4MPI : mpi; 1470 } 1471 if (h263caps->option_of_cifMPI && h263caps->cifMPI) 1472 { 1473 mpi = (h263caps->cifMPI < mpi) ? h263caps->cifMPI : mpi; 1474 } 1475 if (h263caps->option_of_qcifMPI && h263caps->qcifMPI) 1476 { 1477 mpi = (h263caps->qcifMPI < mpi) ? h263caps->qcifMPI : mpi; 1478 } 1479 return mpi ? (unsigned)(30.0 / mpi) : 0; 1480 } 1481 1482 unsigned GetMaxFrameRate_M4V(PS_GenericCapability m4vcaps) 1483 { 1484 OSCL_UNUSED_ARG(m4vcaps); 1485 return 15; 1486 } 1487 1488 unsigned GetVideoFrameSize_H263(PS_H263VideoCapability h263caps, bool width) 1489 { 1490 unsigned frame_width = 0; 1491 unsigned frame_height = 0; 1492 1493 if (h263caps->option_of_cif16MPI && h263caps->cif16MPI) 1494 { 1495 //frame_width = 352; 1496 //frame_height = 288; 1497 } 1498 if (h263caps->option_of_cif4MPI && h263caps->cif4MPI) 1499 { 1500 //frame_width = 352; 1501 //frame_height = 288; 1502 } 1503 if (h263caps->option_of_cifMPI && h263caps->cifMPI) 1504 { 1505 frame_width = 352; 1506 frame_height = 288; 1507 } 1508 if (h263caps->option_of_qcifMPI && h263caps->qcifMPI) 1509 { 1510 frame_width = 176; 1511 frame_height = 144; 1512 } 1513 1514 if (width == true) 1515 { 1516 return frame_width; 1517 } 1518 else 1519 { 1520 return frame_height; 1521 } 1522 1523 } 1524 1525 unsigned GetVideoFrameSize_M4V(PS_GenericCapability m4vcaps , bool width) 1526 { 1527 OSCL_UNUSED_ARG(m4vcaps); 1528 if (width == true) 1529 { 1530 return 176; 1531 } 1532 else 1533 { 1534 return 144; 1535 } 1536 } 1537 1538 1539 bool FindCodecForMediaType(PV2WayMediaType media, 1540 Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator>&list, 1541 int* index) 1542 { 1543 for (unsigned ii = 0; ii < list.size(); ++ii) 1544 { 1545 if (GetMediaType(list[ii]->codec) == media) 1546 { 1547 *index = ii; 1548 return true; 1549 } 1550 } 1551 return false; 1552 } 1553 1554 bool IsSupported(Oscl_Vector<H324ChannelParameters, PVMFTscAlloc>& list, 1555 PV2WayMediaType media_type, 1556 CodecCapabilityInfo& codec_info, 1557 int* index) 1558 { 1559 for (unsigned nn = 0; nn < list.size(); ++nn) 1560 { 1561 H324ChannelParameters& param = list[nn]; 1562 if (param.GetMediaType() != media_type) 1563 continue; 1564 Oscl_Vector<FormatCapabilityInfo, OsclMemAllocator>* codecs = 1565 param.GetCodecs(); 1566 if (!codecs) 1567 { 1568 return false; 1569 } 1570 codec_info.codec = PVMFFormatTypeToPVCodecType((*codecs)[0].format); 1571 codec_info.dir = (*codecs)[0].dir; 1572 *index = nn; 1573 return true; 1574 } 1575 return false; 1576 } 1577 1578 bool IsResolutionSupported(const PVMFVideoResolution& resolution, 1579 const Oscl_Vector < PVMFVideoResolutionRange, 1580 OsclMemAllocator > & resolutions) 1581 { 1582 for (unsigned ii = 0; ii < resolutions.size(); ++ii) 1583 { 1584 if (resolution.height >= resolutions[ii].iFirst.height && 1585 resolution.height <= resolutions[ii].iLast.height && 1586 resolution.width >= resolutions[ii].iFirst.width && 1587 resolution.width <= resolutions[ii].iLast.width) 1588 { 1589 return true; 1590 } 1591 } 1592 return false; 1593 } 1594 1595 PS_H223LogicalChannelParameters 1596 GetH223LogicalChannelParameters(uint8 al_index, 1597 bool segmentable, 1598 uint32 al_specific) 1599 { 1600 PS_H223LogicalChannelParameters pParameter = 1601 (PS_H223LogicalChannelParameters)OSCL_DEFAULT_MALLOC( 1602 sizeof(S_H223LogicalChannelParameters)); 1603 oscl_memset(pParameter , 0, sizeof(S_H223LogicalChannelParameters)); 1604 1605 pParameter->segmentableFlag = segmentable; 1606 pParameter->adaptationLayerType.index = (uint16)al_index; 1607 if (pParameter->adaptationLayerType.index == 5) 1608 { 1609 pParameter->adaptationLayerType.al3 = (PS_Al3) OSCL_DEFAULT_MALLOC(sizeof(S_Al3)); 1610 oscl_memset(pParameter->adaptationLayerType.al3, 0, sizeof(S_Al3)); 1611 pParameter->adaptationLayerType.al3->controlFieldOctets = (uint8)al_specific; 1612 pParameter->adaptationLayerType.al3->sendBufferSize = DEF_AL3_SEND_BUFFER_SIZE; 1613 } 1614 return pParameter; 1615 } 1616 1617 uint16 GetCodecCapabilityInfo(PS_TerminalCapabilitySet pTcs, 1618 PS_AlternativeCapabilitySet pAcs, 1619 Oscl_Vector < CodecCapabilityInfo*, 1620 OsclMemAllocator > & in_codecs_acs) 1621 { 1622 uint16 num_media_types = 0; 1623 PV2WayMediaType cur_media_type = PV_MEDIA_NONE; 1624 for (int ll = 0; ll < pAcs->size; ++ll) 1625 { 1626 PS_Capability capability = LookupCapability(pTcs, 1627 (uint16)pAcs->item[ll]); 1628 if (!capability) 1629 { 1630 continue; 1631 } 1632 CodecCapabilityInfo* cci = GetCodecCapabilityInfo(capability); 1633 if (cci == NULL) 1634 { 1635 continue; 1636 } 1637 PV2WayMediaType mediaType = GetMediaType(cci->codec); 1638 if (mediaType == PV_MEDIA_NONE) 1639 { 1640 delete cci; 1641 } 1642 else 1643 { 1644 if (mediaType != cur_media_type) 1645 { 1646 num_media_types++; 1647 cur_media_type = mediaType; 1648 } 1649 in_codecs_acs.push_back(cci); 1650 } 1651 } 1652 return num_media_types; 1653 } 1654 1655 void Deallocate(Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator>& cci_list) 1656 { 1657 for (unsigned ii = 0; ii < cci_list.size(); ++ii) 1658 { 1659 delete cci_list[ii]; 1660 } 1661 cci_list.clear(); 1662 } 1663 1664 CodecCapabilityInfo* IsSupported(CodecCapabilityInfo* codecInfo, 1665 Oscl_Vector<CodecCapabilityInfo*, OsclMemAllocator>& list) 1666 { 1667 for (unsigned ii = 0; ii < list.size(); ++ii) 1668 { 1669 if (list[ii]->codec == codecInfo->codec) 1670 return list[ii]; 1671 } 1672 return NULL; 1673 } 1674 1675 PVMFStatus SetFormatSpecificInfo(PS_DataType pDataType, uint8* fsi, uint32 fsi_len) 1676 { 1677 PVCodecType_t codec_type = GetCodecType(pDataType); 1678 if (codec_type != PV_VID_TYPE_MPEG4) 1679 { 1680 return PVMFFailure; 1681 } 1682 PS_OCTETSTRING octet_string = pDataType->videoData->genericVideoCapability->nonCollapsing[2].parameterValue.octetString; 1683 OSCL_ASSERT(octet_string != NULL); 1684 if (octet_string->data) 1685 { 1686 OSCL_DEFAULT_FREE(octet_string->data); 1687 octet_string->data = NULL; 1688 octet_string->size = 0; 1689 } 1690 octet_string->data = (uint8*)OSCL_DEFAULT_MALLOC(fsi_len); 1691 oscl_memcpy(octet_string->data, 1692 fsi, 1693 fsi_len); 1694 octet_string->size = fsi_len; 1695 return PVMFSuccess; 1696 } 1697 1698 uint32 SetFillerFsi(uint8* dest, uint32 dest_len) 1699 { 1700 if (dest_len != PV2WAY_FILLER_FSI_LEN) 1701 return 0; 1702 uint8 buf[PV2WAY_FILLER_FSI_LEN] = PV2WAY_FILLER_FSI; 1703 oscl_memcpy(dest, buf, dest_len); 1704 return dest_len; 1705 } 1706 1707 bool IsFillerFsi(uint8* fsi, uint32 fsi_len) 1708 { 1709 if (fsi_len != PV2WAY_FILLER_FSI_LEN) 1710 return false; 1711 uint8 buf[PV2WAY_FILLER_FSI_LEN] = PV2WAY_FILLER_FSI; 1712 if (oscl_memcmp(fsi, buf, fsi_len) == 0) 1713 return true; 1714 return false; 1715 } 1716 1717 1718