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 /* 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 int buf_size = 3 * width * height / 2;
1117 pv->buf_out[0] = hb_buffer_init( buf_size );
1118 pv->buf_out[1] = hb_buffer_init( buf_size );
1119 pv->buf_settings = hb_buffer_init( 0 );
1121 pv->yadif_deinterlaced_frames = 0;
1122 pv->blend_deinterlaced_frames = 0;
1123 pv->unfiltered_frames = 0;
1125 pv->yadif_ready = 0;
1127 pv->mode = MODE_DEFAULT;
1128 pv->spatial_metric = 2;
1129 pv->motion_threshold = 6;
1130 pv->spatial_threshold = 9;
1131 pv->block_threshold = 80;
1132 pv->block_width = 16;
1133 pv->block_height = 16;
1135 pv->parity = PARITY_DEFAULT;
1137 pv->mcdeint_mode = MCDEINT_MODE_DEFAULT;
1138 pv->mcdeint_qp = MCDEINT_QP_DEFAULT;
1142 sscanf( settings, "%d:%d:%d:%d:%d:%d:%d",
1144 &pv->spatial_metric,
1145 &pv->motion_threshold,
1146 &pv->spatial_threshold,
1147 &pv->block_threshold,
1149 &pv->block_height );
1152 pv->cpu_count = hb_get_cpu_count();
1155 if( pv->mode == 2 || pv->mode == 3 )
1157 pv->mcdeint_mode = 0;
1160 /* Allocate yadif specific buffers */
1162 for( i = 0; i < 3; i++ )
1164 int is_chroma = !!i;
1165 int w = ((width + 31) & (~31))>>is_chroma;
1166 int h = ((height+6+ 31) & (~31))>>is_chroma;
1168 pv->ref_stride[i] = w;
1170 for( j = 0; j < 3; j++ )
1172 pv->ref[j][i] = malloc( w*h*sizeof(uint8_t) ) + 3*w;
1176 /* Allocate a buffer to store a comb mask. */
1177 for( i = 0; i < 3; i++ )
1179 int is_chroma = !!i;
1180 int w = ((pv->width[0] + 31) & (~31))>>is_chroma;
1181 int h = ((pv->height[0]+6+ 31) & (~31))>>is_chroma;
1183 pv->mask[i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1187 * Create yadif threads and locks.
1189 pv->yadif_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1190 pv->yadif_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1191 pv->yadif_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1192 pv->yadif_arguments = malloc( sizeof( yadif_arguments_t ) * pv->cpu_count );
1194 for( i = 0; i < pv->cpu_count; i++ )
1196 yadif_thread_arg_t *thread_args;
1198 thread_args = malloc( sizeof( yadif_thread_arg_t ) );
1202 thread_args->pv = pv;
1203 thread_args->segment = i;
1205 pv->yadif_begin_lock[i] = hb_lock_init();
1206 pv->yadif_complete_lock[i] = hb_lock_init();
1209 * Important to start off with the threads locked waiting
1212 hb_lock( pv->yadif_begin_lock[i] );
1214 pv->yadif_arguments[i].stop = 0;
1215 pv->yadif_arguments[i].dst = NULL;
1217 pv->yadif_threads[i] = hb_thread_init( "yadif_filter_segment",
1218 yadif_decomb_filter_thread,
1220 HB_NORMAL_PRIORITY );
1224 hb_error( "yadif could not create threads" );
1229 * Create decomb threads and locks.
1231 pv->decomb_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1232 pv->decomb_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1233 pv->decomb_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1234 pv->decomb_arguments = malloc( sizeof( decomb_arguments_t ) * pv->cpu_count );
1236 for( i = 0; i < pv->cpu_count; i++ )
1238 decomb_thread_arg_t *decomb_thread_args;
1240 decomb_thread_args = malloc( sizeof( decomb_thread_arg_t ) );
1242 if( decomb_thread_args )
1244 decomb_thread_args->pv = pv;
1245 decomb_thread_args->segment = i;
1247 pv->decomb_begin_lock[i] = hb_lock_init();
1248 pv->decomb_complete_lock[i] = hb_lock_init();
1251 * Important to start off with the threads locked waiting
1254 hb_lock( pv->decomb_begin_lock[i] );
1256 pv->decomb_arguments[i].stop = 0;
1258 pv->decomb_threads[i] = hb_thread_init( "decomb_filter_segment",
1259 decomb_filter_thread,
1261 HB_NORMAL_PRIORITY );
1265 hb_error( "decomb could not create threads" );
1271 /* Allocate mcdeint specific buffers */
1272 if( pv->mcdeint_mode >= 0 )
1275 avcodec_register_all();
1277 AVCodec * enc = avcodec_find_encoder( CODEC_ID_SNOW );
1280 for (i = 0; i < 3; i++ )
1282 AVCodecContext * avctx_enc;
1284 avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context();
1286 avctx_enc->width = width;
1287 avctx_enc->height = height;
1288 avctx_enc->time_base = (AVRational){1,25}; // meaningless
1289 avctx_enc->gop_size = 300;
1290 avctx_enc->max_b_frames = 0;
1291 avctx_enc->pix_fmt = PIX_FMT_YUV420P;
1292 avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
1293 avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
1294 avctx_enc->global_quality = 1;
1295 avctx_enc->flags2 = CODEC_FLAG2_MEMC_ONLY;
1296 avctx_enc->me_cmp = FF_CMP_SAD; //SSE;
1297 avctx_enc->me_sub_cmp = FF_CMP_SAD; //SSE;
1298 avctx_enc->mb_cmp = FF_CMP_SSE;
1300 switch( pv->mcdeint_mode )
1303 avctx_enc->refs = 3;
1305 avctx_enc->me_method = ME_UMH;
1307 avctx_enc->flags |= CODEC_FLAG_4MV;
1308 avctx_enc->dia_size =2;
1310 avctx_enc->flags |= CODEC_FLAG_QPEL;
1313 avcodec_open(avctx_enc, enc);
1316 pv->mcdeint_frame = avcodec_alloc_frame();
1317 pv->mcdeint_outbuf_size = width * height * 10;
1318 pv->mcdeint_outbuf = malloc( pv->mcdeint_outbuf_size );
1324 void hb_decomb_close( hb_filter_private_t * pv )
1331 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);
1333 /* Cleanup frame buffers */
1334 if( pv->buf_out[0] )
1336 hb_buffer_close( &pv->buf_out[0] );
1338 if( pv->buf_out[1] )
1340 hb_buffer_close( &pv->buf_out[1] );
1342 if (pv->buf_settings )
1344 hb_buffer_close( &pv->buf_settings );
1347 /* Cleanup yadif specific buffers */
1349 for( i = 0; i<3*3; i++ )
1351 uint8_t **p = &pv->ref[i%3][i/3];
1354 free( *p - 3*pv->ref_stride[i/3] );
1359 /* Cleanup combing mask. */
1360 for( i = 0; i<3*3; i++ )
1362 uint8_t **p = &pv->mask[i/3];
1365 free( *p - 3*pv->ref_stride[i/3] );
1370 for( i = 0; i < pv->cpu_count; i++)
1373 * Tell each yadif thread to stop, and then cleanup.
1375 pv->yadif_arguments[i].stop = 1;
1376 hb_unlock( pv->yadif_begin_lock[i] );
1378 hb_thread_close( &pv->yadif_threads[i] );
1379 hb_lock_close( &pv->yadif_begin_lock[i] );
1380 hb_lock_close( &pv->yadif_complete_lock[i] );
1384 * free memory for yadif structs
1386 free( pv->yadif_threads );
1387 free( pv->yadif_begin_lock );
1388 free( pv->yadif_complete_lock );
1389 free( pv->yadif_arguments );
1391 for( i = 0; i < pv->cpu_count; i++)
1394 * Tell each decomb thread to stop, and then cleanup.
1396 pv->decomb_arguments[i].stop = 1;
1397 hb_unlock( pv->decomb_begin_lock[i] );
1399 hb_thread_close( &pv->decomb_threads[i] );
1400 hb_lock_close( &pv->decomb_begin_lock[i] );
1401 hb_lock_close( &pv->decomb_complete_lock[i] );
1405 * free memory for decomb structs
1407 free( pv->decomb_threads );
1408 free( pv->decomb_begin_lock );
1409 free( pv->decomb_complete_lock );
1410 free( pv->decomb_arguments );
1412 /* Cleanup mcdeint specific buffers */
1413 if( pv->mcdeint_mode >= 0 )
1415 if( pv->mcdeint_avctx_enc )
1417 avcodec_close( pv->mcdeint_avctx_enc );
1418 av_freep( &pv->mcdeint_avctx_enc );
1420 if( pv->mcdeint_outbuf )
1422 free( pv->mcdeint_outbuf );
1429 int hb_decomb_work( const hb_buffer_t * cbuf_in,
1430 hb_buffer_t ** buf_out,
1434 hb_filter_private_t * pv )
1436 hb_buffer_t * buf_in = (hb_buffer_t *)cbuf_in;
1439 pix_fmt != pv->pix_fmt ||
1440 width != pv->width[0] ||
1441 height != pv->height[0] )
1443 return FILTER_FAILED;
1446 avpicture_fill( &pv->pic_in, buf_in->data,
1447 pix_fmt, width, height );
1449 /* Determine if top-field first layout */
1451 if( pv->parity < 0 )
1453 tff = !!(buf_in->flags & PIC_FLAG_TOP_FIELD_FIRST);
1457 tff = (pv->parity & 1) ^ 1;
1460 /* Store current frame in yadif cache */
1461 store_ref( (const uint8_t**)pv->pic_in.data, pv );
1463 /* If yadif is not ready, store another ref and return FILTER_DELAY */
1464 if( pv->yadif_ready == 0 )
1466 store_ref( (const uint8_t**)pv->pic_in.data, pv );
1468 hb_buffer_copy_settings( pv->buf_settings, buf_in );
1470 /* don't let 'work_loop' send a chapter mark upstream */
1471 buf_in->new_chap = 0;
1473 pv->yadif_ready = 1;
1475 return FILTER_DELAY;
1478 /* Perform yadif filtering */
1480 for( frame = 0; frame <= ( ( pv->mode == 2 || pv->mode == 3 )? 1 : 0 ) ; frame++ )
1482 int parity = frame ^ tff ^ 1;
1484 avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,
1485 pix_fmt, width, height );
1487 yadif_filter( pv->pic_out.data, parity, tff, pv );
1489 if( pv->mcdeint_mode >= 0 )
1491 /* Perform mcdeint filtering */
1492 avpicture_fill( &pv->pic_in, pv->buf_out[(frame^1)]->data,
1493 pix_fmt, width, height );
1495 mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );
1498 *buf_out = pv->buf_out[!(frame^1)];
1501 /* Copy buffered settings to output buffer settings */
1502 hb_buffer_copy_settings( *buf_out, pv->buf_settings );
1504 /* Replace buffered settings with input buffer settings */
1505 hb_buffer_copy_settings( pv->buf_settings, buf_in );
1507 /* don't let 'work_loop' send a chapter mark upstream */
1508 buf_in->new_chap = 0;