Commit 0e58865d authored by David Conrad's avatar David Conrad

Move VC1 loop filter to DSPContext

Originally committed as revision 18520 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 9bf0fdf3
...@@ -482,6 +482,7 @@ typedef struct DSPContext { ...@@ -482,6 +482,7 @@ typedef struct DSPContext {
void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block); void (*vc1_inv_trans_4x4)(uint8_t *dest, int line_size, DCTELEM *block);
void (*vc1_v_overlap)(uint8_t* src, int stride); void (*vc1_v_overlap)(uint8_t* src, int stride);
void (*vc1_h_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 /* put 8x8 block with bicubic interpolation and quarterpel precision
* last argument is actually round value instead of height * last argument is actually round value instead of height
*/ */
......
This diff is collapsed.
...@@ -78,6 +78,73 @@ static void vc1_h_overlap_c(uint8_t* src, int stride) ...@@ -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 /** Do inverse transform on 8x8 block
*/ */
...@@ -450,6 +517,7 @@ void ff_vc1dsp_init(DSPContext* dsp, AVCodecContext *avctx) { ...@@ -450,6 +517,7 @@ void ff_vc1dsp_init(DSPContext* dsp, AVCodecContext *avctx) {
dsp->vc1_inv_trans_4x4 = vc1_inv_trans_4x4_c; dsp->vc1_inv_trans_4x4 = vc1_inv_trans_4x4_c;
dsp->vc1_h_overlap = vc1_h_overlap_c; dsp->vc1_h_overlap = vc1_h_overlap_c;
dsp->vc1_v_overlap = vc1_v_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[ 0] = ff_put_vc1_mspel_mc00_c;
dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_c; dsp->put_vc1_mspel_pixels_tab[ 1] = put_vc1_mspel_mc10_c;
......
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