# HG changeset patch # User mellum # Date 1025665266 0 # Node ID c9f724e3a7976db783e05927146edfd6d6ca437c # Parent fb670ca9f8eb862e5698824f4c7de3ba2a912cd9 Update and activate dct_unquantize_h263_mvi. Thanks to Mns Rullgrd for some improvements. diff -r fb670ca9f8eb -r c9f724e3a797 alpha/mpegvideo_alpha.c --- a/alpha/mpegvideo_alpha.c Wed Jul 03 01:09:44 2002 +0000 +++ b/alpha/mpegvideo_alpha.c Wed Jul 03 03:01:06 2002 +0000 @@ -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; + /* 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) */ - levels = levels * qmul; - levels += zap(qadd, zeromask); + 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); - /* Re-negate negative words. */ - levels -= corr; - levels ^= negmask; + /* Negate qadd for negative levels. */ + add = qadd ^ negmask; + add += WORD_VEC(0x0001) & negmask; + /* Set qadd to 0 for levels == 0. */ + add = zap(add, zeros); - stq(levels, block); - } while (block += 4, --i); + 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; } } diff -r fb670ca9f8eb -r c9f724e3a797 mpegvideo.c --- a/mpegvideo.c Wed Jul 03 01:09:44 2002 +0000 +++ b/mpegvideo.c Wed Jul 03 03:01:06 2002 +0000 @@ -132,6 +132,9 @@ #ifdef HAVE_MMX MPV_common_init_mmx(s); #endif +#ifdef ARCH_ALPHA + MPV_common_init_axp(s); +#endif //setup default unquantizers (mpeg4 might change it later) if(s->out_format == FMT_H263) s->dct_unquantize = s->dct_unquantize_h263; diff -r fb670ca9f8eb -r c9f724e3a797 mpegvideo.h --- a/mpegvideo.h Wed Jul 03 01:09:44 2002 +0000 +++ b/mpegvideo.h Wed Jul 03 03:01:06 2002 +0000 @@ -451,6 +451,9 @@ #ifdef HAVE_MMX void MPV_common_init_mmx(MpegEncContext *s); #endif +#ifdef ARCH_ALPHA +void MPV_common_init_axp(MpegEncContext *s); +#endif extern int (*dct_quantize)(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow); extern void (*draw_edges)(UINT8 *buf, int wrap, int width, int height, int w); void ff_conceal_past_errors(MpegEncContext *s, int conceal_all);