OSDN Git Service

import 0.9.3
[handbrake-jp/handbrake-jp.git] / libhb / deinterlace.c
1 /*
2  Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
3
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  GNU General Public License for more details.
13
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "hb.h"
20 #include "libavcodec/avcodec.h"
21 #include "mpeg2dec/mpeg2.h"
22
23 #define SUPPRESS_AV_LOG
24
25 #define YADIF_MODE_DEFAULT     -1
26 #define YADIF_PARITY_DEFAULT   -1
27
28 #define MCDEINT_MODE_DEFAULT   -1
29 #define MCDEINT_QP_DEFAULT      1
30
31 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
32 #define MIN3(a,b,c) MIN(MIN(a,b),c)
33 #define MAX3(a,b,c) MAX(MAX(a,b),c)
34
35 typedef struct yadif_arguments_s {
36     uint8_t **dst;
37     int parity;
38     int tff;
39     int stop;
40 } yadif_arguments_t;
41
42 struct hb_filter_private_s
43 {
44     int              pix_fmt;
45     int              width[3];
46     int              height[3];
47
48     int              yadif_mode;
49     int              yadif_parity;
50     int              yadif_ready;
51
52     uint8_t        * yadif_ref[4][3];
53     int              yadif_ref_stride[3];
54
55     int              cpu_count;
56
57     hb_thread_t    ** yadif_threads;        // Threads for Yadif - one per CPU
58     hb_lock_t      ** yadif_begin_lock;     // Thread has work
59     hb_lock_t      ** yadif_complete_lock;  // Thread has completed work
60     yadif_arguments_t *yadif_arguments;     // Arguments to thread for work
61
62     int              mcdeint_mode;
63     int              mcdeint_qp;
64
65     int              mcdeint_outbuf_size;
66     uint8_t        * mcdeint_outbuf;
67     AVCodecContext * mcdeint_avctx_enc;
68     AVFrame        * mcdeint_frame;
69     AVFrame        * mcdeint_frame_dec;
70
71     AVPicture        pic_in;
72     AVPicture        pic_out;
73     hb_buffer_t *    buf_out[2];
74     hb_buffer_t *    buf_settings;
75 };
76
77 hb_filter_private_t * hb_deinterlace_init( int pix_fmt,
78                                            int width,
79                                            int height,
80                                            char * settings );
81
82 int hb_deinterlace_work( hb_buffer_t * buf_in,
83                          hb_buffer_t ** buf_out,
84                          int pix_fmt,
85                          int width,
86                          int height,
87                          hb_filter_private_t * pv );
88
89 void hb_deinterlace_close( hb_filter_private_t * pv );
90
91 hb_filter_object_t hb_filter_deinterlace =
92 {
93     FILTER_DEINTERLACE,
94     "Deinterlace (ffmpeg or yadif/mcdeint)",
95     NULL,
96     hb_deinterlace_init,
97     hb_deinterlace_work,
98     hb_deinterlace_close,
99 };
100
101
102 static void yadif_store_ref( const uint8_t ** pic,
103                              hb_filter_private_t * pv )
104 {
105     memcpy( pv->yadif_ref[3],
106             pv->yadif_ref[0],
107             sizeof(uint8_t *)*3 );
108
109     memmove( pv->yadif_ref[0],
110              pv->yadif_ref[1],
111              sizeof(uint8_t *)*3*3 );
112
113     int i;
114     for( i = 0; i < 3; i++ )
115     {
116         const uint8_t * src = pic[i];
117         uint8_t * ref = pv->yadif_ref[2][i];
118
119         int w = pv->width[i];
120         int ref_stride = pv->yadif_ref_stride[i];
121
122         int y;
123         for( y = 0; y < pv->height[i]; y++ )
124         {
125             memcpy(ref, src, w);
126             src = (uint8_t*)src + w;
127             ref = (uint8_t*)ref + ref_stride;
128         }
129     }
130 }
131
132 static void yadif_filter_line( uint8_t *dst,
133                                uint8_t *prev,
134                                uint8_t *cur,
135                                uint8_t *next,
136                                int plane,
137                                int parity,
138                                hb_filter_private_t * pv )
139 {
140     uint8_t *prev2 = parity ? prev : cur ;
141     uint8_t *next2 = parity ? cur  : next;
142
143     int w = pv->width[plane];
144     int refs = pv->yadif_ref_stride[plane];
145
146     int x;
147     for( x = 0; x < w; x++)
148     {
149         int c              = cur[-refs];
150         int d              = (prev2[0] + next2[0])>>1;
151         int e              = cur[+refs];
152         int temporal_diff0 = ABS(prev2[0] - next2[0]);
153         int temporal_diff1 = ( ABS(prev[-refs] - c) + ABS(prev[+refs] - e) ) >> 1;
154         int temporal_diff2 = ( ABS(next[-refs] - c) + ABS(next[+refs] - e) ) >> 1;
155         int diff           = MAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
156         int spatial_pred   = (c+e)>>1;
157         int spatial_score  = ABS(cur[-refs-1] - cur[+refs-1]) + ABS(c-e) +
158                              ABS(cur[-refs+1] - cur[+refs+1]) - 1;
159
160 #define YADIF_CHECK(j)\
161         {   int score = ABS(cur[-refs-1+j] - cur[+refs-1-j])\
162                       + ABS(cur[-refs  +j] - cur[+refs  -j])\
163                       + ABS(cur[-refs+1+j] - cur[+refs+1-j]);\
164             if( score < spatial_score ){\
165                 spatial_score = score;\
166                 spatial_pred  = (cur[-refs  +j] + cur[+refs  -j])>>1;\
167
168         YADIF_CHECK(-1) YADIF_CHECK(-2) }} }}
169         YADIF_CHECK( 1) YADIF_CHECK( 2) }} }}
170
171         if( pv->yadif_mode < 2 )
172         {
173             int b = (prev2[-2*refs] + next2[-2*refs])>>1;
174             int f = (prev2[+2*refs] + next2[+2*refs])>>1;
175
176             int max = MAX3(d-e, d-c, MIN(b-c, f-e));
177             int min = MIN3(d-e, d-c, MAX(b-c, f-e));
178
179             diff = MAX3( diff, min, -max );
180         }
181
182         if( spatial_pred > d + diff )
183         {
184             spatial_pred = d + diff;
185         }
186         else if( spatial_pred < d - diff )
187         {
188             spatial_pred = d - diff;
189         }
190
191         dst[0] = spatial_pred;
192
193         dst++;
194         cur++;
195         prev++;
196         next++;
197         prev2++;
198         next2++;
199     }
200 }
201
202 typedef struct yadif_thread_arg_s {
203     hb_filter_private_t *pv;
204     int segment;
205 } yadif_thread_arg_t;
206
207 /*
208  * deinterlace this segment of all three planes in a single thread.
209  */
210 void yadif_filter_thread( void *thread_args_v )
211 {
212     yadif_arguments_t *yadif_work = NULL;
213     hb_filter_private_t * pv;
214     int run = 1;
215     int plane;
216     int segment, segment_start, segment_stop;
217     yadif_thread_arg_t *thread_args = thread_args_v;
218     uint8_t **dst;
219     int parity, tff, y, w, h, ref_stride, penultimate, ultimate;
220
221
222     pv = thread_args->pv;
223     segment = thread_args->segment;
224
225     hb_log("Yadif Deinterlace thread started for segment %d", segment);
226
227     while( run )
228     {
229         /*
230          * Wait here until there is work to do. hb_lock() blocks until
231          * render releases it to say that there is more work to do.
232          */
233         hb_lock( pv->yadif_begin_lock[segment] );
234
235         yadif_work = &pv->yadif_arguments[segment];
236
237         if( yadif_work->stop )
238         {
239             /*
240              * No more work to do, exit this thread.
241              */
242             run = 0;
243             continue;
244         } 
245
246         if( yadif_work->dst == NULL )
247         {
248             hb_error( "Thread started when no work available" );
249             hb_snooze(500);
250             continue;
251         }
252         
253         /*
254          * Process all three planes, but only this segment of it.
255          */
256         for( plane = 0; plane < 3; plane++)
257         {
258
259             dst = yadif_work->dst;
260             parity = yadif_work->parity;
261             tff = yadif_work->tff;
262             w = pv->width[plane];
263             h = pv->height[plane];
264             penultimate = h -2;
265             ultimate = h - 1;
266             ref_stride = pv->yadif_ref_stride[plane];
267             segment_start = ( h / pv->cpu_count ) * segment;
268             if( segment == pv->cpu_count - 1 )
269             {
270                 /*
271                  * Final segment
272                  */
273                 segment_stop = h;
274             } else {
275                 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
276             }
277
278             for( y = segment_start; y < segment_stop; y++ )
279             {
280                 if( ( ( y ^ parity ) &  1 ) )
281                 {
282                     /* This is the bottom field when TFF and vice-versa.
283                        It's the field that gets filtered. Because yadif
284                        needs 2 lines above and below the one being filtered,
285                        we need to mirror the edges. When TFF, this means
286                        replacing the 2nd line with a copy of the 1st,
287                        and the last with the second-to-last.                  */
288                     if( y > 1 && y < ( h -2 ) )
289                     {
290                         /* This isn't the top or bottom, proceed as normal to yadif. */
291                         uint8_t *prev = &pv->yadif_ref[0][plane][y*ref_stride];
292                         uint8_t *cur  = &pv->yadif_ref[1][plane][y*ref_stride];
293                         uint8_t *next = &pv->yadif_ref[2][plane][y*ref_stride];
294                         uint8_t *dst2 = &dst[plane][y*w];
295
296                         yadif_filter_line( dst2, 
297                                            prev, 
298                                            cur, 
299                                            next, 
300                                            plane, 
301                                            parity ^ tff, 
302                                            pv );
303                     }
304                     else if( y == 0 )
305                     {
306                         /* BFF, so y0 = y1 */
307                         memcpy( &dst[plane][y*w],
308                                 &pv->yadif_ref[1][plane][1*ref_stride],
309                                 w * sizeof(uint8_t) );
310                     }
311                     else if( y == 1 )
312                     {
313                         /* TFF, so y1 = y0 */
314                         memcpy( &dst[plane][y*w],
315                                 &pv->yadif_ref[1][plane][0],
316                                 w * sizeof(uint8_t) );
317                     }
318                     else if( y == penultimate )
319                     {
320                         /* BFF, so penultimate y = ultimate y */
321                         memcpy( &dst[plane][y*w],
322                                 &pv->yadif_ref[1][plane][ultimate*ref_stride],
323                                 w * sizeof(uint8_t) );
324                     }
325                     else if( y == ultimate )
326                     {
327                         /* TFF, so ultimate y = penultimate y */
328                         memcpy( &dst[plane][y*w],
329                                 &pv->yadif_ref[1][plane][penultimate*ref_stride],
330                                 w * sizeof(uint8_t) );
331                     }
332                 }
333                 else
334                 {
335                     /* Preserve this field unfiltered */
336                     memcpy( &dst[plane][y*w],
337                             &pv->yadif_ref[1][plane][y*ref_stride],
338                             w * sizeof(uint8_t) );
339                 }
340             }
341         }
342         /*
343          * Finished this segment, let everyone know.
344          */
345         hb_unlock( pv->yadif_complete_lock[segment] );
346     }
347     free( thread_args_v );
348 }
349
350
351 /*
352  * threaded yadif - each thread deinterlaces a single segment of all
353  * three planes. Where a segment is defined as the frame divided by
354  * the number of CPUs.
355  *
356  * This function blocks until the frame is deinterlaced.
357  */
358 static void yadif_filter( uint8_t ** dst,
359                           int parity,
360                           int tff,
361                           hb_filter_private_t * pv )
362 {
363
364     int segment;
365
366     for( segment = 0; segment < pv->cpu_count; segment++ )
367     {  
368         /*
369          * Setup the work for this plane.
370          */
371         pv->yadif_arguments[segment].parity = parity;
372         pv->yadif_arguments[segment].tff = tff;
373         pv->yadif_arguments[segment].dst = dst;
374
375         /*
376          * Let the thread for this plane know that we've setup work 
377          * for it by releasing the begin lock (ensuring that the
378          * complete lock is already locked so that we block when
379          * we try to lock it again below).
380          */
381         hb_lock( pv->yadif_complete_lock[segment] );
382         hb_unlock( pv->yadif_begin_lock[segment] );
383     }
384
385     /*
386      * Wait until all three threads have completed by trying to get
387      * the complete lock that we locked earlier for each thread, which
388      * will block until that thread has completed the work on that
389      * plane.
390      */
391     for( segment = 0; segment < pv->cpu_count; segment++ )
392     {
393         hb_lock( pv->yadif_complete_lock[segment] );
394         hb_unlock( pv->yadif_complete_lock[segment] );
395     }
396
397     /*
398      * Entire frame is now deinterlaced.
399      */
400 }
401
402 static void mcdeint_filter( uint8_t ** dst,
403                             uint8_t ** src,
404                             int parity,
405                             hb_filter_private_t * pv )
406 {
407     int x, y, i;
408     int out_size;
409
410 #ifdef SUPPRESS_AV_LOG
411     /* TODO: temporarily change log level to suppress obnoxious debug output */
412     int loglevel = av_log_get_level();
413     av_log_set_level( AV_LOG_QUIET );
414 #endif
415
416     for( i=0; i<3; i++ )
417     {
418         pv->mcdeint_frame->data[i] = src[i];
419         pv->mcdeint_frame->linesize[i] = pv->width[i];
420     }
421     pv->mcdeint_avctx_enc->me_cmp     = FF_CMP_SAD;
422     pv->mcdeint_avctx_enc->me_sub_cmp = FF_CMP_SAD;
423     pv->mcdeint_frame->quality        = pv->mcdeint_qp * FF_QP2LAMBDA;
424
425     out_size = avcodec_encode_video( pv->mcdeint_avctx_enc,
426                                      pv->mcdeint_outbuf,
427                                      pv->mcdeint_outbuf_size,
428                                      pv->mcdeint_frame );
429
430     pv->mcdeint_frame_dec = pv->mcdeint_avctx_enc->coded_frame;
431
432     for( i = 0; i < 3; i++ )
433     {
434         int w    = pv->width[i];
435         int h    = pv->height[i];
436         int fils = pv->mcdeint_frame_dec->linesize[i];
437         int srcs = pv->width[i];
438
439         for( y = 0; y < h; y++ )
440         {
441             if( (y ^ parity) & 1 )
442             {
443                 for( x = 0; x < w; x++ )
444                 {
445                     if( (x-2)+(y-1)*w >= 0 && (x+2)+(y+1)*w < w*h )
446                     {
447                         uint8_t * filp =
448                             &pv->mcdeint_frame_dec->data[i][x + y*fils];
449                         uint8_t * srcp = &src[i][x + y*srcs];
450
451                         int diff0 = filp[-fils] - srcp[-srcs];
452                         int diff1 = filp[+fils] - srcp[+srcs];
453
454                         int spatial_score =
455                               ABS(srcp[-srcs-1] - srcp[+srcs-1])
456                             + ABS(srcp[-srcs  ] - srcp[+srcs  ])
457                             + ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
458
459                         int temp = filp[0];
460
461 #define MCDEINT_CHECK(j)\
462                         {   int score = ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
463                                       + ABS(srcp[-srcs  +j] - srcp[+srcs  -j])\
464                                       + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
465                             if( score < spatial_score ) {\
466                                 spatial_score = score;\
467                                 diff0 = filp[-fils+j] - srcp[-srcs+j];\
468                                 diff1 = filp[+fils-j] - srcp[+srcs-j];
469
470                         MCDEINT_CHECK(-1) MCDEINT_CHECK(-2) }} }}
471                         MCDEINT_CHECK( 1) MCDEINT_CHECK( 2) }} }}
472
473                         if(diff0 + diff1 > 0)
474                         {
475                             temp -= (diff0 + diff1 -
476                                      ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
477                         }
478                         else
479                         {
480                             temp -= (diff0 + diff1 +
481                                      ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
482                         }
483
484                         filp[0] = dst[i][x + y*w] =
485                             temp > 255U ? ~(temp>>31) : temp;
486                     }
487                     else
488                     {
489                         dst[i][x + y*w] =
490                             pv->mcdeint_frame_dec->data[i][x + y*fils];
491                     }
492                 }
493             }
494         }
495
496         for( y = 0; y < h; y++ )
497         {
498             if( !((y ^ parity) & 1) )
499             {
500                 for( x = 0; x < w; x++ )
501                 {
502                     pv->mcdeint_frame_dec->data[i][x + y*fils] =
503                         dst[i][x + y*w]= src[i][x + y*srcs];
504                 }
505             }
506         }
507     }
508
509 #ifdef SUPPRESS_AV_LOG
510     /* TODO: restore previous log level */
511     av_log_set_level(loglevel);
512 #endif
513 }
514
515 hb_filter_private_t * hb_deinterlace_init( int pix_fmt,
516                                            int width,
517                                            int height,
518                                            char * settings )
519 {
520     if( pix_fmt != PIX_FMT_YUV420P )
521     {
522         return 0;
523     }
524
525     hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) );
526
527     pv->pix_fmt = pix_fmt;
528
529     pv->width[0]  = width;
530     pv->height[0] = height;
531     pv->width[1]  = pv->width[2]  = width >> 1;
532     pv->height[1] = pv->height[2] = height >> 1;
533
534     pv->buf_out[0] = hb_video_buffer_init( width, height );
535     pv->buf_out[1] = hb_video_buffer_init( width, height );
536     pv->buf_settings = hb_buffer_init( 0 );
537
538     pv->yadif_ready    = 0;
539     pv->yadif_mode     = YADIF_MODE_DEFAULT;
540     pv->yadif_parity   = YADIF_PARITY_DEFAULT;
541
542     pv->mcdeint_mode   = MCDEINT_MODE_DEFAULT;
543     pv->mcdeint_qp     = MCDEINT_QP_DEFAULT;
544
545     if( settings )
546     {
547         sscanf( settings, "%d:%d:%d:%d",
548                 &pv->yadif_mode,
549                 &pv->yadif_parity,
550                 &pv->mcdeint_mode,
551                 &pv->mcdeint_qp );
552     }
553
554     pv->cpu_count = hb_get_cpu_count();
555
556     /* Allocate yadif specific buffers */
557     if( pv->yadif_mode >= 0 )
558     {
559         int i, j;
560         for( i = 0; i < 3; i++ )
561         {
562             int is_chroma = !!i;
563             int w = ((width   + 31) & (~31))>>is_chroma;
564             int h = ((height+6+ 31) & (~31))>>is_chroma;
565
566             pv->yadif_ref_stride[i] = w;
567
568             for( j = 0; j < 3; j++ )
569             {
570                 pv->yadif_ref[j][i] = malloc( w*h*sizeof(uint8_t) ) + 3*w;
571             }
572         }
573
574         /*
575          * Create yadif threads and locks.
576          */
577         pv->yadif_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
578         pv->yadif_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
579         pv->yadif_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
580         pv->yadif_arguments = malloc( sizeof( yadif_arguments_t ) * pv->cpu_count );
581
582         for( i = 0; i < pv->cpu_count; i++ )
583         {
584             yadif_thread_arg_t *thread_args;
585
586             thread_args = malloc( sizeof( yadif_thread_arg_t ) );
587
588             if( thread_args ) {
589                 thread_args->pv = pv;
590                 thread_args->segment = i;
591
592                 pv->yadif_begin_lock[i] = hb_lock_init();
593                 pv->yadif_complete_lock[i] = hb_lock_init();
594
595                 /*
596                  * Important to start off with the threads locked waiting
597                  * on input.
598                  */
599                 hb_lock( pv->yadif_begin_lock[i] );
600
601                 pv->yadif_arguments[i].stop = 0;
602                 pv->yadif_arguments[i].dst = NULL;
603                 
604                 pv->yadif_threads[i] = hb_thread_init( "yadif_filter_segment",
605                                                        yadif_filter_thread,
606                                                        thread_args,
607                                                        HB_NORMAL_PRIORITY );
608             } else {
609                 hb_error( "Yadif could not create threads" );
610             }
611         }
612     }
613
614     /* Allocate mcdeint specific buffers */
615     if( pv->mcdeint_mode >= 0 )
616     {
617         avcodec_init();
618         avcodec_register_all();
619
620         AVCodec * enc = avcodec_find_encoder( CODEC_ID_SNOW );
621
622         int i;
623         for (i = 0; i < 3; i++ )
624         {
625             AVCodecContext * avctx_enc;
626
627             avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context();
628
629             avctx_enc->width                    = width;
630             avctx_enc->height                   = height;
631             avctx_enc->time_base                = (AVRational){1,25};  // meaningless
632             avctx_enc->gop_size                 = 300;
633             avctx_enc->max_b_frames             = 0;
634             avctx_enc->pix_fmt                  = PIX_FMT_YUV420P;
635             avctx_enc->flags                    = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
636             avctx_enc->strict_std_compliance    = FF_COMPLIANCE_EXPERIMENTAL;
637             avctx_enc->global_quality           = 1;
638             avctx_enc->flags2                   = CODEC_FLAG2_MEMC_ONLY;
639             avctx_enc->me_cmp                   = FF_CMP_SAD; //SSE;
640             avctx_enc->me_sub_cmp               = FF_CMP_SAD; //SSE;
641             avctx_enc->mb_cmp                   = FF_CMP_SSE;
642
643             switch( pv->mcdeint_mode )
644             {
645                 case 3:
646                     avctx_enc->refs = 3;
647                 case 2:
648                     avctx_enc->me_method = ME_UMH;
649                 case 1:
650                     avctx_enc->flags |= CODEC_FLAG_4MV;
651                     avctx_enc->dia_size =2;
652                 case 0:
653                     avctx_enc->flags |= CODEC_FLAG_QPEL;
654             }
655
656             avcodec_open(avctx_enc, enc);
657         }
658
659         pv->mcdeint_frame       = avcodec_alloc_frame();
660         pv->mcdeint_outbuf_size = width * height * 10;
661         pv->mcdeint_outbuf      = malloc( pv->mcdeint_outbuf_size );
662     }
663
664     return pv;
665 }
666
667 void hb_deinterlace_close( hb_filter_private_t * pv )
668 {
669     if( !pv )
670     {
671         return;
672     }
673
674     /* Cleanup frame buffers */
675     if( pv->buf_out[0] )
676     {
677         hb_buffer_close( &pv->buf_out[0] );
678     }
679     if( pv->buf_out[1] )
680     {
681         hb_buffer_close( &pv->buf_out[1] );
682     }
683     if (pv->buf_settings )
684     {
685         hb_buffer_close( &pv->buf_settings );
686     }
687
688     /* Cleanup yadif specific buffers */
689     if( pv->yadif_mode >= 0 )
690     {
691         int i;
692         for( i = 0; i<3*3; i++ )
693         {
694             uint8_t **p = &pv->yadif_ref[i%3][i/3];
695             if (*p)
696             {
697                 free( *p - 3*pv->yadif_ref_stride[i/3] );
698                 *p = NULL;
699             }
700         }
701
702         for( i = 0; i < pv->cpu_count; i++)
703         {
704             /*
705              * Tell each yadif thread to stop, and then cleanup.
706              */
707             pv->yadif_arguments[i].stop = 1;
708             hb_unlock(  pv->yadif_begin_lock[i] );
709
710             hb_thread_close( &pv->yadif_threads[i] );
711             hb_lock_close( &pv->yadif_begin_lock[i] );
712             hb_lock_close( &pv->yadif_complete_lock[i] );
713         }
714         
715         /*
716          * free memory for yadif structs
717          */
718         free( pv->yadif_threads );
719         free( pv->yadif_begin_lock );
720         free( pv->yadif_complete_lock );
721         free( pv->yadif_arguments );
722     }
723
724     /* Cleanup mcdeint specific buffers */
725     if( pv->mcdeint_mode >= 0 )
726     {
727         if( pv->mcdeint_avctx_enc )
728         {
729             avcodec_close( pv->mcdeint_avctx_enc );
730             av_freep( &pv->mcdeint_avctx_enc );
731         }
732         if( pv->mcdeint_outbuf )
733         {
734             free( pv->mcdeint_outbuf );
735         }
736     }
737
738     free( pv );
739 }
740
741 int hb_deinterlace_work( hb_buffer_t * buf_in,
742                          hb_buffer_t ** buf_out,
743                          int pix_fmt,
744                          int width,
745                          int height,
746                          hb_filter_private_t * pv )
747 {
748     if( !pv ||
749         pix_fmt != pv->pix_fmt ||
750         width   != pv->width[0] ||
751         height  != pv->height[0] )
752     {
753         return FILTER_FAILED;
754     }
755
756     avpicture_fill( &pv->pic_in, buf_in->data,
757                     pix_fmt, width, height );
758
759     /* Use libavcodec deinterlace if yadif_mode < 0 */
760     if( pv->yadif_mode < 0 )
761     {
762         avpicture_fill( &pv->pic_out, pv->buf_out[0]->data,
763                         pix_fmt, width, height );
764
765         avpicture_deinterlace( &pv->pic_out, &pv->pic_in,
766                                pix_fmt, width, height );
767
768         hb_buffer_copy_settings( pv->buf_out[0], buf_in );
769
770         *buf_out = pv->buf_out[0];
771
772         return FILTER_OK;
773     }
774
775     /* Determine if top-field first layout */
776     int tff;
777     if( pv->yadif_parity < 0 )
778     {
779         tff = !!(buf_in->flags & PIC_FLAG_TOP_FIELD_FIRST);
780     }
781     else
782     {
783         tff = (pv->yadif_parity & 1) ^ 1;
784     }
785
786     /* Store current frame in yadif cache */
787     yadif_store_ref( (const uint8_t**)pv->pic_in.data, pv );
788
789     /* If yadif is not ready, store another ref and return FILTER_DELAY */
790     if( pv->yadif_ready == 0 )
791     {
792         yadif_store_ref( (const uint8_t**)pv->pic_in.data, pv );
793
794         hb_buffer_copy_settings( pv->buf_settings, buf_in );
795
796         /* don't let 'work_loop' send a chapter mark upstream */
797         buf_in->new_chap  = 0;
798
799         pv->yadif_ready = 1;
800
801         return FILTER_DELAY;
802     }
803
804     /* Perform yadif and mcdeint filtering */
805     int frame;
806     for( frame = 0; frame <= (pv->yadif_mode & 1); frame++ )
807     {
808         int parity = frame ^ tff ^ 1;
809
810         avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,
811                         pix_fmt, width, height );
812
813         yadif_filter( pv->pic_out.data, parity, tff, pv );
814
815         if( pv->mcdeint_mode >= 0 )
816         {
817             avpicture_fill( &pv->pic_in,  pv->buf_out[(frame^1)]->data,
818                             pix_fmt, width, height );
819
820             mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );
821
822             *buf_out = pv->buf_out[ (frame^1)];
823         }
824         else
825         {
826             *buf_out = pv->buf_out[!(frame^1)];
827         }
828     }
829
830     /* Copy buffered settings to output buffer settings */
831     hb_buffer_copy_settings( *buf_out, pv->buf_settings );
832
833     /* Replace buffered settings with input buffer settings */
834     hb_buffer_copy_settings( pv->buf_settings, buf_in );
835
836     /* don't let 'work_loop' send a chapter mark upstream */
837     buf_in->new_chap  = 0;
838
839     return FILTER_OK;
840 }
841
842