summaryrefslogtreecommitdiffstats
path: root/libhb/decomb.c
diff options
context:
space:
mode:
Diffstat (limited to 'libhb/decomb.c')
-rw-r--r--libhb/decomb.c158
1 files changed, 73 insertions, 85 deletions
diff --git a/libhb/decomb.c b/libhb/decomb.c
index b9baa963a..7d911ff28 100644
--- a/libhb/decomb.c
+++ b/libhb/decomb.c
@@ -139,7 +139,6 @@ typedef struct yadif_thread_arg_s {
struct hb_filter_private_s
{
- int pix_fmt;
int width[3];
int height[3];
@@ -221,28 +220,24 @@ struct hb_filter_private_s
// int alternator; // for bobbing parity when framedoubling
};
-hb_filter_private_t * hb_decomb_init( int pix_fmt,
- int width,
- int height,
- char * settings );
+static int hb_decomb_init( hb_filter_object_t * filter,
+ hb_filter_init_t * init );
-int hb_decomb_work( const hb_buffer_t * buf_in,
- hb_buffer_t ** buf_out,
- int pix_fmt,
- int width,
- int height,
- hb_filter_private_t * pv );
+static int hb_decomb_work( hb_filter_object_t * filter,
+ hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out );
-void hb_decomb_close( hb_filter_private_t * pv );
+static void hb_decomb_close( hb_filter_object_t * filter );
hb_filter_object_t hb_filter_decomb =
{
- FILTER_DECOMB,
- "Decomb",
- NULL,
- hb_decomb_init,
- hb_decomb_work,
- hb_decomb_close,
+ .id = HB_FILTER_DECOMB,
+ .enforce_order = 1,
+ .name = "Decomb",
+ .settings = NULL,
+ .init = hb_decomb_init,
+ .work = hb_decomb_work,
+ .close = hb_decomb_close,
};
int cubic_interpolate_pixel( int y0, int y1, int y2, int y3 )
@@ -790,7 +785,7 @@ int check_filtered_combing_mask( hb_filter_private_t * pv )
pv->mask_box_x = x;
pv->mask_box_y = y;
- if ( block_score <= threshold && !( pv->buf_settings->flags & 16) )
+ if ( block_score <= threshold && !( pv->buf_settings->s.flags & 16) )
{
/* Blend video content that scores between
( threshold / 2 ) and threshold. */
@@ -799,7 +794,7 @@ int check_filtered_combing_mask( hb_filter_private_t * pv )
}
else if( block_score > threshold )
{
- if( pv->buf_settings->flags & 16 )
+ if( pv->buf_settings->s.flags & 16 )
{
/* Blend progressive content above the threshold.*/
pv->mask_box_color = 2;
@@ -919,7 +914,7 @@ int check_combing_mask( hb_filter_private_t * pv )
pv->mask_box_x = x;
pv->mask_box_y = y;
- if ( block_score <= threshold && !( pv->buf_settings->flags & 16) )
+ if ( block_score <= threshold && !( pv->buf_settings->s.flags & 16) )
{
/* Blend video content that scores between
( threshold / 2 ) and threshold. */
@@ -928,7 +923,7 @@ int check_combing_mask( hb_filter_private_t * pv )
}
else if( block_score > threshold )
{
- if( pv->buf_settings->flags & 16 )
+ if( pv->buf_settings->s.flags & 16 )
{
/* Blend progressive content above the threshold.*/
pv->mask_box_color = 2;
@@ -1994,29 +1989,22 @@ static void yadif_filter( uint8_t ** dst,
}
}
-hb_filter_private_t * hb_decomb_init( int pix_fmt,
- int width,
- int height,
- char * settings )
+static int hb_decomb_init( hb_filter_object_t * filter,
+ hb_filter_init_t * init )
{
- if( pix_fmt != PIX_FMT_YUV420P )
- {
- return 0;
- }
-
- hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) );
-
- pv->pix_fmt = pix_fmt;
+ filter->private_data = calloc( 1, sizeof(struct hb_filter_private_s) );
+ hb_filter_private_t * pv = filter->private_data;
- pv->width[0] = width;
- pv->height[0] = height;
- pv->width[1] = pv->width[2] = width >> 1;
- pv->height[1] = pv->height[2] = height >> 1;
+ pv->width[0] = hb_image_stride( init->pix_fmt, init->width, 0 );
+ pv->height[0] = hb_image_height( init->pix_fmt, init->height, 0 );
+ pv->width[1] = pv->width[2] = hb_image_stride( init->pix_fmt, init->width, 1 );
+ pv->height[1] = pv->height[2] = hb_image_height( init->pix_fmt, init->height, 1 );
build_gamma_lut( pv );
- pv->buf_out[0] = hb_video_buffer_init( width, height );
- pv->buf_out[1] = hb_video_buffer_init( width, height );
+ pv->buf_out[0] = hb_video_buffer_init( init->width, init->height );
+ pv->buf_out[1] = hb_video_buffer_init( init->width, init->height );
+
pv->buf_settings = hb_buffer_init( 0 );
pv->deinterlaced_frames = 0;
@@ -2049,9 +2037,9 @@ hb_filter_private_t * hb_decomb_init( int pix_fmt,
pv->mcdeint_mode = MCDEINT_MODE_DEFAULT;
int mcdeint_qp = MCDEINT_QP_DEFAULT;
- if( settings )
+ if( filter->settings )
{
- sscanf( settings, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+ sscanf( filter->settings, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
&pv->mode,
&pv->spatial_metric,
&pv->motion_threshold,
@@ -2084,8 +2072,8 @@ hb_filter_private_t * hb_decomb_init( int pix_fmt,
for( i = 0; i < 3; i++ )
{
int is_chroma = !!i;
- int w = ((width + 31) & (~31))>>is_chroma;
- int h = ((height+6+ 31) & (~31))>>is_chroma;
+ int w = ((init->width + 31) & (~31))>>is_chroma;
+ int h = ((init->height+6+ 31) & (~31))>>is_chroma;
pv->ref_stride[i] = w;
@@ -2110,11 +2098,11 @@ hb_filter_private_t * hb_decomb_init( int pix_fmt,
if( pv->mode & MODE_EEDI2 )
{
/* Allocate half-height eedi2 buffers */
- height = pv->height[0] / 2;
+ int height = pv->height[0] / 2;
for( i = 0; i < 3; i++ )
{
int is_chroma = !!i;
- int w = ((width + 31) & (~31))>>is_chroma;
+ int w = ((init->width + 31) & (~31))>>is_chroma;
int h = ((height+6+ 31) & (~31))>>is_chroma;
for( j = 0; j < 4; j++ )
@@ -2128,7 +2116,7 @@ hb_filter_private_t * hb_decomb_init( int pix_fmt,
for( i = 0; i < 3; i++ )
{
int is_chroma = !!i;
- int w = ((width + 31) & (~31))>>is_chroma;
+ int w = ((init->width + 31) & (~31))>>is_chroma;
int h = ((height+6+ 31) & (~31))>>is_chroma;
for( j = 0; j < 5; j++ )
@@ -2276,14 +2264,17 @@ hb_filter_private_t * hb_decomb_init( int pix_fmt,
}
}
}
+
+ mcdeint_init( &pv->mcdeint, pv->mcdeint_mode, mcdeint_qp,
+ init->pix_fmt, init->width, init->height );
- mcdeint_init( &pv->mcdeint, pv->mcdeint_mode, mcdeint_qp, width, height );
-
- return pv;
+ return 0;
}
-void hb_decomb_close( hb_filter_private_t * pv )
+static void hb_decomb_close( hb_filter_object_t * filter )
{
+ hb_filter_private_t * pv = filter->private_data;
+
if( !pv )
{
return;
@@ -2451,33 +2442,30 @@ void hb_decomb_close( hb_filter_private_t * pv )
mcdeint_close( &pv->mcdeint );
free( pv );
+ filter->private_data = NULL;
}
-int hb_decomb_work( const hb_buffer_t * cbuf_in,
- hb_buffer_t ** buf_out,
- int pix_fmt,
- int width,
- int height,
- hb_filter_private_t * pv )
+static int hb_decomb_work( hb_filter_object_t * filter,
+ hb_buffer_t ** buf_in,
+ hb_buffer_t ** buf_out )
{
- hb_buffer_t * buf_in = (hb_buffer_t *)cbuf_in;
+ hb_filter_private_t * pv = filter->private_data;
+ hb_buffer_t * in = *buf_in;
- if( !pv ||
- pix_fmt != pv->pix_fmt ||
- width != pv->width[0] ||
- height != pv->height[0] )
+ if ( in->size <= 0 )
{
- return FILTER_FAILED;
+ *buf_out = in;
+ *buf_in = NULL;
+ return HB_FILTER_DONE;
}
- avpicture_fill( &pv->pic_in, buf_in->data,
- pix_fmt, width, height );
+ hb_avpicture_fill( &pv->pic_in, in );
/* Determine if top-field first layout */
int tff;
if( pv->parity < 0 )
{
- tff = !!(buf_in->flags & PIC_FLAG_TOP_FIELD_FIRST);
+ tff = !!(in->s.flags & PIC_FLAG_TOP_FIELD_FIRST);
}
else
{
@@ -2492,18 +2480,16 @@ int hb_decomb_work( const hb_buffer_t * cbuf_in,
{
store_ref( (const uint8_t**)pv->pic_in.data, pv );
- hb_buffer_copy_settings( pv->buf_settings, buf_in );
-
- /* don't let 'work_loop' send a chapter mark upstream */
- buf_in->new_chap = 0;
+ pv->buf_settings->s = in->s;
+ hb_buffer_move_subs( pv->buf_settings, in );
pv->yadif_ready = 1;
- return FILTER_DELAY;
+ return HB_FILTER_DELAY;
}
- /* Perform yadif filtering */
- int frame;
+ /* Perform yadif filtering */
+ int frame, out_frame;
for( frame = 0; frame <= ( ( pv->mode & MODE_MCDEINT ) ? 1 : 0 ) ; frame++ )
// This would be what to use for bobbing: for( frame = 0; frame <= 0 ; frame++ )
{
@@ -2531,8 +2517,8 @@ int hb_decomb_work( const hb_buffer_t * cbuf_in,
#endif
pv->tff = !parity;
- avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,
- pix_fmt, width, height );
+ hb_buffer_t *b = pv->buf_out[!(frame^1)];
+ hb_avpicture_fill( &pv->pic_out, b );
/* XXX
Should check here and only bother filtering field 2 when
@@ -2548,27 +2534,29 @@ int hb_decomb_work( const hb_buffer_t * cbuf_in,
if( pv->mcdeint_mode >= 0 /* && pv->yadif_arguments[0].is_combed */)
{
/* Perform mcdeint filtering */
- avpicture_fill( &pv->pic_in, pv->buf_out[(frame^1)]->data,
- pix_fmt, width, height );
+ b = pv->buf_out[(frame^1)];
+ hb_avpicture_fill( &pv->pic_in, b );
mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv->width, pv->height, &pv->mcdeint );
- *buf_out = pv->buf_out[(frame^1)];
+ out_frame = frame ^ 1;
}
else
{
- *buf_out = pv->buf_out[!(frame^1)];
+ out_frame = !(frame ^ 1);
}
}
+ *buf_out = pv->buf_out[out_frame];
+ // Allocate a replacement for the buffer we just consumed
+ pv->buf_out[out_frame] = hb_video_buffer_init( pv->width[0], pv->height[0] );
/* Copy buffered settings to output buffer settings */
- hb_buffer_copy_settings( *buf_out, pv->buf_settings );
+ (*buf_out)->s = pv->buf_settings->s;
+ hb_buffer_move_subs( *buf_out, pv->buf_settings );
/* Replace buffered settings with input buffer settings */
- hb_buffer_copy_settings( pv->buf_settings, buf_in );
-
- /* don't let 'work_loop' send a chapter mark upstream */
- buf_in->new_chap = 0;
+ pv->buf_settings->s = in->s;
+ hb_buffer_move_subs( pv->buf_settings, in );
- return FILTER_OK;
+ return HB_FILTER_OK;
}