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
22 7:2:6:9:80:16:16:10:20:20:4:2:50:24:1
25 #define MODE_YADIF 1 // Use yadif
26 #define MODE_BLEND 2 // Use blending interpolation
27 #define MODE_CUBIC 4 // Use cubic interpolation
28 #define MODE_EEDI2 8 // Use EEDI2 interpolation
29 #define MODE_MCDEINT 16 // Post-process with mcdeint
30 #define MODE_MASK 32 // Output combing masks instead of pictures
33 These modes can be layered. For example, Yadif (1) + EEDI2 (8) = 9,
34 which will feed EEDI2 interpolations to yadif.
39 3: Switch between yadif and blend
40 4: Just cubic interpolate
42 6: Switch between cubic and blend
43 7: Switch between cubic->yadif and blend
44 8: Just EEDI2 interpolate
46 10: Switch between EEDI2 and blend
47 11: Switch between EEDI2->yadif and blend
50 19: Switch between blending and yadif -> mcdeint
52 21: Cubic->yadif->mcdeint
53 22: Cubic or blend -> mcdeint
54 23: Cubic->yadif or blend -> mcdeint
56 25: EEDI2->yadif->mcdeint
57 ...okay I'm getting bored now listing all these different modes
58 32: Passes through the combing mask for every combed frame (white for combed pixels, otherwise black)
59 33+: Overlay the combing mask for every combed frame on top of the filtered output (white for combed pixels)
61 12-15: EEDI2 will override cubic interpolation
62 16: DOES NOT WORK BY ITSELF-- mcdeint needs to be fed by another deinterlacer
67 #include "mpeg2dec/mpeg2.h"
70 #define SUPPRESS_AV_LOG
72 #define PARITY_DEFAULT -1
74 #define MCDEINT_MODE_DEFAULT -1
75 #define MCDEINT_QP_DEFAULT 1
77 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
78 #define MIN3(a,b,c) MIN(MIN(a,b),c)
79 #define MAX3(a,b,c) MAX(MAX(a,b),c)
81 // Some names to correspond to the pv->eedi_half array's contents
86 // Some names to correspond to the pv->eedi_full array's contents
93 struct yadif_arguments_s {
101 struct decomb_arguments_s {
105 struct eedi2_arguments_s {
109 typedef struct yadif_arguments_s yadif_arguments_t;
110 typedef struct decomb_arguments_s decomb_arguments_t;
111 typedef struct eedi2_arguments_s eedi2_arguments_t;
113 typedef struct eedi2_thread_arg_s {
114 hb_filter_private_t *pv;
116 } eedi2_thread_arg_t;
118 typedef struct decomb_thread_arg_s {
119 hb_filter_private_t *pv;
121 } decomb_thread_arg_t;
123 typedef struct yadif_thread_arg_s {
124 hb_filter_private_t *pv;
126 } yadif_thread_arg_t;
128 struct hb_filter_private_s
137 int motion_threshold;
138 int spatial_threshold;
144 int magnitude_threshold;
145 int variance_threshold;
146 int laplacian_threshold;
147 int dilation_threshold;
148 int erosion_threshold;
150 int maximum_search_distance;
161 int mcdeint_outbuf_size;
162 uint8_t * mcdeint_outbuf;
163 AVCodecContext * mcdeint_avctx_enc;
164 AVFrame * mcdeint_frame;
165 AVFrame * mcdeint_frame_dec;
167 int deinterlaced_frames;
169 int unfiltered_frames;
174 /* Make a buffer to store a comb mask. */
177 uint8_t * eedi_half[4][3];
178 uint8_t * eedi_full[5][3];
186 hb_buffer_t * buf_out[2];
187 hb_buffer_t * buf_settings;
191 hb_thread_t ** yadif_threads; // Threads for Yadif - one per CPU
192 hb_lock_t ** yadif_begin_lock; // Thread has work
193 hb_lock_t ** yadif_complete_lock; // Thread has completed work
194 yadif_arguments_t *yadif_arguments; // Arguments to thread for work
196 hb_thread_t ** decomb_threads; // Threads for comb detection - one per CPU
197 hb_lock_t ** decomb_begin_lock; // Thread has work
198 hb_lock_t ** decomb_complete_lock; // Thread has completed work
199 decomb_arguments_t *decomb_arguments; // Arguments to thread for work
201 hb_thread_t ** eedi2_threads; // Threads for eedi2 - one per plane
202 hb_lock_t ** eedi2_begin_lock; // Thread has work
203 hb_lock_t ** eedi2_complete_lock; // Thread has completed work
204 eedi2_arguments_t *eedi2_arguments; // Arguments to thread for work
206 // int alternator; // for bobbing parity when framedoubling
209 hb_filter_private_t * hb_decomb_init( int pix_fmt,
214 int hb_decomb_work( const hb_buffer_t * buf_in,
215 hb_buffer_t ** buf_out,
219 hb_filter_private_t * pv );
221 void hb_decomb_close( hb_filter_private_t * pv );
223 hb_filter_object_t hb_filter_decomb =
233 int cubic_interpolate_pixel( int y0, int y1, int y2, int y3 )
235 /* From http://www.neuron2.net/library/cubicinterp.html */
236 int result = ( y0 * -3 ) + ( y1 * 23 ) + ( y2 * 23 ) + ( y3 * -3 );
243 else if( result < 0 )
251 static void cubic_interpolate_line( uint8_t *dst,
255 hb_filter_private_t * pv )
257 int w = pv->width[plane];
258 int refs = pv->ref_stride[plane];
261 for( x = 0; x < w; x++)
272 else if( y == 2 || y == 1 )
274 /* There's only one sample above this pixel, use it twice. */
280 /* No samples above, triple up on the one below. */
285 if( y <= ( pv->height[plane] - 4 ) )
291 else if( y == ( pv->height[plane] - 3 ) || y == ( pv->height[plane] - 2 ) )
293 /* There's only one sample below, use it twice. */
297 else if( y == pv->height[plane] - 1)
299 /* No samples below, triple up on the one above. */
304 dst[0] = cubic_interpolate_pixel( a, b, c, d );
311 void apply_mask_line( uint8_t * srcp,
317 for( x = 0; x < width; x++ )
326 void apply_mask( hb_filter_private_t * pv )
330 for( plane = 0; plane < 3; plane++ )
332 uint8_t * srcp = ( pv->mode & MODE_MCDEINT ) ? pv->pic_in.data[plane] : pv->pic_out.data[plane];
333 uint8_t * mskp = pv->mask[plane];
335 for( height = 0; height < pv->height[plane]; height++ )
337 if( pv->mode == MODE_MASK && plane == 0 )
339 memcpy( srcp, mskp, pv->width[plane] );
341 else if( pv->mode == MODE_MASK )
343 memset( srcp, 128, pv->width[plane] );
345 else if( plane == 0 )
347 apply_mask_line( srcp, mskp, pv->width[plane] );
350 srcp += pv->pic_out.linesize[plane];
351 mskp += pv->ref_stride[plane];
356 static void store_ref( const uint8_t ** pic,
357 hb_filter_private_t * pv )
361 sizeof(uint8_t *)*3 );
365 sizeof(uint8_t *)*3*3 );
368 for( i = 0; i < 3; i++ )
370 const uint8_t * src = pic[i];
371 uint8_t * ref = pv->ref[2][i];
373 int w = pv->width[i];
374 int h = pv->height[i];
375 int ref_stride = pv->ref_stride[i];
378 for( y = 0; y < h; y++ )
381 src = (uint8_t*)src + w;
382 ref = (uint8_t*)ref + ref_stride;
387 /* This function may be useful in the future, if we want to output
388 a reference to an AVPicture, since they have different strides.
389 static void get_ref( uint8_t ** pic, hb_filter_private_t * pv, int frm )
392 for( i = 0; i < 3; i++ )
394 uint8_t * dst = pic[i];
395 const uint8_t * ref = pv->ref[frm][i];
396 int w = pv->width[i];
397 int ref_stride = pv->ref_stride[i];
400 for( y = 0; y < pv->height[i]; y++ )
410 int blend_filter_pixel( int up2, int up1, int current, int down1, int down2 )
412 /* Low-pass 5-tap filter */
416 result += current * 6;
433 static void blend_filter_line( uint8_t *dst,
437 hb_filter_private_t * pv )
439 int w = pv->width[plane];
440 int refs = pv->ref_stride[plane];
443 for( x = 0; x < w; x++)
455 /* First line, so A and B don't exist.*/
461 /* Second line, no A. */
464 else if( y == (pv->height[plane] - 2) )
466 /* Second to last line, no E. */
469 else if( y == (pv->height[plane] -1) )
471 /* Last line, no D or E. */
476 dst[0] = blend_filter_pixel( a, b, c, d, e );
483 int check_combing_mask( hb_filter_private_t * pv )
485 /* Go through the mask in X*Y blocks. If any of these windows
486 have threshold or more combed pixels, consider the whole
487 frame to be combed and send it on to be deinterlaced. */
489 /* Block mask threshold -- The number of pixels
490 in a block_width * block_height window of
491 he mask that need to show combing for the
492 whole frame to be seen as such. */
493 int threshold = pv->block_threshold;
494 int block_width = pv->block_width;
495 int block_height = pv->block_height;
496 int block_x, block_y;
497 int block_score = 0; int send_to_blend = 0;
501 for( k = 0; k < 1; k++ )
503 int ref_stride = pv->ref_stride[k];
504 for( y = 0; y < ( pv->height[k] - block_height ); y = y + block_height )
506 for( x = 0; x < ( pv->width[k] - block_width ); x = x + block_width )
509 for( block_y = 0; block_y < block_height; block_y++ )
511 for( block_x = 0; block_x < block_width; block_x++ )
513 int mask_y = y + block_y;
514 int mask_x = x + block_x;
516 /* We only want to mark a pixel in a block as combed
517 if the pixels above and below are as well. Got to
518 handle the top and bottom lines separately. */
519 if( y + block_y == 0 )
521 if( pv->mask[k][mask_y*ref_stride+mask_x ] == 255 &&
522 pv->mask[k][mask_y*ref_stride+mask_x + 1] == 255 )
525 else if( y + block_y == pv->height[k] - 1 )
527 if( pv->mask[k][mask_y*ref_stride+mask_x - 1] == 255 &&
528 pv->mask[k][mask_y*ref_stride+mask_x ] == 255 )
533 if( pv->mask[k][mask_y*ref_stride+mask_x - 1] == 255 &&
534 pv->mask[k][mask_y*ref_stride+mask_x ] == 255 &&
535 pv->mask[k][mask_y*ref_stride+mask_x + 1] == 255 )
541 if( block_score >= ( threshold / 2 ) )
544 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");
546 if ( block_score <= threshold && !( pv->buf_settings->flags & 16) )
548 /* Blend video content that scores between
549 ( threshold / 2 ) and threshold. */
552 else if( block_score > threshold )
554 if( pv->buf_settings->flags & 16 )
556 /* Blend progressive content above the threshold.*/
561 /* Yadif deinterlace video content above the threshold. */
576 /* Consider this frame to be uncombed. */
581 void detect_combed_segment( hb_filter_private_t * pv, int segment_start, int segment_stop )
583 /* A mish-mash of various comb detection tricks
584 picked up from neuron2's Decomb plugin for
585 AviSynth and tritical's IsCombedT and
586 IsCombedTIVTC plugins. */
588 int x, y, k, width, height;
590 /* Comb scoring algorithm */
591 int spatial_metric = pv->spatial_metric;
592 /* Motion threshold */
593 int mthresh = pv->motion_threshold;
594 /* Spatial threshold */
595 int athresh = pv->spatial_threshold;
596 int athresh_squared = athresh * athresh;
597 int athresh6 = 6 *athresh;
599 /* One pas for Y, one pass for U, one pass for V */
600 for( k = 0; k < 1; k++ )
602 int ref_stride = pv->ref_stride[k];
603 width = pv->width[k];
604 height = pv->height[k];
606 /* Comb detection has to start at y = 2 and end at
607 y = height - 2, because it needs to examine
608 2 pixels above and 2 below the current pixel. */
609 if( segment_start < 2 )
611 if( segment_stop > height - 2 )
612 segment_stop = height - 2;
614 for( y = segment_start; y < segment_stop; y++ )
616 /* These are just to make the buffer locations easier to read. */
617 int back_2 = ( y - 2 )*ref_stride ;
618 int back_1 = ( y - 1 )*ref_stride;
619 int current = y*ref_stride;
620 int forward_1 = ( y + 1 )*ref_stride;
621 int forward_2 = ( y + 2 )*ref_stride;
623 /* We need to examine a column of 5 pixels
624 in the prev, cur, and next frames. */
625 uint8_t previous_frame[5];
626 uint8_t current_frame[5];
627 uint8_t next_frame[5];
629 for( x = 0; x < width; x++ )
631 /* Fill up the current frame array with the current pixel values.*/
632 current_frame[0] = pv->ref[1][k][back_2 + x];
633 current_frame[1] = pv->ref[1][k][back_1 + x];
634 current_frame[2] = pv->ref[1][k][current + x];
635 current_frame[3] = pv->ref[1][k][forward_1 + x];
636 current_frame[4] = pv->ref[1][k][forward_2 + x];
638 int up_diff = current_frame[2] - current_frame[1];
639 int down_diff = current_frame[2] - current_frame[3];
641 if( ( up_diff > athresh && down_diff > athresh ) ||
642 ( up_diff < -athresh && down_diff < -athresh ) )
644 /* The pixel above and below are different,
645 and they change in the same "direction" too.*/
649 /* Make sure there's sufficient motion between frame t-1 to frame t+1. */
650 previous_frame[0] = pv->ref[0][k][back_2 + x];
651 previous_frame[1] = pv->ref[0][k][back_1 + x];
652 previous_frame[2] = pv->ref[0][k][current + x];
653 previous_frame[3] = pv->ref[0][k][forward_1 + x];
654 previous_frame[4] = pv->ref[0][k][forward_2 + x];
655 next_frame[0] = pv->ref[2][k][back_2 + x];
656 next_frame[1] = pv->ref[2][k][back_1 + x];
657 next_frame[2] = pv->ref[2][k][current + x];
658 next_frame[3] = pv->ref[2][k][forward_1 + x];
659 next_frame[4] = pv->ref[2][k][forward_2 + x];
661 if( abs( previous_frame[2] - current_frame[2] ) > mthresh &&
662 abs( current_frame[1] - next_frame[1] ) > mthresh &&
663 abs( current_frame[3] - next_frame[3] ) > mthresh )
665 if( abs( next_frame[2] - current_frame[2] ) > mthresh &&
666 abs( previous_frame[1] - current_frame[1] ) > mthresh &&
667 abs( previous_frame[3] - current_frame[3] ) > mthresh )
672 /* User doesn't want to check for motion,
673 so move on to the spatial check. */
677 if( motion || ( pv->deinterlaced_frames==0 && pv->blended_frames==0 && pv->unfiltered_frames==0) )
679 /* That means it's time for the spatial check.
680 We've got several options here. */
681 if( spatial_metric == 0 )
683 /* Simple 32detect style comb detection */
684 if( ( abs( current_frame[2] - current_frame[4] ) < 10 ) &&
685 ( abs( current_frame[2] - current_frame[3] ) > 15 ) )
687 pv->mask[k][y*ref_stride + x] = 255;
691 pv->mask[k][y*ref_stride + x] = 0;
694 else if( spatial_metric == 1 )
696 /* This, for comparison, is what IsCombed uses.
697 It's better, but still noise senstive. */
698 int combing = ( current_frame[1] - current_frame[2] ) *
699 ( current_frame[3] - current_frame[2] );
701 if( combing > athresh_squared )
702 pv->mask[k][y*ref_stride + x] = 255;
704 pv->mask[k][y*ref_stride + x] = 0;
706 else if( spatial_metric == 2 )
708 /* Tritical's noise-resistant combing scorer.
709 The check is done on a bob+blur convolution. */
710 int combing = abs( current_frame[0]
711 + ( 4 * current_frame[2] )
713 - ( 3 * ( current_frame[1]
714 + current_frame[3] ) ) );
716 /* If the frame is sufficiently combed,
717 then mark it down on the mask as 255. */
718 if( combing > athresh6 )
719 pv->mask[k][y*ref_stride + x] = 255;
721 pv->mask[k][y*ref_stride + x] = 0;
726 pv->mask[k][y*ref_stride + x] = 0;
731 pv->mask[k][y*ref_stride + x] = 0;
738 // This function calls all the eedi2 filters in sequence for a given plane.
739 // It outputs the final interpolated image to pv->eedi_full[DST2PF].
740 void eedi2_interpolate_plane( hb_filter_private_t * pv, int k )
742 /* We need all these pointers. No, seriously.
743 I swear. It's not a joke. They're used.
745 uint8_t * mskp = pv->eedi_half[MSKPF][k];
746 uint8_t * srcp = pv->eedi_half[SRCPF][k];
747 uint8_t * tmpp = pv->eedi_half[TMPPF][k];
748 uint8_t * dstp = pv->eedi_half[DSTPF][k];
749 uint8_t * dst2p = pv->eedi_full[DST2PF][k];
750 uint8_t * tmp2p2 = pv->eedi_full[TMP2PF2][k];
751 uint8_t * msk2p = pv->eedi_full[MSK2PF][k];
752 uint8_t * tmp2p = pv->eedi_full[TMP2PF][k];
753 uint8_t * dst2mp = pv->eedi_full[DST2MPF][k];
757 int * tmpc = pv->tmpc;
759 int pitch = pv->ref_stride[k];
760 int height = pv->height[k]; int width = pv->width[k];
761 int half_height = height / 2;
764 eedi2_build_edge_mask( mskp, pitch, srcp, pitch,
765 pv->magnitude_threshold, pv->variance_threshold, pv->laplacian_threshold,
766 half_height, width );
767 eedi2_erode_edge_mask( mskp, pitch, tmpp, pitch, pv->erosion_threshold, half_height, width );
768 eedi2_dilate_edge_mask( tmpp, pitch, mskp, pitch, pv->dilation_threshold, half_height, width );
769 eedi2_erode_edge_mask( mskp, pitch, tmpp, pitch, pv->erosion_threshold, half_height, width );
770 eedi2_remove_small_gaps( tmpp, pitch, mskp, pitch, half_height, width );
773 eedi2_calc_directions( k, mskp, pitch, srcp, pitch, tmpp, pitch,
774 pv->maximum_search_distance, pv->noise_threshold,
775 half_height, width );
776 eedi2_filter_dir_map( mskp, pitch, tmpp, pitch, dstp, pitch, half_height, width );
777 eedi2_expand_dir_map( mskp, pitch, dstp, pitch, tmpp, pitch, half_height, width );
778 eedi2_filter_map( mskp, pitch, tmpp, pitch, dstp, pitch, half_height, width );
780 // upscale 2x vertically
781 eedi2_upscale_by_2( srcp, dst2p, half_height, pitch );
782 eedi2_upscale_by_2( dstp, tmp2p2, half_height, pitch );
783 eedi2_upscale_by_2( mskp, msk2p, half_height, pitch );
785 // upscale the direction mask
786 eedi2_mark_directions_2x( msk2p, pitch, tmp2p2, pitch, tmp2p, pitch, pv->tff, height, width );
787 eedi2_filter_dir_map_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
788 eedi2_expand_dir_map_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
789 eedi2_fill_gaps_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
790 eedi2_fill_gaps_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
792 // interpolate a full-size plane
793 eedi2_interpolate_lattice( k, tmp2p, pitch, dst2p, pitch, tmp2p2, pitch, pv->tff,
794 pv->noise_threshold, height, width );
796 if( pv->post_processing == 1 || pv->post_processing == 3 )
798 // make sure the edge directions are consistent
799 eedi2_bit_blit( tmp2p2, pitch, tmp2p, pitch, pv->width[k], pv->height[k] );
800 eedi2_filter_dir_map_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
801 eedi2_expand_dir_map_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
802 eedi2_post_process( tmp2p, pitch, tmp2p2, pitch, dst2p, pitch, pv->tff, height, width );
804 if( pv->post_processing == 2 || pv->post_processing == 3 )
806 // filter junctions and corners
807 eedi2_gaussian_blur1( srcp, pitch, tmpp, pitch, srcp, pitch, half_height, width );
808 eedi2_calc_derivatives( srcp, pitch, half_height, width, cx2, cy2, cxy );
809 eedi2_gaussian_blur_sqrt2( cx2, tmpc, cx2, pitch, half_height, width);
810 eedi2_gaussian_blur_sqrt2( cy2, tmpc, cy2, pitch, half_height, width);
811 eedi2_gaussian_blur_sqrt2( cxy, tmpc, cxy, pitch, half_height, width);
812 eedi2_post_process_corner( cx2, cy2, cxy, pitch, tmp2p2, pitch, dst2p, pitch, height, width, pv->tff );
817 * eedi2 interpolate this plane in a single thread.
819 void eedi2_filter_thread( void *thread_args_v )
821 eedi2_arguments_t *eedi2_work = NULL;
822 hb_filter_private_t * pv;
825 eedi2_thread_arg_t *thread_args = thread_args_v;
827 pv = thread_args->pv;
828 plane = thread_args->plane;
830 hb_log("eedi2 thread started for plane %d", plane);
835 * Wait here until there is work to do. hb_lock() blocks until
836 * render releases it to say that there is more work to do.
838 hb_lock( pv->eedi2_begin_lock[plane] );
840 eedi2_work = &pv->eedi2_arguments[plane];
842 if( eedi2_work->stop )
845 * No more work to do, exit this thread.
854 eedi2_interpolate_plane( pv, plane );
857 * Finished this segment, let everyone know.
859 hb_unlock( pv->eedi2_complete_lock[plane] );
861 free( thread_args_v );
864 // Sets up the input field planes for EEDI2 in pv->eedi_half[SRCPF]
865 // and then runs eedi2_filter_thread for each plane.
866 void eedi2_planer( hb_filter_private_t * pv )
868 /* Copy the first field from the source to a half-height frame. */
870 for( i = 0; i < 3; i++ )
872 int pitch = pv->ref_stride[i];
873 int start_line = !pv->tff;
874 eedi2_fill_half_height_buffer_plane( &pv->ref[1][i][pitch*start_line], pv->eedi_half[SRCPF][i], pitch, pv->height[i] );
878 for( plane = 0; plane < 3; plane++ )
881 * Let the thread for this plane know that we've setup work
882 * for it by releasing the begin lock (ensuring that the
883 * complete lock is already locked so that we block when
884 * we try to lock it again below).
886 hb_lock( pv->eedi2_complete_lock[plane] );
887 hb_unlock( pv->eedi2_begin_lock[plane] );
891 * Wait until all three threads have completed by trying to get
892 * the complete lock that we locked earlier for each thread, which
893 * will block until that thread has completed the work on that
896 for( plane = 0; plane < 3; plane++ )
898 hb_lock( pv->eedi2_complete_lock[plane] );
899 hb_unlock( pv->eedi2_complete_lock[plane] );
905 * comb detect this segment of all three planes in a single thread.
907 void decomb_filter_thread( void *thread_args_v )
909 decomb_arguments_t *decomb_work = NULL;
910 hb_filter_private_t * pv;
912 int segment, segment_start, segment_stop, plane;
913 decomb_thread_arg_t *thread_args = thread_args_v;
915 pv = thread_args->pv;
916 segment = thread_args->segment;
918 hb_log("decomb thread started for segment %d", segment);
923 * Wait here until there is work to do. hb_lock() blocks until
924 * render releases it to say that there is more work to do.
926 hb_lock( pv->decomb_begin_lock[segment] );
928 decomb_work = &pv->decomb_arguments[segment];
930 if( decomb_work->stop )
933 * No more work to do, exit this thread.
940 * Process segment (for now just from luma)
942 for( plane = 0; plane < 1; plane++)
945 int h = pv->height[plane];
946 segment_start = ( h / pv->cpu_count ) * segment;
947 if( segment == pv->cpu_count - 1 )
954 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
957 detect_combed_segment( pv, segment_start, segment_stop );
960 * Finished this segment, let everyone know.
962 hb_unlock( pv->decomb_complete_lock[segment] );
964 free( thread_args_v );
967 int comb_segmenter( hb_filter_private_t * pv )
971 for( segment = 0; segment < pv->cpu_count; segment++ )
974 * Let the thread for this plane know that we've setup work
975 * for it by releasing the begin lock (ensuring that the
976 * complete lock is already locked so that we block when
977 * we try to lock it again below).
979 hb_lock( pv->decomb_complete_lock[segment] );
980 hb_unlock( pv->decomb_begin_lock[segment] );
984 * Wait until all three threads have completed by trying to get
985 * the complete lock that we locked earlier for each thread, which
986 * will block until that thread has completed the work on that
989 for( segment = 0; segment < pv->cpu_count; segment++ )
991 hb_lock( pv->decomb_complete_lock[segment] );
992 hb_unlock( pv->decomb_complete_lock[segment] );
995 return check_combing_mask( pv );
998 static void yadif_filter_line( uint8_t *dst,
1005 hb_filter_private_t * pv )
1007 /* While prev and next point to the previous and next frames,
1008 prev2 and next2 will shift depending on the parity, usually 1.
1009 They are the previous and next fields, the fields temporally adjacent
1010 to the other field in the current frame--the one not being filtered. */
1011 uint8_t *prev2 = parity ? prev : cur ;
1012 uint8_t *next2 = parity ? cur : next;
1014 int w = pv->width[plane];
1015 int refs = pv->ref_stride[plane];
1017 int eedi2_mode = ( pv->mode & MODE_EEDI2 );
1019 /* We can replace spatial_pred with this interpolation*/
1020 uint8_t * eedi2_guess = &pv->eedi_full[DST2PF][plane][y*refs];
1022 /* Decomb's cubic interpolation can only function when there are
1023 three samples above and below, so regress to yadif's traditional
1024 two-tap interpolation when filtering at the top and bottom edges. */
1025 int vertical_edge = 0;
1026 if( ( y < 3 ) || ( y > ( pv->height[plane] - 4 ) ) )
1029 for( x = 0; x < w; x++)
1033 /* Temporal average: the current location in the adjacent fields */
1034 int d = (prev2[0] + next2[0])>>1;
1038 /* How the current pixel changes between the adjacent fields */
1039 int temporal_diff0 = ABS(prev2[0] - next2[0]);
1040 /* The average of how much the pixels above and below change from the frame before to now. */
1041 int temporal_diff1 = ( ABS(prev[-refs] - cur[-refs]) + ABS(prev[+refs] - cur[+refs]) ) >> 1;
1042 /* The average of how much the pixels above and below change from now to the next frame. */
1043 int temporal_diff2 = ( ABS(next[-refs] - cur[-refs]) + ABS(next[+refs] - cur[+refs]) ) >> 1;
1044 /* For the actual difference, use the largest of the previous average diffs. */
1045 int diff = MAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
1051 /* Who needs yadif's spatial predictions when we can have EEDI2's? */
1052 spatial_pred = eedi2_guess[0];
1055 else // Yadif spatial interpolation
1057 /* SAD of how the pixel-1, the pixel, and the pixel+1 change from the line above to below. */
1058 int spatial_score = ABS(cur[-refs-1] - cur[+refs-1]) + ABS(cur[-refs]-cur[+refs]) +
1059 ABS(cur[-refs+1] - cur[+refs+1]) - 1;
1061 /* Spatial pred is either a bilinear or cubic vertical interpolation. */
1062 if( ( pv->mode & MODE_CUBIC ) && !vertical_edge)
1064 spatial_pred = cubic_interpolate_pixel( cur[-3*refs], cur[-refs], cur[+refs], cur[3*refs] );
1068 spatial_pred = (c+e)>>1;
1071 /* EDDI: Edge Directed Deinterlacing Interpolation
1072 Checks 4 different slopes to see if there is more similarity along a diagonal
1073 than there was vertically. If a diagonal is more similar, then it indicates
1074 an edge, so interpolate along that instead of a vertical line, using either
1075 linear or cubic interpolation depending on mode. */
1076 #define YADIF_CHECK(j)\
1077 { int score = ABS(cur[-refs-1+j] - cur[+refs-1-j])\
1078 + ABS(cur[-refs +j] - cur[+refs -j])\
1079 + ABS(cur[-refs+1+j] - cur[+refs+1-j]);\
1080 if( score < spatial_score ){\
1081 spatial_score = score;\
1082 if( ( pv->mode & MODE_CUBIC ) && !vertical_edge )\
1087 spatial_pred = cubic_interpolate_pixel(cur[-3 * refs - 3], cur[-refs -1], cur[+refs + 1], cur[3* refs + 3] );\
1090 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 ) );\
1093 spatial_pred = cubic_interpolate_pixel(cur[-3 * refs +3], cur[-refs +1], cur[+refs - 1], cur[3* refs -3] );\
1096 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 ) );\
1102 spatial_pred = ( cur[-refs +j] + cur[+refs -j] ) >>1;\
1105 if( x >= 2 && x <= w - 3 )
1108 if( x >= 3 && x <= w - 4 )
1110 YADIF_CHECK(-2) }} }}
1113 if( x >= 2 && x <= w - 3 )
1116 if( x >= 3 && x <= w - 4 )
1118 YADIF_CHECK(2) }} }}
1123 /* Temporally adjust the spatial prediction by
1124 comparing against lines in the adjacent fields. */
1125 int b = (prev2[-2*refs] + next2[-2*refs])>>1;
1126 int f = (prev2[+2*refs] + next2[+2*refs])>>1;
1128 /* Find the median value */
1129 int max = MAX3(d-e, d-c, MIN(b-c, f-e));
1130 int min = MIN3(d-e, d-c, MAX(b-c, f-e));
1131 diff = MAX3( diff, min, -max );
1133 if( spatial_pred > d + diff )
1135 spatial_pred = d + diff;
1137 else if( spatial_pred < d - diff )
1139 spatial_pred = d - diff;
1142 dst[0] = spatial_pred;
1154 * deinterlace this segment of all three planes in a single thread.
1156 void yadif_decomb_filter_thread( void *thread_args_v )
1158 yadif_arguments_t *yadif_work = NULL;
1159 hb_filter_private_t * pv;
1162 int segment, segment_start, segment_stop;
1163 yadif_thread_arg_t *thread_args = thread_args_v;
1165 int parity, tff, y, w, h, penultimate, ultimate, ref_stride, is_combed;
1167 pv = thread_args->pv;
1168 segment = thread_args->segment;
1170 hb_log("yadif thread started for segment %d", segment);
1175 * Wait here until there is work to do. hb_lock() blocks until
1176 * render releases it to say that there is more work to do.
1178 hb_lock( pv->yadif_begin_lock[segment] );
1180 yadif_work = &pv->yadif_arguments[segment];
1182 if( yadif_work->stop )
1185 * No more work to do, exit this thread.
1191 if( yadif_work->dst == NULL )
1193 hb_error( "thread started when no work available" );
1198 is_combed = pv->yadif_arguments[segment].is_combed;
1201 * Process all three planes, but only this segment of it.
1203 for( plane = 0; plane < 3; plane++)
1206 dst = yadif_work->dst;
1207 parity = yadif_work->parity;
1208 tff = yadif_work->tff;
1209 w = pv->width[plane];
1210 h = pv->height[plane];
1211 penultimate = h - 2;
1213 ref_stride = pv->ref_stride[plane];
1214 segment_start = ( h / pv->cpu_count ) * segment;
1215 if( segment == pv->cpu_count - 1 )
1222 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
1225 for( y = segment_start; y < segment_stop; y++ )
1227 if( is_combed == 2 )
1229 /* This line gets blend filtered, not yadif filtered. */
1230 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
1231 uint8_t *dst2 = &dst[plane][y*w];
1232 /* These will be useful if we ever do temporal blending. */
1233 // uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
1234 // uint8_t *next = &pv->ref[2][plane][y*ref_stride];
1236 blend_filter_line( dst2, cur, plane, y, pv );
1238 else if( pv->mode == MODE_CUBIC && is_combed && ( ( y ^ parity ) & 1 ) )
1240 /* Just apply vertical cubic interpolation */
1241 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
1242 uint8_t *dst2 = &dst[plane][y*w];
1244 cubic_interpolate_line( dst2, cur, plane, y, pv );
1246 else if( pv->mode & MODE_YADIF && ( ( y ^ parity ) & 1 ) && ( is_combed == 1 ) )
1248 /* This line gets yadif filtered. It is the bottom field
1249 when TFF and vice-versa. It's the field that gets
1250 filtered. Because yadif needs 2 lines above and below
1251 the one being filtered, we need to mirror the edges.
1252 When TFF, this means replacing the 2nd line with a
1253 copy of the 1st, and the last with the second-to-last. */
1254 if( y > 1 && y < ( h -2 ) )
1256 /* This isn't the top or bottom, proceed as normal to yadif. */
1257 uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
1258 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
1259 uint8_t *next = &pv->ref[2][plane][y*ref_stride];
1260 uint8_t *dst2 = &dst[plane][y*w];
1262 yadif_filter_line( dst2,
1273 /* BFF, so y0 = y1 */
1274 memcpy( &dst[plane][y*w],
1275 &pv->ref[1][plane][1*ref_stride],
1276 w * sizeof(uint8_t) );
1280 /* TFF, so y1 = y0 */
1281 memcpy( &dst[plane][y*w],
1282 &pv->ref[1][plane][0],
1283 w * sizeof(uint8_t) );
1285 else if( y == penultimate )
1287 /* BFF, so penultimate y = ultimate y */
1288 memcpy( &dst[plane][y*w],
1289 &pv->ref[1][plane][ultimate*ref_stride],
1290 w * sizeof(uint8_t) );
1292 else if( y == ultimate )
1294 /* TFF, so ultimate y = penultimate y */
1295 memcpy( &dst[plane][y*w],
1296 &pv->ref[1][plane][penultimate*ref_stride],
1297 w * sizeof(uint8_t) );
1302 memcpy( &dst[plane][y*w],
1303 &pv->ref[1][plane][y*ref_stride],
1304 w * sizeof(uint8_t) );
1309 * Finished this segment, let everyone know.
1311 hb_unlock( pv->yadif_complete_lock[segment] );
1313 free( thread_args_v );
1316 static void yadif_filter( uint8_t ** dst,
1319 hb_filter_private_t * pv )
1321 /* If we're running comb detection, do it now, otherwise default to true. */
1322 int is_combed = pv->spatial_metric >= 0 ? comb_segmenter( pv ) : 1;
1324 /* The comb detector suggests three different values:
1325 0: Don't comb this frame.
1326 1: Deinterlace this frame.
1327 2: Blend this frame.
1328 Since that might conflict with the filter's mode,
1329 it may be necesary to adjust this value. */
1330 if( is_combed == 1 && (pv->mode == MODE_BLEND) )
1332 /* All combed frames are getting blended */
1335 else if( is_combed == 2 && !( pv->mode & MODE_BLEND ) )
1337 /* Blending is disabled, so force interpolation of these frames. */
1340 if( is_combed == 1 &&
1341 ( pv->mode & MODE_BLEND ) &&
1342 !( pv->mode & ( MODE_YADIF | MODE_EEDI2 | MODE_CUBIC ) ) )
1344 /* Deinterlacers are disabled, blending isn't, so blend these frames. */
1347 else if( is_combed &&
1348 !( pv->mode & ( MODE_BLEND | MODE_YADIF | MODE_EEDI2 | MODE_CUBIC | MODE_MASK ) ) )
1350 /* No deinterlacer or mask chosen, pass the frame through. */
1354 if( is_combed == 1 )
1356 pv->deinterlaced_frames++;
1358 else if( is_combed == 2 )
1360 pv->blended_frames++;
1364 pv->unfiltered_frames++;
1367 if( is_combed == 1 && ( pv->mode & MODE_EEDI2 ) )
1369 /* Generate an EEDI2 interpolation */
1375 if( ( pv->mode & MODE_EEDI2 ) && !( pv->mode & MODE_YADIF ) && is_combed == 1 )
1377 // Just pass through the EEDI2 interpolation
1379 for( i = 0; i < 3; i++ )
1381 uint8_t * ref = pv->eedi_full[DST2PF][i];
1382 uint8_t * dest = dst[i];
1384 int w = pv->width[i];
1385 int ref_stride = pv->ref_stride[i];
1388 for( y = 0; y < pv->height[i]; y++ )
1390 memcpy(dest, ref, w);
1400 for( segment = 0; segment < pv->cpu_count; segment++ )
1403 * Setup the work for this plane.
1405 pv->yadif_arguments[segment].parity = parity;
1406 pv->yadif_arguments[segment].tff = tff;
1407 pv->yadif_arguments[segment].dst = dst;
1408 pv->yadif_arguments[segment].is_combed = is_combed;
1411 * Let the thread for this plane know that we've setup work
1412 * for it by releasing the begin lock (ensuring that the
1413 * complete lock is already locked so that we block when
1414 * we try to lock it again below).
1416 hb_lock( pv->yadif_complete_lock[segment] );
1417 hb_unlock( pv->yadif_begin_lock[segment] );
1421 * Wait until all three threads have completed by trying to get
1422 * the complete lock that we locked earlier for each thread, which
1423 * will block until that thread has completed the work on that
1426 for( segment = 0; segment < pv->cpu_count; segment++ )
1428 hb_lock( pv->yadif_complete_lock[segment] );
1429 hb_unlock( pv->yadif_complete_lock[segment] );
1433 * Entire frame is now deinterlaced.
1439 /* Just passing through... */
1441 /* For mcdeint's benefit... */
1442 pv->yadif_arguments[0].is_combed = is_combed; // 0
1445 for( i = 0; i < 3; i++ )
1447 uint8_t * ref = pv->ref[1][i];
1448 uint8_t * dest = dst[i];
1450 int w = pv->width[i];
1451 int ref_stride = pv->ref_stride[i];
1454 for( y = 0; y < pv->height[i]; y++ )
1456 memcpy(dest, ref, w);
1463 if( pv->mode & MODE_MASK && pv->spatial_metric >= 0 )
1465 if( pv->mode == MODE_MASK || is_combed )
1470 static void mcdeint_filter( uint8_t ** dst,
1473 hb_filter_private_t * pv )
1478 #ifdef SUPPRESS_AV_LOG
1479 /* TODO: temporarily change log level to suppress obnoxious debug output */
1480 int loglevel = av_log_get_level();
1481 av_log_set_level( AV_LOG_QUIET );
1484 for( i=0; i<3; i++ )
1486 pv->mcdeint_frame->data[i] = src[i];
1487 pv->mcdeint_frame->linesize[i] = pv->width[i];
1489 pv->mcdeint_avctx_enc->me_cmp = FF_CMP_SAD;
1490 pv->mcdeint_avctx_enc->me_sub_cmp = FF_CMP_SAD;
1491 pv->mcdeint_frame->quality = pv->mcdeint_qp * FF_QP2LAMBDA;
1493 out_size = avcodec_encode_video( pv->mcdeint_avctx_enc,
1495 pv->mcdeint_outbuf_size,
1496 pv->mcdeint_frame );
1498 pv->mcdeint_frame_dec = pv->mcdeint_avctx_enc->coded_frame;
1500 for( i = 0; i < 3; i++ )
1502 int w = pv->width[i];
1503 int h = pv->height[i];
1504 int fils = pv->mcdeint_frame_dec->linesize[i];
1505 int srcs = pv->width[i];
1507 for( y = 0; y < h; y++ )
1509 if( (y ^ parity) & 1 )
1511 for( x = 0; x < w; x++ )
1513 if( (x-1)+(y-1)*w >= 0 && (x+1)+(y+1)*w < w*h )
1516 &pv->mcdeint_frame_dec->data[i][x + y*fils];
1517 uint8_t * srcp = &src[i][x + y*srcs];
1519 int diff0 = filp[-fils] - srcp[-srcs];
1520 int diff1 = filp[+fils] - srcp[+srcs];
1524 ABS(srcp[-srcs-1] - srcp[+srcs-1]) +
1525 ABS(srcp[-srcs ] - srcp[+srcs ]) +
1526 ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
1530 #define MCDEINT_CHECK(j)\
1531 { int score = ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
1532 + ABS(srcp[-srcs +j] - srcp[+srcs -j])\
1533 + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
1534 if( score < spatial_score ) {\
1535 spatial_score = score;\
1536 diff0 = filp[-fils+j] - srcp[-srcs+j];\
1537 diff1 = filp[+fils-j] - srcp[+srcs-j];
1539 if( x >= 2 && x <= w - 3 )
1542 if( x >= 3 && x <= w - 4 )
1544 MCDEINT_CHECK(-2) }} }}
1547 if( x >= 2 && x <= w - 3 )
1550 if( x >= 3 && x <= w - 4 )
1552 MCDEINT_CHECK(2) }} }}
1556 if(diff0 + diff1 > 0)
1558 temp -= (diff0 + diff1 -
1559 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1563 temp -= (diff0 + diff1 +
1564 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1567 filp[0] = dst[i][x + y*w] =
1568 temp > 255U ? ~(temp>>31) : temp;
1573 pv->mcdeint_frame_dec->data[i][x + y*fils];
1579 for( x = 0; x < w; x++ )
1581 pv->mcdeint_frame_dec->data[i][x + y*fils] =
1582 dst[i][x + y*w]= src[i][x + y*srcs];
1588 #ifdef SUPPRESS_AV_LOG
1589 /* TODO: restore previous log level */
1590 av_log_set_level(loglevel);
1594 hb_filter_private_t * hb_decomb_init( int pix_fmt,
1599 if( pix_fmt != PIX_FMT_YUV420P )
1604 hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) );
1606 pv->pix_fmt = pix_fmt;
1608 pv->width[0] = width;
1609 pv->height[0] = height;
1610 pv->width[1] = pv->width[2] = width >> 1;
1611 pv->height[1] = pv->height[2] = height >> 1;
1613 pv->buf_out[0] = hb_video_buffer_init( width, height );
1614 pv->buf_out[1] = hb_video_buffer_init( width, height );
1615 pv->buf_settings = hb_buffer_init( 0 );
1617 pv->deinterlaced_frames = 0;
1618 pv->blended_frames = 0;
1619 pv->unfiltered_frames = 0;
1621 pv->yadif_ready = 0;
1623 pv->mode = MODE_YADIF | MODE_BLEND | MODE_CUBIC;
1624 pv->spatial_metric = 2;
1625 pv->motion_threshold = 6;
1626 pv->spatial_threshold = 9;
1627 pv->block_threshold = 80;
1628 pv->block_width = 16;
1629 pv->block_height = 16;
1631 pv->magnitude_threshold = 10;
1632 pv->variance_threshold = 20;
1633 pv->laplacian_threshold = 20;
1634 pv->dilation_threshold = 4;
1635 pv->erosion_threshold = 2;
1636 pv->noise_threshold = 50;
1637 pv->maximum_search_distance = 24;
1638 pv->post_processing = 1;
1640 pv->parity = PARITY_DEFAULT;
1642 pv->mcdeint_mode = MCDEINT_MODE_DEFAULT;
1643 pv->mcdeint_qp = MCDEINT_QP_DEFAULT;
1647 sscanf( settings, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
1649 &pv->spatial_metric,
1650 &pv->motion_threshold,
1651 &pv->spatial_threshold,
1652 &pv->block_threshold,
1655 &pv->magnitude_threshold,
1656 &pv->variance_threshold,
1657 &pv->laplacian_threshold,
1658 &pv->dilation_threshold,
1659 &pv->erosion_threshold,
1660 &pv->noise_threshold,
1661 &pv->maximum_search_distance,
1662 &pv->post_processing );
1665 pv->cpu_count = hb_get_cpu_count();
1668 if( pv->mode & MODE_MCDEINT )
1670 pv->mcdeint_mode = 2;
1673 /* Allocate yadif specific buffers */
1675 for( i = 0; i < 3; i++ )
1677 int is_chroma = !!i;
1678 int w = ((width + 31) & (~31))>>is_chroma;
1679 int h = ((height+6+ 31) & (~31))>>is_chroma;
1681 pv->ref_stride[i] = w;
1683 for( j = 0; j < 3; j++ )
1685 pv->ref[j][i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1689 /* Allocate a buffer to store a comb mask. */
1690 for( i = 0; i < 3; i++ )
1692 int is_chroma = !!i;
1693 int w = ((pv->width[0] + 31) & (~31))>>is_chroma;
1694 int h = ((pv->height[0]+6+ 31) & (~31))>>is_chroma;
1696 pv->mask[i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1699 if( pv->mode & MODE_EEDI2 )
1701 /* Allocate half-height eedi2 buffers */
1702 height = pv->height[0] / 2;
1703 for( i = 0; i < 3; i++ )
1705 int is_chroma = !!i;
1706 int w = ((width + 31) & (~31))>>is_chroma;
1707 int h = ((height+6+ 31) & (~31))>>is_chroma;
1709 for( j = 0; j < 4; j++ )
1711 pv->eedi_half[j][i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1715 /* Allocate full-height eedi2 buffers */
1716 height = pv->height[0];
1717 for( i = 0; i < 3; i++ )
1719 int is_chroma = !!i;
1720 int w = ((width + 31) & (~31))>>is_chroma;
1721 int h = ((height+6+ 31) & (~31))>>is_chroma;
1723 for( j = 0; j < 5; j++ )
1725 pv->eedi_full[j][i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1731 * Create yadif threads and locks.
1733 pv->yadif_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1734 pv->yadif_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1735 pv->yadif_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1736 pv->yadif_arguments = malloc( sizeof( yadif_arguments_t ) * pv->cpu_count );
1738 for( i = 0; i < pv->cpu_count; i++ )
1740 yadif_thread_arg_t *thread_args;
1742 thread_args = malloc( sizeof( yadif_thread_arg_t ) );
1746 thread_args->pv = pv;
1747 thread_args->segment = i;
1749 pv->yadif_begin_lock[i] = hb_lock_init();
1750 pv->yadif_complete_lock[i] = hb_lock_init();
1753 * Important to start off with the threads locked waiting
1756 hb_lock( pv->yadif_begin_lock[i] );
1758 pv->yadif_arguments[i].stop = 0;
1759 pv->yadif_arguments[i].dst = NULL;
1761 pv->yadif_threads[i] = hb_thread_init( "yadif_filter_segment",
1762 yadif_decomb_filter_thread,
1764 HB_NORMAL_PRIORITY );
1768 hb_error( "yadif could not create threads" );
1773 * Create decomb threads and locks.
1775 pv->decomb_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1776 pv->decomb_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1777 pv->decomb_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1778 pv->decomb_arguments = malloc( sizeof( decomb_arguments_t ) * pv->cpu_count );
1780 for( i = 0; i < pv->cpu_count; i++ )
1782 decomb_thread_arg_t *decomb_thread_args;
1784 decomb_thread_args = malloc( sizeof( decomb_thread_arg_t ) );
1786 if( decomb_thread_args )
1788 decomb_thread_args->pv = pv;
1789 decomb_thread_args->segment = i;
1791 pv->decomb_begin_lock[i] = hb_lock_init();
1792 pv->decomb_complete_lock[i] = hb_lock_init();
1795 * Important to start off with the threads locked waiting
1798 hb_lock( pv->decomb_begin_lock[i] );
1800 pv->decomb_arguments[i].stop = 0;
1802 pv->decomb_threads[i] = hb_thread_init( "decomb_filter_segment",
1803 decomb_filter_thread,
1805 HB_NORMAL_PRIORITY );
1809 hb_error( "decomb could not create threads" );
1813 if( pv->mode & MODE_EEDI2 )
1816 * Create eedi2 threads and locks.
1818 pv->eedi2_threads = malloc( sizeof( hb_thread_t* ) * 3 );
1819 pv->eedi2_begin_lock = malloc( sizeof( hb_lock_t * ) * 3 );
1820 pv->eedi2_complete_lock = malloc( sizeof( hb_lock_t * ) * 3 );
1821 pv->eedi2_arguments = malloc( sizeof( eedi2_arguments_t ) * 3 );
1823 if( pv->post_processing > 1 )
1825 pv->cx2 = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1826 pv->cy2 = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1827 pv->cxy = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1828 pv->tmpc = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1829 if( !pv->cx2 || !pv->cy2 || !pv->cxy || !pv->tmpc )
1830 hb_log("EEDI2: failed to malloc derivative arrays");
1832 hb_log("EEDI2: successfully mallloced derivative arrays");
1835 for( i = 0; i < 3; i++ )
1837 eedi2_thread_arg_t *eedi2_thread_args;
1839 eedi2_thread_args = malloc( sizeof( eedi2_thread_arg_t ) );
1841 if( eedi2_thread_args )
1843 eedi2_thread_args->pv = pv;
1844 eedi2_thread_args->plane = i;
1846 pv->eedi2_begin_lock[i] = hb_lock_init();
1847 pv->eedi2_complete_lock[i] = hb_lock_init();
1850 * Important to start off with the threads locked waiting
1853 hb_lock( pv->eedi2_begin_lock[i] );
1855 pv->eedi2_arguments[i].stop = 0;
1857 pv->eedi2_threads[i] = hb_thread_init( "eedi2_filter_segment",
1858 eedi2_filter_thread,
1860 HB_NORMAL_PRIORITY );
1864 hb_error( "eedi2 could not create threads" );
1870 /* Allocate mcdeint specific buffers */
1871 if( pv->mcdeint_mode >= 0 )
1874 avcodec_register_all();
1875 AVCodec * enc = avcodec_find_encoder( CODEC_ID_SNOW );
1877 for (i = 0; i < 3; i++ )
1879 AVCodecContext * avctx_enc;
1881 avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context();
1883 avctx_enc->width = width;
1884 avctx_enc->height = height;
1885 avctx_enc->time_base = (AVRational){1,25}; // meaningless
1886 avctx_enc->gop_size = 300;
1887 avctx_enc->max_b_frames = 0;
1888 avctx_enc->pix_fmt = PIX_FMT_YUV420P;
1889 avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
1890 avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
1891 avctx_enc->global_quality = 1;
1892 avctx_enc->flags2 = CODEC_FLAG2_MEMC_ONLY;
1893 avctx_enc->me_cmp = FF_CMP_SAD; //SSE;
1894 avctx_enc->me_sub_cmp = FF_CMP_SAD; //SSE;
1895 avctx_enc->mb_cmp = FF_CMP_SSE;
1897 switch( pv->mcdeint_mode )
1900 avctx_enc->refs = 3;
1902 avctx_enc->me_method = ME_ITER;
1904 avctx_enc->flags |= CODEC_FLAG_4MV;
1905 avctx_enc->dia_size =2;
1907 avctx_enc->flags |= CODEC_FLAG_QPEL;
1910 hb_avcodec_open(avctx_enc, enc);
1913 pv->mcdeint_frame = avcodec_alloc_frame();
1914 pv->mcdeint_outbuf_size = width * height * 10;
1915 pv->mcdeint_outbuf = malloc( pv->mcdeint_outbuf_size );
1921 void hb_decomb_close( hb_filter_private_t * pv )
1928 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);
1930 /* Cleanup frame buffers */
1931 if( pv->buf_out[0] )
1933 hb_buffer_close( &pv->buf_out[0] );
1935 if( pv->buf_out[1] )
1937 hb_buffer_close( &pv->buf_out[1] );
1939 if (pv->buf_settings )
1941 hb_buffer_close( &pv->buf_settings );
1944 /* Cleanup yadif specific buffers */
1946 for( i = 0; i<3*3; i++ )
1948 uint8_t **p = &pv->ref[i%3][i/3];
1951 free( *p - 3*pv->ref_stride[i/3] );
1956 /* Cleanup combing mask. */
1957 for( i = 0; i<3*3; i++ )
1959 uint8_t **p = &pv->mask[i/3];
1962 free( *p - 3*pv->ref_stride[i/3] );
1967 if( pv->mode & MODE_EEDI2 )
1969 /* Cleanup eedi-half buffers */
1971 for( i = 0; i<3; i++ )
1973 for( j = 0; j < 4; j++ )
1975 uint8_t **p = &pv->eedi_half[j][i];
1978 free( *p - 3*pv->ref_stride[i] );
1984 /* Cleanup eedi-full buffers */
1985 for( i = 0; i<3; i++ )
1987 for( j = 0; j < 5; j++ )
1989 uint8_t **p = &pv->eedi_full[j][i];
1992 free( *p - 3*pv->ref_stride[i] );
1999 if( pv->post_processing > 1 && ( pv->mode & MODE_EEDI2 ) )
2001 if (pv->cx2) eedi2_aligned_free(pv->cx2);
2002 if (pv->cy2) eedi2_aligned_free(pv->cy2);
2003 if (pv->cxy) eedi2_aligned_free(pv->cxy);
2004 if (pv->tmpc) eedi2_aligned_free(pv->tmpc);
2007 for( i = 0; i < pv->cpu_count; i++)
2010 * Tell each yadif thread to stop, and then cleanup.
2012 pv->yadif_arguments[i].stop = 1;
2013 hb_unlock( pv->yadif_begin_lock[i] );
2015 hb_thread_close( &pv->yadif_threads[i] );
2016 hb_lock_close( &pv->yadif_begin_lock[i] );
2017 hb_lock_close( &pv->yadif_complete_lock[i] );
2021 * free memory for yadif structs
2023 free( pv->yadif_threads );
2024 free( pv->yadif_begin_lock );
2025 free( pv->yadif_complete_lock );
2026 free( pv->yadif_arguments );
2028 for( i = 0; i < pv->cpu_count; i++)
2031 * Tell each decomb thread to stop, and then cleanup.
2033 pv->decomb_arguments[i].stop = 1;
2034 hb_unlock( pv->decomb_begin_lock[i] );
2036 hb_thread_close( &pv->decomb_threads[i] );
2037 hb_lock_close( &pv->decomb_begin_lock[i] );
2038 hb_lock_close( &pv->decomb_complete_lock[i] );
2042 * free memory for decomb structs
2044 free( pv->decomb_threads );
2045 free( pv->decomb_begin_lock );
2046 free( pv->decomb_complete_lock );
2047 free( pv->decomb_arguments );
2049 if( pv->mode & MODE_EEDI2 )
2051 for( i = 0; i < 3; i++)
2054 * Tell each eedi2 thread to stop, and then cleanup.
2056 pv->eedi2_arguments[i].stop = 1;
2057 hb_unlock( pv->eedi2_begin_lock[i] );
2059 hb_thread_close( &pv->eedi2_threads[i] );
2060 hb_lock_close( &pv->eedi2_begin_lock[i] );
2061 hb_lock_close( &pv->eedi2_complete_lock[i] );
2065 * free memory for eedi2 structs
2067 free( pv->eedi2_threads );
2068 free( pv->eedi2_begin_lock );
2069 free( pv->eedi2_complete_lock );
2070 free( pv->eedi2_arguments );
2073 /* Cleanup mcdeint specific buffers */
2074 if( pv->mcdeint_mode >= 0 )
2076 if( pv->mcdeint_avctx_enc )
2078 hb_avcodec_close( pv->mcdeint_avctx_enc );
2079 av_freep( &pv->mcdeint_avctx_enc );
2081 if( pv->mcdeint_outbuf )
2083 free( pv->mcdeint_outbuf );
2090 int hb_decomb_work( const hb_buffer_t * cbuf_in,
2091 hb_buffer_t ** buf_out,
2095 hb_filter_private_t * pv )
2097 hb_buffer_t * buf_in = (hb_buffer_t *)cbuf_in;
2100 pix_fmt != pv->pix_fmt ||
2101 width != pv->width[0] ||
2102 height != pv->height[0] )
2104 return FILTER_FAILED;
2107 avpicture_fill( &pv->pic_in, buf_in->data,
2108 pix_fmt, width, height );
2110 /* Determine if top-field first layout */
2112 if( pv->parity < 0 )
2114 tff = !!(buf_in->flags & PIC_FLAG_TOP_FIELD_FIRST);
2118 tff = (pv->parity & 1) ^ 1;
2121 /* Store current frame in yadif cache */
2122 store_ref( (const uint8_t**)pv->pic_in.data, pv );
2124 /* If yadif is not ready, store another ref and return FILTER_DELAY */
2125 if( pv->yadif_ready == 0 )
2127 store_ref( (const uint8_t**)pv->pic_in.data, pv );
2129 hb_buffer_copy_settings( pv->buf_settings, buf_in );
2131 /* don't let 'work_loop' send a chapter mark upstream */
2132 buf_in->new_chap = 0;
2134 pv->yadif_ready = 1;
2136 return FILTER_DELAY;
2139 /* Perform yadif filtering */
2141 for( frame = 0; frame <= ( ( pv->mode & MODE_MCDEINT ) ? 1 : 0 ) ; frame++ )
2142 // This would be what to use for bobbing: for( frame = 0; frame <= 0 ; frame++ )
2146 /* Perhaps skip the second run if the frame is uncombed? */
2147 if( frame && !pv->yadif_arguments[0].is_combed )
2152 int parity = frame ^ tff ^ 1;
2154 // This will be for bobbing
2156 if( pv->alternator )
2168 avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,
2169 pix_fmt, width, height );
2172 Should check here and only bother filtering field 2 when
2173 field 1 was detected as combed.
2174 And when it's not, it's a progressive frame,
2175 so mcdeint should be skipped...
2177 yadif_filter( pv->pic_out.data, parity, tff, pv );
2179 /* Commented out code in the line below would skip mcdeint
2180 on uncombed frames. Possibly a bad idea, since mcdeint
2181 maintains the same snow context for the entire video... */
2182 if( pv->mcdeint_mode >= 0 /* && pv->yadif_arguments[0].is_combed */)
2184 /* Perform mcdeint filtering */
2185 avpicture_fill( &pv->pic_in, pv->buf_out[(frame^1)]->data,
2186 pix_fmt, width, height );
2188 mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );
2191 *buf_out = pv->buf_out[!(frame^1)];
2194 /* Copy buffered settings to output buffer settings */
2195 hb_buffer_copy_settings( *buf_out, pv->buf_settings );
2197 /* Replace buffered settings with input buffer settings */
2198 hb_buffer_copy_settings( pv->buf_settings, buf_in );
2200 /* don't let 'work_loop' send a chapter mark upstream */
2201 buf_in->new_chap = 0;