# HG changeset patch # User pulento # Date 1014060807 0 # Node ID 56ee684c48bb809fcd5bc851c05e56ef6d1a22a7 # Parent 6f48cacd9ed94bb85775c657bec22c0e7c81cba2 - H.263+ decoder support for Advanded INTRA Coding (buggy) diff -r 6f48cacd9ed9 -r 56ee684c48bb h263.c --- a/h263.c Mon Feb 18 09:40:05 2002 +0000 +++ b/h263.c Mon Feb 18 19:33:27 2002 +0000 @@ -273,6 +273,97 @@ } } +static int h263_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr) +{ + int a, c, x, y, wrap, pred, scale; + UINT16 *dc_val; + + /* find prediction */ + if (n < 4) { + x = 2 * s->mb_x + 1 + (n & 1); + y = 2 * s->mb_y + 1 + ((n & 2) >> 1); + wrap = s->mb_width * 2 + 2; + dc_val = s->dc_val[0]; + scale = s->y_dc_scale; + } else { + x = s->mb_x + 1; + y = s->mb_y + 1; + wrap = s->mb_width + 2; + dc_val = s->dc_val[n - 4 + 1]; + scale = s->c_dc_scale; + } + + /* B C + * A X + */ + a = dc_val[(x - 1) + (y) * wrap]; + c = dc_val[(x) + (y - 1) * wrap]; + + if (s->ac_pred) { + if (s->h263_aic_dir) + pred = a; + else + pred = c; + } else if (a != 1024 && c != 1024) + pred = (a + c) >> 1; + else if (a != 1024) + pred = a; + else + pred = c; + + + /* we assume pred is positive */ + pred = (pred) / scale; + + /* prepare address for prediction update */ + *dc_val_ptr = &dc_val[(x) + (y) * wrap]; + + return pred; +} + +void h263_pred_ac(MpegEncContext * s, INT16 *block, int n) +{ + int x, y, wrap, i; + INT16 *ac_val, *ac_val1; + + /* find prediction */ + if (n < 4) { + x = 2 * s->mb_x + 1 + (n & 1); + y = 2 * s->mb_y + 1 + ((n & 2) >> 1); + wrap = s->mb_width * 2 + 2; + ac_val = s->ac_val[0][0]; + } else { + x = s->mb_x + 1; + y = s->mb_y + 1; + wrap = s->mb_width + 2; + ac_val = s->ac_val[n - 4 + 1][0]; + } + ac_val += ((y) * wrap + (x)) * 16; + ac_val1 = ac_val; + + if (s->ac_pred) { + if (s->h263_aic_dir) { + /* left prediction */ + ac_val -= 16; + for(i=1;i<8;i++) { + block[block_permute_op(i*8)] += ac_val[i]; + } + } else { + /* top prediction */ + ac_val -= 16 * wrap; + for(i=1;i<8;i++) { + block[block_permute_op(i)] += ac_val[i + 8]; + } + } + } + /* left copy */ + for(i=1;i<8;i++) + ac_val1[i] = block[block_permute_op(i * 8)]; + /* top copy */ + for(i=1;i<8;i++) + ac_val1[8 + i] = block[block_permute_op(i)]; +} + static inline int mid_pred(int a, int b, int c) { int vmin, vmax; @@ -821,8 +912,10 @@ &mvtab[0][0], 2, 1); init_rl(&rl_inter); init_rl(&rl_intra); + init_rl(&rl_intra_aic); init_vlc_rl(&rl_inter); init_vlc_rl(&rl_intra); + init_vlc_rl(&rl_intra_aic); init_vlc(&dc_lum, 9, 13, &DCtab_lum[0][1], 2, 1, &DCtab_lum[0][0], 2, 1); @@ -959,8 +1052,10 @@ } } else { s->ac_pred = 0; - if (s->h263_pred) { + if (s->h263_pred || s->h263_aic) { s->ac_pred = get_bits1(&s->gb); + if (s->ac_pred && s->h263_aic) + s->h263_aic_dir = get_bits1(&s->gb); } cbpy = get_vlc(&s->gb, &cbpy_vlc); cbp = (cbpc & 3) | (cbpy << 2); @@ -1059,9 +1154,21 @@ { int code, level, i, j, last, run; RLTable *rl = &rl_inter; + UINT16 *dc_val; + const UINT8 *scan_table; - if (s->mb_intra) { - /* DC coef */ + scan_table = zigzag_direct; + if (s->h263_aic) { + rl = &rl_intra_aic; + i = 0; + if (s->ac_pred) { + if (s->h263_aic_dir) + scan_table = ff_alternate_vertical_scan; /* left */ + else + scan_table = ff_alternate_horizontal_scan; /* top */ + } + } else if (s->mb_intra) { + /* DC coef */ if (s->h263_rv10 && s->rv10_version == 3 && s->pict_type == I_TYPE) { int component, diff; component = (n <= 3 ? 0 : n - 4 + 1); @@ -1082,11 +1189,21 @@ level = 128; } block[0] = level; - i = 1; + i = 1; } else { - i = 0; + i = 0; } if (!coded) { + if (s->mb_intra && s->h263_aic) { + level = h263_pred_dc(s, n, &dc_val); + if (level < 0) + level = 0; + *dc_val = level * s->y_dc_scale; + block[0] = level; + h263_pred_ac(s, block, n); + i = 64; + //i = 1; + } s->block_last_index[n] = i - 1; return 0; } @@ -1112,15 +1229,29 @@ if (get_bits1(&s->gb)) level = -level; } + if (!i && s->h263_aic) { + level += h263_pred_dc(s, n, &dc_val); + if (level < 0) + level = 0; + else if (level & 1) + level++; + *dc_val = level * s->y_dc_scale; + + } i += run; if (i >= 64) return -1; - j = zigzag_direct[i]; + j = scan_table[i]; block[j] = level; if (last) break; i++; } + + if (s->h263_aic) { + h263_pred_ac(s, block, n); + i = 64; + } s->block_last_index[n] = i; return 0; } @@ -1325,7 +1456,10 @@ if (get_bits1(&s->gb) != 0) { s->mv_type = MV_TYPE_8X8; /* Advanced prediction mode */ } - skip_bits(&s->gb, 8); + if (get_bits1(&s->gb) != 0) { /* Advanced Intra Coding (AIC) */ + s->h263_aic = 1; + } + skip_bits(&s->gb, 7); skip_bits(&s->gb, 3); /* Reserved */ } else if (ufep != 0) return -1; diff -r 6f48cacd9ed9 -r 56ee684c48bb h263data.h --- a/h263data.h Mon Feb 18 09:40:05 2002 +0000 +++ b/h263data.h Mon Feb 18 19:33:27 2002 +0000 @@ -125,6 +125,47 @@ inter_level, }; +/* table used for Advanced INTRA Coding, just RUN and LEVEL change */ +const INT8 inter_level_aic[102] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 2, 1, 2, 2, 4, 5, + 6, 7, 3, 2, 3, 4, 5, 2, + 3, 4, 2, 3, 1, 2, 25, 1, + 2, 24, 8, 2, 7, 4, 6, 1, + 9, 23, 2, 3, 1, 10, 12, 11, + 18, 17, 16, 15, 14, 13, 20, 19, + 22, 21, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 1, 3, 1, 1, + 1, 1, 1, 1, 1, 4, 1, 1, + 1, 1, 2, 2, 6, 5, 2, 2, + 3, 7, 3, 4, 9, 8, 1, 1, + 1, 2, 2, 2, 3, 10, +}; + +const INT8 inter_run_aic[102] = { + 0, 1, 3, 5, 7, 8, 9, 10, + 11, 4, 9, 13, 0, 1, 1, 1, + 1, 1, 0, 3, 2, 3, 0, 4, + 3, 0, 5, 5, 2, 6, 0, 4, + 7, 0, 0, 8, 0, 2, 0, 12, + 0, 0, 2, 1, 6, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 14, 20, 1, 19, 2, + 3, 0, 5, 6, 4, 0, 9, 10, + 11, 12, 13, 8, 7, 0, 17, 18, + 16, 15, 2, 1, 0, 0, 4, 3, + 1, 0, 2, 1, 0, 0, 21, 22, + 23, 7, 6, 5, 3, 0, +}; + +static RLTable rl_intra_aic = { + 102, + 58, + inter_vlc, + inter_run_aic, + inter_level_aic, +}; + static const UINT16 h263_format[8][2] = { { 0, 0 }, { 128, 96 }, diff -r 6f48cacd9ed9 -r 56ee684c48bb h263dec.c --- a/h263dec.c Mon Feb 18 09:40:05 2002 +0000 +++ b/h263dec.c Mon Feb 18 19:33:27 2002 +0000 @@ -156,6 +156,9 @@ msmpeg4_dc_scale(s); } else if (s->h263_pred) { h263_dc_scale(s); + } else if (s->h263_aic) { + s->y_dc_scale = s->qscale; + s->c_dc_scale = s->qscale; } else { /* default quantization values */ s->y_dc_scale = 8; diff -r 6f48cacd9ed9 -r 56ee684c48bb i386/mpegvideo_mmx.c --- a/i386/mpegvideo_mmx.c Mon Feb 18 09:40:05 2002 +0000 +++ b/i386/mpegvideo_mmx.c Mon Feb 18 19:33:27 2002 +0000 @@ -83,7 +83,10 @@ int i, level, qmul, qadd, nCoeffs; qmul = s->qscale << 1; - qadd = (s->qscale - 1) | 1; + if (s->h263_aic && s->mb_intra) + qadd = 0; + else + qadd = (s->qscale - 1) | 1; if (s->mb_intra) { if (n < 4) diff -r 6f48cacd9ed9 -r 56ee684c48bb mpegvideo.c --- a/mpegvideo.c Mon Feb 18 09:40:05 2002 +0000 +++ b/mpegvideo.c Mon Feb 18 19:33:27 2002 +0000 @@ -181,7 +181,7 @@ memset(s->motion_val, 0, size * 2 * sizeof(INT16)); } - if (s->h263_pred) { + if (s->h263_pred || s->h263_plus) { int y_size, c_size, i, size; /* dc values */ @@ -1062,10 +1062,20 @@ sub_pixels_2(s->block[5], ptr, s->linesize >> 1, dxy); } emms_c(); - //if (s->avg_mb_var) - // printf("\nqscale=%2d dquant=%2d var=%4d avgvar=%4d", s->qscale, - // s->qscale*(s->mb_var[s->mb_width*mb_y+mb_x]/s->avg_mb_var), - // s->mb_var[s->mb_width*mb_y+mb_x], s->avg_mb_var); + +#if 0 + { + float adap_parm; + + adap_parm = ((s->avg_mb_var << 1) + s->mb_var[s->mb_width*mb_y+mb_x] + 1.0) / + ((s->mb_var[s->mb_width*mb_y+mb_x] << 1) + s->avg_mb_var + 1.0); + + printf("\ntype=%c qscale=%2d adap=%0.2f dquant=%4.2f var=%4d avgvar=%4d", + (s->mb_type[s->mb_width*mb_y+mb_x] > 0) ? 'I' : 'P', + s->qscale, adap_parm, s->qscale*adap_parm, + s->mb_var[s->mb_width*mb_y+mb_x], s->avg_mb_var); + } +#endif /* DCT & quantize */ if (s->h263_msmpeg4) { msmpeg4_dc_scale(s); @@ -1331,7 +1341,10 @@ } qmul = s->qscale << 1; - qadd = (s->qscale - 1) | 1; + if (s->h263_aic && s->mb_intra) + qadd = 0; + else + qadd = (s->qscale - 1) | 1; for(;ipicture_number, (double)total_bits, + (double)s->wanted_bits, (float)s->frame_rate / FRAME_RATE_BASE * total_bits / s->picture_number, - diff, q); + (int)diff, q); #endif return qscale; } diff -r 6f48cacd9ed9 -r 56ee684c48bb mpegvideo.h --- a/mpegvideo.h Mon Feb 18 09:40:05 2002 +0000 +++ b/mpegvideo.h Mon Feb 18 19:33:27 2002 +0000 @@ -146,10 +146,12 @@ int gob_number; int gob_index; int first_gob_line; - + /* H.263+ specific */ int umvplus; int umvplus_dec; + int h263_aic; /* Advanded INTRA Coding (AIC) */ + int h263_aic_dir; /* AIC direction: 0 = left, 1 = top */ /* mpeg4 specific */ int time_increment_bits;