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. */
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 /* Decomb's cubic interpolation can only function when there are
634 three samples above and below, so regress to yadif's traditional
635 two-tap interpolation when filtering at the top and bottom edges. */
637 if( ( y < 3 ) || ( y > ( pv->height[plane] - 4 ) ) )
640 for( x = 0; x < w; x++)
644 /* Temporal average: the current location in the adjacent fields */
645 int d = (prev2[0] + next2[0])>>1;
649 /* How the current pixel changes between the adjacent fields */
650 int temporal_diff0 = ABS(prev2[0] - next2[0]);
651 /* The average of how much the pixels above and below change from the frame before to now. */
652 int temporal_diff1 = ( ABS(prev[-refs] - cur[-refs]) + ABS(prev[+refs] - cur[+refs]) ) >> 1;
653 /* The average of how much the pixels above and below change from now to the next frame. */
654 int temporal_diff2 = ( ABS(next[-refs] - cur[-refs]) + ABS(next[+refs] - cur[+refs]) ) >> 1;
655 /* For the actual difference, use the largest of the previous average diffs. */
656 int diff = MAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
658 /* SAD of how the pixel-1, the pixel, and the pixel+1 change from the line above to below. */
659 int spatial_score = ABS(cur[-refs-1] - cur[+refs-1]) + ABS(cur[-refs]-cur[+refs]) +
660 ABS(cur[-refs+1] - cur[+refs+1]) - 1;
663 /* Spatial pred is either a bilinear or cubic vertical interpolation. */
664 if( pv->mode > 0 && !edge)
666 spatial_pred = cubic_interpolate( cur[-3*refs], cur[-refs], cur[+refs], cur[3*refs] );
670 spatial_pred = (c+e)>>1;
673 /* EDDI: Edge Directed Deinterlacing Interpolation
674 Uses the Martinez-Lim Line Shift Parametric Modeling algorithm...I think.
675 Checks 4 different slopes to see if there is more similarity along a diagonal
676 than there was vertically. If a diagonal is more similar, then it indicates
677 an edge, so interpolate along that instead of a vertical line, using either
678 linear or cubic interpolation depending on mode. */
679 #define YADIF_CHECK(j)\
680 { int score = ABS(cur[-refs-1+j] - cur[+refs-1-j])\
681 + ABS(cur[-refs +j] - cur[+refs -j])\
682 + ABS(cur[-refs+1+j] - cur[+refs+1-j]);\
683 if( score < spatial_score ){\
684 spatial_score = score;\
685 if( pv->mode > 0 && !edge )\
690 spatial_pred = cubic_interpolate(cur[-3 * refs - 3], cur[-refs -1], cur[+refs + 1], cur[3* refs + 3] );\
693 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 ) );\
696 spatial_pred = cubic_interpolate(cur[-3 * refs +3], cur[-refs +1], cur[+refs - 1], cur[3* refs -3] );\
699 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 ) );\
705 spatial_pred = ( cur[-refs +j] + cur[+refs -j] ) >>1;\
708 YADIF_CHECK(-1) YADIF_CHECK(-2) }} }}
709 YADIF_CHECK( 1) YADIF_CHECK( 2) }} }}
711 /* Temporally adjust the spatial prediction by
712 comparing against lines in the adjacent fields. */
713 int b = (prev2[-2*refs] + next2[-2*refs])>>1;
714 int f = (prev2[+2*refs] + next2[+2*refs])>>1;
716 /* Find the median value */
717 int max = MAX3(d-e, d-c, MIN(b-c, f-e));
718 int min = MIN3(d-e, d-c, MAX(b-c, f-e));
719 diff = MAX3( diff, min, -max );
721 if( spatial_pred > d + diff )
723 spatial_pred = d + diff;
725 else if( spatial_pred < d - diff )
727 spatial_pred = d - diff;
730 dst[0] = spatial_pred;
741 typedef struct yadif_thread_arg_s {
742 hb_filter_private_t *pv;
744 } yadif_thread_arg_t;
747 * deinterlace this segment of all three planes in a single thread.
749 void yadif_decomb_filter_thread( void *thread_args_v )
751 yadif_arguments_t *yadif_work = NULL;
752 hb_filter_private_t * pv;
755 int segment, segment_start, segment_stop;
756 yadif_thread_arg_t *thread_args = thread_args_v;
758 int parity, tff, y, w, h, penultimate, ultimate, ref_stride, is_combed;
760 pv = thread_args->pv;
761 segment = thread_args->segment;
763 hb_log("yadif thread started for segment %d", segment);
768 * Wait here until there is work to do. hb_lock() blocks until
769 * render releases it to say that there is more work to do.
771 hb_lock( pv->yadif_begin_lock[segment] );
773 yadif_work = &pv->yadif_arguments[segment];
775 if( yadif_work->stop )
778 * No more work to do, exit this thread.
784 if( yadif_work->dst == NULL )
786 hb_error( "thread started when no work available" );
791 is_combed = pv->yadif_arguments[segment].is_combed;
794 * Process all three planes, but only this segment of it.
796 for( plane = 0; plane < 3; plane++)
799 dst = yadif_work->dst;
800 parity = yadif_work->parity;
801 tff = yadif_work->tff;
802 w = pv->width[plane];
803 h = pv->height[plane];
806 ref_stride = pv->ref_stride[plane];
807 segment_start = ( h / pv->cpu_count ) * segment;
808 if( segment == pv->cpu_count - 1 )
815 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
818 for( y = segment_start; y < segment_stop; y++ )
820 if( ( pv->mode == 4 && is_combed ) || is_combed == 2 )
822 /* This line gets blend filtered, not yadif filtered. */
823 uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
824 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
825 uint8_t *next = &pv->ref[2][plane][y*ref_stride];
826 uint8_t *dst2 = &dst[plane][y*w];
828 blend_filter_line( dst2, cur, plane, y, pv );
830 else if( ( ( y ^ parity ) & 1 ) && ( is_combed == 1 ) )
832 /* This line gets yadif filtered. It is the bottom field
833 when TFF and vice-versa. It's the field that gets
834 filtered. Because yadif needs 2 lines above and below
835 the one being filtered, we need to mirror the edges.
836 When TFF, this means replacing the 2nd line with a
837 copy of the 1st, and the last with the second-to-last. */
838 if( y > 1 && y < ( h -2 ) )
840 /* This isn't the top or bottom, proceed as normal to yadif. */
841 uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
842 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
843 uint8_t *next = &pv->ref[2][plane][y*ref_stride];
844 uint8_t *dst2 = &dst[plane][y*w];
846 yadif_filter_line( dst2,
857 /* BFF, so y0 = y1 */
858 memcpy( &dst[plane][y*w],
859 &pv->ref[1][plane][1*ref_stride],
860 w * sizeof(uint8_t) );
864 /* TFF, so y1 = y0 */
865 memcpy( &dst[plane][y*w],
866 &pv->ref[1][plane][0],
867 w * sizeof(uint8_t) );
869 else if( y == penultimate )
871 /* BFF, so penultimate y = ultimate y */
872 memcpy( &dst[plane][y*w],
873 &pv->ref[1][plane][ultimate*ref_stride],
874 w * sizeof(uint8_t) );
876 else if( y == ultimate )
878 /* TFF, so ultimate y = penultimate y */
879 memcpy( &dst[plane][y*w],
880 &pv->ref[1][plane][penultimate*ref_stride],
881 w * sizeof(uint8_t) );
886 memcpy( &dst[plane][y*w],
887 &pv->ref[1][plane][y*ref_stride],
888 w * sizeof(uint8_t) );
893 * Finished this segment, let everyone know.
895 hb_unlock( pv->yadif_complete_lock[segment] );
897 free( thread_args_v );
900 static void yadif_filter( uint8_t ** dst,
903 hb_filter_private_t * pv )
906 int is_combed = comb_segmenter( pv );
910 pv->yadif_deinterlaced_frames++;
912 else if( is_combed == 2 )
914 pv->blend_deinterlaced_frames++;
918 pv->unfiltered_frames++;
925 for( segment = 0; segment < pv->cpu_count; segment++ )
928 * Setup the work for this plane.
930 pv->yadif_arguments[segment].parity = parity;
931 pv->yadif_arguments[segment].tff = tff;
932 pv->yadif_arguments[segment].dst = dst;
933 pv->yadif_arguments[segment].is_combed = is_combed;
936 * Let the thread for this plane know that we've setup work
937 * for it by releasing the begin lock (ensuring that the
938 * complete lock is already locked so that we block when
939 * we try to lock it again below).
941 hb_lock( pv->yadif_complete_lock[segment] );
942 hb_unlock( pv->yadif_begin_lock[segment] );
946 * Wait until all three threads have completed by trying to get
947 * the complete lock that we locked earlier for each thread, which
948 * will block until that thread has completed the work on that
951 for( segment = 0; segment < pv->cpu_count; segment++ )
953 hb_lock( pv->yadif_complete_lock[segment] );
954 hb_unlock( pv->yadif_complete_lock[segment] );
958 * Entire frame is now deinterlaced.
963 /* Just passing through... */
965 for( i = 0; i < 3; i++ )
967 uint8_t * ref = pv->ref[1][i];
968 uint8_t * dest = dst[i];
970 int w = pv->width[i];
971 int ref_stride = pv->ref_stride[i];
974 for( y = 0; y < pv->height[i]; y++ )
976 memcpy(dest, ref, w);
984 static void mcdeint_filter( uint8_t ** dst,
987 hb_filter_private_t * pv )
992 #ifdef SUPPRESS_AV_LOG
993 /* TODO: temporarily change log level to suppress obnoxious debug output */
994 int loglevel = av_log_get_level();
995 av_log_set_level( AV_LOG_QUIET );
1000 pv->mcdeint_frame->data[i] = src[i];
1001 pv->mcdeint_frame->linesize[i] = pv->width[i];
1003 pv->mcdeint_avctx_enc->me_cmp = FF_CMP_SAD;
1004 pv->mcdeint_avctx_enc->me_sub_cmp = FF_CMP_SAD;
1005 pv->mcdeint_frame->quality = pv->mcdeint_qp * FF_QP2LAMBDA;
1007 out_size = avcodec_encode_video( pv->mcdeint_avctx_enc,
1009 pv->mcdeint_outbuf_size,
1010 pv->mcdeint_frame );
1012 pv->mcdeint_frame_dec = pv->mcdeint_avctx_enc->coded_frame;
1014 for( i = 0; i < 3; i++ )
1016 int w = pv->width[i];
1017 int h = pv->height[i];
1018 int fils = pv->mcdeint_frame_dec->linesize[i];
1019 int srcs = pv->width[i];
1021 for( y = 0; y < h; y++ )
1023 if( (y ^ parity) & 1 )
1025 for( x = 0; x < w; x++ )
1027 if( (x-2)+(y-1)*w >= 0 && (x+2)+(y+1)*w < w*h )
1030 &pv->mcdeint_frame_dec->data[i][x + y*fils];
1031 uint8_t * srcp = &src[i][x + y*srcs];
1033 int diff0 = filp[-fils] - srcp[-srcs];
1034 int diff1 = filp[+fils] - srcp[+srcs];
1037 ABS(srcp[-srcs-1] - srcp[+srcs-1])
1038 + ABS(srcp[-srcs ] - srcp[+srcs ])
1039 + ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
1043 #define MCDEINT_CHECK(j)\
1044 { int score = ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
1045 + ABS(srcp[-srcs +j] - srcp[+srcs -j])\
1046 + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
1047 if( score < spatial_score ) {\
1048 spatial_score = score;\
1049 diff0 = filp[-fils+j] - srcp[-srcs+j];\
1050 diff1 = filp[+fils-j] - srcp[+srcs-j];
1052 MCDEINT_CHECK(-1) MCDEINT_CHECK(-2) }} }}
1053 MCDEINT_CHECK( 1) MCDEINT_CHECK( 2) }} }}
1055 if(diff0 + diff1 > 0)
1057 temp -= (diff0 + diff1 -
1058 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1062 temp -= (diff0 + diff1 +
1063 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1066 filp[0] = dst[i][x + y*w] =
1067 temp > 255U ? ~(temp>>31) : temp;
1072 pv->mcdeint_frame_dec->data[i][x + y*fils];
1078 for( y = 0; y < h; y++ )
1080 if( !((y ^ parity) & 1) )
1082 for( x = 0; x < w; x++ )
1084 pv->mcdeint_frame_dec->data[i][x + y*fils] =
1085 dst[i][x + y*w]= src[i][x + y*srcs];
1091 #ifdef SUPPRESS_AV_LOG
1092 /* TODO: restore previous log level */
1093 av_log_set_level(loglevel);
1097 hb_filter_private_t * hb_decomb_init( int pix_fmt,
1102 if( pix_fmt != PIX_FMT_YUV420P )
1107 hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) );
1109 pv->pix_fmt = pix_fmt;
1111 pv->width[0] = width;
1112 pv->height[0] = height;
1113 pv->width[1] = pv->width[2] = width >> 1;
1114 pv->height[1] = pv->height[2] = height >> 1;
1116 pv->buf_out[0] = hb_video_buffer_init( width, height );
1117 pv->buf_out[1] = hb_video_buffer_init( width, height );
1118 pv->buf_settings = hb_buffer_init( 0 );
1120 pv->yadif_deinterlaced_frames = 0;
1121 pv->blend_deinterlaced_frames = 0;
1122 pv->unfiltered_frames = 0;
1124 pv->yadif_ready = 0;
1126 pv->mode = MODE_DEFAULT;
1127 pv->spatial_metric = 2;
1128 pv->motion_threshold = 6;
1129 pv->spatial_threshold = 9;
1130 pv->block_threshold = 80;
1131 pv->block_width = 16;
1132 pv->block_height = 16;
1134 pv->parity = PARITY_DEFAULT;
1136 pv->mcdeint_mode = MCDEINT_MODE_DEFAULT;
1137 pv->mcdeint_qp = MCDEINT_QP_DEFAULT;
1141 sscanf( settings, "%d:%d:%d:%d:%d:%d:%d",
1143 &pv->spatial_metric,
1144 &pv->motion_threshold,
1145 &pv->spatial_threshold,
1146 &pv->block_threshold,
1148 &pv->block_height );
1151 pv->cpu_count = hb_get_cpu_count();
1154 if( pv->mode == 2 || pv->mode == 3 )
1156 pv->mcdeint_mode = 0;
1159 /* Allocate yadif specific buffers */
1161 for( i = 0; i < 3; i++ )
1163 int is_chroma = !!i;
1164 int w = ((width + 31) & (~31))>>is_chroma;
1165 int h = ((height+6+ 31) & (~31))>>is_chroma;
1167 pv->ref_stride[i] = w;
1169 for( j = 0; j < 3; j++ )
1171 pv->ref[j][i] = malloc( w*h*sizeof(uint8_t) ) + 3*w;
1175 /* Allocate a buffer to store a comb mask. */
1176 for( i = 0; i < 3; i++ )
1178 int is_chroma = !!i;
1179 int w = ((pv->width[0] + 31) & (~31))>>is_chroma;
1180 int h = ((pv->height[0]+6+ 31) & (~31))>>is_chroma;
1182 pv->mask[i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1186 * Create yadif threads and locks.
1188 pv->yadif_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1189 pv->yadif_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1190 pv->yadif_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1191 pv->yadif_arguments = malloc( sizeof( yadif_arguments_t ) * pv->cpu_count );
1193 for( i = 0; i < pv->cpu_count; i++ )
1195 yadif_thread_arg_t *thread_args;
1197 thread_args = malloc( sizeof( yadif_thread_arg_t ) );
1201 thread_args->pv = pv;
1202 thread_args->segment = i;
1204 pv->yadif_begin_lock[i] = hb_lock_init();
1205 pv->yadif_complete_lock[i] = hb_lock_init();
1208 * Important to start off with the threads locked waiting
1211 hb_lock( pv->yadif_begin_lock[i] );
1213 pv->yadif_arguments[i].stop = 0;
1214 pv->yadif_arguments[i].dst = NULL;
1216 pv->yadif_threads[i] = hb_thread_init( "yadif_filter_segment",
1217 yadif_decomb_filter_thread,
1219 HB_NORMAL_PRIORITY );
1223 hb_error( "yadif could not create threads" );
1228 * Create decomb threads and locks.
1230 pv->decomb_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1231 pv->decomb_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1232 pv->decomb_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1233 pv->decomb_arguments = malloc( sizeof( decomb_arguments_t ) * pv->cpu_count );
1235 for( i = 0; i < pv->cpu_count; i++ )
1237 decomb_thread_arg_t *decomb_thread_args;
1239 decomb_thread_args = malloc( sizeof( decomb_thread_arg_t ) );
1241 if( decomb_thread_args )
1243 decomb_thread_args->pv = pv;
1244 decomb_thread_args->segment = i;
1246 pv->decomb_begin_lock[i] = hb_lock_init();
1247 pv->decomb_complete_lock[i] = hb_lock_init();
1250 * Important to start off with the threads locked waiting
1253 hb_lock( pv->decomb_begin_lock[i] );
1255 pv->decomb_arguments[i].stop = 0;
1257 pv->decomb_threads[i] = hb_thread_init( "decomb_filter_segment",
1258 decomb_filter_thread,
1260 HB_NORMAL_PRIORITY );
1264 hb_error( "decomb could not create threads" );
1270 /* Allocate mcdeint specific buffers */
1271 if( pv->mcdeint_mode >= 0 )
1274 avcodec_register_all();
1276 AVCodec * enc = avcodec_find_encoder( CODEC_ID_SNOW );
1279 for (i = 0; i < 3; i++ )
1281 AVCodecContext * avctx_enc;
1283 avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context();
1285 avctx_enc->width = width;
1286 avctx_enc->height = height;
1287 avctx_enc->time_base = (AVRational){1,25}; // meaningless
1288 avctx_enc->gop_size = 300;
1289 avctx_enc->max_b_frames = 0;
1290 avctx_enc->pix_fmt = PIX_FMT_YUV420P;
1291 avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
1292 avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
1293 avctx_enc->global_quality = 1;
1294 avctx_enc->flags2 = CODEC_FLAG2_MEMC_ONLY;
1295 avctx_enc->me_cmp = FF_CMP_SAD; //SSE;
1296 avctx_enc->me_sub_cmp = FF_CMP_SAD; //SSE;
1297 avctx_enc->mb_cmp = FF_CMP_SSE;
1299 switch( pv->mcdeint_mode )
1302 avctx_enc->refs = 3;
1304 avctx_enc->me_method = ME_UMH;
1306 avctx_enc->flags |= CODEC_FLAG_4MV;
1307 avctx_enc->dia_size =2;
1309 avctx_enc->flags |= CODEC_FLAG_QPEL;
1312 hb_avcodec_open(avctx_enc, enc);
1315 pv->mcdeint_frame = avcodec_alloc_frame();
1316 pv->mcdeint_outbuf_size = width * height * 10;
1317 pv->mcdeint_outbuf = malloc( pv->mcdeint_outbuf_size );
1323 void hb_decomb_close( hb_filter_private_t * pv )
1330 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);
1332 /* Cleanup frame buffers */
1333 if( pv->buf_out[0] )
1335 hb_buffer_close( &pv->buf_out[0] );
1337 if( pv->buf_out[1] )
1339 hb_buffer_close( &pv->buf_out[1] );
1341 if (pv->buf_settings )
1343 hb_buffer_close( &pv->buf_settings );
1346 /* Cleanup yadif specific buffers */
1348 for( i = 0; i<3*3; i++ )
1350 uint8_t **p = &pv->ref[i%3][i/3];
1353 free( *p - 3*pv->ref_stride[i/3] );
1358 /* Cleanup combing mask. */
1359 for( i = 0; i<3*3; i++ )
1361 uint8_t **p = &pv->mask[i/3];
1364 free( *p - 3*pv->ref_stride[i/3] );
1369 for( i = 0; i < pv->cpu_count; i++)
1372 * Tell each yadif thread to stop, and then cleanup.
1374 pv->yadif_arguments[i].stop = 1;
1375 hb_unlock( pv->yadif_begin_lock[i] );
1377 hb_thread_close( &pv->yadif_threads[i] );
1378 hb_lock_close( &pv->yadif_begin_lock[i] );
1379 hb_lock_close( &pv->yadif_complete_lock[i] );
1383 * free memory for yadif structs
1385 free( pv->yadif_threads );
1386 free( pv->yadif_begin_lock );
1387 free( pv->yadif_complete_lock );
1388 free( pv->yadif_arguments );
1390 for( i = 0; i < pv->cpu_count; i++)
1393 * Tell each decomb thread to stop, and then cleanup.
1395 pv->decomb_arguments[i].stop = 1;
1396 hb_unlock( pv->decomb_begin_lock[i] );
1398 hb_thread_close( &pv->decomb_threads[i] );
1399 hb_lock_close( &pv->decomb_begin_lock[i] );
1400 hb_lock_close( &pv->decomb_complete_lock[i] );
1404 * free memory for decomb structs
1406 free( pv->decomb_threads );
1407 free( pv->decomb_begin_lock );
1408 free( pv->decomb_complete_lock );
1409 free( pv->decomb_arguments );
1411 /* Cleanup mcdeint specific buffers */
1412 if( pv->mcdeint_mode >= 0 )
1414 if( pv->mcdeint_avctx_enc )
1416 hb_avcodec_close( pv->mcdeint_avctx_enc );
1417 av_freep( &pv->mcdeint_avctx_enc );
1419 if( pv->mcdeint_outbuf )
1421 free( pv->mcdeint_outbuf );
1428 int hb_decomb_work( const hb_buffer_t * cbuf_in,
1429 hb_buffer_t ** buf_out,
1433 hb_filter_private_t * pv )
1435 hb_buffer_t * buf_in = (hb_buffer_t *)cbuf_in;
1438 pix_fmt != pv->pix_fmt ||
1439 width != pv->width[0] ||
1440 height != pv->height[0] )
1442 return FILTER_FAILED;
1445 avpicture_fill( &pv->pic_in, buf_in->data,
1446 pix_fmt, width, height );
1448 /* Determine if top-field first layout */
1450 if( pv->parity < 0 )
1452 tff = !!(buf_in->flags & PIC_FLAG_TOP_FIELD_FIRST);
1456 tff = (pv->parity & 1) ^ 1;
1459 /* Store current frame in yadif cache */
1460 store_ref( (const uint8_t**)pv->pic_in.data, pv );
1462 /* If yadif is not ready, store another ref and return FILTER_DELAY */
1463 if( pv->yadif_ready == 0 )
1465 store_ref( (const uint8_t**)pv->pic_in.data, pv );
1467 hb_buffer_copy_settings( pv->buf_settings, buf_in );
1469 /* don't let 'work_loop' send a chapter mark upstream */
1470 buf_in->new_chap = 0;
1472 pv->yadif_ready = 1;
1474 return FILTER_DELAY;
1477 /* Perform yadif filtering */
1479 for( frame = 0; frame <= ( ( pv->mode == 2 || pv->mode == 3 )? 1 : 0 ) ; frame++ )
1481 int parity = frame ^ tff ^ 1;
1483 avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,
1484 pix_fmt, width, height );
1486 yadif_filter( pv->pic_out.data, parity, tff, pv );
1488 if( pv->mcdeint_mode >= 0 )
1490 /* Perform mcdeint filtering */
1491 avpicture_fill( &pv->pic_in, pv->buf_out[(frame^1)]->data,
1492 pix_fmt, width, height );
1494 mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );
1497 *buf_out = pv->buf_out[!(frame^1)];
1500 /* Copy buffered settings to output buffer settings */
1501 hb_buffer_copy_settings( *buf_out, pv->buf_settings );
1503 /* Replace buffered settings with input buffer settings */
1504 hb_buffer_copy_settings( pv->buf_settings, buf_in );
1506 /* don't let 'work_loop' send a chapter mark upstream */
1507 buf_in->new_chap = 0;