OSDN Git Service

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