+typedef struct yadif_thread_arg_s {
+ hb_filter_private_t *pv;
+ int segment;
+} yadif_thread_arg_t;
+
+/*
+ * deinterlace this segment of all three planes in a single thread.
+ */
+void yadif_decomb_filter_thread( void *thread_args_v )
+{
+ yadif_arguments_t *yadif_work = NULL;
+ hb_filter_private_t * pv;
+ int run = 1;
+ int plane;
+ int segment, segment_start, segment_stop;
+ yadif_thread_arg_t *thread_args = thread_args_v;
+ uint8_t **dst;
+ int parity, tff, y, w, h, ref_stride, is_combed;
+
+ pv = thread_args->pv;
+ segment = thread_args->segment;
+
+ hb_log("yadif thread started for segment %d", segment);
+
+ while( run )
+ {
+ /*
+ * Wait here until there is work to do. hb_lock() blocks until
+ * render releases it to say that there is more work to do.
+ */
+ hb_lock( pv->yadif_begin_lock[segment] );
+
+ yadif_work = &pv->yadif_arguments[segment];
+
+ if( yadif_work->stop )
+ {
+ /*
+ * No more work to do, exit this thread.
+ */
+ run = 0;
+ continue;
+ }
+
+ if( yadif_work->dst == NULL )
+ {
+ hb_error( "thread started when no work available" );
+ hb_snooze(500);
+ continue;
+ }
+
+ is_combed = pv->yadif_arguments[segment].is_combed;
+
+ /*
+ * Process all three planes, but only this segment of it.
+ */
+ for( plane = 0; plane < 3; plane++)
+ {
+
+ dst = yadif_work->dst;
+ parity = yadif_work->parity;
+ tff = yadif_work->tff;
+ w = pv->width[plane];
+ h = pv->height[plane];
+ ref_stride = pv->ref_stride[plane];
+ segment_start = ( h / pv->cpu_count ) * segment;
+ if( segment == pv->cpu_count - 1 )
+ {
+ /*
+ * Final segment
+ */
+ segment_stop = h;
+ } else {
+ segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
+ }
+
+ for( y = segment_start; y < segment_stop; y++ )
+ {
+ if( ( pv->mode == 4 && is_combed ) || is_combed == 2 )
+ {
+ uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
+ uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
+ uint8_t *next = &pv->ref[2][plane][y*ref_stride];
+ uint8_t *dst2 = &dst[plane][y*w];
+
+ blend_filter_line( dst2, cur, plane, y, pv );
+ }
+ else if( (y ^ parity) & 1 && is_combed == 1 )
+ {
+ uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
+ uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
+ uint8_t *next = &pv->ref[2][plane][y*ref_stride];
+ uint8_t *dst2 = &dst[plane][y*w];
+
+ yadif_filter_line( dst2, prev, cur, next, plane, parity ^ tff, y, pv );
+ }
+ else
+ {
+ memcpy( &dst[plane][y*w],
+ &pv->ref[1][plane][y*ref_stride],
+ w * sizeof(uint8_t) );
+ }
+ }
+ }
+ /*
+ * Finished this segment, let everyone know.
+ */
+ hb_unlock( pv->yadif_complete_lock[segment] );
+ }
+ free( thread_args_v );
+}
+