diff options
author | Falk Hüffner <mellum@users.sourceforge.net> | 2002-07-03 07:01:06 +0400 |
---|---|---|
committer | Falk Hüffner <mellum@users.sourceforge.net> | 2002-07-03 07:01:06 +0400 |
commit | e0580f8c688f0dcb87f2bf71b08f477ba583e8dd (patch) | |
tree | 009a07b3b0233a93a398f212ba94e984a5712685 /libavcodec/alpha/mpegvideo_alpha.c | |
parent | dde3f77dbc30a6564ca8ad373b7517f282983bdb (diff) |
Update and activate dct_unquantize_h263_mvi. Thanks to Måns Rullgård
for some improvements.
Originally committed as revision 714 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/alpha/mpegvideo_alpha.c')
-rw-r--r-- | libavcodec/alpha/mpegvideo_alpha.c | 105 |
1 files changed, 53 insertions, 52 deletions
diff --git a/libavcodec/alpha/mpegvideo_alpha.c b/libavcodec/alpha/mpegvideo_alpha.c index eb1997eee7..443857e571 100644 --- a/libavcodec/alpha/mpegvideo_alpha.c +++ b/libavcodec/alpha/mpegvideo_alpha.c @@ -23,69 +23,70 @@ extern UINT8 zigzag_end[64]; -static void dct_unquantize_h263_axp(MpegEncContext *s, - DCTELEM *block, int n, int qscale) +static void dct_unquantize_h263_mvi(MpegEncContext *s, DCTELEM *block, + int n, int qscale) { - int i, level; - UINT64 qmul, qadd; + int i, n_coeffs; + uint64_t qmul, qadd; + uint64_t correction; + DCTELEM *orig_block = block; + DCTELEM block0; ASM_ACCEPT_MVI; - + 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; + if (!s->h263_aic) { + if (n < 4) + block0 = block[0] * s->y_dc_scale; + else + block0 = block[0] * s->c_dc_scale; + } + n_coeffs = 64; // does not always use zigzag table } else { - i = zigzag_end[s->block_last_index[n]] / 4; + n_coeffs = zigzag_end[s->block_last_index[n]]; } - qmul = s->qscale << 1; + + qmul = 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); + /* This mask kills spill from negative subwords to the next subword. */ + correction = WORD_VEC((qmul - 1) + 1); /* multiplication / addition */ + + for(i = 0; i < n_coeffs; block += 4, i += 4) { + uint64_t levels, negmask, zeros, add; + + levels = ldq(block); + if (levels == 0) + continue; + + negmask = maxsw4(levels, -1); /* negative -> ffff (-1) */ + negmask = minsw4(negmask, 0); /* positive -> 0000 (0) */ + + zeros = cmpbge(0, levels); + zeros &= zeros >> 1; + /* zeros |= zeros << 1 is not needed since qadd <= 255, so + zapping the lower byte suffices. */ + + levels *= qmul; + levels -= correction & (negmask << 16); + + /* Negate qadd for negative levels. */ + add = qadd ^ negmask; + add += WORD_VEC(0x0001) & negmask; + /* Set qadd to 0 for levels == 0. */ + add = zap(add, zeros); + + levels += add; + + stq(levels, block); + } + + if (s->mb_intra && !s->h263_aic) + orig_block[0] = block0; } 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; + s->dct_unquantize_h263 = dct_unquantize_h263_mvi; } } |