summaryrefslogtreecommitdiff
path: root/libavcodec/h263.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/h263.c')
-rw-r--r--libavcodec/h263.c148
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;