1 /* $Id: decomb.c,v 1.14 2008/04/25 5:00:00 jbrjake Exp $
3 This file is part of the HandBrake source code.
4 Homepage: <http://handbrake.fr/>.
5 It may be used under the terms of the GNU General Public License.
7 The yadif algorithm was created by Michael Niedermayer. */
9 #include "libavcodec/avcodec.h"
10 #include "mpeg2dec/mpeg2.h"
12 #define SUPPRESS_AV_LOG
14 #define MODE_DEFAULT 1
15 #define PARITY_DEFAULT -1
17 #define MCDEINT_MODE_DEFAULT -1
18 #define MCDEINT_QP_DEFAULT 1
20 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
21 #define MIN3(a,b,c) MIN(MIN(a,b),c)
22 #define MAX3(a,b,c) MAX(MAX(a,b),c)
24 typedef struct yadif_arguments_s {
32 typedef struct decomb_arguments_s {
36 struct hb_filter_private_s
45 int spatial_threshold;
57 int mcdeint_outbuf_size;
58 uint8_t * mcdeint_outbuf;
59 AVCodecContext * mcdeint_avctx_enc;
60 AVFrame * mcdeint_frame;
61 AVFrame * mcdeint_frame_dec;
63 int yadif_deinterlaced_frames;
64 int blend_deinterlaced_frames;
65 int unfiltered_frames;
70 /* Make a buffer to store a comb mask. */
75 hb_buffer_t * buf_out[2];
76 hb_buffer_t * buf_settings;
80 hb_thread_t ** yadif_threads; // Threads for Yadif - one per CPU
81 hb_lock_t ** yadif_begin_lock; // Thread has work
82 hb_lock_t ** yadif_complete_lock; // Thread has completed work
83 yadif_arguments_t *yadif_arguments; // Arguments to thread for work
85 hb_thread_t ** decomb_threads; // Threads for comb detection - one per CPU
86 hb_lock_t ** decomb_begin_lock; // Thread has work
87 hb_lock_t ** decomb_complete_lock; // Thread has completed work
88 decomb_arguments_t *decomb_arguments; // Arguments to thread for work
92 hb_filter_private_t * hb_decomb_init( int pix_fmt,
97 int hb_decomb_work( const hb_buffer_t * buf_in,
98 hb_buffer_t ** buf_out,
102 hb_filter_private_t * pv );
104 void hb_decomb_close( hb_filter_private_t * pv );
106 hb_filter_object_t hb_filter_decomb =
109 "Deinterlaces selectively with yadif/mcdeint and lowpass5 blending",
116 int cubic_interpolate( int y0, int y1, int y2, int y3 )
118 /* From http://www.neuron2.net/library/cubicinterp.html */
119 int result = ( y0 * -3 ) + ( y1 * 23 ) + ( y2 * 23 ) + ( y3 * -3 );
126 else if( result < 0 )
134 static void store_ref( const uint8_t ** pic,
135 hb_filter_private_t * pv )
139 sizeof(uint8_t *)*3 );
143 sizeof(uint8_t *)*3*3 );
146 for( i = 0; i < 3; i++ )
148 const uint8_t * src = pic[i];
149 uint8_t * ref = pv->ref[2][i];
151 int w = pv->width[i];
152 int h = pv->height[i];
153 int ref_stride = pv->ref_stride[i];
156 for( y = 0; y < pv->height[i]; y++ )
159 src = (uint8_t*)src + w;
160 ref = (uint8_t*)ref + ref_stride;
165 static void get_ref( uint8_t ** pic, hb_filter_private_t * pv, int frm )
168 for( i = 0; i < 3; i++ )
170 uint8_t * dst = pic[i];
171 const uint8_t * ref = pv->ref[frm][i];
172 int w = pv->width[i];
173 int ref_stride = pv->ref_stride[i];
176 for( y = 0; y < pv->height[i]; y++ )
185 int blend_filter_pixel( int up2, int up1, int current, int down1, int down2 )
187 /* Low-pass 5-tap filter */
191 result += current * 6;
208 static void blend_filter_line( uint8_t *dst,
212 hb_filter_private_t * pv )
214 int w = pv->width[plane];
215 int refs = pv->ref_stride[plane];
218 for( x = 0; x < w; x++)
230 /* First line, so A and B don't exist.*/
236 /* Second line, no A. */
239 else if( y == (pv->height[plane] - 2) )
241 /* Second to last line, no E. */
244 else if( y == (pv->height[plane] -1) )
246 /* Last line, no D or E. */
251 dst[0] = blend_filter_pixel( a, b, c, d, e );
258 int check_combing_mask( hb_filter_private_t * pv )
260 /* Go through the mask in X*Y blocks. If any of these windows
261 have threshold or more combed pixels, consider the whole
262 frame to be combed and send it on to be deinterlaced. */
264 /* Block mask threshold -- The number of pixels
265 in a block_width * block_height window of
266 he mask that need to show combing for the
267 whole frame to be seen as such. */
268 int threshold = pv->block_threshold;
269 int block_width = pv->block_width;
270 int block_height = pv->block_height;
271 int block_x, block_y;
272 int block_score = 0; int send_to_blend = 0;
276 for( k = 0; k < 1; k++ )
278 int ref_stride = pv->ref_stride[k];
279 for( y = 0; y < ( pv->height[k] - block_height ); y = y + block_height )
281 for( x = 0; x < ( pv->width[k] - block_width ); x = x + block_width )
284 for( block_y = 0; block_y < block_height; block_y++ )
286 for( block_x = 0; block_x < block_width; block_x++ )
288 int mask_y = y + block_y;
289 int mask_x = x + block_x;
291 /* We only want to mark a pixel in a block as combed
292 if the pixels above and below are as well. Got to
293 handle the top and bottom lines separately. */
294 if( y + block_y == 0 )
296 if( pv->mask[k][mask_y*ref_stride+mask_x ] == 255 &&
297 pv->mask[k][mask_y*ref_stride+mask_x + 1] == 255 )
300 else if( y + block_y == pv->height[k] - 1 )
302 if( pv->mask[k][mask_y*ref_stride+mask_x - 1] == 255 &&
303 pv->mask[k][mask_y*ref_stride+mask_x ] == 255 )
308 if( pv->mask[k][mask_y*ref_stride+mask_x - 1] == 255 &&
309 pv->mask[k][mask_y*ref_stride+mask_x ] == 255 &&
310 pv->mask[k][mask_y*ref_stride+mask_x + 1] == 255 )
316 if( block_score >= ( threshold / 2 ) )
319 hb_log("decomb: frame %i | score %i | type %s", pv->yadif_deinterlaced_frames + pv->blend_deinterlaced_frames + pv->unfiltered_frames + 1, block_score, pv->buf_settings->flags & 16 ? "Film" : "Video");
321 if ( block_score <= threshold && !( pv->buf_settings->flags & 16) )
323 /* Blend video content that scores between
324 ( threshold / 2 ) and threshold. */
327 else if( block_score > threshold )
329 if( pv->buf_settings->flags & 16 )
331 /* Blend progressive content above the threshold.*/
336 /* Yadif deinterlace video content above the threshold. */
351 /* Consider this frame to be uncombed. */
356 int detect_combed_segment( hb_filter_private_t * pv, int segment_start, int segment_stop )
358 /* A mish-mash of various comb detection tricks
359 picked up from neuron2's Decomb plugin for
360 AviSynth and tritical's IsCombedT and
361 IsCombedTIVTC plugins. */
363 int x, y, k, width, height;
365 /* Comb scoring algorithm */
366 int spatial_metric = pv->spatial_metric;
367 /* Motion threshold */
368 int mthresh = pv->motion_threshold;
369 /* Spatial threshold */
370 int athresh = pv->spatial_threshold;
371 int athresh_squared = athresh * athresh;
372 int athresh6 = 6 *athresh;
374 /* One pas for Y, one pass for U, one pass for V */
375 for( k = 0; k < 1; k++ )
377 int ref_stride = pv->ref_stride[k];
378 width = pv->width[k];
379 height = pv->height[k];
381 /* Comb detection has to start at y = 2 and end at
382 y = height - 2, because it needs to examine
383 2 pixels above and 2 below the current pixel. */
384 if( segment_start < 2 )
386 if( segment_stop > height - 2 )
387 segment_stop = height - 2;
389 for( y = segment_start; y < segment_stop; y++ )
391 /* These are just to make the buffer locations easier to read. */
392 int back_2 = ( y - 2 )*ref_stride ;
393 int back_1 = ( y - 1 )*ref_stride;
394 int current = y*ref_stride;
395 int forward_1 = ( y + 1 )*ref_stride;
396 int forward_2 = ( y + 2 )*ref_stride;
398 /* We need to examine a column of 5 pixels
399 in the prev, cur, and next frames. */
400 uint8_t previous_frame[5];
401 uint8_t current_frame[5];
402 uint8_t next_frame[5];
404 for( x = 0; x < width; x++ )
406 /* Fill up the current frame array with the current pixel values.*/
407 current_frame[0] = pv->ref[1][k][back_2 + x];
408 current_frame[1] = pv->ref[1][k][back_1 + x];
409 current_frame[2] = pv->ref[1][k][current + x];
410 current_frame[3] = pv->ref[1][k][forward_1 + x];
411 current_frame[4] = pv->ref[1][k][forward_2 + x];
413 int up_diff = current_frame[2] - current_frame[1];
414 int down_diff = current_frame[2] - current_frame[3];
416 if( ( up_diff > athresh && down_diff > athresh ) ||
417 ( up_diff < -athresh && down_diff < -athresh ) )
419 /* The pixel above and below are different,
420 and they change in the same "direction" too.*/
424 /* Make sure there's sufficient motion between frame t-1 to frame t+1. */
425 previous_frame[0] = pv->ref[0][k][back_2 + x];
426 previous_frame[1] = pv->ref[0][k][back_1 + x];
427 previous_frame[2] = pv->ref[0][k][current + x];
428 previous_frame[3] = pv->ref[0][k][forward_1 + x];
429 previous_frame[4] = pv->ref[0][k][forward_2 + x];
430 next_frame[0] = pv->ref[2][k][back_2 + x];
431 next_frame[1] = pv->ref[2][k][back_1 + x];
432 next_frame[2] = pv->ref[2][k][current + x];
433 next_frame[3] = pv->ref[2][k][forward_1 + x];
434 next_frame[4] = pv->ref[2][k][forward_2 + x];
436 if( abs( previous_frame[2] - current_frame[2] ) > mthresh &&
437 abs( current_frame[1] - next_frame[1] ) > mthresh &&
438 abs( current_frame[3] - next_frame[3] ) > mthresh )
440 if( abs( next_frame[2] - current_frame[2] ) > mthresh &&
441 abs( previous_frame[1] - current_frame[1] ) > mthresh &&
442 abs( previous_frame[3] - current_frame[3] ) > mthresh )
447 /* User doesn't want to check for motion,
448 so move on to the spatial check. */
452 if( motion || ( pv->yadif_deinterlaced_frames==0 && pv->blend_deinterlaced_frames==0 && pv->unfiltered_frames==0) )
454 /* That means it's time for the spatial check.
455 We've got several options here. */
456 if( spatial_metric == 0 )
458 /* Simple 32detect style comb detection */
459 if( ( abs( current_frame[2] - current_frame[4] ) < 10 ) &&
460 ( abs( current_frame[2] - current_frame[3] ) > 15 ) )
462 pv->mask[k][y*ref_stride + x] = 255;
466 pv->mask[k][y*ref_stride + x] = 0;
469 else if( spatial_metric == 1 )
471 /* This, for comparison, is what IsCombed uses.
472 It's better, but still noise senstive. */
473 int combing = ( current_frame[1] - current_frame[2] ) *
474 ( current_frame[3] - current_frame[2] );
476 if( combing > athresh_squared )
477 pv->mask[k][y*ref_stride + x] = 255;
479 pv->mask[k][y*ref_stride + x] = 0;
481 else if( spatial_metric == 2 )
483 /* Tritical's noise-resistant combing scorer.
484 The check is done on a bob+blur convolution. */
485 int combing = abs( current_frame[0]
486 + ( 4 * current_frame[2] )
488 - ( 3 * ( current_frame[1]
489 + current_frame[3] ) ) );
491 /* If the frame is sufficiently combed,
492 then mark it down on the mask as 255. */
493 if( combing > athresh6 )
494 pv->mask[k][y*ref_stride + x] = 255;
496 pv->mask[k][y*ref_stride + x] = 0;
501 pv->mask[k][y*ref_stride + x] = 0;
506 pv->mask[k][y*ref_stride + x] = 0;
513 typedef struct decomb_thread_arg_s {
514 hb_filter_private_t *pv;
516 } decomb_thread_arg_t;
519 * comb detect this segment of all three planes in a single thread.
521 void decomb_filter_thread( void *thread_args_v )
523 decomb_arguments_t *decomb_work = NULL;
524 hb_filter_private_t * pv;
526 int segment, segment_start, segment_stop, plane;
527 decomb_thread_arg_t *thread_args = thread_args_v;
529 pv = thread_args->pv;
530 segment = thread_args->segment;
532 hb_log("decomb thread started for segment %d", segment);
537 * Wait here until there is work to do. hb_lock() blocks until
538 * render releases it to say that there is more work to do.
540 hb_lock( pv->decomb_begin_lock[segment] );
542 decomb_work = &pv->decomb_arguments[segment];
544 if( decomb_work->stop )
547 * No more work to do, exit this thread.
554 * Process segment (for now just from luma)
556 for( plane = 0; plane < 1; plane++)
559 int w = pv->width[plane];
560 int h = pv->height[plane];
561 int ref_stride = pv->ref_stride[plane];
562 segment_start = ( h / pv->cpu_count ) * segment;
563 if( segment == pv->cpu_count - 1 )
570 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
573 detect_combed_segment( pv, segment_start, segment_stop );
576 * Finished this segment, let everyone know.
578 hb_unlock( pv->decomb_complete_lock[segment] );
580 free( thread_args_v );
583 int comb_segmenter( hb_filter_private_t * pv )
587 for( segment = 0; segment < pv->cpu_count; segment++ )
590 * Let the thread for this plane know that we've setup work
591 * for it by releasing the begin lock (ensuring that the
592 * complete lock is already locked so that we block when
593 * we try to lock it again below).
595 hb_lock( pv->decomb_complete_lock[segment] );
596 hb_unlock( pv->decomb_begin_lock[segment] );
600 * Wait until all three threads have completed by trying to get
601 * the complete lock that we locked earlier for each thread, which
602 * will block until that thread has completed the work on that
605 for( segment = 0; segment < pv->cpu_count; segment++ )
607 hb_lock( pv->decomb_complete_lock[segment] );
608 hb_unlock( pv->decomb_complete_lock[segment] );
611 return check_combing_mask( pv );
614 static void yadif_filter_line( uint8_t *dst,
621 hb_filter_private_t * pv )
623 /* While prev and next point to the previous and next frames,
624 prev2 and next2 will shift depending on the parity, usually 1.
625 They are the previous and next fields, the fields temporally adjacent
626 to the other field in the current frame--the one not being filtered. */
627 uint8_t *prev2 = parity ? prev : cur ;
628 uint8_t *next2 = parity ? cur : next;
629 int w = pv->width[plane];
630 int refs = pv->ref_stride[plane];
633 for( x = 0; x < w; x++)
637 /* Temporal average: the current location in the adjacent fields */
638 int d = (prev2[0] + next2[0])>>1;
642 /* How the current pixel changes between the adjacent fields */
643 int temporal_diff0 = ABS(prev2[0] - next2[0]);
644 /* The average of how much the pixels above and below change from the frame before to now. */
645 int temporal_diff1 = ( ABS(prev[-refs] - cur[-refs]) + ABS(prev[+refs] - cur[+refs]) ) >> 1;
646 /* The average of how much the pixels above and below change from now to the next frame. */
647 int temporal_diff2 = ( ABS(next[-refs] - cur[-refs]) + ABS(next[+refs] - cur[+refs]) ) >> 1;
648 /* For the actual difference, use the largest of the previous average diffs. */
649 int diff = MAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
651 /* SAD of how the pixel-1, the pixel, and the pixel+1 change from the line above to below. */
652 int spatial_score = ABS(cur[-refs-1] - cur[+refs-1]) + ABS(cur[-refs]-cur[+refs]) +
653 ABS(cur[-refs+1] - cur[+refs+1]) - 1;
656 /* Spatial pred is either a bilinear or cubic vertical interpolation. */
659 spatial_pred = cubic_interpolate( cur[-3*refs], cur[-refs], cur[+refs], cur[3*refs] );
663 spatial_pred = (c+e)>>1;
666 /* EDDI: Edge Directed Deinterlacing Interpolation
667 Uses the Martinez-Lim Line Shift Parametric Modeling algorithm...I think.
668 Checks 4 different slopes to see if there is more similarity along a diagonal
669 than there was vertically. If a diagonal is more similar, then it indicates
670 an edge, so interpolate along that instead of a vertical line, using either
671 linear or cubic interpolation depending on mode. */
672 #define YADIF_CHECK(j)\
673 { int score = ABS(cur[-refs-1+j] - cur[+refs-1-j])\
674 + ABS(cur[-refs +j] - cur[+refs -j])\
675 + ABS(cur[-refs+1+j] - cur[+refs+1-j]);\
676 if( score < spatial_score ){\
677 spatial_score = score;\
683 spatial_pred = cubic_interpolate(cur[-3 * refs - 3], cur[-refs -1], cur[+refs + 1], cur[3* refs + 3] );\
686 spatial_pred = cubic_interpolate( ( ( cur[-3*refs - 4] + cur[-refs - 4] ) / 2 ) , cur[-refs -2], cur[+refs + 2], ( ( cur[3*refs + 4] + cur[refs + 4] ) / 2 ) );\
689 spatial_pred = cubic_interpolate(cur[-3 * refs +3], cur[-refs +1], cur[+refs - 1], cur[3* refs -3] );\
692 spatial_pred = cubic_interpolate(( ( cur[-3*refs + 4] + cur[-refs + 4] ) / 2 ), cur[-refs +2], cur[+refs - 2], ( ( cur[3*refs - 4] + cur[refs - 4] ) / 2 ) );\
698 spatial_pred = ( cur[-refs +j] + cur[+refs -j] ) >>1;\
701 YADIF_CHECK(-1) YADIF_CHECK(-2) }} }}
702 YADIF_CHECK( 1) YADIF_CHECK( 2) }} }}
704 /* Temporally adjust the spatial prediction by
705 comparing against lines in the adjacent fields. */
706 int b = (prev2[-2*refs] + next2[-2*refs])>>1;
707 int f = (prev2[+2*refs] + next2[+2*refs])>>1;
709 /* Find the median value */
710 int max = MAX3(d-e, d-c, MIN(b-c, f-e));
711 int min = MIN3(d-e, d-c, MAX(b-c, f-e));
712 diff = MAX3( diff, min, -max );
714 if( spatial_pred > d + diff )
716 spatial_pred = d + diff;
718 else if( spatial_pred < d - diff )
720 spatial_pred = d - diff;
723 dst[0] = spatial_pred;
734 typedef struct yadif_thread_arg_s {
735 hb_filter_private_t *pv;
737 } yadif_thread_arg_t;
740 * deinterlace this segment of all three planes in a single thread.
742 void yadif_decomb_filter_thread( void *thread_args_v )
744 yadif_arguments_t *yadif_work = NULL;
745 hb_filter_private_t * pv;
748 int segment, segment_start, segment_stop;
749 yadif_thread_arg_t *thread_args = thread_args_v;
751 int parity, tff, y, w, h, ref_stride, is_combed;
753 pv = thread_args->pv;
754 segment = thread_args->segment;
756 hb_log("yadif thread started for segment %d", segment);
761 * Wait here until there is work to do. hb_lock() blocks until
762 * render releases it to say that there is more work to do.
764 hb_lock( pv->yadif_begin_lock[segment] );
766 yadif_work = &pv->yadif_arguments[segment];
768 if( yadif_work->stop )
771 * No more work to do, exit this thread.
777 if( yadif_work->dst == NULL )
779 hb_error( "thread started when no work available" );
784 is_combed = pv->yadif_arguments[segment].is_combed;
787 * Process all three planes, but only this segment of it.
789 for( plane = 0; plane < 3; plane++)
792 dst = yadif_work->dst;
793 parity = yadif_work->parity;
794 tff = yadif_work->tff;
795 w = pv->width[plane];
796 h = pv->height[plane];
797 ref_stride = pv->ref_stride[plane];
798 segment_start = ( h / pv->cpu_count ) * segment;
799 if( segment == pv->cpu_count - 1 )
806 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
809 for( y = segment_start; y < segment_stop; y++ )
811 if( ( pv->mode == 4 && is_combed ) || is_combed == 2 )
813 uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
814 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
815 uint8_t *next = &pv->ref[2][plane][y*ref_stride];
816 uint8_t *dst2 = &dst[plane][y*w];
818 blend_filter_line( dst2, cur, plane, y, pv );
820 else if( (y ^ parity) & 1 && is_combed == 1 )
822 uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
823 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
824 uint8_t *next = &pv->ref[2][plane][y*ref_stride];
825 uint8_t *dst2 = &dst[plane][y*w];
827 yadif_filter_line( dst2, prev, cur, next, plane, parity ^ tff, y, pv );
831 memcpy( &dst[plane][y*w],
832 &pv->ref[1][plane][y*ref_stride],
833 w * sizeof(uint8_t) );
838 * Finished this segment, let everyone know.
840 hb_unlock( pv->yadif_complete_lock[segment] );
842 free( thread_args_v );
845 static void yadif_filter( uint8_t ** dst,
848 hb_filter_private_t * pv )
851 int is_combed = comb_segmenter( pv );
855 pv->yadif_deinterlaced_frames++;
857 else if( is_combed == 2 )
859 pv->blend_deinterlaced_frames++;
863 pv->unfiltered_frames++;
870 for( segment = 0; segment < pv->cpu_count; segment++ )
873 * Setup the work for this plane.
875 pv->yadif_arguments[segment].parity = parity;
876 pv->yadif_arguments[segment].tff = tff;
877 pv->yadif_arguments[segment].dst = dst;
878 pv->yadif_arguments[segment].is_combed = is_combed;
881 * Let the thread for this plane know that we've setup work
882 * for it by releasing the begin lock (ensuring that the
883 * complete lock is already locked so that we block when
884 * we try to lock it again below).
886 hb_lock( pv->yadif_complete_lock[segment] );
887 hb_unlock( pv->yadif_begin_lock[segment] );
891 * Wait until all three threads have completed by trying to get
892 * the complete lock that we locked earlier for each thread, which
893 * will block until that thread has completed the work on that
896 for( segment = 0; segment < pv->cpu_count; segment++ )
898 hb_lock( pv->yadif_complete_lock[segment] );
899 hb_unlock( pv->yadif_complete_lock[segment] );
903 * Entire frame is now deinterlaced.
908 /* Just passing through... */
910 for( i = 0; i < 3; i++ )
912 uint8_t * ref = pv->ref[1][i];
913 uint8_t * dest = dst[i];
915 int w = pv->width[i];
916 int ref_stride = pv->ref_stride[i];
919 for( y = 0; y < pv->height[i]; y++ )
921 memcpy(dest, ref, w);
929 static void mcdeint_filter( uint8_t ** dst,
932 hb_filter_private_t * pv )
937 #ifdef SUPPRESS_AV_LOG
938 /* TODO: temporarily change log level to suppress obnoxious debug output */
939 int loglevel = av_log_get_level();
940 av_log_set_level( AV_LOG_QUIET );
945 pv->mcdeint_frame->data[i] = src[i];
946 pv->mcdeint_frame->linesize[i] = pv->width[i];
948 pv->mcdeint_avctx_enc->me_cmp = FF_CMP_SAD;
949 pv->mcdeint_avctx_enc->me_sub_cmp = FF_CMP_SAD;
950 pv->mcdeint_frame->quality = pv->mcdeint_qp * FF_QP2LAMBDA;
952 out_size = avcodec_encode_video( pv->mcdeint_avctx_enc,
954 pv->mcdeint_outbuf_size,
957 pv->mcdeint_frame_dec = pv->mcdeint_avctx_enc->coded_frame;
959 for( i = 0; i < 3; i++ )
961 int w = pv->width[i];
962 int h = pv->height[i];
963 int fils = pv->mcdeint_frame_dec->linesize[i];
964 int srcs = pv->width[i];
966 for( y = 0; y < h; y++ )
968 if( (y ^ parity) & 1 )
970 for( x = 0; x < w; x++ )
972 if( (x-2)+(y-1)*w >= 0 && (x+2)+(y+1)*w < w*h )
975 &pv->mcdeint_frame_dec->data[i][x + y*fils];
976 uint8_t * srcp = &src[i][x + y*srcs];
978 int diff0 = filp[-fils] - srcp[-srcs];
979 int diff1 = filp[+fils] - srcp[+srcs];
982 ABS(srcp[-srcs-1] - srcp[+srcs-1])
983 + ABS(srcp[-srcs ] - srcp[+srcs ])
984 + ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
988 #define MCDEINT_CHECK(j)\
989 { int score = ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
990 + ABS(srcp[-srcs +j] - srcp[+srcs -j])\
991 + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
992 if( score < spatial_score ) {\
993 spatial_score = score;\
994 diff0 = filp[-fils+j] - srcp[-srcs+j];\
995 diff1 = filp[+fils-j] - srcp[+srcs-j];
997 MCDEINT_CHECK(-1) MCDEINT_CHECK(-2) }} }}
998 MCDEINT_CHECK( 1) MCDEINT_CHECK( 2) }} }}
1000 if(diff0 + diff1 > 0)
1002 temp -= (diff0 + diff1 -
1003 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1007 temp -= (diff0 + diff1 +
1008 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1011 filp[0] = dst[i][x + y*w] =
1012 temp > 255U ? ~(temp>>31) : temp;
1017 pv->mcdeint_frame_dec->data[i][x + y*fils];
1023 for( y = 0; y < h; y++ )
1025 if( !((y ^ parity) & 1) )
1027 for( x = 0; x < w; x++ )
1029 pv->mcdeint_frame_dec->data[i][x + y*fils] =
1030 dst[i][x + y*w]= src[i][x + y*srcs];
1036 #ifdef SUPPRESS_AV_LOG
1037 /* TODO: restore previous log level */
1038 av_log_set_level(loglevel);
1042 hb_filter_private_t * hb_decomb_init( int pix_fmt,
1047 if( pix_fmt != PIX_FMT_YUV420P )
1052 hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) );
1054 pv->pix_fmt = pix_fmt;
1056 pv->width[0] = width;
1057 pv->height[0] = height;
1058 pv->width[1] = pv->width[2] = width >> 1;
1059 pv->height[1] = pv->height[2] = height >> 1;
1061 int buf_size = 3 * width * height / 2;
1062 pv->buf_out[0] = hb_buffer_init( buf_size );
1063 pv->buf_out[1] = hb_buffer_init( buf_size );
1064 pv->buf_settings = hb_buffer_init( 0 );
1066 pv->yadif_deinterlaced_frames = 0;
1067 pv->blend_deinterlaced_frames = 0;
1068 pv->unfiltered_frames = 0;
1070 pv->yadif_ready = 0;
1072 pv->mode = MODE_DEFAULT;
1073 pv->spatial_metric = 2;
1074 pv->motion_threshold = 6;
1075 pv->spatial_threshold = 9;
1076 pv->block_threshold = 80;
1077 pv->block_width = 16;
1078 pv->block_height = 16;
1080 pv->parity = PARITY_DEFAULT;
1082 pv->mcdeint_mode = MCDEINT_MODE_DEFAULT;
1083 pv->mcdeint_qp = MCDEINT_QP_DEFAULT;
1087 sscanf( settings, "%d:%d:%d:%d:%d:%d:%d",
1089 &pv->spatial_metric,
1090 &pv->motion_threshold,
1091 &pv->spatial_threshold,
1092 &pv->block_threshold,
1094 &pv->block_height );
1097 pv->cpu_count = hb_get_cpu_count();
1100 if( pv->mode == 2 || pv->mode == 3 )
1102 pv->mcdeint_mode = 0;
1105 /* Allocate yadif specific buffers */
1107 for( i = 0; i < 3; i++ )
1109 int is_chroma = !!i;
1110 int w = ((width + 31) & (~31))>>is_chroma;
1111 int h = ((height+6+ 31) & (~31))>>is_chroma;
1113 pv->ref_stride[i] = w;
1115 for( j = 0; j < 3; j++ )
1117 pv->ref[j][i] = malloc( w*h*sizeof(uint8_t) ) + 3*w;
1121 /* Allocate a buffer to store a comb mask. */
1122 for( i = 0; i < 3; i++ )
1124 int is_chroma = !!i;
1125 int w = ((pv->width[0] + 31) & (~31))>>is_chroma;
1126 int h = ((pv->height[0]+6+ 31) & (~31))>>is_chroma;
1128 pv->mask[i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1132 * Create yadif threads and locks.
1134 pv->yadif_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1135 pv->yadif_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1136 pv->yadif_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1137 pv->yadif_arguments = malloc( sizeof( yadif_arguments_t ) * pv->cpu_count );
1139 for( i = 0; i < pv->cpu_count; i++ )
1141 yadif_thread_arg_t *thread_args;
1143 thread_args = malloc( sizeof( yadif_thread_arg_t ) );
1147 thread_args->pv = pv;
1148 thread_args->segment = i;
1150 pv->yadif_begin_lock[i] = hb_lock_init();
1151 pv->yadif_complete_lock[i] = hb_lock_init();
1154 * Important to start off with the threads locked waiting
1157 hb_lock( pv->yadif_begin_lock[i] );
1159 pv->yadif_arguments[i].stop = 0;
1160 pv->yadif_arguments[i].dst = NULL;
1162 pv->yadif_threads[i] = hb_thread_init( "yadif_filter_segment",
1163 yadif_decomb_filter_thread,
1165 HB_NORMAL_PRIORITY );
1169 hb_error( "yadif could not create threads" );
1174 * Create decomb threads and locks.
1176 pv->decomb_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1177 pv->decomb_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1178 pv->decomb_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1179 pv->decomb_arguments = malloc( sizeof( decomb_arguments_t ) * pv->cpu_count );
1181 for( i = 0; i < pv->cpu_count; i++ )
1183 decomb_thread_arg_t *decomb_thread_args;
1185 decomb_thread_args = malloc( sizeof( decomb_thread_arg_t ) );
1187 if( decomb_thread_args )
1189 decomb_thread_args->pv = pv;
1190 decomb_thread_args->segment = i;
1192 pv->decomb_begin_lock[i] = hb_lock_init();
1193 pv->decomb_complete_lock[i] = hb_lock_init();
1196 * Important to start off with the threads locked waiting
1199 hb_lock( pv->decomb_begin_lock[i] );
1201 pv->decomb_arguments[i].stop = 0;
1203 pv->decomb_threads[i] = hb_thread_init( "decomb_filter_segment",
1204 decomb_filter_thread,
1206 HB_NORMAL_PRIORITY );
1210 hb_error( "decomb could not create threads" );
1216 /* Allocate mcdeint specific buffers */
1217 if( pv->mcdeint_mode >= 0 )
1220 avcodec_register_all();
1222 AVCodec * enc = avcodec_find_encoder( CODEC_ID_SNOW );
1225 for (i = 0; i < 3; i++ )
1227 AVCodecContext * avctx_enc;
1229 avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context();
1231 avctx_enc->width = width;
1232 avctx_enc->height = height;
1233 avctx_enc->time_base = (AVRational){1,25}; // meaningless
1234 avctx_enc->gop_size = 300;
1235 avctx_enc->max_b_frames = 0;
1236 avctx_enc->pix_fmt = PIX_FMT_YUV420P;
1237 avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
1238 avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
1239 avctx_enc->global_quality = 1;
1240 avctx_enc->flags2 = CODEC_FLAG2_MEMC_ONLY;
1241 avctx_enc->me_cmp = FF_CMP_SAD; //SSE;
1242 avctx_enc->me_sub_cmp = FF_CMP_SAD; //SSE;
1243 avctx_enc->mb_cmp = FF_CMP_SSE;
1245 switch( pv->mcdeint_mode )
1248 avctx_enc->refs = 3;
1250 avctx_enc->me_method = ME_UMH;
1252 avctx_enc->flags |= CODEC_FLAG_4MV;
1253 avctx_enc->dia_size =2;
1255 avctx_enc->flags |= CODEC_FLAG_QPEL;
1258 avcodec_open(avctx_enc, enc);
1261 pv->mcdeint_frame = avcodec_alloc_frame();
1262 pv->mcdeint_outbuf_size = width * height * 10;
1263 pv->mcdeint_outbuf = malloc( pv->mcdeint_outbuf_size );
1269 void hb_decomb_close( hb_filter_private_t * pv )
1276 hb_log("decomb: yadif deinterlaced %i | blend deinterlaced %i | unfiltered %i | total %i", pv->yadif_deinterlaced_frames, pv->blend_deinterlaced_frames, pv->unfiltered_frames, pv->yadif_deinterlaced_frames + pv->blend_deinterlaced_frames + pv->unfiltered_frames);
1278 /* Cleanup frame buffers */
1279 if( pv->buf_out[0] )
1281 hb_buffer_close( &pv->buf_out[0] );
1283 if( pv->buf_out[1] )
1285 hb_buffer_close( &pv->buf_out[1] );
1287 if (pv->buf_settings )
1289 hb_buffer_close( &pv->buf_settings );
1292 /* Cleanup yadif specific buffers */
1294 for( i = 0; i<3*3; i++ )
1296 uint8_t **p = &pv->ref[i%3][i/3];
1299 free( *p - 3*pv->ref_stride[i/3] );
1304 /* Cleanup combing mask. */
1305 for( i = 0; i<3*3; i++ )
1307 uint8_t **p = &pv->mask[i/3];
1310 free( *p - 3*pv->ref_stride[i/3] );
1315 for( i = 0; i < pv->cpu_count; i++)
1318 * Tell each yadif thread to stop, and then cleanup.
1320 pv->yadif_arguments[i].stop = 1;
1321 hb_unlock( pv->yadif_begin_lock[i] );
1323 hb_thread_close( &pv->yadif_threads[i] );
1324 hb_lock_close( &pv->yadif_begin_lock[i] );
1325 hb_lock_close( &pv->yadif_complete_lock[i] );
1329 * free memory for yadif structs
1331 free( pv->yadif_threads );
1332 free( pv->yadif_begin_lock );
1333 free( pv->yadif_complete_lock );
1334 free( pv->yadif_arguments );
1336 for( i = 0; i < pv->cpu_count; i++)
1339 * Tell each decomb thread to stop, and then cleanup.
1341 pv->decomb_arguments[i].stop = 1;
1342 hb_unlock( pv->decomb_begin_lock[i] );
1344 hb_thread_close( &pv->decomb_threads[i] );
1345 hb_lock_close( &pv->decomb_begin_lock[i] );
1346 hb_lock_close( &pv->decomb_complete_lock[i] );
1350 * free memory for decomb structs
1352 free( pv->decomb_threads );
1353 free( pv->decomb_begin_lock );
1354 free( pv->decomb_complete_lock );
1355 free( pv->decomb_arguments );
1357 /* Cleanup mcdeint specific buffers */
1358 if( pv->mcdeint_mode >= 0 )
1360 if( pv->mcdeint_avctx_enc )
1362 avcodec_close( pv->mcdeint_avctx_enc );
1363 av_freep( &pv->mcdeint_avctx_enc );
1365 if( pv->mcdeint_outbuf )
1367 free( pv->mcdeint_outbuf );
1374 int hb_decomb_work( const hb_buffer_t * cbuf_in,
1375 hb_buffer_t ** buf_out,
1379 hb_filter_private_t * pv )
1381 hb_buffer_t * buf_in = (hb_buffer_t *)cbuf_in;
1384 pix_fmt != pv->pix_fmt ||
1385 width != pv->width[0] ||
1386 height != pv->height[0] )
1388 return FILTER_FAILED;
1391 avpicture_fill( &pv->pic_in, buf_in->data,
1392 pix_fmt, width, height );
1394 /* Determine if top-field first layout */
1396 if( pv->parity < 0 )
1398 tff = !!(buf_in->flags & PIC_FLAG_TOP_FIELD_FIRST);
1402 tff = (pv->parity & 1) ^ 1;
1405 /* Store current frame in yadif cache */
1406 store_ref( (const uint8_t**)pv->pic_in.data, pv );
1408 /* If yadif is not ready, store another ref and return FILTER_DELAY */
1409 if( pv->yadif_ready == 0 )
1411 store_ref( (const uint8_t**)pv->pic_in.data, pv );
1413 hb_buffer_copy_settings( pv->buf_settings, buf_in );
1415 /* don't let 'work_loop' send a chapter mark upstream */
1416 buf_in->new_chap = 0;
1418 pv->yadif_ready = 1;
1420 return FILTER_DELAY;
1423 /* Perform yadif filtering */
1425 for( frame = 0; frame <= ( ( pv->mode == 2 || pv->mode == 3 )? 1 : 0 ) ; frame++ )
1427 int parity = frame ^ tff ^ 1;
1429 avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,
1430 pix_fmt, width, height );
1432 yadif_filter( pv->pic_out.data, parity, tff, pv );
1434 if( pv->mcdeint_mode >= 0 )
1436 /* Perform mcdeint filtering */
1437 avpicture_fill( &pv->pic_in, pv->buf_out[(frame^1)]->data,
1438 pix_fmt, width, height );
1440 mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );
1443 *buf_out = pv->buf_out[!(frame^1)];
1446 /* Copy buffered settings to output buffer settings */
1447 hb_buffer_copy_settings( *buf_out, pv->buf_settings );
1449 /* Replace buffered settings with input buffer settings */
1450 hb_buffer_copy_settings( pv->buf_settings, buf_in );
1452 /* don't let 'work_loop' send a chapter mark upstream */
1453 buf_in->new_chap = 0;