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.
8 Tritical's work inspired much of the comb detection code:
9 http://web.missouri.edu/~kes25c/
14 Mode : Spatial metric : Motion thresh : Spatial thresh : Block thresh :
15 Block width : Block height
18 Magnitude thresh : Variance thresh : Laplacian thresh : Dilation thresh :
19 Erosion thresh : Noise thresh : Max search distance : Post-processing
25 7:2:6:9:80:16:16:10:20:20:4:2:50:24:1:-1
28 #define MODE_YADIF 1 // Use yadif
29 #define MODE_BLEND 2 // Use blending interpolation
30 #define MODE_CUBIC 4 // Use cubic interpolation
31 #define MODE_EEDI2 8 // Use EEDI2 interpolation
32 #define MODE_MCDEINT 16 // Post-process with mcdeint
33 #define MODE_MASK 32 // Output combing masks instead of pictures
36 These modes can be layered. For example, Yadif (1) + EEDI2 (8) = 9,
37 which will feed EEDI2 interpolations to yadif.
42 3: Switch between yadif and blend
43 4: Just cubic interpolate
45 6: Switch between cubic and blend
46 7: Switch between cubic->yadif and blend
47 8: Just EEDI2 interpolate
49 10: Switch between EEDI2 and blend
50 11: Switch between EEDI2->yadif and blend
53 19: Switch between blending and yadif -> mcdeint
55 21: Cubic->yadif->mcdeint
56 22: Cubic or blend -> mcdeint
57 23: Cubic->yadif or blend -> mcdeint
59 25: EEDI2->yadif->mcdeint
60 ...okay I'm getting bored now listing all these different modes
61 32: Passes through the combing mask for every combed frame (white for combed pixels, otherwise black)
62 33+: Overlay the combing mask for every combed frame on top of the filtered output (white for combed pixels)
64 12-15: EEDI2 will override cubic interpolation
65 16: DOES NOT WORK BY ITSELF-- mcdeint needs to be fed by another deinterlacer
70 #include "mpeg2dec/mpeg2.h"
73 #define SUPPRESS_AV_LOG
75 #define PARITY_DEFAULT -1
77 #define MCDEINT_MODE_DEFAULT -1
78 #define MCDEINT_QP_DEFAULT 1
80 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
81 #define MIN3(a,b,c) MIN(MIN(a,b),c)
82 #define MAX3(a,b,c) MAX(MAX(a,b),c)
84 // Some names to correspond to the pv->eedi_half array's contents
89 // Some names to correspond to the pv->eedi_full array's contents
96 struct yadif_arguments_s {
104 struct decomb_arguments_s {
108 struct eedi2_arguments_s {
112 typedef struct yadif_arguments_s yadif_arguments_t;
113 typedef struct decomb_arguments_s decomb_arguments_t;
114 typedef struct eedi2_arguments_s eedi2_arguments_t;
116 typedef struct eedi2_thread_arg_s {
117 hb_filter_private_t *pv;
119 } eedi2_thread_arg_t;
121 typedef struct decomb_thread_arg_s {
122 hb_filter_private_t *pv;
124 } decomb_thread_arg_t;
126 typedef struct yadif_thread_arg_s {
127 hb_filter_private_t *pv;
129 } yadif_thread_arg_t;
131 struct hb_filter_private_s
140 int motion_threshold;
141 int spatial_threshold;
147 int magnitude_threshold;
148 int variance_threshold;
149 int laplacian_threshold;
150 int dilation_threshold;
151 int erosion_threshold;
153 int maximum_search_distance;
164 int mcdeint_outbuf_size;
165 uint8_t * mcdeint_outbuf;
166 AVCodecContext * mcdeint_avctx_enc;
167 AVFrame * mcdeint_frame;
168 AVFrame * mcdeint_frame_dec;
170 int deinterlaced_frames;
172 int unfiltered_frames;
177 /* Make a buffer to store a comb mask. */
180 uint8_t * eedi_half[4][3];
181 uint8_t * eedi_full[5][3];
189 hb_buffer_t * buf_out[2];
190 hb_buffer_t * buf_settings;
194 hb_thread_t ** yadif_threads; // Threads for Yadif - one per CPU
195 hb_lock_t ** yadif_begin_lock; // Thread has work
196 hb_lock_t ** yadif_complete_lock; // Thread has completed work
197 yadif_arguments_t *yadif_arguments; // Arguments to thread for work
199 hb_thread_t ** decomb_threads; // Threads for comb detection - one per CPU
200 hb_lock_t ** decomb_begin_lock; // Thread has work
201 hb_lock_t ** decomb_complete_lock; // Thread has completed work
202 decomb_arguments_t *decomb_arguments; // Arguments to thread for work
204 hb_thread_t ** eedi2_threads; // Threads for eedi2 - one per plane
205 hb_lock_t ** eedi2_begin_lock; // Thread has work
206 hb_lock_t ** eedi2_complete_lock; // Thread has completed work
207 eedi2_arguments_t *eedi2_arguments; // Arguments to thread for work
209 // int alternator; // for bobbing parity when framedoubling
212 hb_filter_private_t * hb_decomb_init( int pix_fmt,
217 int hb_decomb_work( const hb_buffer_t * buf_in,
218 hb_buffer_t ** buf_out,
222 hb_filter_private_t * pv );
224 void hb_decomb_close( hb_filter_private_t * pv );
226 hb_filter_object_t hb_filter_decomb =
236 int cubic_interpolate_pixel( int y0, int y1, int y2, int y3 )
238 /* From http://www.neuron2.net/library/cubicinterp.html */
239 int result = ( y0 * -3 ) + ( y1 * 23 ) + ( y2 * 23 ) + ( y3 * -3 );
246 else if( result < 0 )
254 static void cubic_interpolate_line( uint8_t *dst,
258 hb_filter_private_t * pv )
260 int w = pv->width[plane];
261 int refs = pv->ref_stride[plane];
264 for( x = 0; x < w; x++)
275 else if( y == 2 || y == 1 )
277 /* There's only one sample above this pixel, use it twice. */
283 /* No samples above, triple up on the one below. */
288 if( y <= ( pv->height[plane] - 4 ) )
294 else if( y == ( pv->height[plane] - 3 ) || y == ( pv->height[plane] - 2 ) )
296 /* There's only one sample below, use it twice. */
300 else if( y == pv->height[plane] - 1)
302 /* No samples below, triple up on the one above. */
307 dst[0] = cubic_interpolate_pixel( a, b, c, d );
314 void apply_mask_line( uint8_t * srcp,
320 for( x = 0; x < width; x++ )
329 void apply_mask( hb_filter_private_t * pv )
333 for( plane = 0; plane < 3; plane++ )
335 uint8_t * srcp = ( pv->mode & MODE_MCDEINT ) ? pv->pic_in.data[plane] : pv->pic_out.data[plane];
336 uint8_t * mskp = pv->mask[plane];
338 for( height = 0; height < pv->height[plane]; height++ )
340 if( pv->mode == MODE_MASK && plane == 0 )
342 memcpy( srcp, mskp, pv->width[plane] );
344 else if( pv->mode == MODE_MASK )
346 memset( srcp, 128, pv->width[plane] );
348 else if( plane == 0 )
350 apply_mask_line( srcp, mskp, pv->width[plane] );
353 srcp += pv->pic_out.linesize[plane];
354 mskp += pv->ref_stride[plane];
359 static void store_ref( const uint8_t ** pic,
360 hb_filter_private_t * pv )
364 sizeof(uint8_t *)*3 );
368 sizeof(uint8_t *)*3*3 );
371 for( i = 0; i < 3; i++ )
373 const uint8_t * src = pic[i];
374 uint8_t * ref = pv->ref[2][i];
376 int w = pv->width[i];
377 int h = pv->height[i];
378 int ref_stride = pv->ref_stride[i];
381 for( y = 0; y < h; y++ )
384 src = (uint8_t*)src + w;
385 ref = (uint8_t*)ref + ref_stride;
390 /* This function may be useful in the future, if we want to output
391 a reference to an AVPicture, since they have different strides.
392 static void get_ref( uint8_t ** pic, hb_filter_private_t * pv, int frm )
395 for( i = 0; i < 3; i++ )
397 uint8_t * dst = pic[i];
398 const uint8_t * ref = pv->ref[frm][i];
399 int w = pv->width[i];
400 int ref_stride = pv->ref_stride[i];
403 for( y = 0; y < pv->height[i]; y++ )
413 int blend_filter_pixel( int up2, int up1, int current, int down1, int down2 )
415 /* Low-pass 5-tap filter */
419 result += current * 6;
436 static void blend_filter_line( uint8_t *dst,
440 hb_filter_private_t * pv )
442 int w = pv->width[plane];
443 int refs = pv->ref_stride[plane];
446 for( x = 0; x < w; x++)
458 /* First line, so A and B don't exist.*/
464 /* Second line, no A. */
467 else if( y == (pv->height[plane] - 2) )
469 /* Second to last line, no E. */
472 else if( y == (pv->height[plane] -1) )
474 /* Last line, no D or E. */
479 dst[0] = blend_filter_pixel( a, b, c, d, e );
486 int check_combing_mask( hb_filter_private_t * pv )
488 /* Go through the mask in X*Y blocks. If any of these windows
489 have threshold or more combed pixels, consider the whole
490 frame to be combed and send it on to be deinterlaced. */
492 /* Block mask threshold -- The number of pixels
493 in a block_width * block_height window of
494 he mask that need to show combing for the
495 whole frame to be seen as such. */
496 int threshold = pv->block_threshold;
497 int block_width = pv->block_width;
498 int block_height = pv->block_height;
499 int block_x, block_y;
500 int block_score = 0; int send_to_blend = 0;
504 for( k = 0; k < 1; k++ )
506 int ref_stride = pv->ref_stride[k];
507 for( y = 0; y < ( pv->height[k] - block_height ); y = y + block_height )
509 for( x = 0; x < ( pv->width[k] - block_width ); x = x + block_width )
512 for( block_y = 0; block_y < block_height; block_y++ )
514 for( block_x = 0; block_x < block_width; block_x++ )
516 int mask_y = y + block_y;
517 int mask_x = x + block_x;
519 /* We only want to mark a pixel in a block as combed
520 if the pixels above and below are as well. Got to
521 handle the top and bottom lines separately. */
522 if( y + block_y == 0 )
524 if( pv->mask[k][mask_y*ref_stride+mask_x ] == 255 &&
525 pv->mask[k][mask_y*ref_stride+mask_x + 1] == 255 )
528 else if( y + block_y == pv->height[k] - 1 )
530 if( pv->mask[k][mask_y*ref_stride+mask_x - 1] == 255 &&
531 pv->mask[k][mask_y*ref_stride+mask_x ] == 255 )
536 if( pv->mask[k][mask_y*ref_stride+mask_x - 1] == 255 &&
537 pv->mask[k][mask_y*ref_stride+mask_x ] == 255 &&
538 pv->mask[k][mask_y*ref_stride+mask_x + 1] == 255 )
544 if( block_score >= ( threshold / 2 ) )
547 hb_log("decomb: frame %i | score %i | type %s", pv->deinterlaced_frames + pv->blended_frames + pv->unfiltered_frames + 1, block_score, pv->buf_settings->flags & 16 ? "Film" : "Video");
549 if ( block_score <= threshold && !( pv->buf_settings->flags & 16) )
551 /* Blend video content that scores between
552 ( threshold / 2 ) and threshold. */
555 else if( block_score > threshold )
557 if( pv->buf_settings->flags & 16 )
559 /* Blend progressive content above the threshold.*/
564 /* Yadif deinterlace video content above the threshold. */
579 /* Consider this frame to be uncombed. */
584 void detect_combed_segment( hb_filter_private_t * pv, int segment_start, int segment_stop )
586 /* A mish-mash of various comb detection tricks
587 picked up from neuron2's Decomb plugin for
588 AviSynth and tritical's IsCombedT and
589 IsCombedTIVTC plugins. */
591 int x, y, k, width, height;
593 /* Comb scoring algorithm */
594 int spatial_metric = pv->spatial_metric;
595 /* Motion threshold */
596 int mthresh = pv->motion_threshold;
597 /* Spatial threshold */
598 int athresh = pv->spatial_threshold;
599 int athresh_squared = athresh * athresh;
600 int athresh6 = 6 *athresh;
602 /* One pas for Y, one pass for U, one pass for V */
603 for( k = 0; k < 1; k++ )
605 int ref_stride = pv->ref_stride[k];
606 width = pv->width[k];
607 height = pv->height[k];
609 /* Comb detection has to start at y = 2 and end at
610 y = height - 2, because it needs to examine
611 2 pixels above and 2 below the current pixel. */
612 if( segment_start < 2 )
614 if( segment_stop > height - 2 )
615 segment_stop = height - 2;
617 for( y = segment_start; y < segment_stop; y++ )
619 /* These are just to make the buffer locations easier to read. */
620 int back_2 = ( y - 2 )*ref_stride ;
621 int back_1 = ( y - 1 )*ref_stride;
622 int current = y*ref_stride;
623 int forward_1 = ( y + 1 )*ref_stride;
624 int forward_2 = ( y + 2 )*ref_stride;
626 /* We need to examine a column of 5 pixels
627 in the prev, cur, and next frames. */
628 uint8_t previous_frame[5];
629 uint8_t current_frame[5];
630 uint8_t next_frame[5];
632 for( x = 0; x < width; x++ )
634 /* Fill up the current frame array with the current pixel values.*/
635 current_frame[0] = pv->ref[1][k][back_2 + x];
636 current_frame[1] = pv->ref[1][k][back_1 + x];
637 current_frame[2] = pv->ref[1][k][current + x];
638 current_frame[3] = pv->ref[1][k][forward_1 + x];
639 current_frame[4] = pv->ref[1][k][forward_2 + x];
641 int up_diff = current_frame[2] - current_frame[1];
642 int down_diff = current_frame[2] - current_frame[3];
644 if( ( up_diff > athresh && down_diff > athresh ) ||
645 ( up_diff < -athresh && down_diff < -athresh ) )
647 /* The pixel above and below are different,
648 and they change in the same "direction" too.*/
652 /* Make sure there's sufficient motion between frame t-1 to frame t+1. */
653 previous_frame[0] = pv->ref[0][k][back_2 + x];
654 previous_frame[1] = pv->ref[0][k][back_1 + x];
655 previous_frame[2] = pv->ref[0][k][current + x];
656 previous_frame[3] = pv->ref[0][k][forward_1 + x];
657 previous_frame[4] = pv->ref[0][k][forward_2 + x];
658 next_frame[0] = pv->ref[2][k][back_2 + x];
659 next_frame[1] = pv->ref[2][k][back_1 + x];
660 next_frame[2] = pv->ref[2][k][current + x];
661 next_frame[3] = pv->ref[2][k][forward_1 + x];
662 next_frame[4] = pv->ref[2][k][forward_2 + x];
664 if( abs( previous_frame[2] - current_frame[2] ) > mthresh &&
665 abs( current_frame[1] - next_frame[1] ) > mthresh &&
666 abs( current_frame[3] - next_frame[3] ) > mthresh )
668 if( abs( next_frame[2] - current_frame[2] ) > mthresh &&
669 abs( previous_frame[1] - current_frame[1] ) > mthresh &&
670 abs( previous_frame[3] - current_frame[3] ) > mthresh )
675 /* User doesn't want to check for motion,
676 so move on to the spatial check. */
680 if( motion || ( pv->deinterlaced_frames==0 && pv->blended_frames==0 && pv->unfiltered_frames==0) )
682 /* That means it's time for the spatial check.
683 We've got several options here. */
684 if( spatial_metric == 0 )
686 /* Simple 32detect style comb detection */
687 if( ( abs( current_frame[2] - current_frame[4] ) < 10 ) &&
688 ( abs( current_frame[2] - current_frame[3] ) > 15 ) )
690 pv->mask[k][y*ref_stride + x] = 255;
694 pv->mask[k][y*ref_stride + x] = 0;
697 else if( spatial_metric == 1 )
699 /* This, for comparison, is what IsCombed uses.
700 It's better, but still noise senstive. */
701 int combing = ( current_frame[1] - current_frame[2] ) *
702 ( current_frame[3] - current_frame[2] );
704 if( combing > athresh_squared )
705 pv->mask[k][y*ref_stride + x] = 255;
707 pv->mask[k][y*ref_stride + x] = 0;
709 else if( spatial_metric == 2 )
711 /* Tritical's noise-resistant combing scorer.
712 The check is done on a bob+blur convolution. */
713 int combing = abs( current_frame[0]
714 + ( 4 * current_frame[2] )
716 - ( 3 * ( current_frame[1]
717 + current_frame[3] ) ) );
719 /* If the frame is sufficiently combed,
720 then mark it down on the mask as 255. */
721 if( combing > athresh6 )
722 pv->mask[k][y*ref_stride + x] = 255;
724 pv->mask[k][y*ref_stride + x] = 0;
729 pv->mask[k][y*ref_stride + x] = 0;
734 pv->mask[k][y*ref_stride + x] = 0;
741 // This function calls all the eedi2 filters in sequence for a given plane.
742 // It outputs the final interpolated image to pv->eedi_full[DST2PF].
743 void eedi2_interpolate_plane( hb_filter_private_t * pv, int k )
745 /* We need all these pointers. No, seriously.
746 I swear. It's not a joke. They're used.
748 uint8_t * mskp = pv->eedi_half[MSKPF][k];
749 uint8_t * srcp = pv->eedi_half[SRCPF][k];
750 uint8_t * tmpp = pv->eedi_half[TMPPF][k];
751 uint8_t * dstp = pv->eedi_half[DSTPF][k];
752 uint8_t * dst2p = pv->eedi_full[DST2PF][k];
753 uint8_t * tmp2p2 = pv->eedi_full[TMP2PF2][k];
754 uint8_t * msk2p = pv->eedi_full[MSK2PF][k];
755 uint8_t * tmp2p = pv->eedi_full[TMP2PF][k];
756 uint8_t * dst2mp = pv->eedi_full[DST2MPF][k];
760 int * tmpc = pv->tmpc;
762 int pitch = pv->ref_stride[k];
763 int height = pv->height[k]; int width = pv->width[k];
764 int half_height = height / 2;
767 eedi2_build_edge_mask( mskp, pitch, srcp, pitch,
768 pv->magnitude_threshold, pv->variance_threshold, pv->laplacian_threshold,
769 half_height, width );
770 eedi2_erode_edge_mask( mskp, pitch, tmpp, pitch, pv->erosion_threshold, half_height, width );
771 eedi2_dilate_edge_mask( tmpp, pitch, mskp, pitch, pv->dilation_threshold, half_height, width );
772 eedi2_erode_edge_mask( mskp, pitch, tmpp, pitch, pv->erosion_threshold, half_height, width );
773 eedi2_remove_small_gaps( tmpp, pitch, mskp, pitch, half_height, width );
776 eedi2_calc_directions( k, mskp, pitch, srcp, pitch, tmpp, pitch,
777 pv->maximum_search_distance, pv->noise_threshold,
778 half_height, width );
779 eedi2_filter_dir_map( mskp, pitch, tmpp, pitch, dstp, pitch, half_height, width );
780 eedi2_expand_dir_map( mskp, pitch, dstp, pitch, tmpp, pitch, half_height, width );
781 eedi2_filter_map( mskp, pitch, tmpp, pitch, dstp, pitch, half_height, width );
783 // upscale 2x vertically
784 eedi2_upscale_by_2( srcp, dst2p, half_height, pitch );
785 eedi2_upscale_by_2( dstp, tmp2p2, half_height, pitch );
786 eedi2_upscale_by_2( mskp, msk2p, half_height, pitch );
788 // upscale the direction mask
789 eedi2_mark_directions_2x( msk2p, pitch, tmp2p2, pitch, tmp2p, pitch, pv->tff, height, width );
790 eedi2_filter_dir_map_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
791 eedi2_expand_dir_map_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
792 eedi2_fill_gaps_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
793 eedi2_fill_gaps_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
795 // interpolate a full-size plane
796 eedi2_interpolate_lattice( k, tmp2p, pitch, dst2p, pitch, tmp2p2, pitch, pv->tff,
797 pv->noise_threshold, height, width );
799 if( pv->post_processing == 1 || pv->post_processing == 3 )
801 // make sure the edge directions are consistent
802 eedi2_bit_blit( tmp2p2, pitch, tmp2p, pitch, pv->width[k], pv->height[k] );
803 eedi2_filter_dir_map_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
804 eedi2_expand_dir_map_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
805 eedi2_post_process( tmp2p, pitch, tmp2p2, pitch, dst2p, pitch, pv->tff, height, width );
807 if( pv->post_processing == 2 || pv->post_processing == 3 )
809 // filter junctions and corners
810 eedi2_gaussian_blur1( srcp, pitch, tmpp, pitch, srcp, pitch, half_height, width );
811 eedi2_calc_derivatives( srcp, pitch, half_height, width, cx2, cy2, cxy );
812 eedi2_gaussian_blur_sqrt2( cx2, tmpc, cx2, pitch, half_height, width);
813 eedi2_gaussian_blur_sqrt2( cy2, tmpc, cy2, pitch, half_height, width);
814 eedi2_gaussian_blur_sqrt2( cxy, tmpc, cxy, pitch, half_height, width);
815 eedi2_post_process_corner( cx2, cy2, cxy, pitch, tmp2p2, pitch, dst2p, pitch, height, width, pv->tff );
820 * eedi2 interpolate this plane in a single thread.
822 void eedi2_filter_thread( void *thread_args_v )
824 eedi2_arguments_t *eedi2_work = NULL;
825 hb_filter_private_t * pv;
828 eedi2_thread_arg_t *thread_args = thread_args_v;
830 pv = thread_args->pv;
831 plane = thread_args->plane;
833 hb_log("eedi2 thread started for plane %d", plane);
838 * Wait here until there is work to do. hb_lock() blocks until
839 * render releases it to say that there is more work to do.
841 hb_lock( pv->eedi2_begin_lock[plane] );
843 eedi2_work = &pv->eedi2_arguments[plane];
845 if( eedi2_work->stop )
848 * No more work to do, exit this thread.
857 eedi2_interpolate_plane( pv, plane );
860 * Finished this segment, let everyone know.
862 hb_unlock( pv->eedi2_complete_lock[plane] );
864 free( thread_args_v );
867 // Sets up the input field planes for EEDI2 in pv->eedi_half[SRCPF]
868 // and then runs eedi2_filter_thread for each plane.
869 void eedi2_planer( hb_filter_private_t * pv )
871 /* Copy the first field from the source to a half-height frame. */
873 for( i = 0; i < 3; i++ )
875 int pitch = pv->ref_stride[i];
876 int start_line = !pv->tff;
877 eedi2_fill_half_height_buffer_plane( &pv->ref[1][i][pitch*start_line], pv->eedi_half[SRCPF][i], pitch, pv->height[i] );
881 for( plane = 0; plane < 3; plane++ )
884 * Let the thread for this plane know that we've setup work
885 * for it by releasing the begin lock (ensuring that the
886 * complete lock is already locked so that we block when
887 * we try to lock it again below).
889 hb_lock( pv->eedi2_complete_lock[plane] );
890 hb_unlock( pv->eedi2_begin_lock[plane] );
894 * Wait until all three threads have completed by trying to get
895 * the complete lock that we locked earlier for each thread, which
896 * will block until that thread has completed the work on that
899 for( plane = 0; plane < 3; plane++ )
901 hb_lock( pv->eedi2_complete_lock[plane] );
902 hb_unlock( pv->eedi2_complete_lock[plane] );
908 * comb detect this segment of all three planes in a single thread.
910 void decomb_filter_thread( void *thread_args_v )
912 decomb_arguments_t *decomb_work = NULL;
913 hb_filter_private_t * pv;
915 int segment, segment_start, segment_stop, plane;
916 decomb_thread_arg_t *thread_args = thread_args_v;
918 pv = thread_args->pv;
919 segment = thread_args->segment;
921 hb_log("decomb thread started for segment %d", segment);
926 * Wait here until there is work to do. hb_lock() blocks until
927 * render releases it to say that there is more work to do.
929 hb_lock( pv->decomb_begin_lock[segment] );
931 decomb_work = &pv->decomb_arguments[segment];
933 if( decomb_work->stop )
936 * No more work to do, exit this thread.
943 * Process segment (for now just from luma)
945 for( plane = 0; plane < 1; plane++)
948 int h = pv->height[plane];
949 segment_start = ( h / pv->cpu_count ) * segment;
950 if( segment == pv->cpu_count - 1 )
957 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
960 detect_combed_segment( pv, segment_start, segment_stop );
963 * Finished this segment, let everyone know.
965 hb_unlock( pv->decomb_complete_lock[segment] );
967 free( thread_args_v );
970 int comb_segmenter( hb_filter_private_t * pv )
974 for( segment = 0; segment < pv->cpu_count; segment++ )
977 * Let the thread for this plane know that we've setup work
978 * for it by releasing the begin lock (ensuring that the
979 * complete lock is already locked so that we block when
980 * we try to lock it again below).
982 hb_lock( pv->decomb_complete_lock[segment] );
983 hb_unlock( pv->decomb_begin_lock[segment] );
987 * Wait until all three threads have completed by trying to get
988 * the complete lock that we locked earlier for each thread, which
989 * will block until that thread has completed the work on that
992 for( segment = 0; segment < pv->cpu_count; segment++ )
994 hb_lock( pv->decomb_complete_lock[segment] );
995 hb_unlock( pv->decomb_complete_lock[segment] );
998 return check_combing_mask( pv );
1001 static void yadif_filter_line( uint8_t *dst,
1008 hb_filter_private_t * pv )
1010 /* While prev and next point to the previous and next frames,
1011 prev2 and next2 will shift depending on the parity, usually 1.
1012 They are the previous and next fields, the fields temporally adjacent
1013 to the other field in the current frame--the one not being filtered. */
1014 uint8_t *prev2 = parity ? prev : cur ;
1015 uint8_t *next2 = parity ? cur : next;
1017 int w = pv->width[plane];
1018 int refs = pv->ref_stride[plane];
1020 int eedi2_mode = ( pv->mode & MODE_EEDI2 );
1022 /* We can replace spatial_pred with this interpolation*/
1023 uint8_t * eedi2_guess = &pv->eedi_full[DST2PF][plane][y*refs];
1025 /* Decomb's cubic interpolation can only function when there are
1026 three samples above and below, so regress to yadif's traditional
1027 two-tap interpolation when filtering at the top and bottom edges. */
1028 int vertical_edge = 0;
1029 if( ( y < 3 ) || ( y > ( pv->height[plane] - 4 ) ) )
1032 for( x = 0; x < w; x++)
1036 /* Temporal average: the current location in the adjacent fields */
1037 int d = (prev2[0] + next2[0])>>1;
1041 /* How the current pixel changes between the adjacent fields */
1042 int temporal_diff0 = ABS(prev2[0] - next2[0]);
1043 /* The average of how much the pixels above and below change from the frame before to now. */
1044 int temporal_diff1 = ( ABS(prev[-refs] - cur[-refs]) + ABS(prev[+refs] - cur[+refs]) ) >> 1;
1045 /* The average of how much the pixels above and below change from now to the next frame. */
1046 int temporal_diff2 = ( ABS(next[-refs] - cur[-refs]) + ABS(next[+refs] - cur[+refs]) ) >> 1;
1047 /* For the actual difference, use the largest of the previous average diffs. */
1048 int diff = MAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
1054 /* Who needs yadif's spatial predictions when we can have EEDI2's? */
1055 spatial_pred = eedi2_guess[0];
1058 else // Yadif spatial interpolation
1060 /* SAD of how the pixel-1, the pixel, and the pixel+1 change from the line above to below. */
1061 int spatial_score = ABS(cur[-refs-1] - cur[+refs-1]) + ABS(cur[-refs]-cur[+refs]) +
1062 ABS(cur[-refs+1] - cur[+refs+1]) - 1;
1064 /* Spatial pred is either a bilinear or cubic vertical interpolation. */
1065 if( ( pv->mode & MODE_CUBIC ) && !vertical_edge)
1067 spatial_pred = cubic_interpolate_pixel( cur[-3*refs], cur[-refs], cur[+refs], cur[3*refs] );
1071 spatial_pred = (c+e)>>1;
1074 /* EDDI: Edge Directed Deinterlacing Interpolation
1075 Checks 4 different slopes to see if there is more similarity along a diagonal
1076 than there was vertically. If a diagonal is more similar, then it indicates
1077 an edge, so interpolate along that instead of a vertical line, using either
1078 linear or cubic interpolation depending on mode. */
1079 #define YADIF_CHECK(j)\
1080 { int score = ABS(cur[-refs-1+j] - cur[+refs-1-j])\
1081 + ABS(cur[-refs +j] - cur[+refs -j])\
1082 + ABS(cur[-refs+1+j] - cur[+refs+1-j]);\
1083 if( score < spatial_score ){\
1084 spatial_score = score;\
1085 if( ( pv->mode & MODE_CUBIC ) && !vertical_edge )\
1090 spatial_pred = cubic_interpolate_pixel(cur[-3 * refs - 3], cur[-refs -1], cur[+refs + 1], cur[3* refs + 3] );\
1093 spatial_pred = cubic_interpolate_pixel( ( ( cur[-3*refs - 4] + cur[-refs - 4] ) / 2 ) , cur[-refs -2], cur[+refs + 2], ( ( cur[3*refs + 4] + cur[refs + 4] ) / 2 ) );\
1096 spatial_pred = cubic_interpolate_pixel(cur[-3 * refs +3], cur[-refs +1], cur[+refs - 1], cur[3* refs -3] );\
1099 spatial_pred = cubic_interpolate_pixel(( ( cur[-3*refs + 4] + cur[-refs + 4] ) / 2 ), cur[-refs +2], cur[+refs - 2], ( ( cur[3*refs - 4] + cur[refs - 4] ) / 2 ) );\
1105 spatial_pred = ( cur[-refs +j] + cur[+refs -j] ) >>1;\
1108 if( x >= 2 && x <= w - 3 )
1111 if( x >= 3 && x <= w - 4 )
1113 YADIF_CHECK(-2) }} }}
1116 if( x >= 2 && x <= w - 3 )
1119 if( x >= 3 && x <= w - 4 )
1121 YADIF_CHECK(2) }} }}
1126 /* Temporally adjust the spatial prediction by
1127 comparing against lines in the adjacent fields. */
1128 int b = (prev2[-2*refs] + next2[-2*refs])>>1;
1129 int f = (prev2[+2*refs] + next2[+2*refs])>>1;
1131 /* Find the median value */
1132 int max = MAX3(d-e, d-c, MIN(b-c, f-e));
1133 int min = MIN3(d-e, d-c, MAX(b-c, f-e));
1134 diff = MAX3( diff, min, -max );
1136 if( spatial_pred > d + diff )
1138 spatial_pred = d + diff;
1140 else if( spatial_pred < d - diff )
1142 spatial_pred = d - diff;
1145 dst[0] = spatial_pred;
1157 * deinterlace this segment of all three planes in a single thread.
1159 void yadif_decomb_filter_thread( void *thread_args_v )
1161 yadif_arguments_t *yadif_work = NULL;
1162 hb_filter_private_t * pv;
1165 int segment, segment_start, segment_stop;
1166 yadif_thread_arg_t *thread_args = thread_args_v;
1168 int parity, tff, y, w, h, penultimate, ultimate, ref_stride, is_combed;
1170 pv = thread_args->pv;
1171 segment = thread_args->segment;
1173 hb_log("yadif thread started for segment %d", segment);
1178 * Wait here until there is work to do. hb_lock() blocks until
1179 * render releases it to say that there is more work to do.
1181 hb_lock( pv->yadif_begin_lock[segment] );
1183 yadif_work = &pv->yadif_arguments[segment];
1185 if( yadif_work->stop )
1188 * No more work to do, exit this thread.
1194 if( yadif_work->dst == NULL )
1196 hb_error( "thread started when no work available" );
1201 is_combed = pv->yadif_arguments[segment].is_combed;
1204 * Process all three planes, but only this segment of it.
1206 for( plane = 0; plane < 3; plane++)
1209 dst = yadif_work->dst;
1210 parity = yadif_work->parity;
1211 tff = yadif_work->tff;
1212 w = pv->width[plane];
1213 h = pv->height[plane];
1214 penultimate = h - 2;
1216 ref_stride = pv->ref_stride[plane];
1217 segment_start = ( h / pv->cpu_count ) * segment;
1218 if( segment == pv->cpu_count - 1 )
1225 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
1228 for( y = segment_start; y < segment_stop; y++ )
1230 if( is_combed == 2 )
1232 /* This line gets blend filtered, not yadif filtered. */
1233 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
1234 uint8_t *dst2 = &dst[plane][y*w];
1235 /* These will be useful if we ever do temporal blending. */
1236 // uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
1237 // uint8_t *next = &pv->ref[2][plane][y*ref_stride];
1239 blend_filter_line( dst2, cur, plane, y, pv );
1241 else if( pv->mode == MODE_CUBIC && is_combed && ( ( y ^ parity ) & 1 ) )
1243 /* Just apply vertical cubic interpolation */
1244 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
1245 uint8_t *dst2 = &dst[plane][y*w];
1247 cubic_interpolate_line( dst2, cur, plane, y, pv );
1249 else if( pv->mode & MODE_YADIF && ( ( y ^ parity ) & 1 ) && ( is_combed == 1 ) )
1251 /* This line gets yadif filtered. It is the bottom field
1252 when TFF and vice-versa. It's the field that gets
1253 filtered. Because yadif needs 2 lines above and below
1254 the one being filtered, we need to mirror the edges.
1255 When TFF, this means replacing the 2nd line with a
1256 copy of the 1st, and the last with the second-to-last. */
1257 if( y > 1 && y < ( h -2 ) )
1259 /* This isn't the top or bottom, proceed as normal to yadif. */
1260 uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
1261 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
1262 uint8_t *next = &pv->ref[2][plane][y*ref_stride];
1263 uint8_t *dst2 = &dst[plane][y*w];
1265 yadif_filter_line( dst2,
1276 /* BFF, so y0 = y1 */
1277 memcpy( &dst[plane][y*w],
1278 &pv->ref[1][plane][1*ref_stride],
1279 w * sizeof(uint8_t) );
1283 /* TFF, so y1 = y0 */
1284 memcpy( &dst[plane][y*w],
1285 &pv->ref[1][plane][0],
1286 w * sizeof(uint8_t) );
1288 else if( y == penultimate )
1290 /* BFF, so penultimate y = ultimate y */
1291 memcpy( &dst[plane][y*w],
1292 &pv->ref[1][plane][ultimate*ref_stride],
1293 w * sizeof(uint8_t) );
1295 else if( y == ultimate )
1297 /* TFF, so ultimate y = penultimate y */
1298 memcpy( &dst[plane][y*w],
1299 &pv->ref[1][plane][penultimate*ref_stride],
1300 w * sizeof(uint8_t) );
1305 memcpy( &dst[plane][y*w],
1306 &pv->ref[1][plane][y*ref_stride],
1307 w * sizeof(uint8_t) );
1312 * Finished this segment, let everyone know.
1314 hb_unlock( pv->yadif_complete_lock[segment] );
1316 free( thread_args_v );
1319 static void yadif_filter( uint8_t ** dst,
1322 hb_filter_private_t * pv )
1324 /* If we're running comb detection, do it now, otherwise default to true. */
1325 int is_combed = pv->spatial_metric >= 0 ? comb_segmenter( pv ) : 1;
1327 /* The comb detector suggests three different values:
1328 0: Don't comb this frame.
1329 1: Deinterlace this frame.
1330 2: Blend this frame.
1331 Since that might conflict with the filter's mode,
1332 it may be necesary to adjust this value. */
1333 if( is_combed == 1 && (pv->mode == MODE_BLEND) )
1335 /* All combed frames are getting blended */
1338 else if( is_combed == 2 && !( pv->mode & MODE_BLEND ) )
1340 /* Blending is disabled, so force interpolation of these frames. */
1343 if( is_combed == 1 &&
1344 ( pv->mode & MODE_BLEND ) &&
1345 !( pv->mode & ( MODE_YADIF | MODE_EEDI2 | MODE_CUBIC ) ) )
1347 /* Deinterlacers are disabled, blending isn't, so blend these frames. */
1350 else if( is_combed &&
1351 !( pv->mode & ( MODE_BLEND | MODE_YADIF | MODE_EEDI2 | MODE_CUBIC | MODE_MASK ) ) )
1353 /* No deinterlacer or mask chosen, pass the frame through. */
1357 if( is_combed == 1 )
1359 pv->deinterlaced_frames++;
1361 else if( is_combed == 2 )
1363 pv->blended_frames++;
1367 pv->unfiltered_frames++;
1370 if( is_combed == 1 && ( pv->mode & MODE_EEDI2 ) )
1372 /* Generate an EEDI2 interpolation */
1378 if( ( pv->mode & MODE_EEDI2 ) && !( pv->mode & MODE_YADIF ) && is_combed == 1 )
1380 // Just pass through the EEDI2 interpolation
1382 for( i = 0; i < 3; i++ )
1384 uint8_t * ref = pv->eedi_full[DST2PF][i];
1385 uint8_t * dest = dst[i];
1387 int w = pv->width[i];
1388 int ref_stride = pv->ref_stride[i];
1391 for( y = 0; y < pv->height[i]; y++ )
1393 memcpy(dest, ref, w);
1403 for( segment = 0; segment < pv->cpu_count; segment++ )
1406 * Setup the work for this plane.
1408 pv->yadif_arguments[segment].parity = parity;
1409 pv->yadif_arguments[segment].tff = tff;
1410 pv->yadif_arguments[segment].dst = dst;
1411 pv->yadif_arguments[segment].is_combed = is_combed;
1414 * Let the thread for this plane know that we've setup work
1415 * for it by releasing the begin lock (ensuring that the
1416 * complete lock is already locked so that we block when
1417 * we try to lock it again below).
1419 hb_lock( pv->yadif_complete_lock[segment] );
1420 hb_unlock( pv->yadif_begin_lock[segment] );
1424 * Wait until all three threads have completed by trying to get
1425 * the complete lock that we locked earlier for each thread, which
1426 * will block until that thread has completed the work on that
1429 for( segment = 0; segment < pv->cpu_count; segment++ )
1431 hb_lock( pv->yadif_complete_lock[segment] );
1432 hb_unlock( pv->yadif_complete_lock[segment] );
1436 * Entire frame is now deinterlaced.
1442 /* Just passing through... */
1444 /* For mcdeint's benefit... */
1445 pv->yadif_arguments[0].is_combed = is_combed; // 0
1448 for( i = 0; i < 3; i++ )
1450 uint8_t * ref = pv->ref[1][i];
1451 uint8_t * dest = dst[i];
1453 int w = pv->width[i];
1454 int ref_stride = pv->ref_stride[i];
1457 for( y = 0; y < pv->height[i]; y++ )
1459 memcpy(dest, ref, w);
1466 if( pv->mode & MODE_MASK && pv->spatial_metric >= 0 )
1468 if( pv->mode == MODE_MASK || is_combed )
1473 static void mcdeint_filter( uint8_t ** dst,
1476 hb_filter_private_t * pv )
1481 #ifdef SUPPRESS_AV_LOG
1482 /* TODO: temporarily change log level to suppress obnoxious debug output */
1483 int loglevel = av_log_get_level();
1484 av_log_set_level( AV_LOG_QUIET );
1487 for( i=0; i<3; i++ )
1489 pv->mcdeint_frame->data[i] = src[i];
1490 pv->mcdeint_frame->linesize[i] = pv->width[i];
1492 pv->mcdeint_avctx_enc->me_cmp = FF_CMP_SAD;
1493 pv->mcdeint_avctx_enc->me_sub_cmp = FF_CMP_SAD;
1494 pv->mcdeint_frame->quality = pv->mcdeint_qp * FF_QP2LAMBDA;
1496 out_size = avcodec_encode_video( pv->mcdeint_avctx_enc,
1498 pv->mcdeint_outbuf_size,
1499 pv->mcdeint_frame );
1501 pv->mcdeint_frame_dec = pv->mcdeint_avctx_enc->coded_frame;
1503 for( i = 0; i < 3; i++ )
1505 int w = pv->width[i];
1506 int h = pv->height[i];
1507 int fils = pv->mcdeint_frame_dec->linesize[i];
1508 int srcs = pv->width[i];
1510 for( y = 0; y < h; y++ )
1512 if( (y ^ parity) & 1 )
1514 for( x = 0; x < w; x++ )
1516 if( (x-1)+(y-1)*w >= 0 && (x+1)+(y+1)*w < w*h )
1519 &pv->mcdeint_frame_dec->data[i][x + y*fils];
1520 uint8_t * srcp = &src[i][x + y*srcs];
1522 int diff0 = filp[-fils] - srcp[-srcs];
1523 int diff1 = filp[+fils] - srcp[+srcs];
1527 ABS(srcp[-srcs-1] - srcp[+srcs-1]) +
1528 ABS(srcp[-srcs ] - srcp[+srcs ]) +
1529 ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
1533 #define MCDEINT_CHECK(j)\
1534 { int score = ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
1535 + ABS(srcp[-srcs +j] - srcp[+srcs -j])\
1536 + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
1537 if( score < spatial_score ) {\
1538 spatial_score = score;\
1539 diff0 = filp[-fils+j] - srcp[-srcs+j];\
1540 diff1 = filp[+fils-j] - srcp[+srcs-j];
1542 if( x >= 2 && x <= w - 3 )
1545 if( x >= 3 && x <= w - 4 )
1547 MCDEINT_CHECK(-2) }} }}
1550 if( x >= 2 && x <= w - 3 )
1553 if( x >= 3 && x <= w - 4 )
1555 MCDEINT_CHECK(2) }} }}
1559 if(diff0 + diff1 > 0)
1561 temp -= (diff0 + diff1 -
1562 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1566 temp -= (diff0 + diff1 +
1567 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1570 filp[0] = dst[i][x + y*w] =
1571 temp > 255U ? ~(temp>>31) : temp;
1576 pv->mcdeint_frame_dec->data[i][x + y*fils];
1582 for( x = 0; x < w; x++ )
1584 pv->mcdeint_frame_dec->data[i][x + y*fils] =
1585 dst[i][x + y*w]= src[i][x + y*srcs];
1591 #ifdef SUPPRESS_AV_LOG
1592 /* TODO: restore previous log level */
1593 av_log_set_level(loglevel);
1597 hb_filter_private_t * hb_decomb_init( int pix_fmt,
1602 if( pix_fmt != PIX_FMT_YUV420P )
1607 hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) );
1609 pv->pix_fmt = pix_fmt;
1611 pv->width[0] = width;
1612 pv->height[0] = height;
1613 pv->width[1] = pv->width[2] = width >> 1;
1614 pv->height[1] = pv->height[2] = height >> 1;
1616 pv->buf_out[0] = hb_video_buffer_init( width, height );
1617 pv->buf_out[1] = hb_video_buffer_init( width, height );
1618 pv->buf_settings = hb_buffer_init( 0 );
1620 pv->deinterlaced_frames = 0;
1621 pv->blended_frames = 0;
1622 pv->unfiltered_frames = 0;
1624 pv->yadif_ready = 0;
1626 pv->mode = MODE_YADIF | MODE_BLEND | MODE_CUBIC;
1627 pv->spatial_metric = 2;
1628 pv->motion_threshold = 6;
1629 pv->spatial_threshold = 9;
1630 pv->block_threshold = 80;
1631 pv->block_width = 16;
1632 pv->block_height = 16;
1634 pv->magnitude_threshold = 10;
1635 pv->variance_threshold = 20;
1636 pv->laplacian_threshold = 20;
1637 pv->dilation_threshold = 4;
1638 pv->erosion_threshold = 2;
1639 pv->noise_threshold = 50;
1640 pv->maximum_search_distance = 24;
1641 pv->post_processing = 1;
1643 pv->parity = PARITY_DEFAULT;
1645 pv->mcdeint_mode = MCDEINT_MODE_DEFAULT;
1646 pv->mcdeint_qp = MCDEINT_QP_DEFAULT;
1650 sscanf( settings, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
1652 &pv->spatial_metric,
1653 &pv->motion_threshold,
1654 &pv->spatial_threshold,
1655 &pv->block_threshold,
1658 &pv->magnitude_threshold,
1659 &pv->variance_threshold,
1660 &pv->laplacian_threshold,
1661 &pv->dilation_threshold,
1662 &pv->erosion_threshold,
1663 &pv->noise_threshold,
1664 &pv->maximum_search_distance,
1665 &pv->post_processing,
1669 pv->cpu_count = hb_get_cpu_count();
1672 if( pv->mode & MODE_MCDEINT )
1674 pv->mcdeint_mode = 2;
1677 /* Allocate yadif specific buffers */
1679 for( i = 0; i < 3; i++ )
1681 int is_chroma = !!i;
1682 int w = ((width + 31) & (~31))>>is_chroma;
1683 int h = ((height+6+ 31) & (~31))>>is_chroma;
1685 pv->ref_stride[i] = w;
1687 for( j = 0; j < 3; j++ )
1689 pv->ref[j][i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1693 /* Allocate a buffer to store a comb mask. */
1694 for( i = 0; i < 3; i++ )
1696 int is_chroma = !!i;
1697 int w = ((pv->width[0] + 31) & (~31))>>is_chroma;
1698 int h = ((pv->height[0]+6+ 31) & (~31))>>is_chroma;
1700 pv->mask[i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1703 if( pv->mode & MODE_EEDI2 )
1705 /* Allocate half-height eedi2 buffers */
1706 height = pv->height[0] / 2;
1707 for( i = 0; i < 3; i++ )
1709 int is_chroma = !!i;
1710 int w = ((width + 31) & (~31))>>is_chroma;
1711 int h = ((height+6+ 31) & (~31))>>is_chroma;
1713 for( j = 0; j < 4; j++ )
1715 pv->eedi_half[j][i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1719 /* Allocate full-height eedi2 buffers */
1720 height = pv->height[0];
1721 for( i = 0; i < 3; i++ )
1723 int is_chroma = !!i;
1724 int w = ((width + 31) & (~31))>>is_chroma;
1725 int h = ((height+6+ 31) & (~31))>>is_chroma;
1727 for( j = 0; j < 5; j++ )
1729 pv->eedi_full[j][i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1735 * Create yadif threads and locks.
1737 pv->yadif_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1738 pv->yadif_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1739 pv->yadif_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1740 pv->yadif_arguments = malloc( sizeof( yadif_arguments_t ) * pv->cpu_count );
1742 for( i = 0; i < pv->cpu_count; i++ )
1744 yadif_thread_arg_t *thread_args;
1746 thread_args = malloc( sizeof( yadif_thread_arg_t ) );
1750 thread_args->pv = pv;
1751 thread_args->segment = i;
1753 pv->yadif_begin_lock[i] = hb_lock_init();
1754 pv->yadif_complete_lock[i] = hb_lock_init();
1757 * Important to start off with the threads locked waiting
1760 hb_lock( pv->yadif_begin_lock[i] );
1762 pv->yadif_arguments[i].stop = 0;
1763 pv->yadif_arguments[i].dst = NULL;
1765 pv->yadif_threads[i] = hb_thread_init( "yadif_filter_segment",
1766 yadif_decomb_filter_thread,
1768 HB_NORMAL_PRIORITY );
1772 hb_error( "yadif could not create threads" );
1777 * Create decomb threads and locks.
1779 pv->decomb_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1780 pv->decomb_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1781 pv->decomb_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1782 pv->decomb_arguments = malloc( sizeof( decomb_arguments_t ) * pv->cpu_count );
1784 for( i = 0; i < pv->cpu_count; i++ )
1786 decomb_thread_arg_t *decomb_thread_args;
1788 decomb_thread_args = malloc( sizeof( decomb_thread_arg_t ) );
1790 if( decomb_thread_args )
1792 decomb_thread_args->pv = pv;
1793 decomb_thread_args->segment = i;
1795 pv->decomb_begin_lock[i] = hb_lock_init();
1796 pv->decomb_complete_lock[i] = hb_lock_init();
1799 * Important to start off with the threads locked waiting
1802 hb_lock( pv->decomb_begin_lock[i] );
1804 pv->decomb_arguments[i].stop = 0;
1806 pv->decomb_threads[i] = hb_thread_init( "decomb_filter_segment",
1807 decomb_filter_thread,
1809 HB_NORMAL_PRIORITY );
1813 hb_error( "decomb could not create threads" );
1817 if( pv->mode & MODE_EEDI2 )
1820 * Create eedi2 threads and locks.
1822 pv->eedi2_threads = malloc( sizeof( hb_thread_t* ) * 3 );
1823 pv->eedi2_begin_lock = malloc( sizeof( hb_lock_t * ) * 3 );
1824 pv->eedi2_complete_lock = malloc( sizeof( hb_lock_t * ) * 3 );
1825 pv->eedi2_arguments = malloc( sizeof( eedi2_arguments_t ) * 3 );
1827 if( pv->post_processing > 1 )
1829 pv->cx2 = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1830 pv->cy2 = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1831 pv->cxy = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1832 pv->tmpc = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1833 if( !pv->cx2 || !pv->cy2 || !pv->cxy || !pv->tmpc )
1834 hb_log("EEDI2: failed to malloc derivative arrays");
1836 hb_log("EEDI2: successfully mallloced derivative arrays");
1839 for( i = 0; i < 3; i++ )
1841 eedi2_thread_arg_t *eedi2_thread_args;
1843 eedi2_thread_args = malloc( sizeof( eedi2_thread_arg_t ) );
1845 if( eedi2_thread_args )
1847 eedi2_thread_args->pv = pv;
1848 eedi2_thread_args->plane = i;
1850 pv->eedi2_begin_lock[i] = hb_lock_init();
1851 pv->eedi2_complete_lock[i] = hb_lock_init();
1854 * Important to start off with the threads locked waiting
1857 hb_lock( pv->eedi2_begin_lock[i] );
1859 pv->eedi2_arguments[i].stop = 0;
1861 pv->eedi2_threads[i] = hb_thread_init( "eedi2_filter_segment",
1862 eedi2_filter_thread,
1864 HB_NORMAL_PRIORITY );
1868 hb_error( "eedi2 could not create threads" );
1874 /* Allocate mcdeint specific buffers */
1875 if( pv->mcdeint_mode >= 0 )
1878 avcodec_register_all();
1879 AVCodec * enc = avcodec_find_encoder( CODEC_ID_SNOW );
1881 for (i = 0; i < 3; i++ )
1883 AVCodecContext * avctx_enc;
1885 avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context();
1887 avctx_enc->width = width;
1888 avctx_enc->height = height;
1889 avctx_enc->time_base = (AVRational){1,25}; // meaningless
1890 avctx_enc->gop_size = 300;
1891 avctx_enc->max_b_frames = 0;
1892 avctx_enc->pix_fmt = PIX_FMT_YUV420P;
1893 avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
1894 avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
1895 avctx_enc->global_quality = 1;
1896 avctx_enc->flags2 = CODEC_FLAG2_MEMC_ONLY;
1897 avctx_enc->me_cmp = FF_CMP_SAD; //SSE;
1898 avctx_enc->me_sub_cmp = FF_CMP_SAD; //SSE;
1899 avctx_enc->mb_cmp = FF_CMP_SSE;
1901 switch( pv->mcdeint_mode )
1904 avctx_enc->refs = 3;
1906 avctx_enc->me_method = ME_ITER;
1908 avctx_enc->flags |= CODEC_FLAG_4MV;
1909 avctx_enc->dia_size =2;
1911 avctx_enc->flags |= CODEC_FLAG_QPEL;
1914 hb_avcodec_open(avctx_enc, enc);
1917 pv->mcdeint_frame = avcodec_alloc_frame();
1918 pv->mcdeint_outbuf_size = width * height * 10;
1919 pv->mcdeint_outbuf = malloc( pv->mcdeint_outbuf_size );
1925 void hb_decomb_close( hb_filter_private_t * pv )
1932 hb_log("decomb: deinterlaced %i | blended %i | unfiltered %i | total %i", pv->deinterlaced_frames, pv->blended_frames, pv->unfiltered_frames, pv->deinterlaced_frames + pv->blended_frames + pv->unfiltered_frames);
1934 /* Cleanup frame buffers */
1935 if( pv->buf_out[0] )
1937 hb_buffer_close( &pv->buf_out[0] );
1939 if( pv->buf_out[1] )
1941 hb_buffer_close( &pv->buf_out[1] );
1943 if (pv->buf_settings )
1945 hb_buffer_close( &pv->buf_settings );
1948 /* Cleanup yadif specific buffers */
1950 for( i = 0; i<3*3; i++ )
1952 uint8_t **p = &pv->ref[i%3][i/3];
1955 free( *p - 3*pv->ref_stride[i/3] );
1960 /* Cleanup combing mask. */
1961 for( i = 0; i<3*3; i++ )
1963 uint8_t **p = &pv->mask[i/3];
1966 free( *p - 3*pv->ref_stride[i/3] );
1971 if( pv->mode & MODE_EEDI2 )
1973 /* Cleanup eedi-half buffers */
1975 for( i = 0; i<3; i++ )
1977 for( j = 0; j < 4; j++ )
1979 uint8_t **p = &pv->eedi_half[j][i];
1982 free( *p - 3*pv->ref_stride[i] );
1988 /* Cleanup eedi-full buffers */
1989 for( i = 0; i<3; i++ )
1991 for( j = 0; j < 5; j++ )
1993 uint8_t **p = &pv->eedi_full[j][i];
1996 free( *p - 3*pv->ref_stride[i] );
2003 if( pv->post_processing > 1 && ( pv->mode & MODE_EEDI2 ) )
2005 if (pv->cx2) eedi2_aligned_free(pv->cx2);
2006 if (pv->cy2) eedi2_aligned_free(pv->cy2);
2007 if (pv->cxy) eedi2_aligned_free(pv->cxy);
2008 if (pv->tmpc) eedi2_aligned_free(pv->tmpc);
2011 for( i = 0; i < pv->cpu_count; i++)
2014 * Tell each yadif thread to stop, and then cleanup.
2016 pv->yadif_arguments[i].stop = 1;
2017 hb_unlock( pv->yadif_begin_lock[i] );
2019 hb_thread_close( &pv->yadif_threads[i] );
2020 hb_lock_close( &pv->yadif_begin_lock[i] );
2021 hb_lock_close( &pv->yadif_complete_lock[i] );
2025 * free memory for yadif structs
2027 free( pv->yadif_threads );
2028 free( pv->yadif_begin_lock );
2029 free( pv->yadif_complete_lock );
2030 free( pv->yadif_arguments );
2032 for( i = 0; i < pv->cpu_count; i++)
2035 * Tell each decomb thread to stop, and then cleanup.
2037 pv->decomb_arguments[i].stop = 1;
2038 hb_unlock( pv->decomb_begin_lock[i] );
2040 hb_thread_close( &pv->decomb_threads[i] );
2041 hb_lock_close( &pv->decomb_begin_lock[i] );
2042 hb_lock_close( &pv->decomb_complete_lock[i] );
2046 * free memory for decomb structs
2048 free( pv->decomb_threads );
2049 free( pv->decomb_begin_lock );
2050 free( pv->decomb_complete_lock );
2051 free( pv->decomb_arguments );
2053 if( pv->mode & MODE_EEDI2 )
2055 for( i = 0; i < 3; i++)
2058 * Tell each eedi2 thread to stop, and then cleanup.
2060 pv->eedi2_arguments[i].stop = 1;
2061 hb_unlock( pv->eedi2_begin_lock[i] );
2063 hb_thread_close( &pv->eedi2_threads[i] );
2064 hb_lock_close( &pv->eedi2_begin_lock[i] );
2065 hb_lock_close( &pv->eedi2_complete_lock[i] );
2069 * free memory for eedi2 structs
2071 free( pv->eedi2_threads );
2072 free( pv->eedi2_begin_lock );
2073 free( pv->eedi2_complete_lock );
2074 free( pv->eedi2_arguments );
2077 /* Cleanup mcdeint specific buffers */
2078 if( pv->mcdeint_mode >= 0 )
2080 if( pv->mcdeint_avctx_enc )
2082 hb_avcodec_close( pv->mcdeint_avctx_enc );
2083 av_freep( &pv->mcdeint_avctx_enc );
2085 if( pv->mcdeint_outbuf )
2087 free( pv->mcdeint_outbuf );
2094 int hb_decomb_work( const hb_buffer_t * cbuf_in,
2095 hb_buffer_t ** buf_out,
2099 hb_filter_private_t * pv )
2101 hb_buffer_t * buf_in = (hb_buffer_t *)cbuf_in;
2104 pix_fmt != pv->pix_fmt ||
2105 width != pv->width[0] ||
2106 height != pv->height[0] )
2108 return FILTER_FAILED;
2111 avpicture_fill( &pv->pic_in, buf_in->data,
2112 pix_fmt, width, height );
2114 /* Determine if top-field first layout */
2116 if( pv->parity < 0 )
2118 tff = !!(buf_in->flags & PIC_FLAG_TOP_FIELD_FIRST);
2122 tff = (pv->parity & 1) ^ 1;
2125 /* Store current frame in yadif cache */
2126 store_ref( (const uint8_t**)pv->pic_in.data, pv );
2128 /* If yadif is not ready, store another ref and return FILTER_DELAY */
2129 if( pv->yadif_ready == 0 )
2131 store_ref( (const uint8_t**)pv->pic_in.data, pv );
2133 hb_buffer_copy_settings( pv->buf_settings, buf_in );
2135 /* don't let 'work_loop' send a chapter mark upstream */
2136 buf_in->new_chap = 0;
2138 pv->yadif_ready = 1;
2140 return FILTER_DELAY;
2143 /* Perform yadif filtering */
2145 for( frame = 0; frame <= ( ( pv->mode & MODE_MCDEINT ) ? 1 : 0 ) ; frame++ )
2146 // This would be what to use for bobbing: for( frame = 0; frame <= 0 ; frame++ )
2150 /* Perhaps skip the second run if the frame is uncombed? */
2151 if( frame && !pv->yadif_arguments[0].is_combed )
2156 int parity = frame ^ tff ^ 1;
2158 // This will be for bobbing
2160 if( pv->alternator )
2172 avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,
2173 pix_fmt, width, height );
2176 Should check here and only bother filtering field 2 when
2177 field 1 was detected as combed.
2178 And when it's not, it's a progressive frame,
2179 so mcdeint should be skipped...
2181 yadif_filter( pv->pic_out.data, parity, tff, pv );
2183 /* Commented out code in the line below would skip mcdeint
2184 on uncombed frames. Possibly a bad idea, since mcdeint
2185 maintains the same snow context for the entire video... */
2186 if( pv->mcdeint_mode >= 0 /* && pv->yadif_arguments[0].is_combed */)
2188 /* Perform mcdeint filtering */
2189 avpicture_fill( &pv->pic_in, pv->buf_out[(frame^1)]->data,
2190 pix_fmt, width, height );
2192 mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );
2195 *buf_out = pv->buf_out[!(frame^1)];
2198 /* Copy buffered settings to output buffer settings */
2199 hb_buffer_copy_settings( *buf_out, pv->buf_settings );
2201 /* Replace buffered settings with input buffer settings */
2202 hb_buffer_copy_settings( pv->buf_settings, buf_in );
2204 /* don't let 'work_loop' send a chapter mark upstream */
2205 buf_in->new_chap = 0;