summaryrefslogtreecommitdiff
path: root/libavcodec/alpha/mpegvideo_alpha.c
diff options
context:
space:
mode:
authorNick Kurshev <nickols_k@mail.ru>2002-01-20 14:48:02 +0000
committerNick Kurshev <nickols_k@mail.ru>2002-01-20 14:48:02 +0000
commit1e98dffb7aa4b4681ecc7949e7ad58acc80ad86a (patch)
treeeda5315707572d48e2f75e55cd210254068fea18 /libavcodec/alpha/mpegvideo_alpha.c
parent4bdd9157cc0b06c7001cb93e5cdd6304306253c4 (diff)
Alpha optimizations by Falk Hueffner <falk.hueffner@student.uni-tuebingen.de>
Originally committed as revision 274 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/alpha/mpegvideo_alpha.c')
-rw-r--r--libavcodec/alpha/mpegvideo_alpha.c88
1 files changed, 88 insertions, 0 deletions
diff --git a/libavcodec/alpha/mpegvideo_alpha.c b/libavcodec/alpha/mpegvideo_alpha.c
new file mode 100644
index 0000000000..db4fd3a9db
--- /dev/null
+++ b/libavcodec/alpha/mpegvideo_alpha.c
@@ -0,0 +1,88 @@
+/*
+ * Alpha optimized DSP utils
+ * Copyright (c) 2002 Falk Hueffner <falk@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "asm.h"
+#include "../dsputil.h"
+#include "../mpegvideo.h"
+
+extern UINT8 zigzag_end[64];
+
+static void dct_unquantize_h263_axp(MpegEncContext *s,
+ DCTELEM *block, int n, int qscale)
+{
+ int i, level;
+ UINT64 qmul, qadd;
+ if (s->mb_intra) {
+ if (n < 4)
+ block[0] = block[0] * s->y_dc_scale;
+ else
+ block[0] = block[0] * s->c_dc_scale;
+ /* Catch up to aligned point. */
+ qmul = s->qscale << 1;
+ qadd = (s->qscale - 1) | 1;
+ for (i = 1; i < 4; ++i) {
+ level = block[i];
+ if (level) {
+ if (level < 0) {
+ level = level * qmul - qadd;
+ } else {
+ level = level * qmul + qadd;
+ }
+ block[i] = level;
+ }
+ }
+ block += 4;
+ i = 60 / 4;
+ } else {
+ i = zigzag_end[s->block_last_index[n]] / 4;
+ }
+ qmul = s->qscale << 1;
+ qadd = WORD_VEC((qscale - 1) | 1);
+ do {
+ UINT64 levels, negmask, zeromask, corr;
+ levels = ldq(block);
+ if (levels == 0)
+ continue;
+ zeromask = cmpbge(0, levels);
+ zeromask &= zeromask >> 1;
+ /* Negate all negative words. */
+ negmask = maxsw4(levels, WORD_VEC(0xffff)); /* negative -> ffff (-1) */
+ negmask = minsw4(negmask, 0); /* positive -> 0000 (0) */
+ corr = negmask & WORD_VEC(0x0001); /* twos-complement correction */
+ levels ^= negmask;
+ levels += corr;
+
+ levels = levels * qmul;
+ levels += zap(qadd, zeromask);
+
+ /* Re-negate negative words. */
+ levels -= corr;
+ levels ^= negmask;
+
+ stq(levels, block);
+ } while (block += 4, --i);
+}
+
+void MPV_common_init_axp(MpegEncContext *s)
+{
+ if (amask(AMASK_MVI) == 0) {
+ if (s->out_format == FMT_H263)
+ s->dct_unquantize = dct_unquantize_h263_axp;
+ }
+}