mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-18 05:24:42 +00:00
Move VC1 loop filter to DSPContext
Originally committed as revision 18520 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
9bf0fdf378
commit
0e58865d6e
@ -482,6 +482,7 @@ typedef struct DSPContext {
|
||||
void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block);
|
||||
void (*vc1_v_overlap)(uint8_t* src, int stride);
|
||||
void (*vc1_h_overlap)(uint8_t* src, int stride);
|
||||
void (*vc1_loop_filter)(uint8_t *src, int step, int stride, int len, int pq);
|
||||
/* put 8x8 block with bicubic interpolation and quarterpel precision
|
||||
* last argument is actually round value instead of height
|
||||
*/
|
||||
|
110
libavcodec/vc1.c
110
libavcodec/vc1.c
@ -310,87 +310,19 @@ static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v)
|
||||
|
||||
/** @} */ //Bitplane group
|
||||
|
||||
/**
|
||||
* VC-1 in-loop deblocking filter for one line
|
||||
* @param src source block type
|
||||
* @param stride block stride
|
||||
* @param pq block quantizer
|
||||
* @return whether other 3 pairs should be filtered or not
|
||||
* @see 8.6
|
||||
*/
|
||||
static av_always_inline int vc1_filter_line(uint8_t* src, int stride, int pq){
|
||||
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
|
||||
|
||||
int a0 = (2*(src[-2*stride] - src[ 1*stride]) - 5*(src[-1*stride] - src[ 0*stride]) + 4) >> 3;
|
||||
int a0_sign = a0 >> 31; /* Store sign */
|
||||
a0 = (a0 ^ a0_sign) - a0_sign; /* a0 = FFABS(a0); */
|
||||
if(a0 < pq){
|
||||
int a1 = FFABS((2*(src[-4*stride] - src[-1*stride]) - 5*(src[-3*stride] - src[-2*stride]) + 4) >> 3);
|
||||
int a2 = FFABS((2*(src[ 0*stride] - src[ 3*stride]) - 5*(src[ 1*stride] - src[ 2*stride]) + 4) >> 3);
|
||||
if(a1 < a0 || a2 < a0){
|
||||
int clip = src[-1*stride] - src[ 0*stride];
|
||||
int clip_sign = clip >> 31;
|
||||
clip = ((clip ^ clip_sign) - clip_sign)>>1;
|
||||
if(clip){
|
||||
int a3 = FFMIN(a1, a2);
|
||||
int d = 5 * (a3 - a0);
|
||||
int d_sign = (d >> 31);
|
||||
d = ((d ^ d_sign) - d_sign) >> 3;
|
||||
d_sign ^= a0_sign;
|
||||
|
||||
if( d_sign ^ clip_sign )
|
||||
d = 0;
|
||||
else{
|
||||
d = FFMIN(d, clip);
|
||||
d = (d ^ d_sign) - d_sign; /* Restore sign */
|
||||
src[-1*stride] = cm[src[-1*stride] - d];
|
||||
src[ 0*stride] = cm[src[ 0*stride] + d];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* VC-1 in-loop deblocking filter
|
||||
* @param src source block type
|
||||
* @param step distance between horizontally adjacent elements
|
||||
* @param stride distance between vertically adjacent elements
|
||||
* @param len edge length to filter (4 or 8 pixels)
|
||||
* @param pq block quantizer
|
||||
* @see 8.6
|
||||
*/
|
||||
static void vc1_loop_filter(uint8_t* src, int step, int stride, int len, int pq)
|
||||
{
|
||||
int i;
|
||||
int filt3;
|
||||
|
||||
for(i = 0; i < len; i += 4){
|
||||
filt3 = vc1_filter_line(src + 2*step, stride, pq);
|
||||
if(filt3){
|
||||
vc1_filter_line(src + 0*step, stride, pq);
|
||||
vc1_filter_line(src + 1*step, stride, pq);
|
||||
vc1_filter_line(src + 3*step, stride, pq);
|
||||
}
|
||||
src += step * 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void vc1_loop_filter_iblk(MpegEncContext *s, int pq)
|
||||
{
|
||||
int i, j;
|
||||
if(!s->first_slice_line)
|
||||
vc1_loop_filter(s->dest[0], 1, s->linesize, 16, pq);
|
||||
vc1_loop_filter(s->dest[0] + 8*s->linesize, 1, s->linesize, 16, pq);
|
||||
s->dsp.vc1_loop_filter(s->dest[0], 1, s->linesize, 16, pq);
|
||||
s->dsp.vc1_loop_filter(s->dest[0] + 8*s->linesize, 1, s->linesize, 16, pq);
|
||||
for(i = !s->mb_x*8; i < 16; i += 8)
|
||||
vc1_loop_filter(s->dest[0] + i, s->linesize, 1, 16, pq);
|
||||
s->dsp.vc1_loop_filter(s->dest[0] + i, s->linesize, 1, 16, pq);
|
||||
for(j = 0; j < 2; j++){
|
||||
if(!s->first_slice_line)
|
||||
vc1_loop_filter(s->dest[j+1], 1, s->uvlinesize, 8, pq);
|
||||
s->dsp.vc1_loop_filter(s->dest[j+1], 1, s->uvlinesize, 8, pq);
|
||||
if(s->mb_x)
|
||||
vc1_loop_filter(s->dest[j+1], s->uvlinesize, 1, 8, pq);
|
||||
s->dsp.vc1_loop_filter(s->dest[j+1], s->uvlinesize, 1, 8, pq);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3050,9 +2982,9 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan
|
||||
s->dsp.vc1_inv_trans_8x8(block);
|
||||
s->dsp.add_pixels_clamped(block, dst, linesize);
|
||||
if(apply_filter && cbp_top & 0xC)
|
||||
vc1_loop_filter(dst, 1, linesize, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(dst, 1, linesize, 8, mquant);
|
||||
if(apply_filter && cbp_left & 0xA)
|
||||
vc1_loop_filter(dst, linesize, 1, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(dst, linesize, 1, 8, mquant);
|
||||
}
|
||||
break;
|
||||
case TT_4X4:
|
||||
@ -3074,9 +3006,9 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan
|
||||
if(!(subblkpat & (1 << (3 - j))) && !skip_block){
|
||||
s->dsp.vc1_inv_trans_4x4(dst + (j&1)*4 + (j&2)*2*linesize, linesize, block + off);
|
||||
if(apply_filter && (j&2 ? pat & (1<<(j-2)) : (cbp_top & (1 << (j + 2)))))
|
||||
vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, 1, linesize, 4, mquant);
|
||||
s->dsp.vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, 1, linesize, 4, mquant);
|
||||
if(apply_filter && (j&1 ? pat & (1<<(j-1)) : (cbp_left & (1 << (j + 1)))))
|
||||
vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, linesize, 1, 4, mquant);
|
||||
s->dsp.vc1_loop_filter(dst + (j&1)*4 + (j&2)*2*linesize, linesize, 1, 4, mquant);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -3099,9 +3031,9 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan
|
||||
if(!(subblkpat & (1 << (1 - j))) && !skip_block){
|
||||
s->dsp.vc1_inv_trans_8x4(dst + j*4*linesize, linesize, block + off);
|
||||
if(apply_filter && j ? pat & 0x3 : (cbp_top & 0xC))
|
||||
vc1_loop_filter(dst + j*4*linesize, 1, linesize, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(dst + j*4*linesize, 1, linesize, 8, mquant);
|
||||
if(apply_filter && cbp_left & (2 << j))
|
||||
vc1_loop_filter(dst + j*4*linesize, linesize, 1, 4, mquant);
|
||||
s->dsp.vc1_loop_filter(dst + j*4*linesize, linesize, 1, 4, mquant);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -3124,9 +3056,9 @@ static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquan
|
||||
if(!(subblkpat & (1 << (1 - j))) && !skip_block){
|
||||
s->dsp.vc1_inv_trans_4x8(dst + j*4, linesize, block + off);
|
||||
if(apply_filter && cbp_top & (2 << j))
|
||||
vc1_loop_filter(dst + j*4, 1, linesize, 4, mquant);
|
||||
s->dsp.vc1_loop_filter(dst + j*4, 1, linesize, 4, mquant);
|
||||
if(apply_filter && j ? pat & 0x5 : (cbp_left & 0xA))
|
||||
vc1_loop_filter(dst + j*4, linesize, 1, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(dst + j*4, linesize, 1, 8, mquant);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -3249,9 +3181,9 @@ static int vc1_decode_p_mb(VC1Context *v)
|
||||
top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4));
|
||||
}
|
||||
if(left_cbp & 0xC)
|
||||
vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant);
|
||||
if(top_cbp & 0xA)
|
||||
vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant);
|
||||
}
|
||||
block_cbp |= 0xF << (i << 2);
|
||||
} else if(val) {
|
||||
@ -3266,9 +3198,9 @@ static int vc1_decode_p_mb(VC1Context *v)
|
||||
top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4));
|
||||
}
|
||||
if(left_cbp & 0xC)
|
||||
vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant);
|
||||
if(top_cbp & 0xA)
|
||||
vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant);
|
||||
}
|
||||
pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp);
|
||||
block_cbp |= pat << (i << 2);
|
||||
@ -3380,9 +3312,9 @@ static int vc1_decode_p_mb(VC1Context *v)
|
||||
top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4));
|
||||
}
|
||||
if(left_cbp & 0xC)
|
||||
vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant);
|
||||
if(top_cbp & 0xA)
|
||||
vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant);
|
||||
}
|
||||
block_cbp |= 0xF << (i << 2);
|
||||
} else if(is_coded[i]) {
|
||||
@ -3397,9 +3329,9 @@ static int vc1_decode_p_mb(VC1Context *v)
|
||||
top_cbp = (i & 2) ? (cbp >> ((i-2)*4)) : (v->cbp[s->mb_x - s->mb_stride] >> ((i+2)*4));
|
||||
}
|
||||
if(left_cbp & 0xC)
|
||||
vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, 1, i & 4 ? s->uvlinesize : s->linesize, 8, mquant);
|
||||
if(top_cbp & 0xA)
|
||||
vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant);
|
||||
s->dsp.vc1_loop_filter(s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize, 1, 8, mquant);
|
||||
}
|
||||
pat = vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), filter, left_cbp, top_cbp);
|
||||
block_cbp |= pat << (i << 2);
|
||||
|
@ -78,6 +78,73 @@ static void vc1_h_overlap_c(uint8_t* src, int stride)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* VC-1 in-loop deblocking filter for one line
|
||||
* @param src source block type
|
||||
* @param stride block stride
|
||||
* @param pq block quantizer
|
||||
* @return whether other 3 pairs should be filtered or not
|
||||
* @see 8.6
|
||||
*/
|
||||
static av_always_inline int vc1_filter_line(uint8_t* src, int stride, int pq){
|
||||
uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
|
||||
|
||||
int a0 = (2*(src[-2*stride] - src[ 1*stride]) - 5*(src[-1*stride] - src[ 0*stride]) + 4) >> 3;
|
||||
int a0_sign = a0 >> 31; /* Store sign */
|
||||
a0 = (a0 ^ a0_sign) - a0_sign; /* a0 = FFABS(a0); */
|
||||
if(a0 < pq){
|
||||
int a1 = FFABS((2*(src[-4*stride] - src[-1*stride]) - 5*(src[-3*stride] - src[-2*stride]) + 4) >> 3);
|
||||
int a2 = FFABS((2*(src[ 0*stride] - src[ 3*stride]) - 5*(src[ 1*stride] - src[ 2*stride]) + 4) >> 3);
|
||||
if(a1 < a0 || a2 < a0){
|
||||
int clip = src[-1*stride] - src[ 0*stride];
|
||||
int clip_sign = clip >> 31;
|
||||
clip = ((clip ^ clip_sign) - clip_sign)>>1;
|
||||
if(clip){
|
||||
int a3 = FFMIN(a1, a2);
|
||||
int d = 5 * (a3 - a0);
|
||||
int d_sign = (d >> 31);
|
||||
d = ((d ^ d_sign) - d_sign) >> 3;
|
||||
d_sign ^= a0_sign;
|
||||
|
||||
if( d_sign ^ clip_sign )
|
||||
d = 0;
|
||||
else{
|
||||
d = FFMIN(d, clip);
|
||||
d = (d ^ d_sign) - d_sign; /* Restore sign */
|
||||
src[-1*stride] = cm[src[-1*stride] - d];
|
||||
src[ 0*stride] = cm[src[ 0*stride] + d];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* VC-1 in-loop deblocking filter
|
||||
* @param src source block type
|
||||
* @param step distance between horizontally adjacent elements
|
||||
* @param stride distance between vertically adjacent elements
|
||||
* @param len edge length to filter (4 or 8 pixels)
|
||||
* @param pq block quantizer
|
||||
* @see 8.6
|
||||
*/
|
||||
static void vc1_loop_filter(uint8_t* src, int step, int stride, int len, int pq)
|
||||
{
|
||||
int i;
|
||||
int filt3;
|
||||
|
||||
for(i = 0; i < len; i += 4){
|
||||
filt3 = vc1_filter_line(src + 2*step, stride, pq);
|
||||
if(filt3){
|
||||
vc1_filter_line(src + 0*step, stride, pq);
|
||||
vc1_filter_line(src + 1*step, stride, pq);
|
||||
vc1_filter_line(src + 3*step, stride, pq);
|
||||
}
|
||||
src += step * 4;
|
||||
}
|
||||
}
|
||||
|
||||
/** Do inverse transform on 8x8 block
|
||||
*/
|
||||
@ -450,6 +517,7 @@ void ff_vc1dsp_init(DSPContext* dsp, AVCodecContext *avctx) {
|
||||
dsp->vc1_inv_trans_4x4 = vc1_inv_trans_4x4_c;
|
||||
dsp->vc1_h_overlap = vc1_h_overlap_c;
|
||||
dsp->vc1_v_overlap = vc1_v_overlap_c;
|
||||
dsp->vc1_loop_filter = vc1_loop_filter;
|
||||
|
||||
dsp->put_vc1_mspel_pixels_tab[ 0] = ff_put_vc1_mspel_mc00_c;
|
||||
dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_c;
|
||||
|
Loading…
Reference in New Issue
Block a user