Mercurial > libavcodec.hg
changeset 350:6ebbecc10063 libavcodec
- Advanced Intra Coding (AIC) support for H.263+ encoder, just DC by now.
- Bug fix H.263+ AIC tables.
- Warning fixes.
author | pulento |
---|---|
date | Thu, 02 May 2002 04:39:45 +0000 |
parents | 34f6c77ff01a |
children | 6cef8253faab |
files | h263.c h263data.h h263dec.c i386/mpegvideo_mmx.c i386/mpegvideo_mmx_template.c i386/simple_idct_mmx.c mpegvideo.c rv10.c |
diffstat | 8 files changed, 254 insertions(+), 110 deletions(-) [+] |
line wrap: on
line diff
--- a/h263.c Wed May 01 18:12:04 2002 +0000 +++ b/h263.c Thu May 02 04:39:45 2002 +0000 @@ -46,6 +46,7 @@ int n, int coded); static int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block, int n, int coded); +static int h263_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr); static inline int mpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr); static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n, int dir); @@ -128,7 +129,7 @@ put_bits(&s->pb, 1, s->umvplus); /* Unrestricted Motion Vector */ put_bits(&s->pb,1,0); /* SAC: off */ put_bits(&s->pb,1,0); /* Advanced Prediction Mode: off */ - put_bits(&s->pb,1,0); /* Advanced Intra Coding: off */ + put_bits(&s->pb,1,s->h263_aic); /* Advanced Intra Coding */ put_bits(&s->pb,1,0); /* Deblocking Filter: off */ put_bits(&s->pb,1,0); /* Slice Structured: off */ put_bits(&s->pb,1,0); /* Reference Picture Selection: off */ @@ -142,7 +143,11 @@ put_bits(&s->pb,1,0); /* Reference Picture Resampling: off */ put_bits(&s->pb,1,0); /* Reduced-Resolution Update: off */ - put_bits(&s->pb,1,0); /* Rounding Type */ + if (s->pict_type == I_TYPE) + s->no_rounding = 0; + else + s->no_rounding ^= 1; + put_bits(&s->pb,1,s->no_rounding); /* Rounding Type */ put_bits(&s->pb,2,0); /* Reserved */ put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */ @@ -539,10 +544,13 @@ int motion_x, int motion_y) { int cbpc, cbpy, i, cbp, pred_x, pred_y; - - // printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); + INT16 pred_dc; + INT16 rec_intradc[6]; + UINT16 *dc_ptr[6]; + + //printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y); if (!s->mb_intra) { - /* compute cbp */ + /* compute cbp */ cbp = 0; for (i = 0; i < 6; i++) { if (s->block_last_index[i] >= 0) @@ -553,16 +561,16 @@ put_bits(&s->pb, 1, 1); return; } - put_bits(&s->pb, 1, 0); /* mb coded */ + put_bits(&s->pb, 1, 0); /* mb coded */ cbpc = cbp & 3; put_bits(&s->pb, - inter_MCBPC_bits[cbpc], - inter_MCBPC_code[cbpc]); + inter_MCBPC_bits[cbpc], + inter_MCBPC_code[cbpc]); cbpy = cbp >> 2; cbpy ^= 0xf; put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); - /* motion vectors: 16x16 mode only now */ + /* motion vectors: 16x16 mode only now */ h263_pred_motion(s, 0, &pred_x, &pred_y); if (!s->umvplus) { @@ -573,42 +581,132 @@ h263p_encode_umotion(s, motion_x - pred_x); h263p_encode_umotion(s, motion_y - pred_y); if (((motion_x - pred_x) == 1) && ((motion_y - pred_y) == 1)) - /* To prevent Start Code emulation */ + /* To prevent Start Code emulation */ put_bits(&s->pb,1,1); } - } else { - /* compute cbp */ - cbp = 0; - for (i = 0; i < 6; i++) { - if (s->block_last_index[i] >= 1) - cbp |= 1 << (5 - i); - } + } else { + int li = s->h263_aic ? 0 : 1; + + cbp = 0; + for(i=0; i<6; i++) { + /* Predict DC */ + if (s->h263_aic && s->mb_intra) { + INT16 level = block[i][0]; + + pred_dc = h263_pred_dc(s, i, &dc_ptr[i]); + level -= pred_dc; + /* Quant */ + if (level < 0) + level = (level + (s->qscale >> 1))/(s->y_dc_scale); + else + level = (level - (s->qscale >> 1))/(s->y_dc_scale); + + /* AIC can change CBP */ + if (level == 0 && s->block_last_index[i] == 0) + s->block_last_index[i] = -1; + else if (level < -127) + level = -127; + else if (level > 127) + level = 127; + + block[i][0] = level; + /* Reconstruction */ + rec_intradc[i] = (s->y_dc_scale*level) + pred_dc; + /* Oddify */ + rec_intradc[i] |= 1; + //if ((rec_intradc[i] % 2) == 0) + // rec_intradc[i]++; + /* Clipping */ + if (rec_intradc[i] < 0) + rec_intradc[i] = 0; + else if (rec_intradc[i] > 2047) + rec_intradc[i] = 2047; + + /* Update AC/DC tables */ + *dc_ptr[i] = rec_intradc[i]; + } + /* compute cbp */ + if (s->block_last_index[i] >= li) + cbp |= 1 << (5 - i); + } - cbpc = cbp & 3; - if (s->pict_type == I_TYPE) { - put_bits(&s->pb, - intra_MCBPC_bits[cbpc], - intra_MCBPC_code[cbpc]); - } else { - put_bits(&s->pb, 1, 0); /* mb coded */ - put_bits(&s->pb, - inter_MCBPC_bits[cbpc + 4], - inter_MCBPC_code[cbpc + 4]); - } - if (s->h263_pred) { - /* XXX: currently, we do not try to use ac prediction */ - put_bits(&s->pb, 1, 0); /* no ac prediction */ - } - cbpy = cbp >> 2; - put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); + cbpc = cbp & 3; + if (s->pict_type == I_TYPE) { + put_bits(&s->pb, + intra_MCBPC_bits[cbpc], + intra_MCBPC_code[cbpc]); + } else { + put_bits(&s->pb, 1, 0); /* mb coded */ + put_bits(&s->pb, + inter_MCBPC_bits[cbpc + 4], + inter_MCBPC_code[cbpc + 4]); + } + if (s->h263_aic) { + /* XXX: currently, we do not try to use ac prediction */ + put_bits(&s->pb, 1, 0); /* no AC prediction */ + } + cbpy = cbp >> 2; + put_bits(&s->pb, cbpy_tab[cbpy][1], cbpy_tab[cbpy][0]); } - /* encode each block */ - for (i = 0; i < 6; i++) { + for(i=0; i<6; i++) { + /* encode each block */ h263_encode_block(s, block[i], i); + + /* Update INTRADC for decoding */ + if (s->h263_aic && s->mb_intra) { + block[i][0] = rec_intradc[i]; + + } } } +static int h263_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr) +{ + int x, y, wrap, a, c, pred_dc, scale; + INT16 *dc_val, *ac_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]; + ac_val = s->ac_val[0][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]; + ac_val = s->ac_val[n - 4 + 1][0]; + scale = s->c_dc_scale; + } + /* B C + * A X + */ + a = dc_val[(x - 1) + (y) * wrap]; + c = dc_val[(x) + (y - 1) * wrap]; + + /* No prediction outside GOB boundary */ + if (s->first_gob_line && ((n < 2) || (n > 3))) + c = 1024; + pred_dc = 1024; + /* just DC prediction */ + if (a != 1024 && c != 1024) + pred_dc = (a + c) >> 1; + else if (a != 1024) + pred_dc = a; + else + pred_dc = c; + + /* we assume pred is positive */ + //pred_dc = (pred_dc + (scale >> 1)) / scale; + *dc_val_ptr = &dc_val[x + y * wrap]; + return pred_dc; +} + + void h263_pred_acdc(MpegEncContext * s, INT16 *block, int n) { int x, y, wrap, a, c, pred_dc, scale, i; @@ -640,6 +738,9 @@ a = dc_val[(x - 1) + (y) * wrap]; c = dc_val[(x) + (y - 1) * wrap]; + /* No prediction outside GOB boundary */ + if (s->first_gob_line && ((n < 2) || (n > 3))) + c = 1024; pred_dc = 1024; if (s->ac_pred) { if (s->h263_aic_dir) { @@ -898,6 +999,7 @@ init_rl(&rl_inter); init_rl(&rl_intra); + init_rl(&rl_intra_aic); init_mv_penalty_and_fcode(s); } @@ -928,11 +1030,11 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) { - int level, run, last, i, j, last_index, last_non_zero, sign, slevel; - int code; - RLTable *rl = &rl_inter; + int level, run, last, i, j, last_index, last_non_zero, sign, slevel, code; + RLTable *rl; - if (s->mb_intra) { + rl = &rl_inter; + if (s->mb_intra && !s->h263_aic) { /* DC coef */ level = block[0]; /* 255 cannot be represented, so we clamp */ @@ -952,23 +1054,25 @@ i = 1; } else { i = 0; + if (s->h263_aic && s->mb_intra) + rl = &rl_intra_aic; } - + /* AC coefs */ last_index = s->block_last_index[n]; last_non_zero = i - 1; for (; i <= last_index; i++) { - j = zigzag_direct[i]; - level = block[j]; - if (level) { - run = i - last_non_zero - 1; - last = (i == last_index); - sign = 0; - slevel = level; - if (level < 0) { - sign = 1; - level = -level; - } + j = zigzag_direct[i]; + level = block[j]; + if (level) { + run = i - last_non_zero - 1; + last = (i == last_index); + sign = 0; + slevel = level; + if (level < 0) { + sign = 1; + level = -level; + } code = get_rl_index(rl, last, run, level); put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); if (code == rl->n) { @@ -978,8 +1082,8 @@ } else { put_bits(&s->pb, 1, sign); } - last_non_zero = i; - } + last_non_zero = i; + } } } @@ -2628,7 +2732,7 @@ skip_bits(&s->gb, 8); // par_height } - if(vol_control=get_bits1(&s->gb)){ /* vol control parameter */ + if ((vol_control=get_bits1(&s->gb))) { /* vol control parameter */ int chroma_format= get_bits(&s->gb, 2); if(chroma_format!=1){ printf("illegal chroma format\n");
--- a/h263data.h Wed May 01 18:12:04 2002 +0000 +++ b/h263data.h Thu May 02 04:39:45 2002 +0000 @@ -125,45 +125,73 @@ 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 UINT16 intra_vlc_aic[103][2] = { +{ 0x2, 2 }, { 0x6, 3 }, { 0xe, 4 }, { 0xc, 5 }, +{ 0xd, 5 }, { 0x10, 6 }, { 0x11, 6 }, { 0x12, 6 }, +{ 0x16, 7 }, { 0x1b, 8 }, { 0x20, 9 }, { 0x21, 9 }, +{ 0x1a, 9 }, { 0x1b, 9 }, { 0x1c, 9 }, { 0x1d, 9 }, +{ 0x1e, 9 }, { 0x1f, 9 }, { 0x23, 11 }, { 0x22, 11 }, +{ 0x57, 12 }, { 0x56, 12 }, { 0x55, 12 }, { 0x54, 12 }, +{ 0x53, 12 }, { 0xf, 4 }, { 0x14, 6 }, { 0x14, 7 }, +{ 0x1e, 8 }, { 0xf, 10 }, { 0x21, 11 }, { 0x50, 12 }, +{ 0xb, 5 }, { 0x15, 7 }, { 0xe, 10 }, { 0x9, 10 }, +{ 0x15, 6 }, { 0x1d, 8 }, { 0xd, 10 }, { 0x51, 12 }, +{ 0x13, 6 }, { 0x23, 9 }, { 0x7, 11 }, { 0x17, 7 }, +{ 0x22, 9 }, { 0x52, 12 }, { 0x1c, 8 }, { 0xc, 10 }, +{ 0x1f, 8 }, { 0xb, 10 }, { 0x25, 9 }, { 0xa, 10 }, +{ 0x24, 9 }, { 0x6, 11 }, { 0x21, 10 }, { 0x20, 10 }, +{ 0x8, 10 }, { 0x20, 11 }, { 0x7, 4 }, { 0xc, 6 }, +{ 0x10, 7 }, { 0x13, 8 }, { 0x11, 9 }, { 0x12, 9 }, +{ 0x4, 10 }, { 0x27, 11 }, { 0x26, 11 }, { 0x5f, 12 }, +{ 0xf, 6 }, { 0x13, 9 }, { 0x5, 10 }, { 0x25, 11 }, +{ 0xe, 6 }, { 0x14, 9 }, { 0x24, 11 }, { 0xd, 6 }, +{ 0x6, 10 }, { 0x5e, 12 }, { 0x11, 7 }, { 0x7, 10 }, +{ 0x13, 7 }, { 0x5d, 12 }, { 0x12, 7 }, { 0x5c, 12 }, +{ 0x14, 8 }, { 0x5b, 12 }, { 0x15, 8 }, { 0x1a, 8 }, +{ 0x19, 8 }, { 0x18, 8 }, { 0x17, 8 }, { 0x16, 8 }, +{ 0x19, 9 }, { 0x15, 9 }, { 0x16, 9 }, { 0x18, 9 }, +{ 0x17, 9 }, { 0x4, 11 }, { 0x5, 11 }, { 0x58, 12 }, +{ 0x59, 12 }, { 0x5a, 12 }, { 0x3, 7 }, }; -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, +const INT8 intra_run_aic[102] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 5, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 11, +12, 13, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 1, + 2, 2, 2, 3, 3, 3, 4, 4, + 5, 5, 6, 6, 7, 7, 8, 9, +10, 11, 12, 13, 14, 15, 16, 17, +18, 19, 20, 21, 22, 23, +}; + +const INT8 intra_level_aic[102] = { + 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, +17, 18, 19, 20, 21, 22, 23, 24, +25, 1, 2, 3, 4, 5, 6, 7, + 1, 2, 3, 4, 1, 2, 3, 4, + 1, 2, 3, 1, 2, 3, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 1, + 1, 1, 1, 2, 3, 4, 5, 6, + 7, 8, 9, 10, 1, 2, 3, 4, + 1, 2, 3, 1, 2, 3, 1, 2, + 1, 2, 1, 2, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, }; static RLTable rl_intra_aic = { 102, 58, - inter_vlc, - inter_run_aic, - inter_level_aic, + intra_vlc_aic, + intra_run_aic, + intra_level_aic, }; static const UINT16 h263_format[8][2] = { @@ -174,4 +202,3 @@ { 704, 576 }, { 1408, 1152 }, }; -
--- a/h263dec.c Wed May 01 18:12:04 2002 +0000 +++ b/h263dec.c Thu May 02 04:39:45 2002 +0000 @@ -28,7 +28,6 @@ static int h263_decode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; - int i; s->avctx = avctx; s->out_format = FMT_H263;
--- a/i386/mpegvideo_mmx.c Wed May 01 18:12:04 2002 +0000 +++ b/i386/mpegvideo_mmx.c Thu May 02 04:39:45 2002 +0000 @@ -557,12 +557,12 @@ s->dct_unquantize_mpeg1 = dct_unquantize_mpeg1_mmx; s->dct_unquantize_mpeg2 = dct_unquantize_mpeg2_mmx; - draw_edges = draw_edges_mmx; + draw_edges = draw_edges_mmx; - if(mm_flags & MM_MMXEXT){ - dct_quantize= dct_quantize_MMX2; - }else{ - dct_quantize= dct_quantize_MMX; - } + if(mm_flags & MM_MMXEXT){ + dct_quantize= dct_quantize_MMX2; + } else { + dct_quantize= dct_quantize_MMX; + } } }
--- a/i386/mpegvideo_mmx_template.c Wed May 01 18:12:04 2002 +0000 +++ b/i386/mpegvideo_mmx_template.c Thu May 02 04:39:45 2002 +0000 @@ -48,6 +48,7 @@ else q = s->c_dc_scale; /* note: block[0] is assumed to be positive */ + if (!s->h263_aic) { #if 1 asm volatile ( "xorl %%edx, %%edx \n\t" @@ -65,6 +66,10 @@ : "%edx" ); #endif + } else + /* For AIC we skip quant/dequant of INTRADC */ + level = block[0]; + block[0]=0; //avoid fake overflow // temp_block[0] = (block[0] + (q >> 1)) / q; last_non_zero_p1 = 1;
--- a/i386/simple_idct_mmx.c Wed May 01 18:12:04 2002 +0000 +++ b/i386/simple_idct_mmx.c Thu May 02 04:39:45 2002 +0000 @@ -32,8 +32,8 @@ #define ROW_SHIFT 11 #define COL_SHIFT 20 // 6 -static uint64_t __attribute__((aligned(8))) wm1010= 0xFFFF0000FFFF0000ULL; -static uint64_t __attribute__((aligned(8))) d40000= 0x0000000000040000ULL; +static const uint64_t __attribute__((aligned(8))) wm1010= 0xFFFF0000FFFF0000ULL; +static const uint64_t __attribute__((aligned(8))) d40000= 0x0000000000040000ULL; static int16_t __attribute__((aligned(8))) temp[64]; static int16_t __attribute__((aligned(8))) coeffs[]= { 1<<(ROW_SHIFT-1), 0, 1<<(ROW_SHIFT-1), 0, @@ -63,12 +63,12 @@ C3, -C1, C3, -C1 }; +#if 0 static void unused_var_killer(){ int a= wm1010 + d40000; temp[0]=a; } -#if 0 static void inline idctCol (int16_t * col, int16_t *input) { #undef C0
--- a/mpegvideo.c Wed May 01 18:12:04 2002 +0000 +++ b/mpegvideo.c Thu May 02 04:39:45 2002 +0000 @@ -449,6 +449,7 @@ s->rtp_payload_size = 1200; s->h263_plus = 1; s->unrestricted_mv = 1; + s->h263_aic = 1; /* These are just to be sure */ s->umvplus = 0; @@ -542,7 +543,7 @@ } /* precompute matrix */ - /* for mjpeg, we do include qscale in the matrix */ + /* for mjpeg, we do include qscale in the matrix */ if (s->out_format != FMT_MJPEG) { convert_matrix(s->q_intra_matrix, s->q_intra_matrix16, s->q_intra_matrix16_bias, s->intra_matrix, s->intra_quant_bias); @@ -1338,8 +1339,8 @@ int i; const int maxlevel= s->max_qcoeff; const int minlevel= s->min_qcoeff; - - for(i=0; i<=last_index; i++){ + + for(i=0;i<=last_index; i++){ const int j = zigzag_direct[i]; int level = block[j]; @@ -1441,6 +1442,9 @@ /* DCT & quantize */ if (s->h263_pred && s->msmpeg4_version!=2) { h263_dc_scale(s); + } else if (s->h263_aic) { + s->y_dc_scale = 2*s->qscale; + s->c_dc_scale = 2*s->qscale; } else { /* default quantization values */ s->y_dc_scale = 8; @@ -1450,14 +1454,16 @@ for(i=0;i<6;i++) { int overflow; s->block_last_index[i] = dct_quantize(s, s->block[i], i, 8, &overflow); - if(overflow) clip_coeffs(s, s->block[i], s->block_last_index[i]); + if (overflow) clip_coeffs(s, s->block[i], s->block_last_index[i]); } }else{ for(i=0;i<6;i++) { int overflow; s->block_last_index[i] = dct_quantize(s, s->block[i], i, s->qscale, &overflow); // FIXME we could decide to change to quantizer instead of clipping - if(overflow) clip_coeffs(s, s->block[i], s->block_last_index[i]); + // JS: I don't think that would be a good idea it could lower quality instead + // of improve it. Just INTRADC clipping deserves changes in quantizer + if (overflow) clip_coeffs(s, s->block[i], s->block_last_index[i]); } } @@ -2018,12 +2024,16 @@ block_permute(block); if (s->mb_intra) { - if (n < 4) - q = s->y_dc_scale; - else - q = s->c_dc_scale; - q = q << 3; - + if (!s->h263_aic) { + if (n < 4) + q = s->y_dc_scale; + else + q = s->c_dc_scale; + q = q << 3; + } else + /* For AIC we skip quant/dequant of INTRADC */ + q = 1 << 3; + /* note: block[0] is assumed to be positive */ block[0] = (block[0] + (q >> 1)) / q; i = 1;