OSDN Git Service

Code comment clean-up, mostly to clarify the difference between the prev and next...
[handbrake-jp/handbrake-jp-git.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;
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             ref_stride = pv->yadif_ref_stride[plane];
265             segment_start = ( h / pv->cpu_count ) * segment;
266             if( segment == pv->cpu_count - 1 )
267             {
268                 /*
269                  * Final segment
270                  */
271                 segment_stop = h;
272             } else {
273                 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
274             }
275
276             for( y = segment_start; y < segment_stop; y++ )
277             {
278                 if( (y ^ parity) &  1 )
279                 {
280                     uint8_t *prev = &pv->yadif_ref[0][plane][y*ref_stride];
281                     uint8_t *cur  = &pv->yadif_ref[1][plane][y*ref_stride];
282                     uint8_t *next = &pv->yadif_ref[2][plane][y*ref_stride];
283                     uint8_t *dst2 = &dst[plane][y*w];
284                     
285                     yadif_filter_line( dst2, 
286                                        prev, 
287                                        cur, 
288                                        next, 
289                                        plane, 
290                                        parity ^ tff, 
291                                        pv );
292                     
293                 }
294                 else
295                 {
296                     memcpy( &dst[plane][y*w],
297                             &pv->yadif_ref[1][plane][y*ref_stride],
298                             w * sizeof(uint8_t) );
299                 }
300             }
301         }
302         /*
303          * Finished this segment, let everyone know.
304          */
305         hb_unlock( pv->yadif_complete_lock[segment] );
306     }
307     free( thread_args_v );
308 }
309
310
311 /*
312  * threaded yadif - each thread deinterlaces a single segment of all
313  * three planes. Where a segment is defined as the frame divided by
314  * the number of CPUs.
315  *
316  * This function blocks until the frame is deinterlaced.
317  */
318 static void yadif_filter( uint8_t ** dst,
319                           int parity,
320                           int tff,
321                           hb_filter_private_t * pv )
322 {
323
324     int segment;
325
326     for( segment = 0; segment < pv->cpu_count; segment++ )
327     {  
328         /*
329          * Setup the work for this plane.
330          */
331         pv->yadif_arguments[segment].parity = parity;
332         pv->yadif_arguments[segment].tff = tff;
333         pv->yadif_arguments[segment].dst = dst;
334
335         /*
336          * Let the thread for this plane know that we've setup work 
337          * for it by releasing the begin lock (ensuring that the
338          * complete lock is already locked so that we block when
339          * we try to lock it again below).
340          */
341         hb_lock( pv->yadif_complete_lock[segment] );
342         hb_unlock( pv->yadif_begin_lock[segment] );
343     }
344
345     /*
346      * Wait until all three threads have completed by trying to get
347      * the complete lock that we locked earlier for each thread, which
348      * will block until that thread has completed the work on that
349      * plane.
350      */
351     for( segment = 0; segment < pv->cpu_count; segment++ )
352     {
353         hb_lock( pv->yadif_complete_lock[segment] );
354         hb_unlock( pv->yadif_complete_lock[segment] );
355     }
356
357     /*
358      * Entire frame is now deinterlaced.
359      */
360 }
361
362 static void mcdeint_filter( uint8_t ** dst,
363                             uint8_t ** src,
364                             int parity,
365                             hb_filter_private_t * pv )
366 {
367     int x, y, i;
368     int out_size;
369
370 #ifdef SUPPRESS_AV_LOG
371     /* TODO: temporarily change log level to suppress obnoxious debug output */
372     int loglevel = av_log_get_level();
373     av_log_set_level( AV_LOG_QUIET );
374 #endif
375
376     for( i=0; i<3; i++ )
377     {
378         pv->mcdeint_frame->data[i] = src[i];
379         pv->mcdeint_frame->linesize[i] = pv->width[i];
380     }
381     pv->mcdeint_avctx_enc->me_cmp     = FF_CMP_SAD;
382     pv->mcdeint_avctx_enc->me_sub_cmp = FF_CMP_SAD;
383     pv->mcdeint_frame->quality        = pv->mcdeint_qp * FF_QP2LAMBDA;
384
385     out_size = avcodec_encode_video( pv->mcdeint_avctx_enc,
386                                      pv->mcdeint_outbuf,
387                                      pv->mcdeint_outbuf_size,
388                                      pv->mcdeint_frame );
389
390     pv->mcdeint_frame_dec = pv->mcdeint_avctx_enc->coded_frame;
391
392     for( i = 0; i < 3; i++ )
393     {
394         int w    = pv->width[i];
395         int h    = pv->height[i];
396         int fils = pv->mcdeint_frame_dec->linesize[i];
397         int srcs = pv->width[i];
398
399         for( y = 0; y < h; y++ )
400         {
401             if( (y ^ parity) & 1 )
402             {
403                 for( x = 0; x < w; x++ )
404                 {
405                     if( (x-2)+(y-1)*w >= 0 && (x+2)+(y+1)*w < w*h )
406                     {
407                         uint8_t * filp =
408                             &pv->mcdeint_frame_dec->data[i][x + y*fils];
409                         uint8_t * srcp = &src[i][x + y*srcs];
410
411                         int diff0 = filp[-fils] - srcp[-srcs];
412                         int diff1 = filp[+fils] - srcp[+srcs];
413
414                         int spatial_score =
415                               ABS(srcp[-srcs-1] - srcp[+srcs-1])
416                             + ABS(srcp[-srcs  ] - srcp[+srcs  ])
417                             + ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
418
419                         int temp = filp[0];
420
421 #define MCDEINT_CHECK(j)\
422                         {   int score = ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
423                                       + ABS(srcp[-srcs  +j] - srcp[+srcs  -j])\
424                                       + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
425                             if( score < spatial_score ) {\
426                                 spatial_score = score;\
427                                 diff0 = filp[-fils+j] - srcp[-srcs+j];\
428                                 diff1 = filp[+fils-j] - srcp[+srcs-j];
429
430                         MCDEINT_CHECK(-1) MCDEINT_CHECK(-2) }} }}
431                         MCDEINT_CHECK( 1) MCDEINT_CHECK( 2) }} }}
432
433                         if(diff0 + diff1 > 0)
434                         {
435                             temp -= (diff0 + diff1 -
436                                      ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
437                         }
438                         else
439                         {
440                             temp -= (diff0 + diff1 +
441                                      ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
442                         }
443
444                         filp[0] = dst[i][x + y*w] =
445                             temp > 255U ? ~(temp>>31) : temp;
446                     }
447                     else
448                     {
449                         dst[i][x + y*w] =
450                             pv->mcdeint_frame_dec->data[i][x + y*fils];
451                     }
452                 }
453             }
454         }
455
456         for( y = 0; y < h; y++ )
457         {
458             if( !((y ^ parity) & 1) )
459             {
460                 for( x = 0; x < w; x++ )
461                 {
462                     pv->mcdeint_frame_dec->data[i][x + y*fils] =
463                         dst[i][x + y*w]= src[i][x + y*srcs];
464                 }
465             }
466         }
467     }
468
469 #ifdef SUPPRESS_AV_LOG
470     /* TODO: restore previous log level */
471     av_log_set_level(loglevel);
472 #endif
473 }
474
475 hb_filter_private_t * hb_deinterlace_init( int pix_fmt,
476                                            int width,
477                                            int height,
478                                            char * settings )
479 {
480     if( pix_fmt != PIX_FMT_YUV420P )
481     {
482         return 0;
483     }
484
485     hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) );
486
487     pv->pix_fmt = pix_fmt;
488
489     pv->width[0]  = width;
490     pv->height[0] = height;
491     pv->width[1]  = pv->width[2]  = width >> 1;
492     pv->height[1] = pv->height[2] = height >> 1;
493
494     int buf_size = 3 * width * height / 2;
495     pv->buf_out[0] = hb_buffer_init( buf_size );
496     pv->buf_out[1] = hb_buffer_init( buf_size );
497     pv->buf_settings = hb_buffer_init( 0 );
498
499     pv->yadif_ready    = 0;
500     pv->yadif_mode     = YADIF_MODE_DEFAULT;
501     pv->yadif_parity   = YADIF_PARITY_DEFAULT;
502
503     pv->mcdeint_mode   = MCDEINT_MODE_DEFAULT;
504     pv->mcdeint_qp     = MCDEINT_QP_DEFAULT;
505
506     if( settings )
507     {
508         sscanf( settings, "%d:%d:%d:%d",
509                 &pv->yadif_mode,
510                 &pv->yadif_parity,
511                 &pv->mcdeint_mode,
512                 &pv->mcdeint_qp );
513     }
514
515     pv->cpu_count = hb_get_cpu_count();
516
517     /* Allocate yadif specific buffers */
518     if( pv->yadif_mode >= 0 )
519     {
520         int i, j;
521         for( i = 0; i < 3; i++ )
522         {
523             int is_chroma = !!i;
524             int w = ((width   + 31) & (~31))>>is_chroma;
525             int h = ((height+6+ 31) & (~31))>>is_chroma;
526
527             pv->yadif_ref_stride[i] = w;
528
529             for( j = 0; j < 3; j++ )
530             {
531                 pv->yadif_ref[j][i] = malloc( w*h*sizeof(uint8_t) ) + 3*w;
532             }
533         }
534
535         /*
536          * Create yadif threads and locks.
537          */
538         pv->yadif_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
539         pv->yadif_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
540         pv->yadif_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
541         pv->yadif_arguments = malloc( sizeof( yadif_arguments_t ) * pv->cpu_count );
542
543         for( i = 0; i < pv->cpu_count; i++ )
544         {
545             yadif_thread_arg_t *thread_args;
546
547             thread_args = malloc( sizeof( yadif_thread_arg_t ) );
548
549             if( thread_args ) {
550                 thread_args->pv = pv;
551                 thread_args->segment = i;
552
553                 pv->yadif_begin_lock[i] = hb_lock_init();
554                 pv->yadif_complete_lock[i] = hb_lock_init();
555
556                 /*
557                  * Important to start off with the threads locked waiting
558                  * on input.
559                  */
560                 hb_lock( pv->yadif_begin_lock[i] );
561
562                 pv->yadif_arguments[i].stop = 0;
563                 pv->yadif_arguments[i].dst = NULL;
564                 
565                 pv->yadif_threads[i] = hb_thread_init( "yadif_filter_segment",
566                                                        yadif_filter_thread,
567                                                        thread_args,
568                                                        HB_NORMAL_PRIORITY );
569             } else {
570                 hb_error( "Yadif could not create threads" );
571             }
572         }
573     }
574
575     /* Allocate mcdeint specific buffers */
576     if( pv->mcdeint_mode >= 0 )
577     {
578         avcodec_init();
579         avcodec_register_all();
580
581         AVCodec * enc = avcodec_find_encoder( CODEC_ID_SNOW );
582
583         int i;
584         for (i = 0; i < 3; i++ )
585         {
586             AVCodecContext * avctx_enc;
587
588             avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context();
589
590             avctx_enc->width                    = width;
591             avctx_enc->height                   = height;
592             avctx_enc->time_base                = (AVRational){1,25};  // meaningless
593             avctx_enc->gop_size                 = 300;
594             avctx_enc->max_b_frames             = 0;
595             avctx_enc->pix_fmt                  = PIX_FMT_YUV420P;
596             avctx_enc->flags                    = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
597             avctx_enc->strict_std_compliance    = FF_COMPLIANCE_EXPERIMENTAL;
598             avctx_enc->global_quality           = 1;
599             avctx_enc->flags2                   = CODEC_FLAG2_MEMC_ONLY;
600             avctx_enc->me_cmp                   = FF_CMP_SAD; //SSE;
601             avctx_enc->me_sub_cmp               = FF_CMP_SAD; //SSE;
602             avctx_enc->mb_cmp                   = FF_CMP_SSE;
603
604             switch( pv->mcdeint_mode )
605             {
606                 case 3:
607                     avctx_enc->refs = 3;
608                 case 2:
609                     avctx_enc->me_method = ME_UMH;
610                 case 1:
611                     avctx_enc->flags |= CODEC_FLAG_4MV;
612                     avctx_enc->dia_size =2;
613                 case 0:
614                     avctx_enc->flags |= CODEC_FLAG_QPEL;
615             }
616
617             avcodec_open(avctx_enc, enc);
618         }
619
620         pv->mcdeint_frame       = avcodec_alloc_frame();
621         pv->mcdeint_outbuf_size = width * height * 10;
622         pv->mcdeint_outbuf      = malloc( pv->mcdeint_outbuf_size );
623     }
624
625     return pv;
626 }
627
628 void hb_deinterlace_close( hb_filter_private_t * pv )
629 {
630     if( !pv )
631     {
632         return;
633     }
634
635     /* Cleanup frame buffers */
636     if( pv->buf_out[0] )
637     {
638         hb_buffer_close( &pv->buf_out[0] );
639     }
640     if( pv->buf_out[1] )
641     {
642         hb_buffer_close( &pv->buf_out[1] );
643     }
644     if (pv->buf_settings )
645     {
646         hb_buffer_close( &pv->buf_settings );
647     }
648
649     /* Cleanup yadif specific buffers */
650     if( pv->yadif_mode >= 0 )
651     {
652         int i;
653         for( i = 0; i<3*3; i++ )
654         {
655             uint8_t **p = &pv->yadif_ref[i%3][i/3];
656             if (*p)
657             {
658                 free( *p - 3*pv->yadif_ref_stride[i/3] );
659                 *p = NULL;
660             }
661         }
662
663         for( i = 0; i < pv->cpu_count; i++)
664         {
665             /*
666              * Tell each yadif thread to stop, and then cleanup.
667              */
668             pv->yadif_arguments[i].stop = 1;
669             hb_unlock(  pv->yadif_begin_lock[i] );
670
671             hb_thread_close( &pv->yadif_threads[i] );
672             hb_lock_close( &pv->yadif_begin_lock[i] );
673             hb_lock_close( &pv->yadif_complete_lock[i] );
674         }
675         
676         /*
677          * free memory for yadif structs
678          */
679         free( pv->yadif_threads );
680         free( pv->yadif_begin_lock );
681         free( pv->yadif_complete_lock );
682         free( pv->yadif_arguments );
683     }
684
685     /* Cleanup mcdeint specific buffers */
686     if( pv->mcdeint_mode >= 0 )
687     {
688         if( pv->mcdeint_avctx_enc )
689         {
690             avcodec_close( pv->mcdeint_avctx_enc );
691             av_freep( &pv->mcdeint_avctx_enc );
692         }
693         if( pv->mcdeint_outbuf )
694         {
695             free( pv->mcdeint_outbuf );
696         }
697     }
698
699     free( pv );
700 }
701
702 int hb_deinterlace_work( hb_buffer_t * buf_in,
703                          hb_buffer_t ** buf_out,
704                          int pix_fmt,
705                          int width,
706                          int height,
707                          hb_filter_private_t * pv )
708 {
709     if( !pv ||
710         pix_fmt != pv->pix_fmt ||
711         width   != pv->width[0] ||
712         height  != pv->height[0] )
713     {
714         return FILTER_FAILED;
715     }
716
717     avpicture_fill( &pv->pic_in, buf_in->data,
718                     pix_fmt, width, height );
719
720     /* Use libavcodec deinterlace if yadif_mode < 0 */
721     if( pv->yadif_mode < 0 )
722     {
723         avpicture_fill( &pv->pic_out, pv->buf_out[0]->data,
724                         pix_fmt, width, height );
725
726         avpicture_deinterlace( &pv->pic_out, &pv->pic_in,
727                                pix_fmt, width, height );
728
729         hb_buffer_copy_settings( pv->buf_out[0], buf_in );
730
731         *buf_out = pv->buf_out[0];
732
733         return FILTER_OK;
734     }
735
736     /* Determine if top-field first layout */
737     int tff;
738     if( pv->yadif_parity < 0 )
739     {
740         tff = !!(buf_in->flags & PIC_FLAG_TOP_FIELD_FIRST);
741     }
742     else
743     {
744         tff = (pv->yadif_parity & 1) ^ 1;
745     }
746
747     /* Store current frame in yadif cache */
748     yadif_store_ref( (const uint8_t**)pv->pic_in.data, pv );
749
750     /* If yadif is not ready, store another ref and return FILTER_DELAY */
751     if( pv->yadif_ready == 0 )
752     {
753         yadif_store_ref( (const uint8_t**)pv->pic_in.data, pv );
754
755         hb_buffer_copy_settings( pv->buf_settings, buf_in );
756
757         /* don't let 'work_loop' send a chapter mark upstream */
758         buf_in->new_chap  = 0;
759
760         pv->yadif_ready = 1;
761
762         return FILTER_DELAY;
763     }
764
765     /* Perform yadif and mcdeint filtering */
766     int frame;
767     for( frame = 0; frame <= (pv->yadif_mode & 1); frame++ )
768     {
769         int parity = frame ^ tff ^ 1;
770
771         avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,
772                         pix_fmt, width, height );
773
774         yadif_filter( pv->pic_out.data, parity, tff, pv );
775
776         if( pv->mcdeint_mode >= 0 )
777         {
778             avpicture_fill( &pv->pic_in,  pv->buf_out[(frame^1)]->data,
779                             pix_fmt, width, height );
780
781             mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );
782
783             *buf_out = pv->buf_out[ (frame^1)];
784         }
785         else
786         {
787             *buf_out = pv->buf_out[!(frame^1)];
788         }
789     }
790
791     /* Copy buffered settings to output buffer settings */
792     hb_buffer_copy_settings( *buf_out, pv->buf_settings );
793
794     /* Replace buffered settings with input buffer settings */
795     hb_buffer_copy_settings( pv->buf_settings, buf_in );
796
797     /* don't let 'work_loop' send a chapter mark upstream */
798     buf_in->new_chap  = 0;
799
800     return FILTER_OK;
801 }
802
803