summaryrefslogtreecommitdiffstats
path: root/libhb/mcdeint.c
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2012-08-27 18:05:13 +0000
committerjstebbins <[email protected]>2012-08-27 18:05:13 +0000
commit0fa931ae3ea9d197fb305b0f49fae4a9b36c0c70 (patch)
tree1c9bd8c0f5c541fc41181453da06814a90f4ede8 /libhb/mcdeint.c
parent80987fa9a86baaddf5627bc4138070fb39b162ac (diff)
libhb: decomb and deinterlace improvements
Use hb_buffer_t for reference buffers. This is what eliminates extra buffer copies. Simplified a lot of the code. This resulted in some minor speed improvements and easier to read code. Allow mcdeint+bob. Previously these could not be used together. Thread the erode-dilate-erode-check steps in decomb3. More speed improvement. Speed of default decomb went from 62fps to 76fps. Speed of fast decomb went from 90fps to 95fps. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@4919 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'libhb/mcdeint.c')
-rw-r--r--libhb/mcdeint.c185
1 files changed, 89 insertions, 96 deletions
diff --git a/libhb/mcdeint.c b/libhb/mcdeint.c
index 4c4c10cef..4c8c7cb1e 100644
--- a/libhb/mcdeint.c
+++ b/libhb/mcdeint.c
@@ -42,46 +42,47 @@ void mcdeint_init( mcdeint_private_t * pv,
AVCodec * enc = avcodec_find_encoder( CODEC_ID_SNOW );
- int i;
- for (i = 0; i < 3; i++ )
+ // Snow ME_ITER will crash if width & height are not 16 pixel
+ // aligned (or 8 pixel if CODEC_FLAG_4MV is set).
+ // Fortunately, our input buffers have padding
+ width = (width + 15) & ~0xf;
+ height = (height + 15) & ~0xf;
+
+ AVCodecContext * avctx_enc;
+
+ avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context3( enc );
+
+ avctx_enc->width = width;
+ avctx_enc->height = height;
+ avctx_enc->time_base = (AVRational){1,25}; // meaningless
+ avctx_enc->gop_size = 300;
+ avctx_enc->max_b_frames = 0;
+ avctx_enc->pix_fmt = pix_fmt;
+ avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
+ avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
+ avctx_enc->global_quality = 1;
+ avctx_enc->me_cmp = FF_CMP_SAD; //SSE;
+ avctx_enc->me_sub_cmp = FF_CMP_SAD; //SSE;
+ avctx_enc->mb_cmp = FF_CMP_SSE;
+
+ switch( pv->mcdeint_mode )
{
- AVCodecContext * avctx_enc;
-
- avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context3( enc );
-
- avctx_enc->width = width;
- avctx_enc->height = height;
- avctx_enc->time_base = (AVRational){1,25}; // meaningless
- avctx_enc->gop_size = 300;
- avctx_enc->max_b_frames = 0;
- avctx_enc->pix_fmt = pix_fmt;
- avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
- avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
- avctx_enc->global_quality = 1;
- avctx_enc->me_cmp = FF_CMP_SAD; //SSE;
- avctx_enc->me_sub_cmp = FF_CMP_SAD; //SSE;
- avctx_enc->mb_cmp = FF_CMP_SSE;
-
- switch( pv->mcdeint_mode )
- {
- case 3:
- avctx_enc->refs = 3;
- case 2:
- avctx_enc->me_method = ME_ITER;
- case 1:
- avctx_enc->flags |= CODEC_FLAG_4MV;
- avctx_enc->dia_size =2;
- case 0:
- avctx_enc->flags |= CODEC_FLAG_QPEL;
- }
-
- hb_avcodec_open(avctx_enc, enc, NULL, 0);
+ case 3:
+ avctx_enc->refs = 3;
+ case 2:
+ avctx_enc->me_method = ME_ITER;
+ case 1:
+ avctx_enc->flags |= CODEC_FLAG_4MV;
+ avctx_enc->dia_size =2;
+ case 0:
+ avctx_enc->flags |= CODEC_FLAG_QPEL;
}
+ hb_avcodec_open(avctx_enc, enc, NULL, 0);
+
pv->mcdeint_frame = avcodec_alloc_frame();
av_new_packet( &pv->mcdeint_pkt, width * height * 10 );
}
-
}
void mcdeint_close( mcdeint_private_t * pv )
@@ -98,11 +99,9 @@ void mcdeint_close( mcdeint_private_t * pv )
}
}
-void mcdeint_filter( uint8_t ** dst,
- uint8_t ** src,
+void mcdeint_filter( hb_buffer_t * dst_buf,
+ hb_buffer_t * src_buf,
int parity,
- int * width,
- int * height,
mcdeint_private_t * pv )
{
int x, y, i;
@@ -115,8 +114,8 @@ void mcdeint_filter( uint8_t ** dst,
for( i=0; i<3; i++ )
{
- pv->mcdeint_frame->data[i] = src[i];
- pv->mcdeint_frame->linesize[i] = width[i];
+ pv->mcdeint_frame->data[i] = src_buf->plane[i].data;
+ pv->mcdeint_frame->linesize[i] = src_buf->plane[i].stride;
}
pv->mcdeint_avctx_enc->me_cmp = FF_CMP_SAD;
pv->mcdeint_avctx_enc->me_sub_cmp = FF_CMP_SAD;
@@ -131,33 +130,33 @@ void mcdeint_filter( uint8_t ** dst,
for( i = 0; i < 3; i++ )
{
- int w = width[i];
- int h = height[i];
+ uint8_t * dst = dst_buf->plane[i].data;
+ uint8_t * src = src_buf->plane[i].data;
+ int w = src_buf->plane[i].stride;
+ int h = src_buf->plane[i].height;
int fils = pv->mcdeint_frame_dec->linesize[i];
- int srcs = width[i];
+ int srcs = src_buf->plane[i].stride;
- for( y = 0; y < h; y++ )
+ for (y = parity; y < h; y += 2)
{
- if( (y ^ parity) & 1 )
+ for( x = 0; x < w; x++ )
{
- for( x = 0; x < w; x++ )
+ if( (x-1)+(y-1)*w >= 0 && (x+1)+(y+1)*w < w*h )
{
- if( (x-1)+(y-1)*w >= 0 && (x+1)+(y+1)*w < w*h )
- {
- uint8_t * filp =
- &pv->mcdeint_frame_dec->data[i][x + y*fils];
- uint8_t * srcp = &src[i][x + y*srcs];
+ uint8_t * filp =
+ &pv->mcdeint_frame_dec->data[i][x + y * fils];
+ uint8_t * srcp = &src[x + y * srcs];
- int diff0 = filp[-fils] - srcp[-srcs];
- int diff1 = filp[+fils] - srcp[+srcs];
- int spatial_score;
-
- spatial_score =
- ABS(srcp[-srcs-1] - srcp[+srcs-1]) +
- ABS(srcp[-srcs ] - srcp[+srcs ]) +
- ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
+ int diff0 = filp[-fils] - srcp[-srcs];
+ int diff1 = filp[+fils] - srcp[+srcs];
+ int spatial_score;
+
+ spatial_score =
+ ABS(srcp[-srcs-1] - srcp[+srcs-1]) +
+ ABS(srcp[-srcs ] - srcp[+srcs ]) +
+ ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
- int temp = filp[0];
+ int temp = filp[0];
#define MCDEINT_CHECK(j)\
{ int score = ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
@@ -168,56 +167,50 @@ void mcdeint_filter( uint8_t ** dst,
diff0 = filp[-fils+j] - srcp[-srcs+j];\
diff1 = filp[+fils-j] - srcp[+srcs-j];
- if( x >= 2 && x <= w - 3 )
- {
- MCDEINT_CHECK(-1)
- if( x >= 3 && x <= w - 4 )
- {
- MCDEINT_CHECK(-2) }} }}
- }
- }
- if( x >= 2 && x <= w - 3 )
- {
- MCDEINT_CHECK(1)
- if( x >= 3 && x <= w - 4 )
- {
- MCDEINT_CHECK(2) }} }}
- }
- }
-
- if(diff0 + diff1 > 0)
+ if( x >= 2 && x <= w - 3 )
+ {
+ MCDEINT_CHECK(-1)
+ if( x >= 3 && x <= w - 4 )
{
- temp -= (diff0 + diff1 -
- ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
+ MCDEINT_CHECK(-2) }} }}
}
- else
+ }
+ if( x >= 2 && x <= w - 3 )
+ {
+ MCDEINT_CHECK(1)
+ if( x >= 3 && x <= w - 4 )
{
- temp -= (diff0 + diff1 +
- ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
+ MCDEINT_CHECK(2) }} }}
}
+ }
- filp[0] = dst[i][x + y*w] =
- temp > 255U ? ~(temp>>31) : temp;
+ if(diff0 + diff1 > 0)
+ {
+ temp -= (diff0 + diff1 -
+ ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
}
else
{
- dst[i][x + y*w] =
- pv->mcdeint_frame_dec->data[i][x + y*fils];
+ temp -= (diff0 + diff1 +
+ ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
}
+
+ filp[0] = dst[x + y*w] =
+ temp > 255U ? ~(temp>>31) : temp;
+ }
+ else
+ {
+ dst[x + y*w] =
+ pv->mcdeint_frame_dec->data[i][x + y*fils];
}
}
}
- for( y = 0; y < h; y++ )
+ for( y = !parity; y < h; y += 2 )
{
- if( !((y ^ parity) & 1) )
- {
- for( x = 0; x < w; x++ )
- {
- pv->mcdeint_frame_dec->data[i][x + y*fils] =
- dst[i][x + y*w]= src[i][x + y*srcs];
- }
- }
+ memcpy(&pv->mcdeint_frame_dec->data[i][y * fils],
+ &src[y * srcs], w);
+ memcpy(&dst[y * w], &src[y * srcs], w);
}
}