1 2 /* 3 * Copyright (C) Texas Instruments - http://www.ti.com/ 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2.1 of the License, or (at your option) any later version. 9 * 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 /* ============================================================================= 22 * Texas Instruments OMAP(TM) Platform Software 23 * (c) Copyright Texas Instruments, Incorporated. All Rights Reserved. 24 * 25 * Use of this software is controlled by the terms and conditions found 26 * in the license agreement under which this software has been supplied. 27 * ============================================================================ */ 28 /** 29 * @file OMX_WmaDecUtils.h 30 * 31 * This is an header file for an audio WMA Decoder that is fully 32 * compliant with the Khronos OpenMAX 1.0 specification. 33 * This the file that the application that uses OMX would include 34 * in its code. 35 * 36 * @path $(CSLPATH)\ 37 * 38 * @rev 1.0 39 */ 40 /* --------------------------------------------------------------------------- */ 41 42 #ifndef OMX_WMADEC_UTILS__H 43 #define OMX_WMADEC_UTILS__H 44 #define OMX_WMADECODER_H 45 #include <pthread.h> 46 47 #include <OMX_TI_Common.h> 48 #include <TIDspOmx.h> 49 #include "LCML_DspCodec.h" 50 #define _ERROR_PROPAGATION__ 51 52 #ifdef __PERF_INSTRUMENTATION__ 53 #include "perf.h" 54 #endif 55 56 #ifdef RESOURCE_MANAGER_ENABLED 57 #include <ResourceManagerProxyAPI.h> 58 #endif 59 60 #include <OMX_Component.h> 61 62 #ifndef ANDROID 63 #define ANDROID 64 #endif 65 66 #ifdef ANDROID 67 #undef LOG_TAG 68 #define LOG_TAG "OMX_WMADEC" 69 70 /* PV opencore capability custom parameter index */ 71 #define PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347 72 #endif 73 74 #ifdef UNDER_CE 75 #ifndef _OMX_EVENT_ 76 #define _OMX_EVENT_ 77 typedef struct OMX_Event { 78 HANDLE event; 79 } OMX_Event; 80 #endif 81 82 int OMX_CreateEvent(OMX_Event *event); 83 int OMX_SignalEvent(OMX_Event *event); 84 int OMX_WaitForEvent(OMX_Event *event); 85 int OMX_DestroyEvent(OMX_Event *event); 86 87 typedef struct OMXBufferStatus /*BUFFERSTATUS*/ 88 { 89 DWORD EmptyBufferSent; 90 DWORD FillBufferSent; 91 DWORD EmptyBufferDone; 92 DWORD FillBufferDone; 93 } OMXBufferStatus; 94 95 #endif 96 97 /* PV opencore capability custom parameter index */ 98 #define PV_OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347 99 100 #ifndef ANDROID 101 #define ANDROID 102 #endif 103 104 #define OBJECTTYPE_LC 2 105 #define OBJECTTYPE_HE 5 106 #define OBJECTTYPE_HE2 29 107 108 109 /* ======================================================================= */ 110 /** 111 * @def WMADEC_COMPONENT_THREAD 112 */ 113 /* ======================================================================= */ 114 #define EXIT_COMPONENT_THRD 10 115 /* ======================================================================= */ 116 /** 117 * @def WMADEC_XXX_VER Component version 118 */ 119 /* ======================================================================= */ 120 #define WMADEC_MAJOR_VER 0xF1 121 #define WMADEC_MINOR_VER 0xF2 122 /* ======================================================================= */ 123 /** 124 * @def INPUT_WMADEC_BUFFER_SIZE Default input buffer size 125 * 126 */ 127 /* ======================================================================= */ 128 #define INPUT_WMADEC_BUFFER_SIZE 16384 129 130 /* ======================================================================= */ 131 /** 132 * @def OUTPUT_WMADEC_BUFFER_SIZE Default output buffer size 133 */ 134 /* ======================================================================= */ 135 #define OUTPUT_WMADEC_BUFFER_SIZE 40960 136 /* ======================================================================= */ 137 /** 138 * @def NUM_WMADEC_INPUT_BUFFERS Default number of input buffers 139 */ 140 /* ======================================================================= */ 141 #define NUM_WMADEC_INPUT_BUFFERS 2 142 /* ======================================================================= */ 143 /** 144 * @def NUM_WMADEC_OUTPUT_BUFFERS Default number of output buffers 145 */ 146 /* ======================================================================= */ 147 #ifdef UNDER_CE 148 #define NUM_WMADEC_OUTPUT_BUFFERS 4 149 #else 150 #define NUM_WMADEC_OUTPUT_BUFFERS 4 151 #endif 152 /* ======================================================================= */ 153 /** 154 * @def NOT_USED Defines a value for "don't care" parameters 155 */ 156 /* ======================================================================= */ 157 #define NOT_USED 10 158 /* ======================================================================= */ 159 /** 160 * @def NORMAL_BUFFER Defines the flag value with all flags turned off 161 */ 162 /* ======================================================================= */ 163 #define NORMAL_BUFFER 0 164 /* ======================================================================= */ 165 /** 166 * @def OMX_WMADEC_DEFAULT_SEGMENT Default segment ID for the LCML 167 */ 168 /* ======================================================================= */ 169 #define OMX_WMADEC_DEFAULT_SEGMENT (0) 170 /* ======================================================================= */ 171 /** 172 * @def OMX_WMADEC_SN_TIMEOUT Timeout value for the socket node 173 */ 174 /* ======================================================================= */ 175 #define OMX_WMADEC_SN_TIMEOUT (-1) 176 /* ======================================================================= */ 177 /** 178 * @def OMX_WMADEC_SN_PRIORITY Priority for the socket node 179 */ 180 /* ======================================================================= */ 181 #define OMX_WMADEC_SN_PRIORITY (10) 182 /* ======================================================================= */ 183 /** 184 * @def WMAD_TIMEOUT Timeout value for the component thread 185 */ 186 /* ======================================================================= */ 187 #define WMAD_TIMEOUT (1000) /* millisecs */ 188 /* ======================================================================= */ 189 /** 190 * @def NUM_WMADEC_OUTPUT_BUFFERS_DASF Number of output buffers for DASF 191 */ 192 /* ======================================================================= */ 193 #define NUM_WMADEC_OUTPUT_BUFFERS_DASF 2 194 /* ======================================================================= */ 195 /** 196 * @def WMADEC_STREAM_COUNT Number of streams 197 */ 198 /* ======================================================================= */ 199 #define WMADEC_STREAM_COUNT 2 200 /* ======================================================================= */ 201 /** 202 * @def WMADEC_DEFAULT_SAMPLING_FREQUENCY Sampling frequency 203 */ 204 /* ======================================================================= */ 205 #define WMADEC_DEFAULT_SAMPLING_FREQUENCY 8000 206 /* ======================================================================= */ 207 /** 208 * @def WMADEC_MAX_NUM_OF_BUFS Maximum number of buffers 209 */ 210 /* ======================================================================= */ 211 #define MAX_NUM_OF_BUFS 10 212 #define WMA_CPU 45 213 /* ======================================================================= */ 214 /** 215 * @def WMADEC_DEFAULT_PACKETS_DWLO Default Packets Number 216 */ 217 /* ======================================================================= */ 218 #define WMADEC_DEFAULT_PACKETS_DWLO 178 219 /* ======================================================================= */ 220 /** 221 * @def WMADEC_DEFAULT_PLAYDURATION_DWLO Default Play Duration 222 */ 223 /* ======================================================================= */ 224 #define WMADEC_DEFAULT_PLAYDURATION_DWLO 917760000 225 /* ======================================================================= */ 226 /** 227 * @def WMADEC_DEFAULT_MAXPACKETSIZE Default Maximum Packet Size 228 */ 229 /* ======================================================================= */ 230 #define WMADEC_DEFAULT_MAXPACKETSIZE 349 231 /* ======================================================================= */ 232 /** 233 * @def WMADEC_DEFAULT_STREAMTYPE_DATA1 Default Stream Data Type values 234 */ 235 /* ======================================================================= */ 236 //Macros for WMA 237 #define GetUnalignedWord( pb, w ) \ 238 (w) = ((OMX_U16) *(pb + 1) << 8) + *pb; 239 240 #define GetUnalignedDword( pb, dw ) \ 241 (dw) = ((OMX_U32) *(pb + 3) << 24) + \ 242 ((OMX_U32) *(pb + 2) << 16) + \ 243 ((OMX_U16) *(pb + 1) << 8) + *pb; 244 245 #define GetUnalignedWordEx( pb, w ) GetUnalignedWord( pb, w ); (pb) += sizeof(OMX_U16); 246 #define GetUnalignedDwordEx( pb, dw ) GetUnalignedDword( pb, dw ); (pb) += sizeof(OMX_U32); 247 #define LoadWORD( w, p ) GetUnalignedWordEx( p, w ) 248 #define LoadDWORD( dw, p ) GetUnalignedDwordEx( p, dw ) 249 250 251 #define WMADEC_DEFAULT_STREAMTYPE_DATA1 -127295936 252 #define WMADEC_DEFAULT_STREAMTYPE_DATA2 23373 253 #define WMADEC_DEFAULT_STREAMTYPE_DATA3 4559 254 #define WMADEC_DEFAULT_STREAMTYPE_DATA40 168 255 #define WMADEC_DEFAULT_STREAMTYPE_DATA41 253 256 #define WMADEC_DEFAULT_STREAMTYPE_DATA42 0 257 #define WMADEC_DEFAULT_STREAMTYPE_DATA43 128 258 #define WMADEC_DEFAULT_STREAMTYPE_DATA44 95 259 #define WMADEC_DEFAULT_STREAMTYPE_DATA45 92 260 #define WMADEC_DEFAULT_STREAMTYPE_DATA46 68 261 #define WMADEC_DEFAULT_STREAMTYPE_DATA47 43 262 263 /* ======================================================================= */ 264 /** 265 * @def WMADEC_DEFAULT_TYPESPECIFIC Default Specific Type 266 */ 267 /* ======================================================================= */ 268 #define WMADEC_DEFAULT_TYPESPECIFIC 28 269 /* ======================================================================= */ 270 /** 271 * @def WMADEC_DEFAULT_STREAMNUM Default Stream Number 272 */ 273 /* ======================================================================= */ 274 #define WMADEC_DEFAULT_STREAMNUM 1 275 /* ======================================================================= */ 276 /** 277 * @def WMADEC_DEFAULT_FORMATTAG Default Format tag 278 */ 279 /* ======================================================================= */ 280 #define WMADEC_DEFAULT_FORMATTAG 353 281 /* ======================================================================= */ 282 /** 283 * @def WMADEC_DEFAULT_SAMPLEPERSEC Default samples per second 284 */ 285 /* ======================================================================= */ 286 #define WMADEC_DEFAULT_SAMPLEPERSEC 8000 287 /* ======================================================================= */ 288 /** 289 * @def WMADEC_DEFAULT_AVGBYTESPERSEC Default average bytes per second 290 */ 291 /* ======================================================================= */ 292 #define WMADEC_DEFAULT_AVGBYTESPERSEC 625 293 /* ======================================================================= */ 294 /** 295 * @def WMADEC_DEFAULT_BLOCKALIGN Default block alignment 296 */ 297 /* ======================================================================= */ 298 #define WMADEC_DEFAULT_BLOCKALIGN 40 299 /* ======================================================================= */ 300 /** 301 * @def WMADEC_DEFAULT_CHANNEL Default channels number 302 */ 303 /* ======================================================================= */ 304 #define WMADEC_DEFAULT_CHANNEL 1 305 /* ======================================================================= */ 306 /** 307 * @def WMADEC_DEFAULT_VALIDBITSPERSAMPLE Default valid bits per sample 308 */ 309 /* ======================================================================= */ 310 #define WMADEC_DEFAULT_VALIDBITSPERSAMPLE 16 311 /* ======================================================================= */ 312 /** 313 * @def WMADEC_DEFAULT_SIZEWAVEHEADER Default wave header size 314 */ 315 /* ======================================================================= */ 316 #define WMADEC_DEFAULT_SIZEWAVEHEADER 10 317 /* ======================================================================= */ 318 /** 319 * @def WMADEC_DEFAULT_CHANNELMASK Default channel mask 320 */ 321 /* ======================================================================= */ 322 #define WMADEC_DEFAULT_CHANNELMASK 0 323 /* ======================================================================= */ 324 /** 325 * @def WMADEC_DEFAULT_ENCODEOPTV Default encode option 326 */ 327 /* ======================================================================= */ 328 #define WMADEC_DEFAULT_ENCODEOPTV 0 329 /* ======================================================================= */ 330 /** 331 * @def WMADEC_DEFAULT_VALIDBITSPERSAMPLE Default valid bits per sample 332 */ 333 /* ======================================================================= */ 334 #define WMADEC_DEFAULT_VALIDBITSPERSAMPLE 16 335 /* ======================================================================= */ 336 /** 337 * @def WMADEC_DEFAULT_SAMPLEPERBLOCK Default samples per block 338 */ 339 /* ======================================================================= */ 340 #define WMADEC_DEFAULT_SAMPLEPERBLOCK 8704 341 /** 342 * @def WMADEC_DEBUG Turns debug messaging on and off 343 */ 344 /* ======================================================================= */ 345 #undef WMADEC_DEBUG 346 /* ======================================================================= */ 347 /** 348 * @def WMADEC_MEMCHECK Turns memory messaging on and off 349 */ 350 /* ======================================================================= */ 351 #undef WMADEC_MEMCHECK 352 /* ======================================================================= */ 353 /** 354 * @def WMADEC_USN_DLL_NAME USN DLL name 355 */ 356 /* ======================================================================= */ 357 #ifdef UNDER_CE 358 #define WMADEC_USN_DLL_NAME "\\windows\\usn.dll64P" 359 #else 360 #define WMADEC_USN_DLL_NAME "usn.dll64P" 361 #endif 362 /* ======================================================================= */ 363 /** 364 * @def WMADEC_DLL_NAME WMA Decoder socket node dll name 365 */ 366 /* ======================================================================= */ 367 #ifdef UNDER_CE 368 #define WMADEC_DLL_NAME "\\windows\\wmadec_sn.dll64P" 369 #else 370 #define WMADEC_DLL_NAME "wmadec_sn.dll64P" 371 #endif 372 /* ======================================================================= */ 373 /** 374 * @def WMADEC_EPRINT Error print macro 375 */ 376 /* ======================================================================= */ 377 #ifndef UNDER_CE 378 #define WMADEC_EPRINT ALOGE 379 #else 380 #define WMADEC_EPRINT printf 381 #endif 382 /* ======================================================================= */ 383 /** 384 * @def WMADEC_DPRINT Debug print macro 385 */ 386 /* ======================================================================= */ 387 #ifndef UNDER_CE 388 #ifdef WMADEC_DEBUG 389 #define WMADEC_DPRINT ALOGI 390 #else 391 #define WMADEC_DPRINT(...) 392 #endif 393 394 #ifdef WMADEC_MEMCHECK 395 #define WMADEC_MEMPRINT(...) fprintf(stderr,__VA_ARGS__) 396 #else 397 #define WMADEC_MEMPRINT(...) 398 #endif 399 400 401 #ifdef WMADEC_DEBUG_MCP 402 #define WMADEC_MCP_DPRINT(...) fprintf(stderr,__VA_ARGS__) 403 #else 404 #define WMADEC_MCP_DPRINT(...) 405 #endif 406 407 #else /*UNDER_CE*/ 408 #ifdef WMADEC_DEBUG 409 #define WMADEC_DPRINT(STR, ARG...) printf() 410 #else 411 #define WMADEC_DPRINT 412 #endif 413 /* ======================================================================= */ 414 /** 415 * @def WMADEC_MEMCHECK Memory print macro 416 */ 417 /* ======================================================================= */ 418 #ifdef WMADEC_MEMCHECK 419 #define WMADEC_MEMPRINT(STR, ARG...) printf() 420 #else 421 #define WMADEC_MEMPRINT 422 #endif 423 424 #endif 425 /* ======================================================================= */ 426 /** 427 * @def WMADEC_NUM_OF_PORTS Number of ports 428 */ 429 /* ======================================================================= */ 430 #define WMADEC_NUM_OF_PORTS 2 431 /* ======================================================================= */ 432 /** 433 * W M A T Y P E S 434 */ 435 /* ======================================================================= */ 436 437 438 #define WAVE_FORMAT_MSAUDIO1 0x0160 439 #define WAVE_FORMAT_WMAUDIO2 0x0161 440 #define WAVE_FORMAT_WMAUDIO3 0x0162 441 #define WAVE_FORMAT_WMAUDIO_LOSSLESS 0x0163 442 #define WAVE_FORMAT_WMAUDIO2_ES 0x0165 443 #define WAVE_FORMAT_WMASPDIF 0x164 444 #define WAVE_FORMAT_WMAUDIO3_ES 0x0166 445 #define WAVE_FORMAT_WMAUDIO_LOSSLESS_ES 0x0167 446 #define WAVE_FORMAT_MSSPEECH 10 447 448 449 /* According with the ASF Specification:*/ 450 #define WAVE_FORMAT_MSAUDIO 0x0161 /*Versions 7,8 and 9 Series*/ 451 #define WAVE_FORMAT_MSAUDIO_9 0x0162 /* 9 series */ 452 #define WAVE_FORMAT_MSAUDIO_9_LOOSELESS 0x0163 /* 9 series */ 453 454 /* ======================================================================= */ 455 /** COMP_PORT_TYPE Port types 456 * 457 * @param INPUT_PORT Input port 458 * 459 * @param OUTPUT_PORT Output port 460 */ 461 /* ==================================================================== */ 462 typedef enum COMP_PORT_TYPE { 463 INPUT_PORT = 0, 464 OUTPUT_PORT 465 }COMP_PORT_TYPE; 466 /* ======================================================================= */ 467 /** StreamType Stream types 468 * 469 * @param DMM DMM 470 * 471 * @param INSTRM Input stream 472 * 473 * @param OUTSTRM Output stream 474 */ 475 /* ==================================================================== */ 476 enum StreamType 477 { 478 DMM, 479 INSTRM, 480 OUTSTRM 481 }; 482 483 typedef OMX_ERRORTYPE (*fpo)(OMX_HANDLETYPE); 484 485 /* =================================================================================== */ 486 /** 487 * Socket node input parameters. 488 */ 489 /* ================================================================================== */ 490 typedef struct WMADEC_AudioCodecParams 491 { 492 unsigned long iSamplingRate; 493 unsigned long iStrmId; 494 unsigned short iAudioFormat; 495 496 }WMADEC_AudioCodecParams; 497 498 typedef enum { 499 WMA_IAUDIO_BLOCK=0, 500 WMA_IAUDIO_INTERLEAVED 501 } WMAAUDIO_PcmFormat; 502 503 504 #define WMA_MONO_CHANNEL 0x0001 505 #define WMA_STEREO_INTERLEAVED 0x0002 506 #define WMA_STEREO_NON_INTERLEAVED 0x0003 507 #define WMA_MONO_DUPLICATED 0x0004 508 509 typedef enum { 510 WMA_IUALG_CMD_STOP = 0, 511 WMA_IUALG_CMD_PAUSE = 1, 512 WMA_IUALG_CMD_GETSTATUS = 2, 513 WMA_IUALG_CMD_SETSTATUS = 3, 514 WMA_IUALG_CMD_USERCMDSTART = 100 515 }WMA_IUALGUALG_Cmd; 516 517 518 typedef struct { 519 OMX_U16 bLastBuffer; 520 }WMADEC_UAlgInBufParamStruct; 521 522 typedef struct 523 { 524 OMX_U32 size; 525 OMX_S32 iOutputFormat; 526 } WMADEC_UALGParams; 527 528 typedef struct { 529 /* Number of frames in a buffer */ 530 unsigned long ulFrameCount; 531 bool ulIsLastBuffer; 532 }WMADEC_UAlgOutBufParamStruct; 533 /* =================================================================================== */ 534 /** 535 * WMA Buffer Header Type 536 */ 537 /* ================================================================================== */ 538 typedef struct LCML_WMADEC_BUFHEADERTYPE { 539 OMX_DIRTYPE eDir; 540 OMX_BUFFERHEADERTYPE* buffer; 541 WMADEC_UAlgInBufParamStruct *pIpParam; 542 /* Output Parameter Information structure */ 543 WMADEC_UAlgOutBufParamStruct *pOpParam; 544 }LCML_WMADEC_BUFHEADERTYPE; 545 546 /* =================================================================================== */ 547 /** 548 * Structure for buffer list 549 */ 550 /* ================================================================================== */ 551 typedef struct _BUFFERLIST BUFFERLIST; 552 struct _BUFFERLIST{ 553 OMX_U16 numBuffers; 554 OMX_BUFFERHEADERTYPE *pBufHdr[MAX_NUM_OF_BUFS]; /* records buffer header send by client */ 555 OMX_U32 bufferOwner[MAX_NUM_OF_BUFS]; 556 OMX_U32 bBufferPending[MAX_NUM_OF_BUFS]; 557 OMX_U8 EosFlagSent; 558 }; 559 560 561 typedef struct PV_OMXComponentCapabilityFlagsType 562 { 563 ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS (for opencore compatability) 564 OMX_BOOL iIsOMXComponentMultiThreaded; 565 OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc; 566 OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc; 567 OMX_BOOL iOMXComponentSupportsMovableInputBuffers; 568 OMX_BOOL iOMXComponentSupportsPartialFrames; 569 OMX_BOOL iOMXComponentNeedsNALStartCode; 570 OMX_BOOL iOMXComponentCanHandleIncompleteFrames; 571 } PV_OMXComponentCapabilityFlagsType; 572 /* =================================================================================== */ 573 /** 574 * RCA_HEADER. Rca data that goes to SN with the first data packet received from test app. 575 */ 576 /* ================================================================================== */ 577 typedef struct RCA_HEADER 578 { 579 QWORD iPackets; 580 QWORD iPlayDuration; 581 OMX_U32 iMaxPacketSize; 582 WMADECGUID iStreamType; 583 OMX_U32 iTypeSpecific; 584 OMX_U16 iStreamNum; 585 OMX_U16 iFormatTag; 586 OMX_U16 iChannel; 587 OMX_U32 iSamplePerSec; 588 OMX_U32 iAvgBytesPerSec; 589 OMX_U16 iBlockAlign; 590 OMX_U16 iValidBitsPerSample; 591 OMX_U16 iNotUsed; 592 OMX_U32 iSamplesPerBlock; 593 OMX_U16 iEncodeOptV; 594 OMX_U32 iNotUsed2; 595 OMX_U8 iReplicatedDataSize; 596 OMX_U32 iPayload; 597 } RCA_HEADER; 598 /* =================================================================================== */ 599 /** 600 * Component private data 601 */ 602 /* ================================================================================== */ 603 typedef struct WMADEC_COMPONENT_PRIVATE 604 { 605 /** Input buffer list */ 606 BUFFERLIST *pInputBufferList; 607 608 /** Number of input buffers at runtime */ 609 OMX_U32 nRuntimeInputBuffers; 610 611 /** Number of output buffers at runtime */ 612 OMX_U32 nRuntimeOutputBuffers; 613 614 /** Output buffer list */ 615 BUFFERLIST *pOutputBufferList; 616 617 /** Structure of callback pointers */ 618 OMX_CALLBACKTYPE cbInfo; 619 /** Handle for use with async callbacks */ 620 621 OMX_PORT_PARAM_TYPE sPortParam; 622 623 /** Input port parameters */ 624 OMX_AUDIO_PARAM_PORTFORMATTYPE sInPortFormat; 625 626 /** Output port parameters */ 627 OMX_AUDIO_PARAM_PORTFORMATTYPE sOutPortFormat; 628 629 /** This will contain info like how many buffers 630 are there for input/output ports, their size etc, but not 631 BUFFERHEADERTYPE POINTERS. */ 632 OMX_PARAM_PORTDEFINITIONTYPE* pPortDef[WMADEC_NUM_OF_PORTS]; 633 634 /** WMA Component Parameters */ 635 OMX_AUDIO_PARAM_WMATYPE* wmaParams[WMADEC_NUM_OF_PORTS]; 636 637 638 /** This is component handle */ 639 OMX_COMPONENTTYPE* pHandle; 640 641 /** Current state of this component */ 642 OMX_STATETYPE curState; 643 644 /** The component thread handle */ 645 pthread_t ComponentThread; 646 647 /** The pipes for sending buffers to the thread */ 648 int dataPipe[2]; 649 650 /** The pipes for sending buffers to the thread */ 651 int cmdPipe[2]; 652 653 /** The pipes for sending buffers to the thread */ 654 int cmdDataPipe[2]; 655 656 /** Set to indicate component is stopping */ 657 OMX_U32 bIsStopping; 658 659 /** Flag set when the EOS marker is sent */ 660 OMX_U32 bIsEOFSent; 661 662 663 /** LCML input buffers received */ 664 OMX_U32 lcml_nCntIp; 665 666 /** LCML output buffers received */ 667 OMX_U32 lcml_nCntOpReceived; 668 669 #ifdef __PERF_INSTRUMENTATION__ 670 PERF_OBJHANDLE pPERF, pPERFcomp; 671 OMX_U32 nLcml_nCntIp; 672 OMX_U32 nLcml_nCntOpReceived; 673 #endif 674 675 /** LCML Handle */ 676 OMX_HANDLETYPE pLcmlHandle; 677 678 /** LCML Buffer Header */ 679 LCML_WMADEC_BUFHEADERTYPE *pLcmlBufHeader[2]; 680 681 /** Sampling frequency */ 682 int iWmaSamplingFrequeny; 683 684 /** Number of channels */ 685 int iWmaChannels; 686 687 /** Flag for DASF mode */ 688 int dasfmode; 689 690 /** Flag set when port definitions are allocated */ 691 OMX_U32 bPortDefsAllocated; 692 693 /** Flag set when component thread is started */ 694 OMX_U32 bCompThreadStarted; 695 696 /** Mark data */ 697 OMX_PTR pMarkData; 698 699 /** Mark buffer */ 700 OMX_MARKTYPE *pMarkBuf; 701 702 /** Mark target component */ 703 OMX_HANDLETYPE hMarkTargetComponent; 704 705 /** Flag set when buffer should not be queued to the DSP */ 706 OMX_U32 bBypassDSP; 707 708 709 /** LCML stream attributes */ 710 LCML_STRMATTR *strmAttr; 711 712 /** Component version */ 713 OMX_U32 nVersion; 714 715 /** WMA Header Info */ 716 WMA_HeadInfo* pHeaderInfo; 717 718 /** WMA Header Info */ 719 TI_OMX_DSP_DEFINITION* pDspDefinition; 720 721 /** Flag set when LCML handle is opened */ 722 int bLcmlHandleOpened; 723 724 /** Keeps track of the number of EmptyThisBuffer() calls */ 725 OMX_U32 nEmptyThisBufferCount; 726 727 /** Keeps track of the number of EmptyBufferDone() calls */ 728 OMX_U32 nEmptyBufferDoneCount; 729 730 /** Flag set when init params have been initialized */ 731 OMX_U32 bInitParamsInitialized; 732 733 /** Stores input buffers while paused */ 734 OMX_BUFFERHEADERTYPE *pInputBufHdrPending[MAX_NUM_OF_BUFS]; 735 736 /** Number of input buffers received while paused */ 737 OMX_U32 nNumInputBufPending; 738 739 /** Stores output buffers while paused */ 740 OMX_BUFFERHEADERTYPE *pOutputBufHdrPending[MAX_NUM_OF_BUFS]; 741 742 /** Number of output buffers received while paused */ 743 OMX_U32 nNumOutputBufPending; 744 745 /** Keeps track of the number of invalid frames that come from the LCML */ 746 OMX_U32 nInvalidFrameCount; 747 748 /** Flags to control port enable command **/ 749 OMX_U32 bEnableCommandPending; 750 751 /** Flag set when a disable command is pending */ 752 OMX_U32 bDisableCommandPending; 753 754 /** Parameter for pending disable command */ 755 OMX_U32 bEnableCommandParam; 756 757 /** Parameter for pending disable command */ 758 OMX_U32 bDisableCommandParam; 759 760 /** Flag to set when socket node stop callback should not transition 761 component to OMX_StateIdle */ 762 OMX_U32 bNoIdleOnStop; 763 764 /** Flag set when idle command is pending */ 765 OMX_U32 bIdleCommandPending; 766 767 /** Flag set when socket node is stopped */ 768 OMX_U32 bDspStoppedWhileExecuting; 769 770 /** Number of outstanding FillBufferDone() calls */ 771 OMX_S32 nOutStandingFillDones; 772 773 /** ID of stream */ 774 OMX_U32 streamID; 775 776 /** Flag set when get status is pending */ 777 OMX_U32 bGetStatusPending; 778 779 /** Pointer to the last output buffer header queued */ 780 OMX_BUFFERHEADERTYPE* LastOutputBufferHdrQueued; 781 782 /** Pointer to WMADEC_AudioCodecParams */ 783 WMADEC_AudioCodecParams *pParams; 784 785 /* Pointer to WMADEC_UALGParams */ 786 WMADEC_UALGParams *pDynParams; 787 788 /* Device string */ 789 OMX_STRING* sDeviceString; 790 791 /**Keep buffer tickcount*/ 792 OMX_U32 arrBufIndexTick[MAX_NUM_OF_BUFS]; 793 794 /** Keep buffer timestamps **/ 795 OMX_S64 arrBufIndex[MAX_NUM_OF_BUFS]; 796 797 /** Index to arrBufIndex[], used for input buffer timestamps */ 798 OMX_U8 IpBufindex; 799 800 /** Index to arrBufIndex[], used for output buffer timestamps */ 801 OMX_U8 OpBufindex; 802 803 /** Flag to flush SN after EOS in order to process more buffers after EOS**/ 804 OMX_U8 SendAfterEOS; 805 806 OMX_U8 InputEosSet; 807 808 OMX_BOOL bPreempted; 809 810 #ifdef RESOURCE_MANAGER_ENABLED 811 RMPROXY_CALLBACKTYPE rmproxyCallback; 812 #endif 813 814 /* Removing sleep() calls. Definition. */ 815 #ifndef UNDER_CE 816 pthread_mutex_t AlloBuf_mutex; 817 pthread_cond_t AlloBuf_threshold; 818 OMX_U8 AlloBuf_waitingsignal; 819 820 pthread_mutex_t InLoaded_mutex; 821 pthread_cond_t InLoaded_threshold; 822 OMX_U8 InLoaded_readytoidle; 823 824 pthread_mutex_t InIdle_mutex; 825 pthread_cond_t InIdle_threshold; 826 OMX_U8 InIdle_goingtoloaded; 827 828 pthread_mutex_t codecStop_mutex; 829 pthread_cond_t codecStop_threshold; 830 OMX_U8 codecStop_waitingsignal; 831 832 pthread_mutex_t codecFlush_mutex; 833 pthread_cond_t codecFlush_threshold; 834 OMX_U8 codecFlush_waitingsignal; 835 836 OMX_U8 nUnhandledFillThisBuffers; 837 OMX_U8 nUnhandledEmptyThisBuffers; 838 OMX_BOOL bFlushOutputPortCommandPending; 839 OMX_BOOL bFlushInputPortCommandPending; 840 841 #else 842 OMX_Event AlloBuf_event; 843 OMX_U8 AlloBuf_waitingsignal; 844 845 OMX_Event InLoaded_event; 846 OMX_U8 InLoaded_readytoidle; 847 848 OMX_Event InIdle_event; 849 OMX_U8 InIdle_goingtoloaded; 850 #endif 851 OMX_BOOL bIsInvalidState; 852 void* PtrCollector[6]; 853 /* Removing sleep() calls. Definition. */ 854 OMX_BOOL bLoadedCommandPending; 855 OMX_PARAM_COMPONENTROLETYPE componentRole; 856 /** Count of number of buffers outstanding with bridge */ 857 OMX_U32 lcml_nIpBuf; 858 /** Count of number of buffers outstanding with bridge */ 859 OMX_U32 lcml_nOpBuf; 860 OMX_U32 app_nBuf; 861 OMX_U32 num_Reclaimed_Op_Buff; 862 863 PV_OMXComponentCapabilityFlagsType iPVCapabilityFlags; 864 OMX_BOOL reconfigInputPort; 865 OMX_BOOL reconfigOutputPort; 866 OMX_BOOL bConfigData; 867 868 OMX_AUDIO_PARAM_WMATYPE *wma_ip; 869 870 OMX_AUDIO_PARAM_PCMMODETYPE *wma_op; 871 872 OMX_U8 first_buffer; 873 874 RCA_HEADER *rcaheader; 875 876 struct OMX_TI_Debug dbg; 877 878 OMX_BUFFERHEADERTYPE *lastout; 879 880 } WMADEC_COMPONENT_PRIVATE; 881 /* =========================================================== */ 882 /** 883 * OMX_ComponentInit() Initializes component 884 * 885 * 886 * @param hComp OMX Handle 887 * 888 * @return OMX_ErrorNone = Successful 889 * Other error code = fail 890 * 891 */ 892 /*================================================================== */ 893 894 OMX_ERRORTYPE OMX_ComponentInit (OMX_HANDLETYPE hComp); 895 896 /* =========================================================== */ 897 /** 898 * WMADEC_StartComponentThread() Starts component thread 899 * 900 * 901 * @param hComp OMX Handle 902 * 903 * @return OMX_ErrorNone = Successful 904 * Other error code = fail 905 * 906 */ 907 /*================================================================== */ 908 OMX_ERRORTYPE WMADEC_StartComponentThread(OMX_HANDLETYPE pHandle); 909 910 /* =========================================================== */ 911 /** 912 * WMADEC_StopComponentThread() Stops component thread 913 * 914 * 915 * @param hComp OMX Handle 916 * 917 * @return OMX_ErrorNone = Successful 918 * Other error code = fail 919 * 920 */ 921 /*================================================================== */ 922 OMX_ERRORTYPE WMADEC_StopComponentThread(OMX_HANDLETYPE pHandle); 923 924 /* =========================================================== */ 925 /** 926 * WMADEC_FreeCompResources() Frees allocated memory 927 * 928 * 929 * @param hComp OMX Handle 930 * 931 * @return OMX_ErrorNone = Successful 932 * Other error code = fail 933 * 934 */ 935 /*================================================================== */ 936 OMX_ERRORTYPE WMADEC_FreeCompResources(OMX_HANDLETYPE pComponent); 937 938 /* =========================================================== */ 939 /** 940 * WMADEC_GetCorresponding_LCMLHeader() Returns LCML header 941 * that corresponds to the given buffer 942 * 943 * @param pComponentPrivate Component private data 944 * 945 * @return OMX_ErrorNone = Successful 946 * Other error code = fail 947 */ 948 /*================================================================== */ 949 OMX_ERRORTYPE WMADECGetCorresponding_LCMLHeader(WMADEC_COMPONENT_PRIVATE *pComponentPrivate, 950 OMX_U8 *pBuffer, 951 OMX_DIRTYPE eDir, 952 LCML_WMADEC_BUFHEADERTYPE **ppLcmlHdr); 953 954 /* =========================================================== */ 955 /** 956 * WMADEC_LCML_Callback() Callback from LCML 957 * 958 * @param event Codec Event 959 * 960 * @param args Arguments from LCML 961 * 962 * @return OMX_ErrorNone = Successful 963 * Other error code = fail 964 */ 965 /*================================================================== */ 966 OMX_ERRORTYPE WMADECLCML_Callback (TUsnCodecEvent event,void * args [10]); 967 968 /* =========================================================== */ 969 /** 970 * WMADEC_Fill_LCMLInitParams() Fills the parameters needed 971 * to initialize the LCML 972 * 973 * @param pHandle OMX Handle 974 * 975 * @param plcml_Init LCML initialization parameters 976 * 977 * @return OMX_ErrorNone = Successful 978 * Other error code = fail 979 * 980 */ 981 /*================================================================== */ 982 OMX_ERRORTYPE WMADECFill_LCMLInitParams(OMX_COMPONENTTYPE* pComponent, 983 LCML_DSP *plcml_Init, OMX_U16 arr[]); 984 985 986 /* =========================================================== */ 987 /** 988 * WMADEC_GetBufferDirection() Returns direction of pBufHeader 989 * 990 * @param pBufHeader Buffer header 991 * 992 * @param eDir Buffer direction 993 * 994 * @param pComponentPrivate Component private data 995 * 996 * @return OMX_ErrorNone = Successful 997 * Other error code = fail 998 */ 999 /*================================================================== */ 1000 OMX_ERRORTYPE WMADECGetBufferDirection(OMX_BUFFERHEADERTYPE *pBufHeader, OMX_DIRTYPE *eDir); 1001 1002 1003 /* =========================================================== */ 1004 /** 1005 * WMADECHandleCommand() Handles commands sent via SendCommand() 1006 * 1007 * @param pComponentPrivate Component private data 1008 * 1009 * @return OMX_ErrorNone = Successful 1010 * Other error code = fail 1011 * @return OMX_ErrorNone = Successful 1012 * Other error code = fail 1013 */ 1014 /*================================================================== */ 1015 OMX_U32 WMADECHandleCommand (WMADEC_COMPONENT_PRIVATE *pComponentPrivate); 1016 1017 /* =========================================================== */ 1018 /** 1019 * WMADECFreeLCMLHandle() Frees the handle to the LCML 1020 * 1021 * @param pComponentPrivate Component private data 1022 * 1023 * @return OMX_ErrorNone = Successful 1024 * Other error code = fail 1025 * @return OMX_ErrorNone = Successful 1026 * Other error code = fail 1027 */ 1028 /*================================================================== */ 1029 OMX_ERRORTYPE WMADECFreeLCMLHandle(WMADEC_COMPONENT_PRIVATE *pComponentPrivate); 1030 1031 /* =========================================================== */ 1032 /** 1033 * WMADECHandleDataBuf_FromApp() Handles data buffers received 1034 * from the IL Client 1035 * 1036 * @param pComponentPrivate Component private data 1037 * 1038 * @return OMX_ErrorNone = Successful 1039 * Other error code = fail 1040 * @return OMX_ErrorNone = Successful 1041 * Other error code = fail 1042 */ 1043 /*================================================================== */ 1044 OMX_ERRORTYPE WMADECHandleDataBuf_FromApp(OMX_BUFFERHEADERTYPE *pBufHeader, 1045 WMADEC_COMPONENT_PRIVATE *pComponentPrivate); 1046 1047 1048 /* =========================================================== */ 1049 /** 1050 * WMADECHandleDataBuf_FromLCML() Handles data buffers received 1051 * from LCML 1052 * 1053 * @param pComponentPrivate Component private data 1054 * 1055 * @return OMX_ErrorNone = Successful 1056 * Other error code = fail 1057 * @return OMX_ErrorNone = Successful 1058 * Other error code = fail 1059 */ 1060 /*================================================================== */ 1061 OMX_ERRORTYPE WMADECHandleDataBuf_FromLCML(WMADEC_COMPONENT_PRIVATE* pComponentPrivate, 1062 LCML_WMADEC_BUFHEADERTYPE* msgBuffer); 1063 1064 1065 /* =========================================================== */ 1066 /** 1067 * WMADEC_FreeLCMLHandle() Frees the handle to the LCML 1068 * 1069 * 1070 * @return OMX_ErrorNone = Successful 1071 * Other error code = fail 1072 */ 1073 /*================================================================== */ 1074 OMX_HANDLETYPE WMADECGetLCMLHandle(WMADEC_COMPONENT_PRIVATE *pComponentPrivate); 1075 1076 /* =========================================================== */ 1077 /** 1078 * WMADEC_CleanupInitParams() Starts component thread 1079 * 1080 * @param pComponent OMX Handle 1081 * 1082 * @return OMX_ErrorNone = Successful 1083 * Other error code = fail 1084 */ 1085 /*================================================================== */ 1086 OMX_ERRORTYPE WMADEC_CleanupInitParams(OMX_HANDLETYPE pComponent); 1087 1088 /* =========================================================== */ 1089 /** 1090 * WMADEC_SetPending() Called when the component queues a buffer 1091 * to the LCML 1092 * 1093 * @param pComponentPrivate Component private data 1094 * 1095 * @param pBufHdr Buffer header 1096 * 1097 * @param eDir Direction of the buffer 1098 * 1099 * @return None 1100 */ 1101 /*================================================================== */ 1102 void WMADEC_SetPending(WMADEC_COMPONENT_PRIVATE *pComponentPrivate, 1103 OMX_BUFFERHEADERTYPE *pBufHdr, OMX_DIRTYPE eDir); 1104 1105 /* =========================================================== */ 1106 /** 1107 * WMADEC_ClearPending() Called when a buffer is returned 1108 * from the LCML 1109 * 1110 * @param pComponentPrivate Component private data 1111 * 1112 * @param pBufHdr Buffer header 1113 * 1114 * @param eDir Direction of the buffer 1115 * 1116 * @return None 1117 */ 1118 /*================================================================== */ 1119 void WMADEC_ClearPending(WMADEC_COMPONENT_PRIVATE *pComponentPrivate, 1120 OMX_BUFFERHEADERTYPE *pBufHdr, OMX_DIRTYPE eDir) ; 1121 1122 /* =========================================================== */ 1123 /** 1124 * WMADEC_CommandToIdle() Called when the component is commanded 1125 * to idle 1126 * 1127 * @param pComponentPrivate Component private data 1128 * 1129 * @return OMX_ErrorNone = Successful 1130 * Other error code = fail 1131 */ 1132 /*================================================================== */ 1133 OMX_ERRORTYPE WMADEC_CommandToIdle(WMADEC_COMPONENT_PRIVATE *pComponentPrivate); 1134 1135 /* =========================================================== */ 1136 /** 1137 * WMADEC_CommandToIdle() Called when the component is commanded 1138 * to idle 1139 * 1140 * @param pComponentPrivate Component private data 1141 * 1142 * @return OMX_ErrorNone = Successful 1143 * Other error code = fail 1144 */ 1145 /*================================================================== */ 1146 OMX_ERRORTYPE WMADEC_CommandToLoaded(WMADEC_COMPONENT_PRIVATE *pComponentPrivate); 1147 1148 /* =========================================================== */ 1149 /** 1150 * WMADEC_CommandToExecuting() Called when the component is commanded 1151 * to executing 1152 * 1153 * @param pComponentPrivate Component private data 1154 * 1155 * @return OMX_ErrorNone = Successful 1156 * Other error code = fail 1157 */ 1158 /*================================================================== */ 1159 OMX_ERRORTYPE WMADEC_CommandToExecuting(WMADEC_COMPONENT_PRIVATE *pComponentPrivate); 1160 1161 /* =========================================================== */ 1162 /** 1163 * WMADEC_CommandToPause() Called when the component is commanded 1164 * to paused 1165 * 1166 * @param pComponentPrivate Component private data 1167 * 1168 * @return OMX_ErrorNone = Successful 1169 * Other error code = fail 1170 */ 1171 /*================================================================== */ 1172 OMX_ERRORTYPE WMADEC_CommandToPause(WMADEC_COMPONENT_PRIVATE *pComponentPrivate); 1173 1174 /* =========================================================== */ 1175 /** 1176 * WMADEC_CommandToWaitForResources() Called when the component is commanded 1177 * to WaitForResources 1178 * 1179 * @param pComponentPrivate Component private data 1180 * 1181 * @return OMX_ErrorNone = Successful 1182 * Other error code = fail 1183 */ 1184 /*================================================================== */ 1185 OMX_ERRORTYPE WMADEC_CommandToWaitForResources(WMADEC_COMPONENT_PRIVATE *pComponentPrivate); 1186 1187 /* =========================================================== */ 1188 /** 1189 * WMADEC_IsPending() 1190 * 1191 * 1192 * @param pComponentPrivate Component private data 1193 * 1194 * @return OMX_ErrorNone = Successful 1195 * Other error code = fail 1196 */ 1197 /*================================================================== */ 1198 OMX_U32 WMADEC_IsPending(WMADEC_COMPONENT_PRIVATE *pComponentPrivate, OMX_BUFFERHEADERTYPE *pBufHdr, OMX_DIRTYPE eDir); 1199 1200 /* =========================================================== */ 1201 /** 1202 * WMADEC_Fill_LCMLInitParamsEx() Fills the parameters needed 1203 * to initialize the LCML without recreating the socket node 1204 * 1205 * @param pComponent OMX Handle 1206 * 1207 * @return None 1208 */ 1209 1210 /*================================================================== */ 1211 OMX_ERRORTYPE WMADECFill_LCMLInitParamsEx(OMX_HANDLETYPE pComponent,OMX_U32 indexport); 1212 1213 /* =========================================================== */ 1214 /** 1215 * WMADEC_IsValid() Returns whether a buffer is valid 1216 * 1217 * 1218 * @param pComponentPrivate Component private data 1219 * 1220 * @param pBuffer Data buffer 1221 * 1222 * @param eDir Buffer direction 1223 * 1224 * @return OMX_True = Valid 1225 * OMX_False= Invalid 1226 */ 1227 /*================================================================== */ 1228 OMX_U32 WMADEC_IsValid(WMADEC_COMPONENT_PRIVATE *pComponentPrivate, 1229 OMX_U8 *pBuffer, OMX_DIRTYPE eDir) ; 1230 /* =========================================================== */ 1231 /** 1232 * WMADEC_TransitionToIdle() Transitions component to idle 1233 * 1234 * 1235 * @param pComponentPrivate Component private data 1236 * 1237 * @return OMX_ErrorNone = No error 1238 * OMX Error code = Error 1239 */ 1240 /*================================================================== */ 1241 OMX_ERRORTYPE WMADEC_TransitionToIdle(WMADEC_COMPONENT_PRIVATE *pComponentPrivate); 1242 /* =========================================================== */ 1243 /** 1244 * WMADEC_ComponentThread() Component thread 1245 * 1246 * @param pThreadData Thread data 1247 * 1248 * @cbData CallBack for ResourceManagerProxy 1249 * @return None 1250 * 1251 */ 1252 /*================================================================== */ 1253 void* WMADEC_ComponentThread (void* pThreadData); 1254 1255 1256 /* ======================================================================= */ 1257 /** OMX_WMADEC_INDEXAUDIOTYPE Defines the custom configuration settings 1258 * for the component 1259 *pHeaderInfo 1260 * @param OMX_IndexCustomWMADECModeDasfConfig Sets the DASF mode 1261 * 1262 * 1263 */ 1264 /* ==================================================================== */ 1265 typedef enum OMX_WMADEC_INDEXAUDIOTYPE { 1266 OMX_IndexCustomWMADECModeDasfConfig = 0xFF000001, 1267 OMX_IndexCustomWMADECHeaderInfoConfig, 1268 OMX_IndexCustomWmaDecLowLatencyConfig, 1269 OMX_IndexCustomWmaDecStreamIDConfig, 1270 OMX_IndexCustomWmaDecDataPath, 1271 OMX_IndexCustomDebug 1272 }OMX_WMADEC_INDEXAUDIOTYPE; 1273 1274 1275 /* =========================================================================*/ 1276 /* func GetBits */ 1277 /* */ 1278 /* desc Gets aBits number of bits from position aPosition of one buffer */ 1279 /* and returns the value in a TUint value. */ 1280 /* =========================================================================*/ 1281 OMX_U32 WMADEC_GetBits(OMX_U32* nPosition, OMX_U8 nBits, OMX_U8* pBuffer, OMX_BOOL bIcreasePosition); 1282 1283 /* =========================================================================*/ 1284 /* func WMADEC_Parser */ 1285 /* */ 1286 /* desc Gets the info from the Buffer to build a RCA header */ 1287 /* and returns the RCA Header filled with the data. */ 1288 /*@return OMX_ErrorNone = No error */ 1289 /* OMX Error code = Error */ 1290 /* =========================================================================*/ 1291 OMX_ERRORTYPE WMADEC_Parser(OMX_U8* pBuffer, RCA_HEADER *pStreamData, struct OMX_TI_Debug dbg); 1292 1293 /* =========================================================================*/ 1294 /* func WMADEC_HandleUSNError */ 1295 /* */ 1296 /* desc Handles error messages returned by the dsp */ 1297 /* */ 1298 /*@return n/a */ 1299 /* */ 1300 /* =========================================================================*/ 1301 void WMADEC_HandleUSNError (WMADEC_COMPONENT_PRIVATE *pComponentPrivate, OMX_U32 arg); 1302 1303 #ifdef RESOURCE_MANAGER_ENABLED 1304 void WMAD_ResourceManagerCallback(RMPROXY_COMMANDDATATYPE cbData); 1305 #endif 1306 1307 #endif 1308 1309