diff options
author | Juanjo <pulento@users.sourceforge.net> | 2002-02-18 19:33:27 +0000 |
---|---|---|
committer | Juanjo <pulento@users.sourceforge.net> | 2002-02-18 19:33:27 +0000 |
commit | d140623fc44c67e8955c56c7cf74c56c94c0f064 (patch) | |
tree | 2e686108e99dc6db02219cdf86fc288f7a3edf46 /libavcodec/h263.c | |
parent | 608d0dee6fdb81ad260e74071a329353d74eef39 (diff) | |
download | ffmpeg-d140623fc44c67e8955c56c7cf74c56c94c0f064.tar.gz |
- H.263+ decoder support for Advanded INTRA Coding (buggy)
Originally committed as revision 310 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/h263.c')
-rw-r--r-- | libavcodec/h263.c | 148 |
1 files changed, 141 insertions, 7 deletions
diff --git a/libavcodec/h263.c b/libavcodec/h263.c index dade959adb..e0b234bbd4 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -273,6 +273,97 @@ void h263_encode_mb(MpegEncContext * s, } } +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 @@ void h263_decode_init_vlc(MpegEncContext *s) &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 @@ int h263_decode_mb(MpegEncContext *s, } } 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 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block, { 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 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block, 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 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block, 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 @@ int h263_decode_picture_header(MpegEncContext *s) 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; |