OSDN Git Service

This huge patch from huevos_rancheros ports a number of video filters from mencoder...
[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 "ffmpeg/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 struct hb_filter_private_s 
36 {
37     int              pix_fmt;
38     int              width[3];
39     int              height[3];
40
41     int              yadif_mode;
42     int              yadif_parity;
43     int              yadif_ready;
44     
45     uint8_t        * yadif_ref[4][3];        
46     int              yadif_ref_stride[3];
47     
48     int              mcdeint_mode;
49     int              mcdeint_qp;
50     
51     int              mcdeint_outbuf_size;
52     uint8_t        * mcdeint_outbuf;
53     AVCodecContext * mcdeint_avctx_enc;
54     AVFrame        * mcdeint_frame;
55     AVFrame        * mcdeint_frame_dec;
56     
57     AVPicture        pic_in;
58     AVPicture        pic_out;            
59     hb_buffer_t *    buf_out[2];
60     hb_buffer_t *    buf_settings;
61 };
62
63 hb_filter_private_t * hb_deinterlace_init( int pix_fmt, 
64                                            int width, 
65                                            int height,
66                                            char * settings );
67
68 int hb_deinterlace_work( const hb_buffer_t * buf_in,
69                          hb_buffer_t ** buf_out,
70                          int pix_fmt,
71                          int width, 
72                          int height,
73                          hb_filter_private_t * pv );
74
75 void hb_deinterlace_close( hb_filter_private_t * pv );
76
77 hb_filter_object_t hb_filter_deinterlace =
78 {   
79     FILTER_DEINTERLACE,
80     "Deinterlace (yadif/mcdeint)",
81     NULL,
82     hb_deinterlace_init,
83     hb_deinterlace_work,
84     hb_deinterlace_close,
85 };
86
87 static void yadif_store_ref( const uint8_t ** pic, 
88                              hb_filter_private_t * pv )
89 {
90     memcpy( pv->yadif_ref[3], 
91             pv->yadif_ref[0], 
92             sizeof(uint8_t *)*3 );
93     
94     memmove( pv->yadif_ref[0], 
95              pv->yadif_ref[1], 
96              sizeof(uint8_t *)*3*3 );    
97     
98     int i;
99     for( i = 0; i < 3; i++ )
100     {
101         const uint8_t * src = pic[i];
102         uint8_t * ref = pv->yadif_ref[2][i];
103         
104         int w = pv->width[i];
105         int h = pv->height[i];
106         int ref_stride = pv->yadif_ref_stride[i];
107         
108         int y;
109         for( y = 0; y < pv->height[i]; y++ )
110         {
111             memcpy(ref, src, w);
112             src = (uint8_t*)src + w;
113             ref = (uint8_t*)ref + ref_stride;
114         }
115     }
116 }
117
118 static void yadif_filter_line( uint8_t *dst,
119                                uint8_t *prev,
120                                uint8_t *cur, 
121                                uint8_t *next,
122                                int plane,
123                                int parity,
124                                hb_filter_private_t * pv )
125 {
126     uint8_t *prev2 = parity ? prev : cur ;
127     uint8_t *next2 = parity ? cur  : next;
128     
129     int w = pv->width[plane];
130     int refs = pv->yadif_ref_stride[plane];
131     
132     int x;
133     for( x = 0; x < w; x++)
134     {
135         int c              = cur[-refs];
136         int d              = (prev2[0] + next2[0])>>1;
137         int e              = cur[+refs];
138         int temporal_diff0 = ABS(prev2[0] - next2[0]);
139         int temporal_diff1 = ( ABS(prev[-refs] - c) + ABS(prev[+refs] - e) ) >> 1;
140         int temporal_diff2 = ( ABS(next[-refs] - c) + ABS(next[+refs] - e) ) >> 1;
141         int diff           = MAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
142         int spatial_pred   = (c+e)>>1;
143         int spatial_score  = ABS(cur[-refs-1] - cur[+refs-1]) + ABS(c-e) +
144                              ABS(cur[-refs+1] - cur[+refs+1]) - 1;
145
146 #define YADIF_CHECK(j)\
147         {   int score = ABS(cur[-refs-1+j] - cur[+refs-1-j])\
148                       + ABS(cur[-refs  +j] - cur[+refs  -j])\
149                       + ABS(cur[-refs+1+j] - cur[+refs+1-j]);\
150             if( score < spatial_score ){\
151                 spatial_score = score;\
152                 spatial_pred  = (cur[-refs  +j] + cur[+refs  -j])>>1;\
153                             
154         YADIF_CHECK(-1) YADIF_CHECK(-2) }} }}
155         YADIF_CHECK( 1) YADIF_CHECK( 2) }} }}
156
157         if( pv->yadif_mode < 2 )
158         {
159             int b = (prev2[-2*refs] + next2[-2*refs])>>1;
160             int f = (prev2[+2*refs] + next2[+2*refs])>>1;
161             
162             int max = MAX3(d-e, d-c, MIN(b-c, f-e));
163             int min = MIN3(d-e, d-c, MAX(b-c, f-e));
164
165             diff = MAX3( diff, min, -max );
166         }
167
168         if( spatial_pred > d + diff )
169         {
170             spatial_pred = d + diff;
171         }
172         else if( spatial_pred < d - diff )
173         {
174             spatial_pred = d - diff;
175         }
176
177         dst[0] = spatial_pred;
178
179         dst++;
180         cur++;
181         prev++;
182         next++;
183         prev2++;
184         next2++;
185     }
186 }
187
188 static void yadif_filter( uint8_t ** dst,
189                           int parity,
190                           int tff,
191                           hb_filter_private_t * pv )
192 {
193     int i;
194     for( i = 0; i < 3; i++ )
195     {   
196         int w = pv->width[i];
197         int h = pv->height[i];
198         int ref_stride = pv->yadif_ref_stride[i];
199         
200         int y;
201         for( y = 0; y < h; y++ )
202         {
203             if( (y ^ parity) &  1 )
204             {
205                 uint8_t *prev = &pv->yadif_ref[0][i][y*ref_stride];
206                 uint8_t *cur  = &pv->yadif_ref[1][i][y*ref_stride];
207                 uint8_t *next = &pv->yadif_ref[2][i][y*ref_stride];
208                 uint8_t *dst2 = &dst[i][y*w];
209                 
210                 yadif_filter_line( dst2, prev, cur, next, i, parity ^ tff, pv );
211             }
212             else
213             {
214                 memcpy( &dst[i][y*w], 
215                         &pv->yadif_ref[1][i][y*ref_stride], 
216                         w * sizeof(uint8_t) );
217             }
218         }
219     }
220 }
221
222 static void mcdeint_filter( uint8_t ** dst, 
223                             uint8_t ** src,
224                             int parity,
225                             hb_filter_private_t * pv )
226 {
227     int x, y, i;
228     int out_size;    
229    
230 #ifdef SUPPRESS_AV_LOG
231     /* TODO: temporarily change log level to suppress obnoxious debug output */
232     int loglevel = av_log_get_level();
233     av_log_set_level( AV_LOG_QUIET );
234 #endif
235     
236     for( i=0; i<3; i++ )
237     {
238         pv->mcdeint_frame->data[i] = src[i];
239         pv->mcdeint_frame->linesize[i] = pv->width[i];
240     }    
241     pv->mcdeint_avctx_enc->me_cmp     = FF_CMP_SAD;
242     pv->mcdeint_avctx_enc->me_sub_cmp = FF_CMP_SAD;
243     pv->mcdeint_frame->quality        = pv->mcdeint_qp * FF_QP2LAMBDA;
244     
245     out_size = avcodec_encode_video( pv->mcdeint_avctx_enc, 
246                                      pv->mcdeint_outbuf, 
247                                      pv->mcdeint_outbuf_size, 
248                                      pv->mcdeint_frame );
249     
250     pv->mcdeint_frame_dec = pv->mcdeint_avctx_enc->coded_frame;
251     
252     for( i = 0; i < 3; i++ )
253     {
254         int w    = pv->width[i];
255         int h    = pv->height[i];
256         int fils = pv->mcdeint_frame_dec->linesize[i];
257         int srcs = pv->width[i];
258         
259         for( y = 0; y < h; y++ )
260         {
261             if( (y ^ parity) & 1 )
262             {
263                 for( x = 0; x < w; x++ )
264                 {
265                     if( (x-2)+(y-1)*w >= 0 && (x+2)+(y+1)*w < w*h )
266                     { 
267                         uint8_t * filp = 
268                             &pv->mcdeint_frame_dec->data[i][x + y*fils];
269                         uint8_t * srcp = &src[i][x + y*srcs];
270
271                         int diff0 = filp[-fils] - srcp[-srcs];
272                         int diff1 = filp[+fils] - srcp[+srcs];
273                         
274                         int spatial_score = 
275                               ABS(srcp[-srcs-1] - srcp[+srcs-1])
276                             + ABS(srcp[-srcs  ] - srcp[+srcs  ])
277                             + ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
278                         
279                         int temp = filp[0];
280                         
281 #define MCDEINT_CHECK(j)\
282                         {   int score = ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
283                                       + ABS(srcp[-srcs  +j] - srcp[+srcs  -j])\
284                                       + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
285                             if( score < spatial_score ) {\
286                                 spatial_score = score;\
287                                 diff0 = filp[-fils+j] - srcp[-srcs+j];\
288                                 diff1 = filp[+fils-j] - srcp[+srcs-j];
289                                         
290                         MCDEINT_CHECK(-1) MCDEINT_CHECK(-2) }} }}
291                         MCDEINT_CHECK( 1) MCDEINT_CHECK( 2) }} }}
292
293                         if(diff0 + diff1 > 0)
294                         {
295                             temp -= (diff0 + diff1 - 
296                                      ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
297                         }
298                         else
299                         {
300                             temp -= (diff0 + diff1 + 
301                                      ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
302                         }
303
304                         filp[0] = dst[i][x + y*w] = 
305                             temp > 255U ? ~(temp>>31) : temp;
306                     }
307                     else
308                     {
309                         dst[i][x + y*w] = 
310                             pv->mcdeint_frame_dec->data[i][x + y*fils];
311                     }
312                 }
313             }
314         }
315
316         for( y = 0; y < h; y++ )
317         {
318             if( !((y ^ parity) & 1) )
319             {
320                 for( x = 0; x < w; x++ )
321                 {
322                     pv->mcdeint_frame_dec->data[i][x + y*fils] =
323                         dst[i][x + y*w]= src[i][x + y*srcs];
324                 }
325             }
326         }
327     }
328
329 #ifdef SUPPRESS_AV_LOG
330     /* TODO: restore previous log level */
331     av_log_set_level(loglevel);
332 #endif
333 }
334
335 hb_filter_private_t * hb_deinterlace_init( int pix_fmt, 
336                                            int width, 
337                                            int height,
338                                            char * settings )
339 {
340     if( pix_fmt != PIX_FMT_YUV420P )
341     {
342         return 0;
343     }
344     
345     hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) );
346     
347     pv->pix_fmt = pix_fmt;
348
349     pv->width[0]  = width;
350     pv->height[0] = height;    
351     pv->width[1]  = pv->width[2]  = width >> 1;
352     pv->height[1] = pv->height[2] = height >> 1;    
353     
354     int buf_size = 3 * width * height / 2;    
355     pv->buf_out[0] = hb_buffer_init( buf_size );
356     pv->buf_out[1] = hb_buffer_init( buf_size );
357     pv->buf_settings = hb_buffer_init( 0 );
358     
359     pv->yadif_ready    = 0;
360     pv->yadif_mode     = YADIF_MODE_DEFAULT;
361     pv->yadif_parity   = YADIF_PARITY_DEFAULT;    
362     
363     pv->mcdeint_mode   = MCDEINT_MODE_DEFAULT;
364     pv->mcdeint_qp     = MCDEINT_QP_DEFAULT;
365     
366     if( settings )
367     {
368         sscanf( settings, "%d:%d:%d:%d", 
369                 &pv->yadif_mode, 
370                 &pv->yadif_parity,
371                 &pv->mcdeint_mode,
372                 &pv->mcdeint_qp );
373     }
374     
375     /* Allocate yadif specific buffers */
376     if( pv->yadif_mode >= 0 )
377     {
378         int i, j;
379         for( i = 0; i < 3; i++ )
380         {   
381             int is_chroma = !!i;
382             int w = ((width   + 31) & (~31))>>is_chroma;
383             int h = ((height+6+ 31) & (~31))>>is_chroma;
384             
385             pv->yadif_ref_stride[i] = w;
386             
387             for( j = 0; j < 3; j++ )
388             {
389                 pv->yadif_ref[j][i] = malloc( w*h*sizeof(uint8_t) ) + 3*w;
390             }        
391         }
392     }
393     
394     /* Allocate mcdeint specific buffers */
395     if( pv->mcdeint_mode >= 0 )
396     {
397         avcodec_init();
398         avcodec_register_all();
399         
400         AVCodec * enc = avcodec_find_encoder( CODEC_ID_SNOW );
401         
402         int i;
403         for (i = 0; i < 3; i++ )
404         {
405             AVCodecContext * avctx_enc;
406             
407             avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context();
408             
409             avctx_enc->width                    = width;
410             avctx_enc->height                   = height;
411             avctx_enc->time_base                = (AVRational){1,25};  // meaningless
412             avctx_enc->gop_size                 = 300;
413             avctx_enc->max_b_frames             = 0;
414             avctx_enc->pix_fmt                  = PIX_FMT_YUV420P;
415             avctx_enc->flags                    = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
416             avctx_enc->strict_std_compliance    = FF_COMPLIANCE_EXPERIMENTAL;
417             avctx_enc->global_quality           = 1;
418             avctx_enc->flags2                   = CODEC_FLAG2_MEMC_ONLY;
419             avctx_enc->me_cmp                   = FF_CMP_SAD; //SSE;
420             avctx_enc->me_sub_cmp               = FF_CMP_SAD; //SSE;
421             avctx_enc->mb_cmp                   = FF_CMP_SSE;
422             
423             switch( pv->mcdeint_mode )
424             {
425                 case 3:
426                     avctx_enc->refs = 3;
427                 case 2:
428                     avctx_enc->me_method = ME_ITER;
429                 case 1:
430                     avctx_enc->flags |= CODEC_FLAG_4MV;
431                     avctx_enc->dia_size =2;
432                 case 0:
433                     avctx_enc->flags |= CODEC_FLAG_QPEL;
434             }
435             
436             avcodec_open(avctx_enc, enc);        
437         }
438         
439         pv->mcdeint_frame       = avcodec_alloc_frame();
440         pv->mcdeint_outbuf_size = width * height * 10;
441         pv->mcdeint_outbuf      = malloc( pv->mcdeint_outbuf_size );
442     }
443
444     return pv;
445 }
446
447 void hb_deinterlace_close( hb_filter_private_t * pv )
448 {
449     if( !pv ) 
450     {
451         return;
452     }
453     
454     /* Cleanup frame buffers */
455     if( pv->buf_out[0] )
456     {
457         hb_buffer_close( &pv->buf_out[0] );
458     }    
459     if( pv->buf_out[1] )
460     {
461         hb_buffer_close( &pv->buf_out[1] );
462     }
463     if (pv->buf_settings )
464     {
465         hb_buffer_close( &pv->buf_settings );
466     }
467
468     /* Cleanup yadif specific buffers */
469     if( pv->yadif_mode >= 0 )
470     {
471         int i;
472         for( i = 0; i<3*3; i++ )
473         {
474             uint8_t **p = &pv->yadif_ref[i%3][i/3];
475             if (*p) 
476             {
477                 free( *p - 3*pv->yadif_ref_stride[i/3] );
478                 *p = NULL;
479             }
480         }
481     }
482     
483     /* Cleanup mcdeint specific buffers */
484     if( pv->mcdeint_mode >= 0 )
485     {
486         if( pv->mcdeint_avctx_enc )
487         {
488             avcodec_close( pv->mcdeint_avctx_enc );
489             av_freep( &pv->mcdeint_avctx_enc );
490         }        
491         if( pv->mcdeint_outbuf )
492         {
493             free( pv->mcdeint_outbuf );
494         }        
495     }    
496     
497     free( pv );
498 }
499
500 int hb_deinterlace_work( const hb_buffer_t * buf_in,
501                          hb_buffer_t ** buf_out,
502                          int pix_fmt,
503                          int width, 
504                          int height,
505                          hb_filter_private_t * pv )
506 {
507     if( !pv || 
508         pix_fmt != pv->pix_fmt ||
509         width   != pv->width[0] ||
510         height  != pv->height[0] )
511     {
512         return FILTER_FAILED;
513     }
514     
515     avpicture_fill( &pv->pic_in, buf_in->data, 
516                     pix_fmt, width, height );
517
518     /* Use libavcodec deinterlace if yadif_mode < 0 */
519     if( pv->yadif_mode < 0 )
520     {        
521         avpicture_fill( &pv->pic_out, pv->buf_out[0]->data, 
522                         pix_fmt, width, height );
523         
524         avpicture_deinterlace( &pv->pic_out, &pv->pic_in, 
525                                pix_fmt, width, height );
526         
527         hb_buffer_copy_settings( pv->buf_out[0], buf_in );
528
529         *buf_out = pv->buf_out[0];
530         
531         return FILTER_OK;
532     }
533     
534     /* Determine if top-field first layout */
535     int tff;
536     if( pv->yadif_parity < 0 )
537     {
538         tff = !!(buf_in->flags & PIC_FLAG_TOP_FIELD_FIRST);
539     }
540     else
541     {
542         tff = (pv->yadif_parity & 1) ^ 1;
543     }
544     
545     /* Store current frame in yadif cache */
546     yadif_store_ref( (const uint8_t**)pv->pic_in.data, pv );
547     
548     /* If yadif is not ready, store another ref and return FILTER_DELAY */
549     if( pv->yadif_ready == 0 )
550     {
551         yadif_store_ref( (const uint8_t**)pv->pic_in.data, pv );
552         
553         hb_buffer_copy_settings( pv->buf_settings, buf_in );
554
555         pv->yadif_ready = 1;
556         
557         return FILTER_DELAY;
558     }
559
560     /* Perform yadif and mcdeint filtering */
561     int frame;
562     for( frame = 0; frame <= (pv->yadif_mode & 1); frame++ )
563     {
564         int parity = frame ^ tff ^ 1;
565         
566         avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data, 
567                         pix_fmt, width, height );
568         
569         yadif_filter( pv->pic_out.data, parity, tff, pv );
570
571         if( pv->mcdeint_mode >= 0 )
572         {
573             avpicture_fill( &pv->pic_in,  pv->buf_out[(frame^1)]->data, 
574                             pix_fmt, width, height );
575             
576             mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );
577             
578             *buf_out = pv->buf_out[ (frame^1)];
579         }
580         else
581         {
582             *buf_out = pv->buf_out[!(frame^1)];
583         }
584     }
585     
586     /* Copy buffered settings to output buffer settings */
587     hb_buffer_copy_settings( *buf_out, pv->buf_settings );
588     
589     /* Replace buffered settings with input buffer settings */
590     hb_buffer_copy_settings( pv->buf_settings, buf_in );    
591
592     return FILTER_OK;
593 }
594
595