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 )
513 for( block_y = 0; block_y < block_height; block_y++ )
515 int mask_y = y + block_y;
516 mask_p = &pv->mask[k][mask_y*ref_stride + x];
518 for( block_x = 0; block_x < block_width; block_x++ )
520 /* We only want to mark a pixel in a block as combed
521 if the adjacent pixels are as well. Got to
522 handle the sides separately. */
523 if( (x + block_x) == 0 )
525 if( mask_p[ 0 ] == 255 &&
529 else if( (x + block_x) == (pv->width[k] -1) )
531 if( mask_p[ -1 ] == 255 &&
537 if( mask_p[ -1 ] == 255 &&
538 mask_p[ 0 ] == 255 &&
546 if( block_score >= ( threshold / 2 ) )
549 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");
551 if ( block_score <= threshold && !( pv->buf_settings->flags & 16) )
553 /* Blend video content that scores between
554 ( threshold / 2 ) and threshold. */
557 else if( block_score > threshold )
559 if( pv->buf_settings->flags & 16 )
561 /* Blend progressive content above the threshold.*/
566 /* Yadif deinterlace video content above the threshold. */
581 /* Consider this frame to be uncombed. */
586 void detect_combed_segment( hb_filter_private_t * pv, int segment_start, int segment_stop )
588 /* A mish-mash of various comb detection tricks
589 picked up from neuron2's Decomb plugin for
590 AviSynth and tritical's IsCombedT and
591 IsCombedTIVTC plugins. */
593 int x, y, k, width, height;
595 /* Comb scoring algorithm */
596 int spatial_metric = pv->spatial_metric;
597 /* Motion threshold */
598 int mthresh = pv->motion_threshold;
599 /* Spatial threshold */
600 int athresh = pv->spatial_threshold;
601 int athresh_squared = athresh * athresh;
602 int athresh6 = 6 *athresh;
604 /* One pas for Y, one pass for U, one pass for V */
605 for( k = 0; k < 1; k++ )
607 int ref_stride = pv->ref_stride[k];
608 width = pv->width[k];
609 height = pv->height[k];
611 /* Comb detection has to start at y = 2 and end at
612 y = height - 2, because it needs to examine
613 2 pixels above and 2 below the current pixel. */
614 if( segment_start < 2 )
616 if( segment_stop > height - 2 )
617 segment_stop = height - 2;
619 for( y = segment_start; y < segment_stop; y++ )
621 /* These are just to make the buffer locations easier to read. */
622 int up_2 = -2*ref_stride ;
623 int up_1 = -1*ref_stride;
624 int down_1 = ref_stride;
625 int down_2 = 2*ref_stride;
627 /* We need to examine a column of 5 pixels
628 in the prev, cur, and next frames. */
629 uint8_t * cur = &pv->ref[1][k][y*ref_stride];
630 uint8_t * prev = &pv->ref[0][k][y*ref_stride];
631 uint8_t * next = &pv->ref[2][k][y*ref_stride];
632 uint8_t * mask = &pv->mask[k][y*ref_stride];
634 for( x = 0; x < width; x++ )
636 int up_diff = cur[0] - cur[up_1];
637 int down_diff = cur[0] - cur[down_1];
639 if( ( up_diff > athresh && down_diff > athresh ) ||
640 ( up_diff < -athresh && down_diff < -athresh ) )
642 /* The pixel above and below are different,
643 and they change in the same "direction" too.*/
647 /* Make sure there's sufficient motion between frame t-1 to frame t+1. */
648 if( abs( prev[0] - cur[0] ) > mthresh &&
649 abs( cur[up_1] - next[up_1] ) > mthresh &&
650 abs( cur[down_1] - next[down_1] ) > mthresh )
652 if( abs( next[0] - cur[0] ) > mthresh &&
653 abs( prev[up_1] - cur[up_1] ) > mthresh &&
654 abs( prev[down_1] - cur[down_1] ) > mthresh )
659 /* User doesn't want to check for motion,
660 so move on to the spatial check. */
664 if( motion || ( pv->deinterlaced_frames==0 && pv->blended_frames==0 && pv->unfiltered_frames==0) )
666 /* That means it's time for the spatial check.
667 We've got several options here. */
668 if( spatial_metric == 0 )
670 /* Simple 32detect style comb detection */
671 if( ( abs( cur[0] - cur[down_2] ) < 10 ) &&
672 ( abs( cur[0] - cur[down_1] ) > 15 ) )
681 else if( spatial_metric == 1 )
683 /* This, for comparison, is what IsCombed uses.
684 It's better, but still noise senstive. */
685 int combing = ( cur[up_1] - cur[0] ) *
686 ( cur[down_1] - cur[0] );
688 if( combing > athresh_squared )
693 else if( spatial_metric == 2 )
695 /* Tritical's noise-resistant combing scorer.
696 The check is done on a bob+blur convolution. */
697 int combing = abs( cur[up_2]
703 /* If the frame is sufficiently combed,
704 then mark it down on the mask as 255. */
705 if( combing > athresh6 )
734 // This function calls all the eedi2 filters in sequence for a given plane.
735 // It outputs the final interpolated image to pv->eedi_full[DST2PF].
736 void eedi2_interpolate_plane( hb_filter_private_t * pv, int k )
738 /* We need all these pointers. No, seriously.
739 I swear. It's not a joke. They're used.
741 uint8_t * mskp = pv->eedi_half[MSKPF][k];
742 uint8_t * srcp = pv->eedi_half[SRCPF][k];
743 uint8_t * tmpp = pv->eedi_half[TMPPF][k];
744 uint8_t * dstp = pv->eedi_half[DSTPF][k];
745 uint8_t * dst2p = pv->eedi_full[DST2PF][k];
746 uint8_t * tmp2p2 = pv->eedi_full[TMP2PF2][k];
747 uint8_t * msk2p = pv->eedi_full[MSK2PF][k];
748 uint8_t * tmp2p = pv->eedi_full[TMP2PF][k];
749 uint8_t * dst2mp = pv->eedi_full[DST2MPF][k];
753 int * tmpc = pv->tmpc;
755 int pitch = pv->ref_stride[k];
756 int height = pv->height[k]; int width = pv->width[k];
757 int half_height = height / 2;
760 eedi2_build_edge_mask( mskp, pitch, srcp, pitch,
761 pv->magnitude_threshold, pv->variance_threshold, pv->laplacian_threshold,
762 half_height, width );
763 eedi2_erode_edge_mask( mskp, pitch, tmpp, pitch, pv->erosion_threshold, half_height, width );
764 eedi2_dilate_edge_mask( tmpp, pitch, mskp, pitch, pv->dilation_threshold, half_height, width );
765 eedi2_erode_edge_mask( mskp, pitch, tmpp, pitch, pv->erosion_threshold, half_height, width );
766 eedi2_remove_small_gaps( tmpp, pitch, mskp, pitch, half_height, width );
769 eedi2_calc_directions( k, mskp, pitch, srcp, pitch, tmpp, pitch,
770 pv->maximum_search_distance, pv->noise_threshold,
771 half_height, width );
772 eedi2_filter_dir_map( mskp, pitch, tmpp, pitch, dstp, pitch, half_height, width );
773 eedi2_expand_dir_map( mskp, pitch, dstp, pitch, tmpp, pitch, half_height, width );
774 eedi2_filter_map( mskp, pitch, tmpp, pitch, dstp, pitch, half_height, width );
776 // upscale 2x vertically
777 eedi2_upscale_by_2( srcp, dst2p, half_height, pitch );
778 eedi2_upscale_by_2( dstp, tmp2p2, half_height, pitch );
779 eedi2_upscale_by_2( mskp, msk2p, half_height, pitch );
781 // upscale the direction mask
782 eedi2_mark_directions_2x( msk2p, pitch, tmp2p2, pitch, tmp2p, pitch, pv->tff, height, width );
783 eedi2_filter_dir_map_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
784 eedi2_expand_dir_map_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
785 eedi2_fill_gaps_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
786 eedi2_fill_gaps_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
788 // interpolate a full-size plane
789 eedi2_interpolate_lattice( k, tmp2p, pitch, dst2p, pitch, tmp2p2, pitch, pv->tff,
790 pv->noise_threshold, height, width );
792 if( pv->post_processing == 1 || pv->post_processing == 3 )
794 // make sure the edge directions are consistent
795 eedi2_bit_blit( tmp2p2, pitch, tmp2p, pitch, pv->width[k], pv->height[k] );
796 eedi2_filter_dir_map_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
797 eedi2_expand_dir_map_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
798 eedi2_post_process( tmp2p, pitch, tmp2p2, pitch, dst2p, pitch, pv->tff, height, width );
800 if( pv->post_processing == 2 || pv->post_processing == 3 )
802 // filter junctions and corners
803 eedi2_gaussian_blur1( srcp, pitch, tmpp, pitch, srcp, pitch, half_height, width );
804 eedi2_calc_derivatives( srcp, pitch, half_height, width, cx2, cy2, cxy );
805 eedi2_gaussian_blur_sqrt2( cx2, tmpc, cx2, pitch, half_height, width);
806 eedi2_gaussian_blur_sqrt2( cy2, tmpc, cy2, pitch, half_height, width);
807 eedi2_gaussian_blur_sqrt2( cxy, tmpc, cxy, pitch, half_height, width);
808 eedi2_post_process_corner( cx2, cy2, cxy, pitch, tmp2p2, pitch, dst2p, pitch, height, width, pv->tff );
813 * eedi2 interpolate this plane in a single thread.
815 void eedi2_filter_thread( void *thread_args_v )
817 eedi2_arguments_t *eedi2_work = NULL;
818 hb_filter_private_t * pv;
821 eedi2_thread_arg_t *thread_args = thread_args_v;
823 pv = thread_args->pv;
824 plane = thread_args->plane;
826 hb_log("eedi2 thread started for plane %d", plane);
831 * Wait here until there is work to do. hb_lock() blocks until
832 * render releases it to say that there is more work to do.
834 hb_lock( pv->eedi2_begin_lock[plane] );
836 eedi2_work = &pv->eedi2_arguments[plane];
838 if( eedi2_work->stop )
841 * No more work to do, exit this thread.
850 eedi2_interpolate_plane( pv, plane );
853 * Finished this segment, let everyone know.
855 hb_unlock( pv->eedi2_complete_lock[plane] );
857 free( thread_args_v );
860 // Sets up the input field planes for EEDI2 in pv->eedi_half[SRCPF]
861 // and then runs eedi2_filter_thread for each plane.
862 void eedi2_planer( hb_filter_private_t * pv )
864 /* Copy the first field from the source to a half-height frame. */
866 for( i = 0; i < 3; i++ )
868 int pitch = pv->ref_stride[i];
869 int start_line = !pv->tff;
870 eedi2_fill_half_height_buffer_plane( &pv->ref[1][i][pitch*start_line], pv->eedi_half[SRCPF][i], pitch, pv->height[i] );
874 for( plane = 0; plane < 3; plane++ )
877 * Let the thread for this plane know that we've setup work
878 * for it by releasing the begin lock (ensuring that the
879 * complete lock is already locked so that we block when
880 * we try to lock it again below).
882 hb_lock( pv->eedi2_complete_lock[plane] );
883 hb_unlock( pv->eedi2_begin_lock[plane] );
887 * Wait until all three threads have completed by trying to get
888 * the complete lock that we locked earlier for each thread, which
889 * will block until that thread has completed the work on that
892 for( plane = 0; plane < 3; plane++ )
894 hb_lock( pv->eedi2_complete_lock[plane] );
895 hb_unlock( pv->eedi2_complete_lock[plane] );
901 * comb detect this segment of all three planes in a single thread.
903 void decomb_filter_thread( void *thread_args_v )
905 decomb_arguments_t *decomb_work = NULL;
906 hb_filter_private_t * pv;
908 int segment, segment_start, segment_stop, plane;
909 decomb_thread_arg_t *thread_args = thread_args_v;
911 pv = thread_args->pv;
912 segment = thread_args->segment;
914 hb_log("decomb thread started for segment %d", segment);
919 * Wait here until there is work to do. hb_lock() blocks until
920 * render releases it to say that there is more work to do.
922 hb_lock( pv->decomb_begin_lock[segment] );
924 decomb_work = &pv->decomb_arguments[segment];
926 if( decomb_work->stop )
929 * No more work to do, exit this thread.
936 * Process segment (for now just from luma)
938 for( plane = 0; plane < 1; plane++)
941 int h = pv->height[plane];
942 segment_start = ( h / pv->cpu_count ) * segment;
943 if( segment == pv->cpu_count - 1 )
950 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
953 detect_combed_segment( pv, segment_start, segment_stop );
956 * Finished this segment, let everyone know.
958 hb_unlock( pv->decomb_complete_lock[segment] );
960 free( thread_args_v );
963 int comb_segmenter( hb_filter_private_t * pv )
967 for( segment = 0; segment < pv->cpu_count; segment++ )
970 * Let the thread for this plane know that we've setup work
971 * for it by releasing the begin lock (ensuring that the
972 * complete lock is already locked so that we block when
973 * we try to lock it again below).
975 hb_lock( pv->decomb_complete_lock[segment] );
976 hb_unlock( pv->decomb_begin_lock[segment] );
980 * Wait until all three threads have completed by trying to get
981 * the complete lock that we locked earlier for each thread, which
982 * will block until that thread has completed the work on that
985 for( segment = 0; segment < pv->cpu_count; segment++ )
987 hb_lock( pv->decomb_complete_lock[segment] );
988 hb_unlock( pv->decomb_complete_lock[segment] );
991 return check_combing_mask( pv );
994 static void yadif_filter_line( uint8_t *dst,
1001 hb_filter_private_t * pv )
1003 /* While prev and next point to the previous and next frames,
1004 prev2 and next2 will shift depending on the parity, usually 1.
1005 They are the previous and next fields, the fields temporally adjacent
1006 to the other field in the current frame--the one not being filtered. */
1007 uint8_t *prev2 = parity ? prev : cur ;
1008 uint8_t *next2 = parity ? cur : next;
1010 int w = pv->width[plane];
1011 int refs = pv->ref_stride[plane];
1013 int eedi2_mode = ( pv->mode & MODE_EEDI2 );
1015 /* We can replace spatial_pred with this interpolation*/
1016 uint8_t * eedi2_guess = &pv->eedi_full[DST2PF][plane][y*refs];
1018 /* Decomb's cubic interpolation can only function when there are
1019 three samples above and below, so regress to yadif's traditional
1020 two-tap interpolation when filtering at the top and bottom edges. */
1021 int vertical_edge = 0;
1022 if( ( y < 3 ) || ( y > ( pv->height[plane] - 4 ) ) )
1025 for( x = 0; x < w; x++)
1029 /* Temporal average: the current location in the adjacent fields */
1030 int d = (prev2[0] + next2[0])>>1;
1034 /* How the current pixel changes between the adjacent fields */
1035 int temporal_diff0 = ABS(prev2[0] - next2[0]);
1036 /* The average of how much the pixels above and below change from the frame before to now. */
1037 int temporal_diff1 = ( ABS(prev[-refs] - cur[-refs]) + ABS(prev[+refs] - cur[+refs]) ) >> 1;
1038 /* The average of how much the pixels above and below change from now to the next frame. */
1039 int temporal_diff2 = ( ABS(next[-refs] - cur[-refs]) + ABS(next[+refs] - cur[+refs]) ) >> 1;
1040 /* For the actual difference, use the largest of the previous average diffs. */
1041 int diff = MAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
1047 /* Who needs yadif's spatial predictions when we can have EEDI2's? */
1048 spatial_pred = eedi2_guess[0];
1051 else // Yadif spatial interpolation
1053 /* SAD of how the pixel-1, the pixel, and the pixel+1 change from the line above to below. */
1054 int spatial_score = ABS(cur[-refs-1] - cur[+refs-1]) + ABS(cur[-refs]-cur[+refs]) +
1055 ABS(cur[-refs+1] - cur[+refs+1]) - 1;
1057 /* Spatial pred is either a bilinear or cubic vertical interpolation. */
1058 if( ( pv->mode & MODE_CUBIC ) && !vertical_edge)
1060 spatial_pred = cubic_interpolate_pixel( cur[-3*refs], cur[-refs], cur[+refs], cur[3*refs] );
1064 spatial_pred = (c+e)>>1;
1067 /* EDDI: Edge Directed Deinterlacing Interpolation
1068 Checks 4 different slopes to see if there is more similarity along a diagonal
1069 than there was vertically. If a diagonal is more similar, then it indicates
1070 an edge, so interpolate along that instead of a vertical line, using either
1071 linear or cubic interpolation depending on mode. */
1072 #define YADIF_CHECK(j)\
1073 { int score = ABS(cur[-refs-1+j] - cur[+refs-1-j])\
1074 + ABS(cur[-refs +j] - cur[+refs -j])\
1075 + ABS(cur[-refs+1+j] - cur[+refs+1-j]);\
1076 if( score < spatial_score ){\
1077 spatial_score = score;\
1078 if( ( pv->mode & MODE_CUBIC ) && !vertical_edge )\
1083 spatial_pred = cubic_interpolate_pixel(cur[-3 * refs - 3], cur[-refs -1], cur[+refs + 1], cur[3* refs + 3] );\
1086 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 ) );\
1089 spatial_pred = cubic_interpolate_pixel(cur[-3 * refs +3], cur[-refs +1], cur[+refs - 1], cur[3* refs -3] );\
1092 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 ) );\
1098 spatial_pred = ( cur[-refs +j] + cur[+refs -j] ) >>1;\
1101 if( x >= 2 && x <= w - 3 )
1104 if( x >= 3 && x <= w - 4 )
1106 YADIF_CHECK(-2) }} }}
1109 if( x >= 2 && x <= w - 3 )
1112 if( x >= 3 && x <= w - 4 )
1114 YADIF_CHECK(2) }} }}
1119 /* Temporally adjust the spatial prediction by
1120 comparing against lines in the adjacent fields. */
1121 int b = (prev2[-2*refs] + next2[-2*refs])>>1;
1122 int f = (prev2[+2*refs] + next2[+2*refs])>>1;
1124 /* Find the median value */
1125 int max = MAX3(d-e, d-c, MIN(b-c, f-e));
1126 int min = MIN3(d-e, d-c, MAX(b-c, f-e));
1127 diff = MAX3( diff, min, -max );
1129 if( spatial_pred > d + diff )
1131 spatial_pred = d + diff;
1133 else if( spatial_pred < d - diff )
1135 spatial_pred = d - diff;
1138 dst[0] = spatial_pred;
1150 * deinterlace this segment of all three planes in a single thread.
1152 void yadif_decomb_filter_thread( void *thread_args_v )
1154 yadif_arguments_t *yadif_work = NULL;
1155 hb_filter_private_t * pv;
1158 int segment, segment_start, segment_stop;
1159 yadif_thread_arg_t *thread_args = thread_args_v;
1161 int parity, tff, y, w, h, penultimate, ultimate, ref_stride, is_combed;
1163 pv = thread_args->pv;
1164 segment = thread_args->segment;
1166 hb_log("yadif thread started for segment %d", segment);
1171 * Wait here until there is work to do. hb_lock() blocks until
1172 * render releases it to say that there is more work to do.
1174 hb_lock( pv->yadif_begin_lock[segment] );
1176 yadif_work = &pv->yadif_arguments[segment];
1178 if( yadif_work->stop )
1181 * No more work to do, exit this thread.
1187 if( yadif_work->dst == NULL )
1189 hb_error( "thread started when no work available" );
1194 is_combed = pv->yadif_arguments[segment].is_combed;
1197 * Process all three planes, but only this segment of it.
1199 for( plane = 0; plane < 3; plane++)
1202 dst = yadif_work->dst;
1203 parity = yadif_work->parity;
1204 tff = yadif_work->tff;
1205 w = pv->width[plane];
1206 h = pv->height[plane];
1207 penultimate = h - 2;
1209 ref_stride = pv->ref_stride[plane];
1210 segment_start = ( h / pv->cpu_count ) * segment;
1211 if( segment == pv->cpu_count - 1 )
1218 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
1221 for( y = segment_start; y < segment_stop; y++ )
1223 if( is_combed == 2 )
1225 /* This line gets blend filtered, not yadif filtered. */
1226 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
1227 uint8_t *dst2 = &dst[plane][y*w];
1228 /* These will be useful if we ever do temporal blending. */
1229 // uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
1230 // uint8_t *next = &pv->ref[2][plane][y*ref_stride];
1232 blend_filter_line( dst2, cur, plane, y, pv );
1234 else if( pv->mode == MODE_CUBIC && is_combed && ( ( y ^ parity ) & 1 ) )
1236 /* Just apply vertical cubic interpolation */
1237 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
1238 uint8_t *dst2 = &dst[plane][y*w];
1240 cubic_interpolate_line( dst2, cur, plane, y, pv );
1242 else if( pv->mode & MODE_YADIF && ( ( y ^ parity ) & 1 ) && ( is_combed == 1 ) )
1244 /* This line gets yadif filtered. It is the bottom field
1245 when TFF and vice-versa. It's the field that gets
1246 filtered. Because yadif needs 2 lines above and below
1247 the one being filtered, we need to mirror the edges.
1248 When TFF, this means replacing the 2nd line with a
1249 copy of the 1st, and the last with the second-to-last. */
1250 if( y > 1 && y < ( h -2 ) )
1252 /* This isn't the top or bottom, proceed as normal to yadif. */
1253 uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
1254 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
1255 uint8_t *next = &pv->ref[2][plane][y*ref_stride];
1256 uint8_t *dst2 = &dst[plane][y*w];
1258 yadif_filter_line( dst2,
1269 /* BFF, so y0 = y1 */
1270 memcpy( &dst[plane][y*w],
1271 &pv->ref[1][plane][1*ref_stride],
1272 w * sizeof(uint8_t) );
1276 /* TFF, so y1 = y0 */
1277 memcpy( &dst[plane][y*w],
1278 &pv->ref[1][plane][0],
1279 w * sizeof(uint8_t) );
1281 else if( y == penultimate )
1283 /* BFF, so penultimate y = ultimate y */
1284 memcpy( &dst[plane][y*w],
1285 &pv->ref[1][plane][ultimate*ref_stride],
1286 w * sizeof(uint8_t) );
1288 else if( y == ultimate )
1290 /* TFF, so ultimate y = penultimate y */
1291 memcpy( &dst[plane][y*w],
1292 &pv->ref[1][plane][penultimate*ref_stride],
1293 w * sizeof(uint8_t) );
1298 memcpy( &dst[plane][y*w],
1299 &pv->ref[1][plane][y*ref_stride],
1300 w * sizeof(uint8_t) );
1305 * Finished this segment, let everyone know.
1307 hb_unlock( pv->yadif_complete_lock[segment] );
1309 free( thread_args_v );
1312 static void yadif_filter( uint8_t ** dst,
1315 hb_filter_private_t * pv )
1317 /* If we're running comb detection, do it now, otherwise default to true. */
1318 int is_combed = pv->spatial_metric >= 0 ? comb_segmenter( pv ) : 1;
1320 /* The comb detector suggests three different values:
1321 0: Don't comb this frame.
1322 1: Deinterlace this frame.
1323 2: Blend this frame.
1324 Since that might conflict with the filter's mode,
1325 it may be necesary to adjust this value. */
1326 if( is_combed == 1 && (pv->mode == MODE_BLEND) )
1328 /* All combed frames are getting blended */
1331 else if( is_combed == 2 && !( pv->mode & MODE_BLEND ) )
1333 /* Blending is disabled, so force interpolation of these frames. */
1336 if( is_combed == 1 &&
1337 ( pv->mode & MODE_BLEND ) &&
1338 !( pv->mode & ( MODE_YADIF | MODE_EEDI2 | MODE_CUBIC ) ) )
1340 /* Deinterlacers are disabled, blending isn't, so blend these frames. */
1343 else if( is_combed &&
1344 !( pv->mode & ( MODE_BLEND | MODE_YADIF | MODE_EEDI2 | MODE_CUBIC | MODE_MASK ) ) )
1346 /* No deinterlacer or mask chosen, pass the frame through. */
1350 if( is_combed == 1 )
1352 pv->deinterlaced_frames++;
1354 else if( is_combed == 2 )
1356 pv->blended_frames++;
1360 pv->unfiltered_frames++;
1363 if( is_combed == 1 && ( pv->mode & MODE_EEDI2 ) )
1365 /* Generate an EEDI2 interpolation */
1371 if( ( pv->mode & MODE_EEDI2 ) && !( pv->mode & MODE_YADIF ) && is_combed == 1 )
1373 // Just pass through the EEDI2 interpolation
1375 for( i = 0; i < 3; i++ )
1377 uint8_t * ref = pv->eedi_full[DST2PF][i];
1378 uint8_t * dest = dst[i];
1380 int w = pv->width[i];
1381 int ref_stride = pv->ref_stride[i];
1384 for( y = 0; y < pv->height[i]; y++ )
1386 memcpy(dest, ref, w);
1396 for( segment = 0; segment < pv->cpu_count; segment++ )
1399 * Setup the work for this plane.
1401 pv->yadif_arguments[segment].parity = parity;
1402 pv->yadif_arguments[segment].tff = tff;
1403 pv->yadif_arguments[segment].dst = dst;
1404 pv->yadif_arguments[segment].is_combed = is_combed;
1407 * Let the thread for this plane know that we've setup work
1408 * for it by releasing the begin lock (ensuring that the
1409 * complete lock is already locked so that we block when
1410 * we try to lock it again below).
1412 hb_lock( pv->yadif_complete_lock[segment] );
1413 hb_unlock( pv->yadif_begin_lock[segment] );
1417 * Wait until all three threads have completed by trying to get
1418 * the complete lock that we locked earlier for each thread, which
1419 * will block until that thread has completed the work on that
1422 for( segment = 0; segment < pv->cpu_count; segment++ )
1424 hb_lock( pv->yadif_complete_lock[segment] );
1425 hb_unlock( pv->yadif_complete_lock[segment] );
1429 * Entire frame is now deinterlaced.
1435 /* Just passing through... */
1437 /* For mcdeint's benefit... */
1438 pv->yadif_arguments[0].is_combed = is_combed; // 0
1441 for( i = 0; i < 3; i++ )
1443 uint8_t * ref = pv->ref[1][i];
1444 uint8_t * dest = dst[i];
1446 int w = pv->width[i];
1447 int ref_stride = pv->ref_stride[i];
1450 for( y = 0; y < pv->height[i]; y++ )
1452 memcpy(dest, ref, w);
1459 if( pv->mode & MODE_MASK && pv->spatial_metric >= 0 )
1461 if( pv->mode == MODE_MASK || is_combed )
1466 static void mcdeint_filter( uint8_t ** dst,
1469 hb_filter_private_t * pv )
1474 #ifdef SUPPRESS_AV_LOG
1475 /* TODO: temporarily change log level to suppress obnoxious debug output */
1476 int loglevel = av_log_get_level();
1477 av_log_set_level( AV_LOG_QUIET );
1480 for( i=0; i<3; i++ )
1482 pv->mcdeint_frame->data[i] = src[i];
1483 pv->mcdeint_frame->linesize[i] = pv->width[i];
1485 pv->mcdeint_avctx_enc->me_cmp = FF_CMP_SAD;
1486 pv->mcdeint_avctx_enc->me_sub_cmp = FF_CMP_SAD;
1487 pv->mcdeint_frame->quality = pv->mcdeint_qp * FF_QP2LAMBDA;
1489 out_size = avcodec_encode_video( pv->mcdeint_avctx_enc,
1491 pv->mcdeint_outbuf_size,
1492 pv->mcdeint_frame );
1494 pv->mcdeint_frame_dec = pv->mcdeint_avctx_enc->coded_frame;
1496 for( i = 0; i < 3; i++ )
1498 int w = pv->width[i];
1499 int h = pv->height[i];
1500 int fils = pv->mcdeint_frame_dec->linesize[i];
1501 int srcs = pv->width[i];
1503 for( y = 0; y < h; y++ )
1505 if( (y ^ parity) & 1 )
1507 for( x = 0; x < w; x++ )
1509 if( (x-1)+(y-1)*w >= 0 && (x+1)+(y+1)*w < w*h )
1512 &pv->mcdeint_frame_dec->data[i][x + y*fils];
1513 uint8_t * srcp = &src[i][x + y*srcs];
1515 int diff0 = filp[-fils] - srcp[-srcs];
1516 int diff1 = filp[+fils] - srcp[+srcs];
1520 ABS(srcp[-srcs-1] - srcp[+srcs-1]) +
1521 ABS(srcp[-srcs ] - srcp[+srcs ]) +
1522 ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
1526 #define MCDEINT_CHECK(j)\
1527 { int score = ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
1528 + ABS(srcp[-srcs +j] - srcp[+srcs -j])\
1529 + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
1530 if( score < spatial_score ) {\
1531 spatial_score = score;\
1532 diff0 = filp[-fils+j] - srcp[-srcs+j];\
1533 diff1 = filp[+fils-j] - srcp[+srcs-j];
1535 if( x >= 2 && x <= w - 3 )
1538 if( x >= 3 && x <= w - 4 )
1540 MCDEINT_CHECK(-2) }} }}
1543 if( x >= 2 && x <= w - 3 )
1546 if( x >= 3 && x <= w - 4 )
1548 MCDEINT_CHECK(2) }} }}
1552 if(diff0 + diff1 > 0)
1554 temp -= (diff0 + diff1 -
1555 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1559 temp -= (diff0 + diff1 +
1560 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1563 filp[0] = dst[i][x + y*w] =
1564 temp > 255U ? ~(temp>>31) : temp;
1569 pv->mcdeint_frame_dec->data[i][x + y*fils];
1575 for( x = 0; x < w; x++ )
1577 pv->mcdeint_frame_dec->data[i][x + y*fils] =
1578 dst[i][x + y*w]= src[i][x + y*srcs];
1584 #ifdef SUPPRESS_AV_LOG
1585 /* TODO: restore previous log level */
1586 av_log_set_level(loglevel);
1590 hb_filter_private_t * hb_decomb_init( int pix_fmt,
1595 if( pix_fmt != PIX_FMT_YUV420P )
1600 hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) );
1602 pv->pix_fmt = pix_fmt;
1604 pv->width[0] = width;
1605 pv->height[0] = height;
1606 pv->width[1] = pv->width[2] = width >> 1;
1607 pv->height[1] = pv->height[2] = height >> 1;
1609 pv->buf_out[0] = hb_video_buffer_init( width, height );
1610 pv->buf_out[1] = hb_video_buffer_init( width, height );
1611 pv->buf_settings = hb_buffer_init( 0 );
1613 pv->deinterlaced_frames = 0;
1614 pv->blended_frames = 0;
1615 pv->unfiltered_frames = 0;
1617 pv->yadif_ready = 0;
1619 pv->mode = MODE_YADIF | MODE_BLEND | MODE_CUBIC;
1620 pv->spatial_metric = 2;
1621 pv->motion_threshold = 6;
1622 pv->spatial_threshold = 9;
1623 pv->block_threshold = 80;
1624 pv->block_width = 16;
1625 pv->block_height = 16;
1627 pv->magnitude_threshold = 10;
1628 pv->variance_threshold = 20;
1629 pv->laplacian_threshold = 20;
1630 pv->dilation_threshold = 4;
1631 pv->erosion_threshold = 2;
1632 pv->noise_threshold = 50;
1633 pv->maximum_search_distance = 24;
1634 pv->post_processing = 1;
1636 pv->parity = PARITY_DEFAULT;
1638 pv->mcdeint_mode = MCDEINT_MODE_DEFAULT;
1639 pv->mcdeint_qp = MCDEINT_QP_DEFAULT;
1643 sscanf( settings, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
1645 &pv->spatial_metric,
1646 &pv->motion_threshold,
1647 &pv->spatial_threshold,
1648 &pv->block_threshold,
1651 &pv->magnitude_threshold,
1652 &pv->variance_threshold,
1653 &pv->laplacian_threshold,
1654 &pv->dilation_threshold,
1655 &pv->erosion_threshold,
1656 &pv->noise_threshold,
1657 &pv->maximum_search_distance,
1658 &pv->post_processing,
1662 pv->cpu_count = hb_get_cpu_count();
1665 if( pv->mode & MODE_MCDEINT )
1667 pv->mcdeint_mode = 2;
1670 /* Allocate yadif specific buffers */
1672 for( i = 0; i < 3; i++ )
1674 int is_chroma = !!i;
1675 int w = ((width + 31) & (~31))>>is_chroma;
1676 int h = ((height+6+ 31) & (~31))>>is_chroma;
1678 pv->ref_stride[i] = w;
1680 for( j = 0; j < 3; j++ )
1682 pv->ref[j][i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1686 /* Allocate a buffer to store a comb mask. */
1687 for( i = 0; i < 3; i++ )
1689 int is_chroma = !!i;
1690 int w = ((pv->width[0] + 31) & (~31))>>is_chroma;
1691 int h = ((pv->height[0]+6+ 31) & (~31))>>is_chroma;
1693 pv->mask[i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1696 if( pv->mode & MODE_EEDI2 )
1698 /* Allocate half-height eedi2 buffers */
1699 height = pv->height[0] / 2;
1700 for( i = 0; i < 3; i++ )
1702 int is_chroma = !!i;
1703 int w = ((width + 31) & (~31))>>is_chroma;
1704 int h = ((height+6+ 31) & (~31))>>is_chroma;
1706 for( j = 0; j < 4; j++ )
1708 pv->eedi_half[j][i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1712 /* Allocate full-height eedi2 buffers */
1713 height = pv->height[0];
1714 for( i = 0; i < 3; i++ )
1716 int is_chroma = !!i;
1717 int w = ((width + 31) & (~31))>>is_chroma;
1718 int h = ((height+6+ 31) & (~31))>>is_chroma;
1720 for( j = 0; j < 5; j++ )
1722 pv->eedi_full[j][i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1728 * Create yadif threads and locks.
1730 pv->yadif_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1731 pv->yadif_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1732 pv->yadif_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1733 pv->yadif_arguments = malloc( sizeof( yadif_arguments_t ) * pv->cpu_count );
1735 for( i = 0; i < pv->cpu_count; i++ )
1737 yadif_thread_arg_t *thread_args;
1739 thread_args = malloc( sizeof( yadif_thread_arg_t ) );
1743 thread_args->pv = pv;
1744 thread_args->segment = i;
1746 pv->yadif_begin_lock[i] = hb_lock_init();
1747 pv->yadif_complete_lock[i] = hb_lock_init();
1750 * Important to start off with the threads locked waiting
1753 hb_lock( pv->yadif_begin_lock[i] );
1755 pv->yadif_arguments[i].stop = 0;
1756 pv->yadif_arguments[i].dst = NULL;
1758 pv->yadif_threads[i] = hb_thread_init( "yadif_filter_segment",
1759 yadif_decomb_filter_thread,
1761 HB_NORMAL_PRIORITY );
1765 hb_error( "yadif could not create threads" );
1770 * Create decomb threads and locks.
1772 pv->decomb_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1773 pv->decomb_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1774 pv->decomb_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1775 pv->decomb_arguments = malloc( sizeof( decomb_arguments_t ) * pv->cpu_count );
1777 for( i = 0; i < pv->cpu_count; i++ )
1779 decomb_thread_arg_t *decomb_thread_args;
1781 decomb_thread_args = malloc( sizeof( decomb_thread_arg_t ) );
1783 if( decomb_thread_args )
1785 decomb_thread_args->pv = pv;
1786 decomb_thread_args->segment = i;
1788 pv->decomb_begin_lock[i] = hb_lock_init();
1789 pv->decomb_complete_lock[i] = hb_lock_init();
1792 * Important to start off with the threads locked waiting
1795 hb_lock( pv->decomb_begin_lock[i] );
1797 pv->decomb_arguments[i].stop = 0;
1799 pv->decomb_threads[i] = hb_thread_init( "decomb_filter_segment",
1800 decomb_filter_thread,
1802 HB_NORMAL_PRIORITY );
1806 hb_error( "decomb could not create threads" );
1810 if( pv->mode & MODE_EEDI2 )
1813 * Create eedi2 threads and locks.
1815 pv->eedi2_threads = malloc( sizeof( hb_thread_t* ) * 3 );
1816 pv->eedi2_begin_lock = malloc( sizeof( hb_lock_t * ) * 3 );
1817 pv->eedi2_complete_lock = malloc( sizeof( hb_lock_t * ) * 3 );
1818 pv->eedi2_arguments = malloc( sizeof( eedi2_arguments_t ) * 3 );
1820 if( pv->post_processing > 1 )
1822 pv->cx2 = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1823 pv->cy2 = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1824 pv->cxy = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1825 pv->tmpc = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1826 if( !pv->cx2 || !pv->cy2 || !pv->cxy || !pv->tmpc )
1827 hb_log("EEDI2: failed to malloc derivative arrays");
1829 hb_log("EEDI2: successfully mallloced derivative arrays");
1832 for( i = 0; i < 3; i++ )
1834 eedi2_thread_arg_t *eedi2_thread_args;
1836 eedi2_thread_args = malloc( sizeof( eedi2_thread_arg_t ) );
1838 if( eedi2_thread_args )
1840 eedi2_thread_args->pv = pv;
1841 eedi2_thread_args->plane = i;
1843 pv->eedi2_begin_lock[i] = hb_lock_init();
1844 pv->eedi2_complete_lock[i] = hb_lock_init();
1847 * Important to start off with the threads locked waiting
1850 hb_lock( pv->eedi2_begin_lock[i] );
1852 pv->eedi2_arguments[i].stop = 0;
1854 pv->eedi2_threads[i] = hb_thread_init( "eedi2_filter_segment",
1855 eedi2_filter_thread,
1857 HB_NORMAL_PRIORITY );
1861 hb_error( "eedi2 could not create threads" );
1867 /* Allocate mcdeint specific buffers */
1868 if( pv->mcdeint_mode >= 0 )
1871 avcodec_register_all();
1872 AVCodec * enc = avcodec_find_encoder( CODEC_ID_SNOW );
1874 for (i = 0; i < 3; i++ )
1876 AVCodecContext * avctx_enc;
1878 avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context();
1880 avctx_enc->width = width;
1881 avctx_enc->height = height;
1882 avctx_enc->time_base = (AVRational){1,25}; // meaningless
1883 avctx_enc->gop_size = 300;
1884 avctx_enc->max_b_frames = 0;
1885 avctx_enc->pix_fmt = PIX_FMT_YUV420P;
1886 avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
1887 avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
1888 avctx_enc->global_quality = 1;
1889 avctx_enc->flags2 = CODEC_FLAG2_MEMC_ONLY;
1890 avctx_enc->me_cmp = FF_CMP_SAD; //SSE;
1891 avctx_enc->me_sub_cmp = FF_CMP_SAD; //SSE;
1892 avctx_enc->mb_cmp = FF_CMP_SSE;
1894 switch( pv->mcdeint_mode )
1897 avctx_enc->refs = 3;
1899 avctx_enc->me_method = ME_ITER;
1901 avctx_enc->flags |= CODEC_FLAG_4MV;
1902 avctx_enc->dia_size =2;
1904 avctx_enc->flags |= CODEC_FLAG_QPEL;
1907 hb_avcodec_open(avctx_enc, enc);
1910 pv->mcdeint_frame = avcodec_alloc_frame();
1911 pv->mcdeint_outbuf_size = width * height * 10;
1912 pv->mcdeint_outbuf = malloc( pv->mcdeint_outbuf_size );
1918 void hb_decomb_close( hb_filter_private_t * pv )
1925 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);
1927 /* Cleanup frame buffers */
1928 if( pv->buf_out[0] )
1930 hb_buffer_close( &pv->buf_out[0] );
1932 if( pv->buf_out[1] )
1934 hb_buffer_close( &pv->buf_out[1] );
1936 if (pv->buf_settings )
1938 hb_buffer_close( &pv->buf_settings );
1941 /* Cleanup yadif specific buffers */
1943 for( i = 0; i<3*3; i++ )
1945 uint8_t **p = &pv->ref[i%3][i/3];
1948 free( *p - 3*pv->ref_stride[i/3] );
1953 /* Cleanup combing mask. */
1954 for( i = 0; i<3*3; i++ )
1956 uint8_t **p = &pv->mask[i/3];
1959 free( *p - 3*pv->ref_stride[i/3] );
1964 if( pv->mode & MODE_EEDI2 )
1966 /* Cleanup eedi-half buffers */
1968 for( i = 0; i<3; i++ )
1970 for( j = 0; j < 4; j++ )
1972 uint8_t **p = &pv->eedi_half[j][i];
1975 free( *p - 3*pv->ref_stride[i] );
1981 /* Cleanup eedi-full buffers */
1982 for( i = 0; i<3; i++ )
1984 for( j = 0; j < 5; j++ )
1986 uint8_t **p = &pv->eedi_full[j][i];
1989 free( *p - 3*pv->ref_stride[i] );
1996 if( pv->post_processing > 1 && ( pv->mode & MODE_EEDI2 ) )
1998 if (pv->cx2) eedi2_aligned_free(pv->cx2);
1999 if (pv->cy2) eedi2_aligned_free(pv->cy2);
2000 if (pv->cxy) eedi2_aligned_free(pv->cxy);
2001 if (pv->tmpc) eedi2_aligned_free(pv->tmpc);
2004 for( i = 0; i < pv->cpu_count; i++)
2007 * Tell each yadif thread to stop, and then cleanup.
2009 pv->yadif_arguments[i].stop = 1;
2010 hb_unlock( pv->yadif_begin_lock[i] );
2012 hb_thread_close( &pv->yadif_threads[i] );
2013 hb_lock_close( &pv->yadif_begin_lock[i] );
2014 hb_lock_close( &pv->yadif_complete_lock[i] );
2018 * free memory for yadif structs
2020 free( pv->yadif_threads );
2021 free( pv->yadif_begin_lock );
2022 free( pv->yadif_complete_lock );
2023 free( pv->yadif_arguments );
2025 for( i = 0; i < pv->cpu_count; i++)
2028 * Tell each decomb thread to stop, and then cleanup.
2030 pv->decomb_arguments[i].stop = 1;
2031 hb_unlock( pv->decomb_begin_lock[i] );
2033 hb_thread_close( &pv->decomb_threads[i] );
2034 hb_lock_close( &pv->decomb_begin_lock[i] );
2035 hb_lock_close( &pv->decomb_complete_lock[i] );
2039 * free memory for decomb structs
2041 free( pv->decomb_threads );
2042 free( pv->decomb_begin_lock );
2043 free( pv->decomb_complete_lock );
2044 free( pv->decomb_arguments );
2046 if( pv->mode & MODE_EEDI2 )
2048 for( i = 0; i < 3; i++)
2051 * Tell each eedi2 thread to stop, and then cleanup.
2053 pv->eedi2_arguments[i].stop = 1;
2054 hb_unlock( pv->eedi2_begin_lock[i] );
2056 hb_thread_close( &pv->eedi2_threads[i] );
2057 hb_lock_close( &pv->eedi2_begin_lock[i] );
2058 hb_lock_close( &pv->eedi2_complete_lock[i] );
2062 * free memory for eedi2 structs
2064 free( pv->eedi2_threads );
2065 free( pv->eedi2_begin_lock );
2066 free( pv->eedi2_complete_lock );
2067 free( pv->eedi2_arguments );
2070 /* Cleanup mcdeint specific buffers */
2071 if( pv->mcdeint_mode >= 0 )
2073 if( pv->mcdeint_avctx_enc )
2075 hb_avcodec_close( pv->mcdeint_avctx_enc );
2076 av_freep( &pv->mcdeint_avctx_enc );
2078 if( pv->mcdeint_outbuf )
2080 free( pv->mcdeint_outbuf );
2087 int hb_decomb_work( const hb_buffer_t * cbuf_in,
2088 hb_buffer_t ** buf_out,
2092 hb_filter_private_t * pv )
2094 hb_buffer_t * buf_in = (hb_buffer_t *)cbuf_in;
2097 pix_fmt != pv->pix_fmt ||
2098 width != pv->width[0] ||
2099 height != pv->height[0] )
2101 return FILTER_FAILED;
2104 avpicture_fill( &pv->pic_in, buf_in->data,
2105 pix_fmt, width, height );
2107 /* Determine if top-field first layout */
2109 if( pv->parity < 0 )
2111 tff = !!(buf_in->flags & PIC_FLAG_TOP_FIELD_FIRST);
2115 tff = (pv->parity & 1) ^ 1;
2118 /* Store current frame in yadif cache */
2119 store_ref( (const uint8_t**)pv->pic_in.data, pv );
2121 /* If yadif is not ready, store another ref and return FILTER_DELAY */
2122 if( pv->yadif_ready == 0 )
2124 store_ref( (const uint8_t**)pv->pic_in.data, pv );
2126 hb_buffer_copy_settings( pv->buf_settings, buf_in );
2128 /* don't let 'work_loop' send a chapter mark upstream */
2129 buf_in->new_chap = 0;
2131 pv->yadif_ready = 1;
2133 return FILTER_DELAY;
2136 /* Perform yadif filtering */
2138 for( frame = 0; frame <= ( ( pv->mode & MODE_MCDEINT ) ? 1 : 0 ) ; frame++ )
2139 // This would be what to use for bobbing: for( frame = 0; frame <= 0 ; frame++ )
2143 /* Perhaps skip the second run if the frame is uncombed? */
2144 if( frame && !pv->yadif_arguments[0].is_combed )
2149 int parity = frame ^ tff ^ 1;
2151 // This will be for bobbing
2153 if( pv->alternator )
2165 avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,
2166 pix_fmt, width, height );
2169 Should check here and only bother filtering field 2 when
2170 field 1 was detected as combed.
2171 And when it's not, it's a progressive frame,
2172 so mcdeint should be skipped...
2174 yadif_filter( pv->pic_out.data, parity, tff, pv );
2176 /* Commented out code in the line below would skip mcdeint
2177 on uncombed frames. Possibly a bad idea, since mcdeint
2178 maintains the same snow context for the entire video... */
2179 if( pv->mcdeint_mode >= 0 /* && pv->yadif_arguments[0].is_combed */)
2181 /* Perform mcdeint filtering */
2182 avpicture_fill( &pv->pic_in, pv->buf_out[(frame^1)]->data,
2183 pix_fmt, width, height );
2185 mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );
2188 *buf_out = pv->buf_out[!(frame^1)];
2191 /* Copy buffered settings to output buffer settings */
2192 hb_buffer_copy_settings( *buf_out, pv->buf_settings );
2194 /* Replace buffered settings with input buffer settings */
2195 hb_buffer_copy_settings( pv->buf_settings, buf_in );
2197 /* don't let 'work_loop' send a chapter mark upstream */
2198 buf_in->new_chap = 0;