You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.4KB

  1. /*
  2. * Alpha optimized DSP utils
  3. * Copyright (c) 2002 Falk Hueffner <falk@debian.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include "asm.h"
  20. #include "../dsputil.h"
  21. #include "../mpegvideo.h"
  22. extern UINT8 zigzag_end[64];
  23. static void dct_unquantize_h263_axp(MpegEncContext *s,
  24. DCTELEM *block, int n, int qscale)
  25. {
  26. int i, level;
  27. UINT64 qmul, qadd;
  28. if (s->mb_intra) {
  29. if (n < 4)
  30. block[0] = block[0] * s->y_dc_scale;
  31. else
  32. block[0] = block[0] * s->c_dc_scale;
  33. /* Catch up to aligned point. */
  34. qmul = s->qscale << 1;
  35. qadd = (s->qscale - 1) | 1;
  36. for (i = 1; i < 4; ++i) {
  37. level = block[i];
  38. if (level) {
  39. if (level < 0) {
  40. level = level * qmul - qadd;
  41. } else {
  42. level = level * qmul + qadd;
  43. }
  44. block[i] = level;
  45. }
  46. }
  47. block += 4;
  48. i = 60 / 4;
  49. } else {
  50. i = zigzag_end[s->block_last_index[n]] / 4;
  51. }
  52. qmul = s->qscale << 1;
  53. qadd = WORD_VEC((qscale - 1) | 1);
  54. do {
  55. UINT64 levels, negmask, zeromask, corr;
  56. levels = ldq(block);
  57. if (levels == 0)
  58. continue;
  59. zeromask = cmpbge(0, levels);
  60. zeromask &= zeromask >> 1;
  61. /* Negate all negative words. */
  62. negmask = maxsw4(levels, WORD_VEC(0xffff)); /* negative -> ffff (-1) */
  63. negmask = minsw4(negmask, 0); /* positive -> 0000 (0) */
  64. corr = negmask & WORD_VEC(0x0001); /* twos-complement correction */
  65. levels ^= negmask;
  66. levels += corr;
  67. levels = levels * qmul;
  68. levels += zap(qadd, zeromask);
  69. /* Re-negate negative words. */
  70. levels -= corr;
  71. levels ^= negmask;
  72. stq(levels, block);
  73. } while (block += 4, --i);
  74. }
  75. void MPV_common_init_axp(MpegEncContext *s)
  76. {
  77. if (amask(AMASK_MVI) == 0) {
  78. if (s->out_format == FMT_H263)
  79. s->dct_unquantize = dct_unquantize_h263_axp;
  80. }
  81. }