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:
parent
608d0dee6f
commit
d140623fc4
@ -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;
|
||||
|
@ -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 },
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user