PageRenderTime 52ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/src/armCOMM.c

https://bitbucket.org/sola/android_frameworks_base
C | 936 lines | 426 code | 115 blank | 395 comment | 45 complexity | 79aa23d9817efd11d0c4c2be36ec1e5c MD5 | raw file
Possible License(s): CC0-1.0
  1. /**
  2. *
  3. * File Name: armCOMM.c
  4. * OpenMAX DL: v1.0.2
  5. * Revision: 9641
  6. * Date: Thursday, February 7, 2008
  7. *
  8. * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
  9. *
  10. *
  11. *
  12. * Defines Common APIs used across OpenMAX API's
  13. */
  14. #include "omxtypes.h"
  15. #include "armCOMM.h"
  16. /***********************************************************************/
  17. /* Miscellaneous Arithmetic operations */
  18. /**
  19. * Function: armRoundFloatToS16
  20. *
  21. * Description:
  22. * Converts a double precision value into a short int after rounding
  23. *
  24. * Parameters:
  25. * [in] Value Float value to be converted
  26. *
  27. * Return Value:
  28. * [out] converted value in OMX_S16 format
  29. *
  30. */
  31. OMX_S16 armRoundFloatToS16 (OMX_F64 Value)
  32. {
  33. if (Value > 0)
  34. {
  35. return (OMX_S16)(Value + .5);
  36. }
  37. else
  38. {
  39. return (OMX_S16)(Value - .5);
  40. }
  41. }
  42. /**
  43. * Function: armRoundFloatToS32
  44. *
  45. * Description:
  46. * Converts a double precision value into a int after rounding
  47. *
  48. * Parameters:
  49. * [in] Value Float value to be converted
  50. *
  51. * Return Value:
  52. * [out] converted value in OMX_S32 format
  53. *
  54. */
  55. OMX_S32 armRoundFloatToS32 (OMX_F64 Value)
  56. {
  57. if (Value > 0)
  58. {
  59. return (OMX_S32)(Value + .5);
  60. }
  61. else
  62. {
  63. return (OMX_S32)(Value - .5);
  64. }
  65. }
  66. /**
  67. * Function: armSatRoundFloatToS16
  68. *
  69. * Description:
  70. * Converts a double precision value into a short int after rounding and saturation
  71. *
  72. * Parameters:
  73. * [in] Value Float value to be converted
  74. *
  75. * Return Value:
  76. * [out] converted value in OMX_S16 format
  77. *
  78. */
  79. OMX_S16 armSatRoundFloatToS16 (OMX_F64 Value)
  80. {
  81. if (Value > 0)
  82. {
  83. Value += 0.5;
  84. if(Value > (OMX_S16)OMX_MAX_S16 )
  85. {
  86. return (OMX_S16)OMX_MAX_S16;
  87. }
  88. else
  89. {
  90. return (OMX_S16)Value;
  91. }
  92. }
  93. else
  94. {
  95. Value -= 0.5;
  96. if(Value < (OMX_S16)OMX_MIN_S16 )
  97. {
  98. return (OMX_S16)OMX_MIN_S16;
  99. }
  100. else
  101. {
  102. return (OMX_S16)Value;
  103. }
  104. }
  105. }
  106. /**
  107. * Function: armSatRoundFloatToS32
  108. *
  109. * Description:
  110. * Converts a double precision value into a int after rounding and saturation
  111. *
  112. * Parameters:
  113. * [in] Value Float value to be converted
  114. *
  115. * Return Value:
  116. * [out] converted value in OMX_S32 format
  117. *
  118. */
  119. OMX_S32 armSatRoundFloatToS32 (OMX_F64 Value)
  120. {
  121. if (Value > 0)
  122. {
  123. Value += 0.5;
  124. if(Value > (OMX_S32)OMX_MAX_S32 )
  125. {
  126. return (OMX_S32)OMX_MAX_S32;
  127. }
  128. else
  129. {
  130. return (OMX_S32)Value;
  131. }
  132. }
  133. else
  134. {
  135. Value -= 0.5;
  136. if(Value < (OMX_S32)OMX_MIN_S32 )
  137. {
  138. return (OMX_S32)OMX_MIN_S32;
  139. }
  140. else
  141. {
  142. return (OMX_S32)Value;
  143. }
  144. }
  145. }
  146. /**
  147. * Function: armSatRoundFloatToU16
  148. *
  149. * Description:
  150. * Converts a double precision value into a unsigned short int after rounding and saturation
  151. *
  152. * Parameters:
  153. * [in] Value Float value to be converted
  154. *
  155. * Return Value:
  156. * [out] converted value in OMX_U16 format
  157. *
  158. */
  159. OMX_U16 armSatRoundFloatToU16 (OMX_F64 Value)
  160. {
  161. Value += 0.5;
  162. if(Value > (OMX_U16)OMX_MAX_U16 )
  163. {
  164. return (OMX_U16)OMX_MAX_U16;
  165. }
  166. else
  167. {
  168. return (OMX_U16)Value;
  169. }
  170. }
  171. /**
  172. * Function: armSatRoundFloatToU32
  173. *
  174. * Description:
  175. * Converts a double precision value into a unsigned int after rounding and saturation
  176. *
  177. * Parameters:
  178. * [in] Value Float value to be converted
  179. *
  180. * Return Value:
  181. * [out] converted value in OMX_U32 format
  182. *
  183. */
  184. OMX_U32 armSatRoundFloatToU32 (OMX_F64 Value)
  185. {
  186. Value += 0.5;
  187. if(Value > (OMX_U32)OMX_MAX_U32 )
  188. {
  189. return (OMX_U32)OMX_MAX_U32;
  190. }
  191. else
  192. {
  193. return (OMX_U32)Value;
  194. }
  195. }
  196. /**
  197. * Function: armRoundFloatToS64
  198. *
  199. * Description:
  200. * Converts a double precision value into a 64 bit int after rounding
  201. *
  202. * Parameters:
  203. * [in] Value Float value to be converted
  204. *
  205. * Return Value:
  206. * [out] converted value in OMX_S64 format
  207. *
  208. */
  209. OMX_S64 armRoundFloatToS64 (OMX_F64 Value)
  210. {
  211. if (Value > 0)
  212. {
  213. return (OMX_S64)(Value + .5);
  214. }
  215. else
  216. {
  217. return (OMX_S64)(Value - .5);
  218. }
  219. }
  220. /**
  221. * Function: armSignCheck
  222. *
  223. * Description:
  224. * Checks the sign of a variable:
  225. * returns 1 if it is Positive
  226. * returns 0 if it is 0
  227. * returns -1 if it is Negative
  228. *
  229. * Remarks:
  230. *
  231. * Parameters:
  232. * [in] var Variable to be checked
  233. *
  234. * Return Value:
  235. * OMX_INT -- returns 1 if it is Positive
  236. * returns 0 if it is 0
  237. * returns -1 if it is Negative
  238. */
  239. OMX_INT armSignCheck (
  240. OMX_S16 var
  241. )
  242. {
  243. OMX_INT Sign;
  244. if (var < 0)
  245. {
  246. Sign = -1;
  247. }
  248. else if ( var > 0)
  249. {
  250. Sign = 1;
  251. }
  252. else
  253. {
  254. Sign = 0;
  255. }
  256. return Sign;
  257. }
  258. /**
  259. * Function: armClip
  260. *
  261. * Description: Clips the input between MAX and MIN value
  262. *
  263. *
  264. * Remarks:
  265. *
  266. * Parameters:
  267. * [in] Min lower bound
  268. * [in] Max upper bound
  269. * [in] src variable to the clipped
  270. *
  271. * Return Value:
  272. * OMX_S32 -- returns clipped value
  273. */
  274. OMX_S32 armClip (
  275. OMX_INT min,
  276. OMX_INT max,
  277. OMX_S32 src
  278. )
  279. {
  280. if (src > max)
  281. {
  282. src = max;
  283. }
  284. else if (src < min)
  285. {
  286. src = min;
  287. }
  288. return src;
  289. }
  290. /**
  291. * Function: armClip_F32
  292. *
  293. * Description: Clips the input between MAX and MIN value
  294. *
  295. *
  296. * Remarks:
  297. *
  298. * Parameters:
  299. * [in] Min lower bound
  300. * [in] Max upper bound
  301. * [in] src variable to the clipped
  302. *
  303. * Return Value:
  304. * OMX_F32 -- returns clipped value
  305. */
  306. OMX_F32 armClip_F32 (
  307. OMX_F32 min,
  308. OMX_F32 max,
  309. OMX_F32 src
  310. )
  311. {
  312. if (src > max)
  313. {
  314. src = max;
  315. }
  316. else if (src < min)
  317. {
  318. src = min;
  319. }
  320. return src;
  321. }
  322. /**
  323. * Function: armShiftSat_F32
  324. *
  325. * Description: Divides a float value by 2^shift and
  326. * saturates it for unsigned value range for satBits.
  327. * Second parameter is like "shifting" the corresponding
  328. * integer value. Takes care of rounding while clipping the final
  329. * value.
  330. *
  331. * Parameters:
  332. * [in] v Number to be operated upon
  333. * [in] shift Divides the input "v" by "2^shift"
  334. * [in] satBits Final range is [0, 2^satBits)
  335. *
  336. * Return Value:
  337. * OMX_S32 -- returns "shifted" saturated value
  338. */
  339. OMX_U32 armShiftSat_F32(OMX_F32 v, OMX_INT shift, OMX_INT satBits)
  340. {
  341. OMX_U32 allOnes = (OMX_U32)(-1);
  342. OMX_U32 maxV = allOnes >> (32-satBits);
  343. OMX_F32 vShifted, vRounded, shiftDiv = (OMX_F32)(1 << shift);
  344. OMX_U32 vInt;
  345. OMX_U32 vIntSat;
  346. if(v <= 0)
  347. return 0;
  348. vShifted = v / shiftDiv;
  349. vRounded = (OMX_F32)(vShifted + 0.5);
  350. vInt = (OMX_U32)vRounded;
  351. vIntSat = vInt;
  352. if(vIntSat > maxV)
  353. vIntSat = maxV;
  354. return vIntSat;
  355. }
  356. /**
  357. * Functions: armSwapElem
  358. *
  359. * Description:
  360. * These function swaps two elements at the specified pointer locations.
  361. * The size of each element could be anything as specified by <elemSize>
  362. *
  363. * Return Value:
  364. * OMXResult -- Error status from the function
  365. */
  366. OMXResult armSwapElem(
  367. OMX_U8 *pBuf1,
  368. OMX_U8 *pBuf2,
  369. OMX_INT elemSize
  370. )
  371. {
  372. OMX_INT i;
  373. OMX_U8 temp;
  374. armRetArgErrIf(!pBuf1 || !pBuf2, OMX_Sts_BadArgErr);
  375. for(i = 0; i < elemSize; i++)
  376. {
  377. temp = *(pBuf1 + i);
  378. *(pBuf1 + i) = *(pBuf2 + i);
  379. *(pBuf2 + i) = temp;
  380. }
  381. return OMX_Sts_NoErr;
  382. }
  383. /**
  384. * Function: armMedianOf3
  385. *
  386. * Description: Finds the median of three numbers
  387. *
  388. * Remarks:
  389. *
  390. * Parameters:
  391. * [in] fEntry First entry
  392. * [in] sEntry second entry
  393. * [in] tEntry Third entry
  394. *
  395. * Return Value:
  396. * OMX_S32 -- returns the median value
  397. */
  398. OMX_S32 armMedianOf3 (
  399. OMX_S32 fEntry,
  400. OMX_S32 sEntry,
  401. OMX_S32 tEntry
  402. )
  403. {
  404. OMX_S32 a, b, c;
  405. a = armMin (fEntry, sEntry);
  406. b = armMax (fEntry, sEntry);
  407. c = armMin (b, tEntry);
  408. return (armMax (a, c));
  409. }
  410. /**
  411. * Function: armLogSize
  412. *
  413. * Description: Finds the size of a positive value and returns the same
  414. *
  415. * Remarks:
  416. *
  417. * Parameters:
  418. * [in] value Positive value
  419. *
  420. * Return Value:
  421. * OMX_U8 -- Returns the minimum number of bits required to represent the positive value.
  422. This is the smallest k>=0 such that that value is less than (1<<k).
  423. */
  424. OMX_U8 armLogSize (
  425. OMX_U16 value
  426. )
  427. {
  428. OMX_U8 i;
  429. for ( i = 0; value > 0; value = value >> 1)
  430. {
  431. i++;
  432. }
  433. return i;
  434. }
  435. /***********************************************************************/
  436. /* Saturating Arithmetic operations */
  437. /**
  438. * Function :armSatAdd_S32()
  439. *
  440. * Description :
  441. * Returns the result of saturated addition of the two inputs Value1, Value2
  442. *
  443. * Parametrs:
  444. * [in] Value1 First Operand
  445. * [in] Value2 Second Operand
  446. *
  447. * Return:
  448. * [out] Result of operation
  449. *
  450. *
  451. **/
  452. OMX_S32 armSatAdd_S32(OMX_S32 Value1,OMX_S32 Value2)
  453. {
  454. OMX_S32 Result;
  455. Result = Value1 + Value2;
  456. if( (Value1^Value2) >= 0)
  457. {
  458. /*Same sign*/
  459. if( (Result^Value1) >= 0)
  460. {
  461. /*Result has not saturated*/
  462. return Result;
  463. }
  464. else
  465. {
  466. if(Value1 >= 0)
  467. {
  468. /*Result has saturated in positive side*/
  469. return OMX_MAX_S32;
  470. }
  471. else
  472. {
  473. /*Result has saturated in negative side*/
  474. return OMX_MIN_S32;
  475. }
  476. }
  477. }
  478. else
  479. {
  480. return Result;
  481. }
  482. }
  483. /**
  484. * Function :armSatAdd_S64()
  485. *
  486. * Description :
  487. * Returns the result of saturated addition of the two inputs Value1, Value2
  488. *
  489. * Parametrs:
  490. * [in] Value1 First Operand
  491. * [in] Value2 Second Operand
  492. *
  493. * Return:
  494. * [out] Result of operation
  495. *
  496. *
  497. **/
  498. OMX_S64 armSatAdd_S64(OMX_S64 Value1,OMX_S64 Value2)
  499. {
  500. OMX_S64 Result;
  501. Result = Value1 + Value2;
  502. if( (Value1^Value2) >= 0)
  503. {
  504. /*Same sign*/
  505. if( (Result^Value1) >= 0)
  506. {
  507. /*Result has not saturated*/
  508. return Result;
  509. }
  510. else
  511. {
  512. if(Value1 >= 0)
  513. {
  514. /*Result has saturated in positive side*/
  515. Result = OMX_MAX_S64;
  516. return Result;
  517. }
  518. else
  519. {
  520. /*Result has saturated in negative side*/
  521. return OMX_MIN_S64;
  522. }
  523. }
  524. }
  525. else
  526. {
  527. return Result;
  528. }
  529. }
  530. /** Function :armSatSub_S32()
  531. *
  532. * Description :
  533. * Returns the result of saturated substraction of the two inputs Value1, Value2
  534. *
  535. * Parametrs:
  536. * [in] Value1 First Operand
  537. * [in] Value2 Second Operand
  538. *
  539. * Return:
  540. * [out] Result of operation
  541. *
  542. **/
  543. OMX_S32 armSatSub_S32(OMX_S32 Value1,OMX_S32 Value2)
  544. {
  545. OMX_S32 Result;
  546. Result = Value1 - Value2;
  547. if( (Value1^Value2) < 0)
  548. {
  549. /*Opposite sign*/
  550. if( (Result^Value1) >= 0)
  551. {
  552. /*Result has not saturated*/
  553. return Result;
  554. }
  555. else
  556. {
  557. if(Value1 >= 0)
  558. {
  559. /*Result has saturated in positive side*/
  560. return OMX_MAX_S32;
  561. }
  562. else
  563. {
  564. /*Result has saturated in negative side*/
  565. return OMX_MIN_S32;
  566. }
  567. }
  568. }
  569. else
  570. {
  571. return Result;
  572. }
  573. }
  574. /**
  575. * Function :armSatMac_S32()
  576. *
  577. * Description :
  578. * Returns the result of Multiplication of Value1 and Value2 and subesquent saturated
  579. * accumulation with Mac
  580. *
  581. * Parametrs:
  582. * [in] Value1 First Operand
  583. * [in] Value2 Second Operand
  584. * [in] Mac Accumulator
  585. *
  586. * Return:
  587. * [out] Result of operation
  588. **/
  589. OMX_S32 armSatMac_S32(OMX_S32 Mac,OMX_S16 Value1,OMX_S16 Value2)
  590. {
  591. OMX_S32 Result;
  592. Result = (OMX_S32)(Value1*Value2);
  593. Result = armSatAdd_S32( Mac , Result );
  594. return Result;
  595. }
  596. /**
  597. * Function :armSatMac_S16S32_S32
  598. *
  599. * Description :
  600. * Returns the result of saturated MAC operation of the three inputs delayElem, filTap , mac
  601. *
  602. * mac = mac + Saturate_in_32Bits(delayElem * filTap)
  603. *
  604. * Parametrs:
  605. * [in] delayElem First 32 bit Operand
  606. * [in] filTap Second 16 bit Operand
  607. * [in] mac Result of MAC operation
  608. *
  609. * Return:
  610. * [out] mac Result of operation
  611. *
  612. **/
  613. OMX_S32 armSatMac_S16S32_S32(OMX_S32 mac, OMX_S32 delayElem, OMX_S16 filTap )
  614. {
  615. OMX_S32 result;
  616. result = armSatMulS16S32_S32(filTap,delayElem);
  617. if ( result > OMX_MAX_S16 )
  618. {
  619. result = OMX_MAX_S32;
  620. }
  621. else if( result < OMX_MIN_S16 )
  622. {
  623. result = OMX_MIN_S32;
  624. }
  625. else
  626. {
  627. result = delayElem * filTap;
  628. }
  629. mac = armSatAdd_S32(mac,result);
  630. return mac;
  631. }
  632. /**
  633. * Function :armSatRoundRightShift_S32_S16
  634. *
  635. * Description :
  636. * Returns the result of rounded right shift operation of input by the scalefactor
  637. *
  638. * output = Saturate_in_16Bits( ( Right/LeftShift( (Round(input) , shift ) )
  639. *
  640. * Parametrs:
  641. * [in] input The input to be operated on
  642. * [in] shift The shift number
  643. *
  644. * Return:
  645. * [out] Result of operation
  646. *
  647. **/
  648. OMX_S16 armSatRoundRightShift_S32_S16(OMX_S32 input, OMX_INT shift)
  649. {
  650. input = armSatRoundLeftShift_S32(input,-shift);
  651. if ( input > OMX_MAX_S16 )
  652. {
  653. return (OMX_S16)OMX_MAX_S16;
  654. }
  655. else if (input < OMX_MIN_S16)
  656. {
  657. return (OMX_S16)OMX_MIN_S16;
  658. }
  659. else
  660. {
  661. return (OMX_S16)input;
  662. }
  663. }
  664. /**
  665. * Function :armSatRoundLeftShift_S32()
  666. *
  667. * Description :
  668. * Returns the result of saturating left-shift operation on input
  669. * Or rounded Right shift if the input Shift is negative.
  670. *
  671. * Parametrs:
  672. * [in] Value Operand
  673. * [in] Shift Operand for shift operation
  674. *
  675. * Return:
  676. * [out] Result of operation
  677. *
  678. **/
  679. OMX_S32 armSatRoundLeftShift_S32(OMX_S32 Value, OMX_INT Shift)
  680. {
  681. OMX_INT i;
  682. if (Shift < 0)
  683. {
  684. Shift = -Shift;
  685. Value = armSatAdd_S32(Value, (1 << (Shift - 1)));
  686. Value = Value >> Shift;
  687. }
  688. else
  689. {
  690. for (i = 0; i < Shift; i++)
  691. {
  692. Value = armSatAdd_S32(Value, Value);
  693. }
  694. }
  695. return Value;
  696. }
  697. /**
  698. * Function :armSatRoundLeftShift_S64()
  699. *
  700. * Description :
  701. * Returns the result of saturating left-shift operation on input
  702. * Or rounded Right shift if the input Shift is negative.
  703. *
  704. * Parametrs:
  705. * [in] Value Operand
  706. * [in] shift Operand for shift operation
  707. *
  708. * Return:
  709. * [out] Result of operation
  710. *
  711. **/
  712. OMX_S64 armSatRoundLeftShift_S64(OMX_S64 Value, OMX_INT Shift)
  713. {
  714. OMX_INT i;
  715. if (Shift < 0)
  716. {
  717. Shift = -Shift;
  718. Value = armSatAdd_S64(Value, ((OMX_S64)1 << (Shift - 1)));
  719. Value = Value >> Shift;
  720. }
  721. else
  722. {
  723. for (i = 0; i < Shift; i++)
  724. {
  725. Value = armSatAdd_S64(Value, Value);
  726. }
  727. }
  728. return Value;
  729. }
  730. /**
  731. * Function :armSatMulS16S32_S32()
  732. *
  733. * Description :
  734. * Returns the result of a S16 data type multiplied with an S32 data type
  735. * in a S32 container
  736. *
  737. * Parametrs:
  738. * [in] input1 Operand 1
  739. * [in] input2 Operand 2
  740. *
  741. * Return:
  742. * [out] Result of operation
  743. *
  744. **/
  745. OMX_S32 armSatMulS16S32_S32(OMX_S16 input1,OMX_S32 input2)
  746. {
  747. OMX_S16 hi2,lo1;
  748. OMX_U16 lo2;
  749. OMX_S32 temp1,temp2;
  750. OMX_S32 result;
  751. lo1 = input1;
  752. hi2 = ( input2 >> 16 );
  753. lo2 = ( (OMX_U32)( input2 << 16 ) >> 16 );
  754. temp1 = hi2 * lo1;
  755. temp2 = ( lo2* lo1 ) >> 16;
  756. result = armSatAdd_S32(temp1,temp2);
  757. return result;
  758. }
  759. /**
  760. * Function :armSatMulS32S32_S32()
  761. *
  762. * Description :
  763. * Returns the result of a S32 data type multiplied with an S32 data type
  764. * in a S32 container
  765. *
  766. * Parametrs:
  767. * [in] input1 Operand 1
  768. * [in] input2 Operand 2
  769. *
  770. * Return:
  771. * [out] Result of operation
  772. *
  773. **/
  774. OMX_S32 armSatMulS32S32_S32(OMX_S32 input1,OMX_S32 input2)
  775. {
  776. OMX_S16 hi1,hi2;
  777. OMX_U16 lo1,lo2;
  778. OMX_S32 temp1,temp2,temp3;
  779. OMX_S32 result;
  780. hi1 = ( input1 >> 16 );
  781. lo1 = ( (OMX_U32)( input1 << 16 ) >> 16 );
  782. hi2 = ( input2 >> 16 );
  783. lo2 = ( (OMX_U32)( input2 << 16 ) >> 16 );
  784. temp1 = hi1 * hi2;
  785. temp2 = ( hi1* lo2 ) >> 16;
  786. temp3 = ( hi2* lo1 ) >> 16;
  787. result = armSatAdd_S32(temp1,temp2);
  788. result = armSatAdd_S32(result,temp3);
  789. return result;
  790. }
  791. /**
  792. * Function :armIntDivAwayFromZero()
  793. *
  794. * Description : Integer division with rounding to the nearest integer.
  795. * Half-integer values are rounded away from zero
  796. * unless otherwise specified. For example 3//2 is rounded
  797. * to 2, and -3//2 is rounded to -2.
  798. *
  799. * Parametrs:
  800. * [in] Num Operand 1
  801. * [in] Deno Operand 2
  802. *
  803. * Return:
  804. * [out] Result of operation input1//input2
  805. *
  806. **/
  807. OMX_S32 armIntDivAwayFromZero (OMX_S32 Num, OMX_S32 Deno)
  808. {
  809. OMX_F64 result;
  810. result = ((OMX_F64)Num)/((OMX_F64)Deno);
  811. if (result >= 0)
  812. {
  813. result += 0.5;
  814. }
  815. else
  816. {
  817. result -= 0.5;
  818. }
  819. return (OMX_S32)(result);
  820. }
  821. /*End of File*/