1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-11-21 10:55:51 +02:00

- H.263+ decoder support for Advanded INTRA Coding (buggy)

Originally committed as revision 310 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Juanjo 2002-02-18 19:33:27 +00:00
parent 608d0dee6f
commit d140623fc4
6 changed files with 214 additions and 17 deletions

View File

@ -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;

View File

@ -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 },

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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;