summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuanjo <pulento@users.sourceforge.net>2002-02-18 19:33:27 +0000
committerJuanjo <pulento@users.sourceforge.net>2002-02-18 19:33:27 +0000
commitd140623fc44c67e8955c56c7cf74c56c94c0f064 (patch)
tree2e686108e99dc6db02219cdf86fc288f7a3edf46
parent608d0dee6fdb81ad260e74071a329353d74eef39 (diff)
downloadffmpeg-streaming-d140623fc44c67e8955c56c7cf74c56c94c0f064.zip
ffmpeg-streaming-d140623fc44c67e8955c56c7cf74c56c94c0f064.tar.gz
- H.263+ decoder support for Advanded INTRA Coding (buggy)
Originally committed as revision 310 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/h263.c148
-rw-r--r--libavcodec/h263data.h41
-rw-r--r--libavcodec/h263dec.c3
-rw-r--r--libavcodec/i386/mpegvideo_mmx.c5
-rw-r--r--libavcodec/mpegvideo.c30
-rw-r--r--libavcodec/mpegvideo.h4
6 files changed, 214 insertions, 17 deletions
diff --git a/libavcodec/h263.c b/libavcodec/h263.c
index dade959..e0b234b 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;
diff --git a/libavcodec/h263data.h b/libavcodec/h263data.h
index d41996a..88e456b 100644
--- a/libavcodec/h263data.h
+++ b/libavcodec/h263data.h
@@ -125,6 +125,47 @@ static RLTable rl_inter = {
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 --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index ea628bf..e0a5f67 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -156,6 +156,9 @@ static int h263_decode_frame(AVCodecContext *avctx,
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 --git a/libavcodec/i386/mpegvideo_mmx.c b/libavcodec/i386/mpegvideo_mmx.c
index 3ca40ca..542d2d8 100644
--- a/libavcodec/i386/mpegvideo_mmx.c
+++ b/libavcodec/i386/mpegvideo_mmx.c
@@ -83,7 +83,10 @@ static void dct_unquantize_h263_mmx(MpegEncContext *s,
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 --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index a8e1907..d67dffe 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -181,7 +181,7 @@ int MPV_common_init(MpegEncContext *s)
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 @@ static void encode_picture(MpegEncContext *s, int picture_number)
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 @@ static void dct_unquantize_h263_c(MpegEncContext *s,
}
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(;i<nCoeffs;i++) {
level = block[i];
@@ -1407,12 +1420,13 @@ static int rate_estimate_qscale(MpegEncContext *s)
q = 31;
qscale = (int)(q + 0.5);
#if defined(DEBUG)
- printf("%d: total=%0.0f br=%0.1f diff=%d qest=%0.1f\n",
+ printf("\n%d: total=%0.0f wanted=%0.0f br=%0.1f diff=%d qest=%2.1f\n",
s->picture_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 --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h
index acbb123..8b39746 100644
--- a/libavcodec/mpegvideo.h
+++ b/libavcodec/mpegvideo.h
@@ -146,10 +146,12 @@ typedef struct MpegEncContext {
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;
OpenPOWER on IntegriCloud