Commit d0ef0962 authored by michael's avatar michael

h263 loop filter

fixed h263 modified quantization
CODEC_FLAG_OBMC


git-svn-id: file:///var/local/repositories/ffmpeg/trunk@2549 9553f0bf-9b14-0410-a0b8-cfaf0461ba5b
parent 8be84f61
......@@ -260,6 +260,8 @@ static const __attribute__((unused)) int Motion_Est_QTab[] =
#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)
......
......@@ -2261,6 +2261,75 @@ static void put_mspel8_mc22_c(uint8_t *dst, uint8_t *src, int stride){
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)
{
......@@ -3049,6 +3118,9 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx)
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);
#endif
......
......@@ -245,6 +245,9 @@ typedef struct DSPContext {
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*/);
......
This diff is collapsed.
......@@ -222,7 +222,7 @@ static const uint8_t modified_quant_tab[2][32]={
}
};
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 uint16_t ff_mba_max[6]={
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
};
......@@ -207,6 +207,8 @@ static int decode_slice(MpegEncContext *s){
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 @@ static int decode_slice(MpegEncContext *s){
}
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);
......
......@@ -2126,6 +2126,7 @@ static int mpeg_decode_slice(AVCodecContext *avctx,
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)
......
......@@ -88,6 +88,11 @@ static const uint8_t h263_chroma_roundtab[16] = {
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 @@ int MPV_common_init(MpegEncContext *s)
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 @@ int MPV_encode_init(AVCodecContext *avctx)
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 @@ int MPV_encode_init(AVCodecContext *avctx)
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 @@ int MPV_encode_init(AVCodecContext *avctx)
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 @@ int MPV_encode_init(AVCodecContext *avctx)
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 @@ int MPV_encode_init(AVCodecContext *avctx)
}
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_dct(MpegEncContext *s,
}
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 @@ void MPV_decode_mb(MpegEncContext *s, DCTELEM block[6][64])
/* 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 @@ static void encode_mb(MpegEncContext *s, int motion_x, int motion_y)
}
}
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 @@ static void encode_picture(MpegEncContext *s, int picture_number)
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 @@ static void encode_picture(MpegEncContext *s, int picture_number)
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));
}
}
......
......@@ -337,6 +337,7 @@ typedef struct MpegEncContext {
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 @@ typedef struct MpegEncContext {
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 @@ typedef struct MpegEncContext {
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_intra_matrix[64];
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 h263_decode_picture_header(MpegEncContext *s);
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);
......
......@@ -382,7 +382,8 @@ static int rv20_decode_picture_header(MpegEncContext *s)
// 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,8 +523,13 @@ static int rv10_decode_packet(AVCodecContext *avctx,
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;
......@@ -555,6 +561,9 @@ static int rv10_decode_packet(AVCodecContext *avctx,
}
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++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment