Statistics
| Branch: | Revision:

ffmpeg / libavcodec / alpha / mpegvideo_alpha.c @ 1e98dffb

History | View | Annotate | Download (2.39 KB)

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

    
20
#include "asm.h"
21
#include "../dsputil.h"
22
#include "../mpegvideo.h"
23

    
24
extern UINT8 zigzag_end[64];
25

    
26
static void dct_unquantize_h263_axp(MpegEncContext *s, 
27
                                    DCTELEM *block, int n, int qscale)
28
{
29
    int i, level;
30
    UINT64 qmul, qadd;
31
    if (s->mb_intra) {
32
        if (n < 4) 
33
            block[0] = block[0] * s->y_dc_scale;
34
        else
35
            block[0] = block[0] * s->c_dc_scale;
36
        /* Catch up to aligned point.  */
37
        qmul = s->qscale << 1;
38
        qadd = (s->qscale - 1) | 1;
39
        for (i = 1; i < 4; ++i) {
40
            level = block[i];
41
            if (level) {
42
                if (level < 0) {
43
                    level = level * qmul - qadd;
44
                } else {
45
                    level = level * qmul + qadd;
46
                }
47
                block[i] = level;
48
            }
49
        }
50
        block += 4;
51
        i = 60 / 4;
52
    } else {
53
        i = zigzag_end[s->block_last_index[n]] / 4;
54
    }
55
    qmul = s->qscale << 1;
56
    qadd = WORD_VEC((qscale - 1) | 1);
57
    do {
58
        UINT64 levels, negmask, zeromask, corr;
59
        levels = ldq(block);
60
        if (levels == 0)
61
            continue;
62
        zeromask = cmpbge(0, levels);
63
        zeromask &= zeromask >> 1;
64
        /* Negate all negative words.  */
65
        negmask = maxsw4(levels, WORD_VEC(0xffff)); /* negative -> ffff (-1) */
66
        negmask = minsw4(negmask, 0);                    /* positive -> 0000 (0) */
67
        corr    = negmask & WORD_VEC(0x0001); /* twos-complement correction */
68
        levels ^= negmask;
69
        levels += corr;
70

    
71
        levels = levels * qmul;
72
        levels += zap(qadd, zeromask);
73

    
74
        /* Re-negate negative words.  */
75
        levels -= corr;
76
        levels ^= negmask;
77

    
78
        stq(levels, block);
79
    } while (block += 4, --i);
80
}
81

    
82
void MPV_common_init_axp(MpegEncContext *s)
83
{
84
    if (amask(AMASK_MVI) == 0) {
85
        if (s->out_format == FMT_H263)
86
            s->dct_unquantize = dct_unquantize_h263_axp;
87
    }
88
}