Mercurial > libavcodec.hg
changeset 1644:835cf346975e libavcodec
h263 loop filter
fixed h263 modified quantization
CODEC_FLAG_OBMC
author | michael |
---|---|
date | Mon, 01 Dec 2003 15:23:14 +0000 |
parents | 9bb07bd315d9 |
children | 901f928ec1f6 |
files | avcodec.h dsputil.c dsputil.h h263.c h263data.h h263dec.c mpeg12.c mpegvideo.c mpegvideo.h rv10.c |
diffstat | 10 files changed, 262 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/avcodec.h Sun Nov 30 19:04:56 2003 +0000 +++ b/avcodec.h Mon Dec 01 15:23:14 2003 +0000 @@ -260,6 +260,8 @@ #define CODEC_FLAG_CBP_RD 0x04000000 ///< use rate distortion optimization for cbp #define CODEC_FLAG_QP_RD 0x08000000 ///< use rate distortion optimization for qp selectioon #define CODEC_FLAG_H263P_AIV 0x00000008 ///< H263 Alternative inter vlc +#define CODEC_FLAG_OBMC 0x00000001 ///< OBMC +#define CODEC_FLAG_LOOP_FILTER 0x00000800 ///< loop filter /* For advanced prediction mode, we reuse the 4MV flag */ /* Unsupported options : * Syntax Arithmetic coding (SAC)
--- a/dsputil.c Sun Nov 30 19:04:56 2003 +0000 +++ b/dsputil.c Mon Dec 01 15:23:14 2003 +0000 @@ -2261,6 +2261,75 @@ wmv2_mspel8_v_lowpass(dst, halfH+8, stride, 8, 8); } +static void h263_v_loop_filter_c(uint8_t *src, int stride, int qscale){ + int x; + const int strength= ff_h263_loop_filter_strength[qscale]; + + for(x=0; x<8; x++){ + int d1, d2, ad1; + int p0= src[x-2*stride]; + int p1= src[x-1*stride]; + int p2= src[x+0*stride]; + int p3= src[x+1*stride]; + int d = (p0 - p3 + 4*(p2 - p1)) / 8; + + if (d<-2*strength) d1= 0; + else if(d<- strength) d1=-2*strength - d; + else if(d< strength) d1= d; + else if(d< 2*strength) d1= 2*strength - d; + else d1= 0; + + p1 += d1; + p2 -= d1; + if(p1&256) p1= ~(p1>>31); + if(p2&256) p2= ~(p2>>31); + + src[x-1*stride] = p1; + src[x+0*stride] = p2; + + ad1= ABS(d1); + + d2= clip((p0-p3)/4, -ad1, ad1); + + src[x-2*stride] = p0 - d2; + src[x+ stride] = p3 + d2; + } +} + +static void h263_h_loop_filter_c(uint8_t *src, int stride, int qscale){ + int y; + const int strength= ff_h263_loop_filter_strength[qscale]; + + for(y=0; y<8; y++){ + int d1, d2, ad1; + int p0= src[y*stride-2]; + int p1= src[y*stride-1]; + int p2= src[y*stride+0]; + int p3= src[y*stride+1]; + int d = (p0 - p3 + 4*(p2 - p1)) / 8; + + if (d<-2*strength) d1= 0; + else if(d<- strength) d1=-2*strength - d; + else if(d< strength) d1= d; + else if(d< 2*strength) d1= 2*strength - d; + else d1= 0; + + p1 += d1; + p2 -= d1; + if(p1&256) p1= ~(p1>>31); + if(p2&256) p2= ~(p2>>31); + + src[y*stride-1] = p1; + src[y*stride+0] = p2; + + ad1= ABS(d1)>>1; + + d2= clip((p0-p3)/4, -ad1, ad1); + + src[y*stride-2] = p0 - d2; + src[y*stride+1] = p3 + d2; + } +} static inline int pix_abs16x16_c(uint8_t *pix1, uint8_t *pix2, int line_size) { @@ -3048,6 +3117,9 @@ c->diff_bytes= diff_bytes_c; c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_c; c->bswap_buf= bswap_buf; + + c->h263_h_loop_filter= h263_h_loop_filter_c; + c->h263_v_loop_filter= h263_v_loop_filter_c; #ifdef HAVE_MMX dsputil_init_mmx(c, avctx);
--- a/dsputil.h Sun Nov 30 19:04:56 2003 +0000 +++ b/dsputil.h Mon Dec 01 15:23:14 2003 +0000 @@ -245,6 +245,9 @@ void (*sub_hfyu_median_prediction)(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w, int *left, int *left_top); void (*bswap_buf)(uint32_t *dst, uint32_t *src, int w); + void (*h263_v_loop_filter)(uint8_t *src, int stride, int qscale); + void (*h263_h_loop_filter)(uint8_t *src, int stride, int qscale); + /* (I)DCT */ void (*fdct)(DCTELEM *block/* align 16*/); void (*fdct248)(DCTELEM *block/* align 16*/);
--- a/h263.c Sun Nov 30 19:04:56 2003 +0000 +++ b/h263.c Mon Dec 01 15:23:14 2003 +0000 @@ -237,17 +237,16 @@ put_bits(&s->pb, 3, format); put_bits(&s->pb,1,0); /* Custom PCF: off */ - s->umvplus = s->unrestricted_mv; put_bits(&s->pb, 1, s->umvplus); /* Unrestricted Motion Vector */ put_bits(&s->pb,1,0); /* SAC: off */ put_bits(&s->pb,1,s->obmc); /* Advanced Prediction Mode */ 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,s->loop_filter); /* Deblocking Filter */ put_bits(&s->pb,1,0); /* Slice Structured: off */ put_bits(&s->pb,1,0); /* Reference Picture Selection: off */ put_bits(&s->pb,1,0); /* Independent Segment Decoding: off */ put_bits(&s->pb,1,s->alt_inter_vlc); /* Alternative Inter VLC */ - put_bits(&s->pb,1,0); /* Modified Quantization: off */ + put_bits(&s->pb,1,s->modified_quant); /* Modified Quantization: */ put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */ put_bits(&s->pb,3,0); /* Reserved */ @@ -279,6 +278,7 @@ /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */ if (s->umvplus) // put_bits(&s->pb,1,1); /* Limited according tables of Annex D */ +//FIXME check actual requested range put_bits(&s->pb,2,1); /* unlimited */ put_bits(&s->pb, 5, s->qscale); @@ -1234,6 +1234,93 @@ } #endif +int ff_h263_loop_filter(MpegEncContext * s){ + int qp_c; + const int linesize = s->linesize; + const int uvlinesize= s->uvlinesize; + const int xy = s->mb_y * s->mb_stride + s->mb_x; + uint8_t *dest_y = s->dest[0]; + uint8_t *dest_cb= s->dest[1]; + uint8_t *dest_cr= s->dest[2]; + +// if(s->pict_type==B_TYPE && !s->readable) return; + + /* + Diag Top + Left Center + */ + if(!IS_SKIP(s->current_picture.mb_type[xy])){ + qp_c= s->qscale; + s->dsp.h263_v_loop_filter(dest_y+8*linesize , linesize, qp_c); + s->dsp.h263_v_loop_filter(dest_y+8*linesize+8, linesize, qp_c); + }else + qp_c= 0; + + if(s->mb_y){ + int qp_dt, qp_t, qp_tc; + + if(IS_SKIP(s->current_picture.mb_type[xy-s->mb_stride])) + qp_t=0; + else + qp_t= s->current_picture.qscale_table[xy-s->mb_stride]; + + if(qp_c) + qp_tc= qp_c; + else + qp_tc= qp_t; + + if(qp_tc){ + const int chroma_qp= s->chroma_qscale_table[qp_tc]; + s->dsp.h263_v_loop_filter(dest_y , linesize, qp_tc); + s->dsp.h263_v_loop_filter(dest_y+8, linesize, qp_tc); + + s->dsp.h263_v_loop_filter(dest_cb , uvlinesize, chroma_qp); + s->dsp.h263_v_loop_filter(dest_cr , uvlinesize, chroma_qp); + } + + if(qp_t) + s->dsp.h263_h_loop_filter(dest_y-8*linesize+8 , linesize, qp_t); + + if(s->mb_x){ + if(qp_t || IS_SKIP(s->current_picture.mb_type[xy-1-s->mb_stride])) + qp_dt= qp_t; + else + qp_dt= s->current_picture.qscale_table[xy-1-s->mb_stride]; + + if(qp_dt){ + const int chroma_qp= s->chroma_qscale_table[qp_dt]; + s->dsp.h263_h_loop_filter(dest_y -8*linesize , linesize, qp_dt); + s->dsp.h263_h_loop_filter(dest_cb-8*uvlinesize, uvlinesize, chroma_qp); + s->dsp.h263_h_loop_filter(dest_cb-8*uvlinesize, uvlinesize, chroma_qp); + } + } + } + + if(qp_c){ + s->dsp.h263_h_loop_filter(dest_y +8, linesize, qp_c); + if(s->mb_y + 1 == s->mb_height) + s->dsp.h263_h_loop_filter(dest_y+8*linesize+8, linesize, qp_c); + } + + if(s->mb_x){ + int qp_lc; + if(qp_c || IS_SKIP(s->current_picture.mb_type[xy-1])) + qp_lc= qp_c; + else + qp_lc= s->current_picture.qscale_table[xy-1]; + + if(qp_lc){ + s->dsp.h263_h_loop_filter(dest_y, linesize, qp_lc); + if(s->mb_y + 1 == s->mb_height){ + const int chroma_qp= s->chroma_qscale_table[qp_lc]; + s->dsp.h263_h_loop_filter(dest_y +8* linesize, linesize, qp_lc); + s->dsp.h263_h_loop_filter(dest_cb , uvlinesize, chroma_qp); + s->dsp.h263_h_loop_filter(dest_cr , uvlinesize, chroma_qp); + } + } + } +} + static int h263_pred_dc(MpegEncContext * s, int n, uint16_t **dc_val_ptr) { int x, y, wrap, a, c, pred_dc, scale; @@ -2162,9 +2249,11 @@ s->qscale = 1; else if (s->qscale > 31) s->qscale = 31; + + s->chroma_qscale= s->chroma_qscale_table[s->qscale]; s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; - s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; + s->c_dc_scale= s->c_dc_scale_table[ s->chroma_qscale ]; } /** @@ -2657,6 +2746,8 @@ s->qscale = get_bits(&s->gb, 5); /* GQUANT */ if(s->qscale==0) return -1; + s->chroma_qscale= s->chroma_qscale_table[s->qscale]; + s->mb_x= 0; s->mb_y= s->gob_index* s->gob_number; if(s->mb_y >= s->mb_height) @@ -2820,7 +2911,7 @@ if(s->shape != BIN_ONLY_SHAPE){ int qscale= get_bits(&s->gb, s->quant_precision); if(qscale) - s->qscale= qscale; + s->chroma_qscale=s->qscale= qscale; } if(s->shape == RECT_SHAPE){ @@ -3302,9 +3393,9 @@ cbp = s->cbp_table[xy]; if(s->current_picture.qscale_table[xy] != s->qscale){ - s->qscale= s->current_picture.qscale_table[xy]; + s->chroma_qscale=s->qscale= s->current_picture.qscale_table[xy]; s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; - s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; + s->c_dc_scale= s->c_dc_scale_table[ s->chroma_qscale ]; } if (s->pict_type == P_TYPE || s->pict_type==S_TYPE) { @@ -3495,7 +3586,7 @@ s->mcsel=0; s->mv[0][0][0] = 0; s->mv[0][0][1] = 0; - s->mb_skiped = !s->obmc; + s->mb_skiped = !(s->obmc | s->loop_filter); } goto end; } @@ -4440,7 +4531,7 @@ av_log(s->avctx, AV_LOG_ERROR, "H263 PB frame not supported\n"); return -1; /* not PB frame */ } - s->qscale = get_bits(&s->gb, 5); + s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ s->width = width; @@ -4459,14 +4550,14 @@ dprintf("ufep=1, format: %d\n", format); skip_bits(&s->gb,1); /* Custom PCF */ s->umvplus = get_bits(&s->gb, 1); /* Unrestricted Motion Vector */ - skip_bits1(&s->gb); /* Syntax-based Arithmetic Coding (SAC) */ + if (get_bits1(&s->gb) != 0) { + av_log(s->avctx, AV_LOG_ERROR, "Syntax-based Arithmetic Coding (SAC) not supported\n"); + } s->obmc= get_bits1(&s->gb); /* Advanced prediction mode */ - s->unrestricted_mv = s->umvplus || s->obmc; s->h263_aic = get_bits1(&s->gb); /* Advanced Intra Coding (AIC) */ - - if (get_bits1(&s->gb) != 0) { - av_log(s->avctx, AV_LOG_ERROR, "Deblocking Filter not supported\n"); - } + s->loop_filter= get_bits1(&s->gb); + s->unrestricted_mv = s->umvplus || s->obmc || s->loop_filter; + if (get_bits1(&s->gb) != 0) { av_log(s->avctx, AV_LOG_ERROR, "Slice Structured not supported\n"); } @@ -4478,6 +4569,8 @@ } s->alt_inter_vlc= get_bits1(&s->gb); s->modified_quant= get_bits1(&s->gb); + if(s->modified_quant) + s->chroma_qscale_table= ff_h263_chroma_qscale_table; skip_bits(&s->gb, 1); /* Prevent start code emulation */ @@ -4539,6 +4632,7 @@ } s->qscale = get_bits(&s->gb, 5); + s->chroma_qscale= s->chroma_qscale_table[s->qscale]; } /* PEI */ while (get_bits1(&s->gb) != 0) { @@ -4555,7 +4649,7 @@ } if(s->avctx->debug&FF_DEBUG_PICT_INFO){ - av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s\n", + av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s\n", s->qscale, av_get_pict_type_char(s->pict_type), s->gb.size_in_bits, 1-s->no_rounding, s->obmc ? " AP" : "", @@ -4564,7 +4658,8 @@ s->h263_plus ? " +" : "", s->h263_aic ? " AIC" : "", s->alt_inter_vlc ? " AIV" : "", - s->modified_quant ? " MQ" : "" + s->modified_quant ? " MQ" : "", + s->loop_filter ? " LOOP" : "" ); } #if 1 @@ -4895,7 +4990,7 @@ s->progressive_sequence= get_bits1(gb)^1; if(!get_bits1(gb) && (s->avctx->debug & FF_DEBUG_PICT_INFO)) - av_log(s->avctx, AV_LOG_ERROR, "OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */ + av_log(s->avctx, AV_LOG_INFO, "MPEG4 OBMC not supported (very likely buggy encoder)\n"); /* OBMC Disable */ if (vo_ver_id == 1) { s->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */ } else { @@ -5251,7 +5346,7 @@ } if (s->shape != BIN_ONLY_SHAPE) { - s->qscale = get_bits(gb, s->quant_precision); + s->chroma_qscale= s->qscale = get_bits(gb, s->quant_precision); if(s->qscale==0){ av_log(s->avctx, AV_LOG_ERROR, "Error, header damaged or not MPEG4 header (qscale=0)\n"); return -1; // makes no sense to continue, as there is nothing left from the image then @@ -5445,7 +5540,7 @@ /* skip unknown header garbage */ skip_bits(&s->gb, 41); - s->qscale = get_bits(&s->gb, 5); + s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */ /* PEI */ @@ -5519,7 +5614,7 @@ if (s->pict_type > P_TYPE) s->pict_type = P_TYPE; skip_bits1(&s->gb); /* deblocking flag */ - s->qscale = get_bits(&s->gb, 5); + s->chroma_qscale= s->qscale = get_bits(&s->gb, 5); s->h263_plus = 0;
--- a/h263data.h Sun Nov 30 19:04:56 2003 +0000 +++ b/h263data.h Mon Dec 01 15:23:14 2003 +0000 @@ -222,7 +222,7 @@ } }; -static const uint8_t chroma_qscale_tab[32]={ +const uint8_t ff_h263_chroma_qscale_table[32]={ // 0 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 26 27 28 29 30 31 0, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9, 9,10,10,11,11,12,12,12,13,13,13,14,14,14,14,14,15,15,15,15,15 }; @@ -234,3 +234,9 @@ const uint8_t ff_mba_length[6]={ 6, 7, 9, 11, 13, 14 }; + +const uint8_t ff_h263_loop_filter_strength[32]={ +// 0 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 26 27 28 29 30 31 + 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9,10,10,10,11,11,11,12,12,12 +}; +
--- a/h263dec.c Sun Nov 30 19:04:56 2003 +0000 +++ b/h263dec.c Mon Dec 01 15:23:14 2003 +0000 @@ -207,6 +207,8 @@ const int xy= s->mb_x + s->mb_y*s->mb_stride; if(ret==SLICE_END){ MPV_decode_mb(s, s->block); + if(s->loop_filter) + ff_h263_loop_filter(s); //printf("%d %d %d %06X\n", s->mb_x, s->mb_y, s->gb.size*8 - get_bits_count(&s->gb), show_bits(&s->gb, 24)); ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, (AC_END|DC_END|MV_END)&part_mask); @@ -231,6 +233,8 @@ } MPV_decode_mb(s, s->block); + if(s->loop_filter) + ff_h263_loop_filter(s); } ff_draw_horiz_band(s, s->mb_y*16, 16);
--- a/mpeg12.c Sun Nov 30 19:04:56 2003 +0000 +++ b/mpeg12.c Mon Dec 01 15:23:14 2003 +0000 @@ -2126,6 +2126,7 @@ s->dsp.clear_blocks(s->block[0]); ret = mpeg_decode_mb(s, s->block); + s->chroma_qscale= s->qscale; dprintf("ret=%d\n", ret); if (ret < 0)
--- a/mpegvideo.c Sun Nov 30 19:04:56 2003 +0000 +++ b/mpegvideo.c Mon Dec 01 15:23:14 2003 +0000 @@ -88,6 +88,11 @@ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, }; +static const uint8_t ff_default_chroma_qscale_table[32]={ +// 0 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 26 27 28 29 30 31 + 0, 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,26,27,28,29,30,31 +}; + #ifdef CONFIG_ENCODERS static uint8_t (*default_mv_penalty)[MAX_MV*2+1]=NULL; static uint8_t default_fcode_tab[MAX_MV*2+1]; @@ -384,6 +389,10 @@ s->block_wrap[4]= s->block_wrap[5]= s->mb_width + 2; + s->y_dc_scale_table= + s->c_dc_scale_table= ff_mpeg1_dc_scale_table; + s->chroma_qscale_table= ff_default_chroma_qscale_table; + y_size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2); c_size = (s->mb_width + 2) * (s->mb_height + 2); yc_size = y_size + 2 * c_size; @@ -668,8 +677,8 @@ s->progressive_sequence= !(avctx->flags & CODEC_FLAG_INTERLACED_DCT); - s->obmc= (s->codec_id == CODEC_ID_H263 || s->codec_id == CODEC_ID_H263P) - && (s->flags & CODEC_FLAG_4MV); + s->obmc= (s->flags & CODEC_FLAG_OBMC); + s->loop_filter= (s->flags & CODEC_FLAG_LOOP_FILTER); if((s->flags & CODEC_FLAG_4MV) && s->codec_id != CODEC_ID_MPEG4 && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P){ @@ -682,6 +691,11 @@ return -1; } + if(s->obmc && s->codec_id != CODEC_ID_H263 && s->codec_id != CODEC_ID_H263P){ + av_log(avctx, AV_LOG_ERROR, "OBMC is only supported with H263(+)\n"); + return -1; + } + if(s->quarter_sample && s->codec_id != CODEC_ID_MPEG4){ av_log(avctx, AV_LOG_ERROR, "qpel not supported by codec\n"); return -1; @@ -770,6 +784,7 @@ return -1; } s->out_format = FMT_H263; + s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0; avctx->delay=0; s->low_delay=1; break; @@ -777,12 +792,18 @@ s->out_format = FMT_H263; s->h263_plus = 1; /* Fx */ - s->unrestricted_mv=(avctx->flags & CODEC_FLAG_H263P_UMV) ? 1:0; + s->umvplus = (avctx->flags & CODEC_FLAG_H263P_UMV) ? 1:0; s->h263_aic= (avctx->flags & CODEC_FLAG_H263P_AIC) ? 1:0; + s->modified_quant= s->h263_aic; s->alt_inter_vlc= (avctx->flags & CODEC_FLAG_H263P_AIV) ? 1:0; + s->obmc= (avctx->flags & CODEC_FLAG_OBMC) ? 1:0; + s->loop_filter= (avctx->flags & CODEC_FLAG_LOOP_FILTER) ? 1:0; + s->unrestricted_mv= s->obmc || s->loop_filter || s->umvplus; + if(s->modified_quant) + s->chroma_qscale_table= ff_h263_chroma_qscale_table; + /* /Fx */ /* These are just to be sure */ - s->umvplus = 1; avctx->delay=0; s->low_delay=1; break; @@ -876,8 +897,6 @@ } s->me.mv_penalty= default_mv_penalty; s->fcode_tab= default_fcode_tab; - s->y_dc_scale_table= - s->c_dc_scale_table= ff_mpeg1_dc_scale_table; /* dont use mv_penalty table for crap MV as it would be confused */ //FIXME remove after fixing / removing old ME @@ -2648,10 +2667,10 @@ } static inline void add_dequant_dct(MpegEncContext *s, - DCTELEM *block, int i, uint8_t *dest, int line_size) + DCTELEM *block, int i, uint8_t *dest, int line_size, int qscale) { if (s->block_last_index[i] >= 0) { - s->dct_unquantize(s, block, i, s->qscale); + s->dct_unquantize(s, block, i, qscale); s->dsp.idct_add (dest, line_size, block); } @@ -2810,14 +2829,14 @@ /* add dct residue */ if(s->encoding || !( s->h263_msmpeg4 || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO || (s->codec_id==CODEC_ID_MPEG4 && !s->mpeg_quant))){ - add_dequant_dct(s, block[0], 0, dest_y, dct_linesize); - add_dequant_dct(s, block[1], 1, dest_y + 8, dct_linesize); - add_dequant_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize); - add_dequant_dct(s, block[3], 3, dest_y + dct_offset + 8, dct_linesize); + add_dequant_dct(s, block[0], 0, dest_y, dct_linesize, s->qscale); + add_dequant_dct(s, block[1], 1, dest_y + 8, dct_linesize, s->qscale); + add_dequant_dct(s, block[2], 2, dest_y + dct_offset, dct_linesize, s->qscale); + add_dequant_dct(s, block[3], 3, dest_y + dct_offset + 8, dct_linesize, s->qscale); if(!(s->flags&CODEC_FLAG_GRAY)){ - add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize); - add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize); + add_dequant_dct(s, block[4], 4, dest_cb, uvlinesize, s->chroma_qscale); + add_dequant_dct(s, block[5], 5, dest_cr, uvlinesize, s->chroma_qscale); } } else if(s->codec_id != CODEC_ID_WMV2){ add_dct(s, block[0], 0, dest_y, dct_linesize); @@ -3105,8 +3124,9 @@ } } s->qscale= last_qp + s->dquant; + s->chroma_qscale= s->chroma_qscale_table[ s->qscale ]; s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; - s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; + s->c_dc_scale= s->c_dc_scale_table[ s->chroma_qscale ]; } if (s->mb_intra) { @@ -3844,8 +3864,9 @@ s->mb_x=0; s->mb_y= mb_y; + s->chroma_qscale= s->chroma_qscale_table[ s->qscale ]; s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; - s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; + s->c_dc_scale= s->c_dc_scale_table[ s->chroma_qscale ]; ff_init_block_index(s); for(mb_x=0; mb_x < s->mb_width; mb_x++) { @@ -4208,6 +4229,8 @@ s, s->new_picture .data[2] + s->mb_x*8 + s->mb_y*s->uvlinesize*8, s->dest[2], w>>1, h>>1, s->uvlinesize); } + if(s->loop_filter) + ff_h263_loop_filter(s); //printf("MB %d %d bits\n", s->mb_x+s->mb_y*s->mb_stride, get_bit_count(&s->pb)); } }
--- a/mpegvideo.h Sun Nov 30 19:04:56 2003 +0000 +++ b/mpegvideo.h Mon Dec 01 15:23:14 2003 +0000 @@ -337,6 +337,7 @@ int y_dc_scale, c_dc_scale; uint8_t *y_dc_scale_table; ///< qscale -> y_dc_scale table uint8_t *c_dc_scale_table; ///< qscale -> c_dc_scale table + const uint8_t *chroma_qscale_table; ///< qscale -> chroma_qscale (h263) uint8_t *coded_block; ///< used for coded block pattern prediction (msmpeg4v3, wmv1) int16_t (*ac_val[3])[16]; ///< used for for mpeg4 AC prediction, all 3 arrays must be continuous int ac_pred; @@ -352,6 +353,7 @@ uint8_t *edge_emu_buffer; ///< points into the middle of allocated_edge_emu_buffer int qscale; ///< QP + int chroma_qscale; ///< chroma QP int lambda; ///< lagrange multipler used in rate distortion int lambda2; ///< (lambda*lambda) >> FF_LAMBDA_SHIFT int *lambda_table; @@ -526,6 +528,7 @@ int h263_aic_dir; ///< AIC direction: 0 = left, 1 = top int alt_inter_vlc; ///< alternative inter vlc int modified_quant; + int loop_filter; /* mpeg4 specific */ int time_increment_resolution; @@ -819,6 +822,8 @@ extern const int16_t ff_mpeg4_default_non_intra_matrix[64]; extern const uint16_t ff_mba_max[6]; extern const uint8_t ff_mba_length[6]; +extern const uint8_t ff_h263_chroma_qscale_table[32]; +extern const uint8_t ff_h263_loop_filter_strength[32]; int ff_h263_decode_init(AVCodecContext *avctx); int ff_h263_decode_frame(AVCodecContext *avctx, @@ -846,6 +851,7 @@ int ff_h263_decode_gob_header(MpegEncContext *s); int ff_mpeg4_decode_picture_header(MpegEncContext * s, GetBitContext *gb); void ff_h263_update_motion_val(MpegEncContext * s); +int ff_h263_loop_filter(MpegEncContext * s); int intel_h263_decode_picture_header(MpegEncContext *s);
--- a/rv10.c Sun Nov 30 19:04:56 2003 +0000 +++ b/rv10.c Mon Dec 01 15:23:14 2003 +0000 @@ -382,7 +382,8 @@ // s->alt_inter_vlc=1; // s->obmc=1; // s->umvplus=1; -// s->modified_quant=1; + s->modified_quant=1; + s->loop_filter=1; if(s->avctx->debug & FF_DEBUG_PICT_INFO){ av_log(s->avctx, AV_LOG_INFO, "num:%5d x:%2d y:%2d type:%d qscale:%2d rnd:%d\n", @@ -522,9 +523,14 @@ s->y_dc_scale_table= s->c_dc_scale_table= ff_mpeg1_dc_scale_table; } + + if(s->modified_quant) + s->chroma_qscale_table= ff_h263_chroma_qscale_table; + + s->chroma_qscale= s->chroma_qscale_table[ s->qscale ]; s->y_dc_scale= s->y_dc_scale_table[ s->qscale ]; - s->c_dc_scale= s->c_dc_scale_table[ s->qscale ]; - + s->c_dc_scale= s->c_dc_scale_table[ s->chroma_qscale ]; + s->rv10_first_dc_coded[0] = 0; s->rv10_first_dc_coded[1] = 0; s->rv10_first_dc_coded[2] = 0; @@ -555,6 +561,9 @@ } ff_h263_update_motion_val(s); MPV_decode_mb(s, s->block); + if(s->loop_filter) + ff_h263_loop_filter(s); + if (++s->mb_x == s->mb_width) { s->mb_x = 0; s->mb_y++;