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 #include "mpeg2dec/mpeg2.h"
17 #define SUPPRESS_AV_LOG
19 #define MODE_DEFAULT 1
20 #define PARITY_DEFAULT -1
22 #define MCDEINT_MODE_DEFAULT -1
23 #define MCDEINT_QP_DEFAULT 1
25 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
26 #define MIN3(a,b,c) MIN(MIN(a,b),c)
27 #define MAX3(a,b,c) MAX(MAX(a,b),c)
29 // Some names to correspond to the pv->eedi_half array's contents
34 // Some names to correspond to the pv->eedi_full array's contents
41 struct yadif_arguments_s {
49 struct decomb_arguments_s {
53 struct eedi2_arguments_s {
57 typedef struct yadif_arguments_s yadif_arguments_t;
58 typedef struct decomb_arguments_s decomb_arguments_t;
59 typedef struct eedi2_arguments_s eedi2_arguments_t;
61 typedef struct eedi2_thread_arg_s {
62 hb_filter_private_t *pv;
66 typedef struct decomb_thread_arg_s {
67 hb_filter_private_t *pv;
69 } decomb_thread_arg_t;
71 typedef struct yadif_thread_arg_s {
72 hb_filter_private_t *pv;
76 struct hb_filter_private_s
86 int spatial_threshold;
92 int magnitude_threshold;
93 int variance_threshold;
94 int laplacian_threshold;
95 int dilation_threshold;
96 int erosion_threshold;
98 int maximum_search_distance;
109 int mcdeint_outbuf_size;
110 uint8_t * mcdeint_outbuf;
111 AVCodecContext * mcdeint_avctx_enc;
112 AVFrame * mcdeint_frame;
113 AVFrame * mcdeint_frame_dec;
115 int yadif_deinterlaced_frames;
116 int blend_deinterlaced_frames;
117 int unfiltered_frames;
122 /* Make a buffer to store a comb mask. */
125 uint8_t * eedi_half[4][3];
126 uint8_t * eedi_full[5][3];
134 hb_buffer_t * buf_out[2];
135 hb_buffer_t * buf_settings;
139 hb_thread_t ** yadif_threads; // Threads for Yadif - one per CPU
140 hb_lock_t ** yadif_begin_lock; // Thread has work
141 hb_lock_t ** yadif_complete_lock; // Thread has completed work
142 yadif_arguments_t *yadif_arguments; // Arguments to thread for work
144 hb_thread_t ** decomb_threads; // Threads for comb detection - one per CPU
145 hb_lock_t ** decomb_begin_lock; // Thread has work
146 hb_lock_t ** decomb_complete_lock; // Thread has completed work
147 decomb_arguments_t *decomb_arguments; // Arguments to thread for work
149 hb_thread_t ** eedi2_threads; // Threads for eedi2 - one per plane
150 hb_lock_t ** eedi2_begin_lock; // Thread has work
151 hb_lock_t ** eedi2_complete_lock; // Thread has completed work
152 eedi2_arguments_t *eedi2_arguments; // Arguments to thread for work
156 hb_filter_private_t * hb_decomb_init( int pix_fmt,
161 int hb_decomb_work( const hb_buffer_t * buf_in,
162 hb_buffer_t ** buf_out,
166 hb_filter_private_t * pv );
168 void hb_decomb_close( hb_filter_private_t * pv );
170 hb_filter_object_t hb_filter_decomb =
180 int cubic_interpolate( int y0, int y1, int y2, int y3 )
182 /* From http://www.neuron2.net/library/cubicinterp.html */
183 int result = ( y0 * -3 ) + ( y1 * 23 ) + ( y2 * 23 ) + ( y3 * -3 );
190 else if( result < 0 )
198 static void store_ref( const uint8_t ** pic,
199 hb_filter_private_t * pv )
203 sizeof(uint8_t *)*3 );
207 sizeof(uint8_t *)*3*3 );
210 for( i = 0; i < 3; i++ )
212 const uint8_t * src = pic[i];
213 uint8_t * ref = pv->ref[2][i];
215 int w = pv->width[i];
216 int h = pv->height[i];
217 int ref_stride = pv->ref_stride[i];
220 for( y = 0; y < pv->height[i]; y++ )
223 src = (uint8_t*)src + w;
224 ref = (uint8_t*)ref + ref_stride;
229 static void get_ref( uint8_t ** pic, hb_filter_private_t * pv, int frm )
232 for( i = 0; i < 3; i++ )
234 uint8_t * dst = pic[i];
235 const uint8_t * ref = pv->ref[frm][i];
236 int w = pv->width[i];
237 int ref_stride = pv->ref_stride[i];
240 for( y = 0; y < pv->height[i]; y++ )
249 int blend_filter_pixel( int up2, int up1, int current, int down1, int down2 )
251 /* Low-pass 5-tap filter */
255 result += current * 6;
272 static void blend_filter_line( uint8_t *dst,
276 hb_filter_private_t * pv )
278 int w = pv->width[plane];
279 int refs = pv->ref_stride[plane];
282 for( x = 0; x < w; x++)
294 /* First line, so A and B don't exist.*/
300 /* Second line, no A. */
303 else if( y == (pv->height[plane] - 2) )
305 /* Second to last line, no E. */
308 else if( y == (pv->height[plane] -1) )
310 /* Last line, no D or E. */
315 dst[0] = blend_filter_pixel( a, b, c, d, e );
322 int check_combing_mask( hb_filter_private_t * pv )
324 /* Go through the mask in X*Y blocks. If any of these windows
325 have threshold or more combed pixels, consider the whole
326 frame to be combed and send it on to be deinterlaced. */
328 /* Block mask threshold -- The number of pixels
329 in a block_width * block_height window of
330 he mask that need to show combing for the
331 whole frame to be seen as such. */
332 int threshold = pv->block_threshold;
333 int block_width = pv->block_width;
334 int block_height = pv->block_height;
335 int block_x, block_y;
336 int block_score = 0; int send_to_blend = 0;
340 for( k = 0; k < 1; k++ )
342 int ref_stride = pv->ref_stride[k];
343 for( y = 0; y < ( pv->height[k] - block_height ); y = y + block_height )
345 for( x = 0; x < ( pv->width[k] - block_width ); x = x + block_width )
348 for( block_y = 0; block_y < block_height; block_y++ )
350 for( block_x = 0; block_x < block_width; block_x++ )
352 int mask_y = y + block_y;
353 int mask_x = x + block_x;
355 /* We only want to mark a pixel in a block as combed
356 if the pixels above and below are as well. Got to
357 handle the top and bottom lines separately. */
358 if( y + block_y == 0 )
360 if( pv->mask[k][mask_y*ref_stride+mask_x ] == 255 &&
361 pv->mask[k][mask_y*ref_stride+mask_x + 1] == 255 )
364 else if( y + block_y == pv->height[k] - 1 )
366 if( pv->mask[k][mask_y*ref_stride+mask_x - 1] == 255 &&
367 pv->mask[k][mask_y*ref_stride+mask_x ] == 255 )
372 if( pv->mask[k][mask_y*ref_stride+mask_x - 1] == 255 &&
373 pv->mask[k][mask_y*ref_stride+mask_x ] == 255 &&
374 pv->mask[k][mask_y*ref_stride+mask_x + 1] == 255 )
380 if( block_score >= ( threshold / 2 ) )
383 hb_log("decomb: frame %i | score %i | type %s", pv->yadif_deinterlaced_frames + pv->blend_deinterlaced_frames + pv->unfiltered_frames + 1, block_score, pv->buf_settings->flags & 16 ? "Film" : "Video");
385 if ( block_score <= threshold && !( pv->buf_settings->flags & 16) )
387 /* Blend video content that scores between
388 ( threshold / 2 ) and threshold. */
391 else if( block_score > threshold )
393 if( pv->buf_settings->flags & 16 )
395 /* Blend progressive content above the threshold.*/
400 /* Yadif deinterlace video content above the threshold. */
415 /* Consider this frame to be uncombed. */
420 int detect_combed_segment( hb_filter_private_t * pv, int segment_start, int segment_stop )
422 /* A mish-mash of various comb detection tricks
423 picked up from neuron2's Decomb plugin for
424 AviSynth and tritical's IsCombedT and
425 IsCombedTIVTC plugins. */
427 int x, y, k, width, height;
429 /* Comb scoring algorithm */
430 int spatial_metric = pv->spatial_metric;
431 /* Motion threshold */
432 int mthresh = pv->motion_threshold;
433 /* Spatial threshold */
434 int athresh = pv->spatial_threshold;
435 int athresh_squared = athresh * athresh;
436 int athresh6 = 6 *athresh;
438 /* One pas for Y, one pass for U, one pass for V */
439 for( k = 0; k < 1; k++ )
441 int ref_stride = pv->ref_stride[k];
442 width = pv->width[k];
443 height = pv->height[k];
445 /* Comb detection has to start at y = 2 and end at
446 y = height - 2, because it needs to examine
447 2 pixels above and 2 below the current pixel. */
448 if( segment_start < 2 )
450 if( segment_stop > height - 2 )
451 segment_stop = height - 2;
453 for( y = segment_start; y < segment_stop; y++ )
455 /* These are just to make the buffer locations easier to read. */
456 int back_2 = ( y - 2 )*ref_stride ;
457 int back_1 = ( y - 1 )*ref_stride;
458 int current = y*ref_stride;
459 int forward_1 = ( y + 1 )*ref_stride;
460 int forward_2 = ( y + 2 )*ref_stride;
462 /* We need to examine a column of 5 pixels
463 in the prev, cur, and next frames. */
464 uint8_t previous_frame[5];
465 uint8_t current_frame[5];
466 uint8_t next_frame[5];
468 for( x = 0; x < width; x++ )
470 /* Fill up the current frame array with the current pixel values.*/
471 current_frame[0] = pv->ref[1][k][back_2 + x];
472 current_frame[1] = pv->ref[1][k][back_1 + x];
473 current_frame[2] = pv->ref[1][k][current + x];
474 current_frame[3] = pv->ref[1][k][forward_1 + x];
475 current_frame[4] = pv->ref[1][k][forward_2 + x];
477 int up_diff = current_frame[2] - current_frame[1];
478 int down_diff = current_frame[2] - current_frame[3];
480 if( ( up_diff > athresh && down_diff > athresh ) ||
481 ( up_diff < -athresh && down_diff < -athresh ) )
483 /* The pixel above and below are different,
484 and they change in the same "direction" too.*/
488 /* Make sure there's sufficient motion between frame t-1 to frame t+1. */
489 previous_frame[0] = pv->ref[0][k][back_2 + x];
490 previous_frame[1] = pv->ref[0][k][back_1 + x];
491 previous_frame[2] = pv->ref[0][k][current + x];
492 previous_frame[3] = pv->ref[0][k][forward_1 + x];
493 previous_frame[4] = pv->ref[0][k][forward_2 + x];
494 next_frame[0] = pv->ref[2][k][back_2 + x];
495 next_frame[1] = pv->ref[2][k][back_1 + x];
496 next_frame[2] = pv->ref[2][k][current + x];
497 next_frame[3] = pv->ref[2][k][forward_1 + x];
498 next_frame[4] = pv->ref[2][k][forward_2 + x];
500 if( abs( previous_frame[2] - current_frame[2] ) > mthresh &&
501 abs( current_frame[1] - next_frame[1] ) > mthresh &&
502 abs( current_frame[3] - next_frame[3] ) > mthresh )
504 if( abs( next_frame[2] - current_frame[2] ) > mthresh &&
505 abs( previous_frame[1] - current_frame[1] ) > mthresh &&
506 abs( previous_frame[3] - current_frame[3] ) > mthresh )
511 /* User doesn't want to check for motion,
512 so move on to the spatial check. */
516 if( motion || ( pv->yadif_deinterlaced_frames==0 && pv->blend_deinterlaced_frames==0 && pv->unfiltered_frames==0) )
518 /* That means it's time for the spatial check.
519 We've got several options here. */
520 if( spatial_metric == 0 )
522 /* Simple 32detect style comb detection */
523 if( ( abs( current_frame[2] - current_frame[4] ) < 10 ) &&
524 ( abs( current_frame[2] - current_frame[3] ) > 15 ) )
526 pv->mask[k][y*ref_stride + x] = 255;
530 pv->mask[k][y*ref_stride + x] = 0;
533 else if( spatial_metric == 1 )
535 /* This, for comparison, is what IsCombed uses.
536 It's better, but still noise senstive. */
537 int combing = ( current_frame[1] - current_frame[2] ) *
538 ( current_frame[3] - current_frame[2] );
540 if( combing > athresh_squared )
541 pv->mask[k][y*ref_stride + x] = 255;
543 pv->mask[k][y*ref_stride + x] = 0;
545 else if( spatial_metric == 2 )
547 /* Tritical's noise-resistant combing scorer.
548 The check is done on a bob+blur convolution. */
549 int combing = abs( current_frame[0]
550 + ( 4 * current_frame[2] )
552 - ( 3 * ( current_frame[1]
553 + current_frame[3] ) ) );
555 /* If the frame is sufficiently combed,
556 then mark it down on the mask as 255. */
557 if( combing > athresh6 )
558 pv->mask[k][y*ref_stride + x] = 255;
560 pv->mask[k][y*ref_stride + x] = 0;
565 pv->mask[k][y*ref_stride + x] = 0;
570 pv->mask[k][y*ref_stride + x] = 0;
577 // This function calls all the eedi2 filters in sequence for a given plane.
578 // It outputs the final interpolated image to pv->eedi_full[DST2PF].
579 void eedi2_interpolate_plane( hb_filter_private_t * pv, int k )
581 /* We need all these pointers. No, seriously.
582 I swear. It's not a joke. They're used.
584 uint8_t * mskp = pv->eedi_half[MSKPF][k];
585 uint8_t * srcp = pv->eedi_half[SRCPF][k];
586 uint8_t * tmpp = pv->eedi_half[TMPPF][k];
587 uint8_t * dstp = pv->eedi_half[DSTPF][k];
588 uint8_t * dst2p = pv->eedi_full[DST2PF][k];
589 uint8_t * tmp2p2 = pv->eedi_full[TMP2PF2][k];
590 uint8_t * msk2p = pv->eedi_full[MSK2PF][k];
591 uint8_t * tmp2p = pv->eedi_full[TMP2PF][k];
592 uint8_t * dst2mp = pv->eedi_full[DST2MPF][k];
596 int * tmpc = pv->tmpc;
598 int pitch = pv->ref_stride[k];
599 int height = pv->height[k]; int width = pv->width[k];
600 int half_height = height / 2;
603 eedi2_build_edge_mask( mskp, pitch, srcp, pitch,
604 pv->magnitude_threshold, pv->variance_threshold, pv->laplacian_threshold,
605 half_height, width );
606 eedi2_erode_edge_mask( mskp, pitch, tmpp, pitch, pv->erosion_threshold, half_height, width );
607 eedi2_dilate_edge_mask( tmpp, pitch, mskp, pitch, pv->dilation_threshold, half_height, width );
608 eedi2_erode_edge_mask( mskp, pitch, tmpp, pitch, pv->erosion_threshold, half_height, width );
609 eedi2_remove_small_gaps( tmpp, pitch, mskp, pitch, half_height, width );
612 eedi2_calc_directions( k, mskp, pitch, srcp, pitch, tmpp, pitch,
613 pv->maximum_search_distance, pv->noise_threshold,
614 half_height, width );
615 eedi2_filter_dir_map( mskp, pitch, tmpp, pitch, dstp, pitch, half_height, width );
616 eedi2_expand_dir_map( mskp, pitch, dstp, pitch, tmpp, pitch, half_height, width );
617 eedi2_filter_map( mskp, pitch, tmpp, pitch, dstp, pitch, half_height, width );
619 // upscale 2x vertically
620 eedi2_upscale_by_2( srcp, dst2p, half_height, pitch );
621 eedi2_upscale_by_2( dstp, tmp2p2, half_height, pitch );
622 eedi2_upscale_by_2( mskp, msk2p, half_height, pitch );
624 // upscale the direction mask
625 eedi2_mark_directions_2x( msk2p, pitch, tmp2p2, pitch, tmp2p, pitch, pv->tff, height, width );
626 eedi2_filter_dir_map_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
627 eedi2_expand_dir_map_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
628 eedi2_fill_gaps_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
629 eedi2_fill_gaps_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
631 // interpolate a full-size plane
632 eedi2_interpolate_lattice( k, tmp2p, pitch, dst2p, pitch, tmp2p2, pitch, pv->tff,
633 pv->noise_threshold, height, width );
635 if( pv->post_processing == 1 || pv->post_processing == 3 )
637 // make sure the edge directions are consistent
638 eedi2_bit_blit( tmp2p2, pitch, tmp2p, pitch, pv->width[k], pv->height[k] );
639 eedi2_filter_dir_map_2x( msk2p, pitch, tmp2p, pitch, dst2mp, pitch, pv->tff, height, width );
640 eedi2_expand_dir_map_2x( msk2p, pitch, dst2mp, pitch, tmp2p, pitch, pv->tff, height, width );
641 eedi2_post_process( tmp2p, pitch, tmp2p2, pitch, dst2p, pitch, pv->tff, height, width );
643 if( pv->post_processing == 2 || pv->post_processing == 3 )
645 // filter junctions and corners
646 eedi2_gaussian_blur1( srcp, pitch, tmpp, pitch, srcp, pitch, half_height, width );
647 eedi2_calc_derivatives( srcp, pitch, half_height, width, cx2, cy2, cxy );
648 eedi2_gaussian_blur_sqrt2( cx2, tmpc, cx2, pitch, half_height, width);
649 eedi2_gaussian_blur_sqrt2( cy2, tmpc, cy2, pitch, half_height, width);
650 eedi2_gaussian_blur_sqrt2( cxy, tmpc, cxy, pitch, half_height, width);
651 eedi2_post_process_corner( cx2, cy2, cxy, pitch, tmp2p2, pitch, dst2p, pitch, height, width, pv->tff );
656 * eedi2 interpolate this plane in a single thread.
658 void eedi2_filter_thread( void *thread_args_v )
660 eedi2_arguments_t *eedi2_work = NULL;
661 hb_filter_private_t * pv;
664 eedi2_thread_arg_t *thread_args = thread_args_v;
666 pv = thread_args->pv;
667 plane = thread_args->plane;
669 hb_log("eedi2 thread started for plane %d", plane);
674 * Wait here until there is work to do. hb_lock() blocks until
675 * render releases it to say that there is more work to do.
677 hb_lock( pv->eedi2_begin_lock[plane] );
679 eedi2_work = &pv->eedi2_arguments[plane];
681 if( eedi2_work->stop )
684 * No more work to do, exit this thread.
693 eedi2_interpolate_plane( pv, plane );
696 * Finished this segment, let everyone know.
698 hb_unlock( pv->eedi2_complete_lock[plane] );
700 free( thread_args_v );
703 // Sets up the input field planes for EEDI2 in pv->eedi_half[SRCPF]
704 // and then runs eedi2_filter_thread for each plane.
705 void eedi2_planer( hb_filter_private_t * pv )
707 /* Copy the first field from the source to a half-height frame. */
709 for( i = 0; i < 3; i++ )
711 int pitch = pv->ref_stride[i];
712 int start_line = !pv->tff;
713 eedi2_fill_half_height_buffer_plane( &pv->ref[1][i][pitch*start_line], pv->eedi_half[SRCPF][i], pitch, pv->height[i] );
717 for( plane = 0; plane < 3; plane++ )
720 * Let the thread for this plane know that we've setup work
721 * for it by releasing the begin lock (ensuring that the
722 * complete lock is already locked so that we block when
723 * we try to lock it again below).
725 hb_lock( pv->eedi2_complete_lock[plane] );
726 hb_unlock( pv->eedi2_begin_lock[plane] );
730 * Wait until all three threads have completed by trying to get
731 * the complete lock that we locked earlier for each thread, which
732 * will block until that thread has completed the work on that
735 for( plane = 0; plane < 3; plane++ )
737 hb_lock( pv->eedi2_complete_lock[plane] );
738 hb_unlock( pv->eedi2_complete_lock[plane] );
744 * comb detect this segment of all three planes in a single thread.
746 void decomb_filter_thread( void *thread_args_v )
748 decomb_arguments_t *decomb_work = NULL;
749 hb_filter_private_t * pv;
751 int segment, segment_start, segment_stop, plane;
752 decomb_thread_arg_t *thread_args = thread_args_v;
754 pv = thread_args->pv;
755 segment = thread_args->segment;
757 hb_log("decomb thread started for segment %d", segment);
762 * Wait here until there is work to do. hb_lock() blocks until
763 * render releases it to say that there is more work to do.
765 hb_lock( pv->decomb_begin_lock[segment] );
767 decomb_work = &pv->decomb_arguments[segment];
769 if( decomb_work->stop )
772 * No more work to do, exit this thread.
779 * Process segment (for now just from luma)
781 for( plane = 0; plane < 1; plane++)
784 int w = pv->width[plane];
785 int h = pv->height[plane];
786 int ref_stride = pv->ref_stride[plane];
787 segment_start = ( h / pv->cpu_count ) * segment;
788 if( segment == pv->cpu_count - 1 )
795 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
798 detect_combed_segment( pv, segment_start, segment_stop );
801 * Finished this segment, let everyone know.
803 hb_unlock( pv->decomb_complete_lock[segment] );
805 free( thread_args_v );
808 int comb_segmenter( hb_filter_private_t * pv )
812 for( segment = 0; segment < pv->cpu_count; segment++ )
815 * Let the thread for this plane know that we've setup work
816 * for it by releasing the begin lock (ensuring that the
817 * complete lock is already locked so that we block when
818 * we try to lock it again below).
820 hb_lock( pv->decomb_complete_lock[segment] );
821 hb_unlock( pv->decomb_begin_lock[segment] );
825 * Wait until all three threads have completed by trying to get
826 * the complete lock that we locked earlier for each thread, which
827 * will block until that thread has completed the work on that
830 for( segment = 0; segment < pv->cpu_count; segment++ )
832 hb_lock( pv->decomb_complete_lock[segment] );
833 hb_unlock( pv->decomb_complete_lock[segment] );
836 return check_combing_mask( pv );
839 static void yadif_filter_line( uint8_t *dst,
846 hb_filter_private_t * pv )
848 /* While prev and next point to the previous and next frames,
849 prev2 and next2 will shift depending on the parity, usually 1.
850 They are the previous and next fields, the fields temporally adjacent
851 to the other field in the current frame--the one not being filtered. */
852 uint8_t *prev2 = parity ? prev : cur ;
853 uint8_t *next2 = parity ? cur : next;
855 int w = pv->width[plane];
856 int refs = pv->ref_stride[plane];
858 int eedi2_mode = (pv->mode == 5);
860 /* We can replace spatial_pred with this interpolation*/
861 uint8_t * eedi2_guess = &pv->eedi_full[DST2PF][plane][y*refs];
863 /* Decomb's cubic interpolation can only function when there are
864 three samples above and below, so regress to yadif's traditional
865 two-tap interpolation when filtering at the top and bottom edges. */
867 if( ( y < 3 ) || ( y > ( pv->height[plane] - 4 ) ) )
870 for( x = 0; x < w; x++)
874 /* Temporal average: the current location in the adjacent fields */
875 int d = (prev2[0] + next2[0])>>1;
879 /* How the current pixel changes between the adjacent fields */
880 int temporal_diff0 = ABS(prev2[0] - next2[0]);
881 /* The average of how much the pixels above and below change from the frame before to now. */
882 int temporal_diff1 = ( ABS(prev[-refs] - cur[-refs]) + ABS(prev[+refs] - cur[+refs]) ) >> 1;
883 /* The average of how much the pixels above and below change from now to the next frame. */
884 int temporal_diff2 = ( ABS(next[-refs] - cur[-refs]) + ABS(next[+refs] - cur[+refs]) ) >> 1;
885 /* For the actual difference, use the largest of the previous average diffs. */
886 int diff = MAX3(temporal_diff0>>1, temporal_diff1, temporal_diff2);
892 /* Who needs yadif's spatial predictions when we can have EEDI2's? */
893 spatial_pred = eedi2_guess[0];
896 else // Yadif spatial interpolation
898 /* SAD of how the pixel-1, the pixel, and the pixel+1 change from the line above to below. */
899 int spatial_score = ABS(cur[-refs-1] - cur[+refs-1]) + ABS(cur[-refs]-cur[+refs]) +
900 ABS(cur[-refs+1] - cur[+refs+1]) - 1;
902 /* Spatial pred is either a bilinear or cubic vertical interpolation. */
903 if( pv->mode > 0 && !edge)
905 spatial_pred = cubic_interpolate( cur[-3*refs], cur[-refs], cur[+refs], cur[3*refs] );
909 spatial_pred = (c+e)>>1;
912 /* EDDI: Edge Directed Deinterlacing Interpolation
913 Checks 4 different slopes to see if there is more similarity along a diagonal
914 than there was vertically. If a diagonal is more similar, then it indicates
915 an edge, so interpolate along that instead of a vertical line, using either
916 linear or cubic interpolation depending on mode. */
917 #define YADIF_CHECK(j)\
918 { int score = ABS(cur[-refs-1+j] - cur[+refs-1-j])\
919 + ABS(cur[-refs +j] - cur[+refs -j])\
920 + ABS(cur[-refs+1+j] - cur[+refs+1-j]);\
921 if( score < spatial_score ){\
922 spatial_score = score;\
923 if( pv->mode > 0 && !edge )\
928 spatial_pred = cubic_interpolate(cur[-3 * refs - 3], cur[-refs -1], cur[+refs + 1], cur[3* refs + 3] );\
931 spatial_pred = cubic_interpolate( ( ( cur[-3*refs - 4] + cur[-refs - 4] ) / 2 ) , cur[-refs -2], cur[+refs + 2], ( ( cur[3*refs + 4] + cur[refs + 4] ) / 2 ) );\
934 spatial_pred = cubic_interpolate(cur[-3 * refs +3], cur[-refs +1], cur[+refs - 1], cur[3* refs -3] );\
937 spatial_pred = cubic_interpolate(( ( cur[-3*refs + 4] + cur[-refs + 4] ) / 2 ), cur[-refs +2], cur[+refs - 2], ( ( cur[3*refs - 4] + cur[refs - 4] ) / 2 ) );\
943 spatial_pred = ( cur[-refs +j] + cur[+refs -j] ) >>1;\
946 YADIF_CHECK(-1) YADIF_CHECK(-2) }} }}
947 YADIF_CHECK( 1) YADIF_CHECK( 2) }} }}
950 /* Temporally adjust the spatial prediction by
951 comparing against lines in the adjacent fields. */
952 int b = (prev2[-2*refs] + next2[-2*refs])>>1;
953 int f = (prev2[+2*refs] + next2[+2*refs])>>1;
955 /* Find the median value */
956 int max = MAX3(d-e, d-c, MIN(b-c, f-e));
957 int min = MIN3(d-e, d-c, MAX(b-c, f-e));
958 diff = MAX3( diff, min, -max );
960 if( spatial_pred > d + diff )
962 spatial_pred = d + diff;
964 else if( spatial_pred < d - diff )
966 spatial_pred = d - diff;
969 dst[0] = spatial_pred;
981 * deinterlace this segment of all three planes in a single thread.
983 void yadif_decomb_filter_thread( void *thread_args_v )
985 yadif_arguments_t *yadif_work = NULL;
986 hb_filter_private_t * pv;
989 int segment, segment_start, segment_stop;
990 yadif_thread_arg_t *thread_args = thread_args_v;
992 int parity, tff, y, w, h, penultimate, ultimate, ref_stride, is_combed;
994 pv = thread_args->pv;
995 segment = thread_args->segment;
997 hb_log("yadif thread started for segment %d", segment);
1002 * Wait here until there is work to do. hb_lock() blocks until
1003 * render releases it to say that there is more work to do.
1005 hb_lock( pv->yadif_begin_lock[segment] );
1007 yadif_work = &pv->yadif_arguments[segment];
1009 if( yadif_work->stop )
1012 * No more work to do, exit this thread.
1018 if( yadif_work->dst == NULL )
1020 hb_error( "thread started when no work available" );
1025 is_combed = pv->yadif_arguments[segment].is_combed;
1028 * Process all three planes, but only this segment of it.
1030 for( plane = 0; plane < 3; plane++)
1033 dst = yadif_work->dst;
1034 parity = yadif_work->parity;
1035 tff = yadif_work->tff;
1036 w = pv->width[plane];
1037 h = pv->height[plane];
1038 penultimate = h - 2;
1040 ref_stride = pv->ref_stride[plane];
1041 segment_start = ( h / pv->cpu_count ) * segment;
1042 if( segment == pv->cpu_count - 1 )
1049 segment_stop = ( h / pv->cpu_count ) * ( segment + 1 );
1052 for( y = segment_start; y < segment_stop; y++ )
1054 if( ( pv->mode == 4 && is_combed ) || is_combed == 2 )
1056 /* This line gets blend filtered, not yadif filtered. */
1057 uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
1058 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
1059 uint8_t *next = &pv->ref[2][plane][y*ref_stride];
1060 uint8_t *dst2 = &dst[plane][y*w];
1062 blend_filter_line( dst2, cur, plane, y, pv );
1064 else if( ( ( y ^ parity ) & 1 ) && ( is_combed == 1 ) )
1066 /* This line gets yadif filtered. It is the bottom field
1067 when TFF and vice-versa. It's the field that gets
1068 filtered. Because yadif needs 2 lines above and below
1069 the one being filtered, we need to mirror the edges.
1070 When TFF, this means replacing the 2nd line with a
1071 copy of the 1st, and the last with the second-to-last. */
1072 if( y > 1 && y < ( h -2 ) )
1074 /* This isn't the top or bottom, proceed as normal to yadif. */
1075 uint8_t *prev = &pv->ref[0][plane][y*ref_stride];
1076 uint8_t *cur = &pv->ref[1][plane][y*ref_stride];
1077 uint8_t *next = &pv->ref[2][plane][y*ref_stride];
1078 uint8_t *dst2 = &dst[plane][y*w];
1080 yadif_filter_line( dst2,
1091 /* BFF, so y0 = y1 */
1092 memcpy( &dst[plane][y*w],
1093 &pv->ref[1][plane][1*ref_stride],
1094 w * sizeof(uint8_t) );
1098 /* TFF, so y1 = y0 */
1099 memcpy( &dst[plane][y*w],
1100 &pv->ref[1][plane][0],
1101 w * sizeof(uint8_t) );
1103 else if( y == penultimate )
1105 /* BFF, so penultimate y = ultimate y */
1106 memcpy( &dst[plane][y*w],
1107 &pv->ref[1][plane][ultimate*ref_stride],
1108 w * sizeof(uint8_t) );
1110 else if( y == ultimate )
1112 /* TFF, so ultimate y = penultimate y */
1113 memcpy( &dst[plane][y*w],
1114 &pv->ref[1][plane][penultimate*ref_stride],
1115 w * sizeof(uint8_t) );
1120 memcpy( &dst[plane][y*w],
1121 &pv->ref[1][plane][y*ref_stride],
1122 w * sizeof(uint8_t) );
1127 * Finished this segment, let everyone know.
1129 hb_unlock( pv->yadif_complete_lock[segment] );
1131 free( thread_args_v );
1134 static void yadif_filter( uint8_t ** dst,
1137 hb_filter_private_t * pv )
1139 /* If we're running comb detection, do it now, otherwise blend if mode 4 and interpolate if not. */
1140 int is_combed = pv->spatial_metric >= 0 ? comb_segmenter( pv ) : pv->mode == 4 ? 2 : 1;
1142 if( is_combed == 1 )
1144 pv->yadif_deinterlaced_frames++;
1146 else if( is_combed == 2 )
1148 pv->blend_deinterlaced_frames++;
1152 pv->unfiltered_frames++;
1155 if( is_combed == 1 && pv->mode == 5 )
1157 /* Generate an EEDI2 interpolation */
1165 for( segment = 0; segment < pv->cpu_count; segment++ )
1168 * Setup the work for this plane.
1170 pv->yadif_arguments[segment].parity = parity;
1171 pv->yadif_arguments[segment].tff = tff;
1172 pv->yadif_arguments[segment].dst = dst;
1173 pv->yadif_arguments[segment].is_combed = is_combed;
1176 * Let the thread for this plane know that we've setup work
1177 * for it by releasing the begin lock (ensuring that the
1178 * complete lock is already locked so that we block when
1179 * we try to lock it again below).
1181 hb_lock( pv->yadif_complete_lock[segment] );
1182 hb_unlock( pv->yadif_begin_lock[segment] );
1186 * Wait until all three threads have completed by trying to get
1187 * the complete lock that we locked earlier for each thread, which
1188 * will block until that thread has completed the work on that
1191 for( segment = 0; segment < pv->cpu_count; segment++ )
1193 hb_lock( pv->yadif_complete_lock[segment] );
1194 hb_unlock( pv->yadif_complete_lock[segment] );
1198 * Entire frame is now deinterlaced.
1203 /* Just passing through... */
1205 for( i = 0; i < 3; i++ )
1207 uint8_t * ref = pv->ref[1][i];
1208 uint8_t * dest = dst[i];
1210 int w = pv->width[i];
1211 int ref_stride = pv->ref_stride[i];
1214 for( y = 0; y < pv->height[i]; y++ )
1216 memcpy(dest, ref, w);
1224 static void mcdeint_filter( uint8_t ** dst,
1227 hb_filter_private_t * pv )
1232 #ifdef SUPPRESS_AV_LOG
1233 /* TODO: temporarily change log level to suppress obnoxious debug output */
1234 int loglevel = av_log_get_level();
1235 av_log_set_level( AV_LOG_QUIET );
1238 for( i=0; i<3; i++ )
1240 pv->mcdeint_frame->data[i] = src[i];
1241 pv->mcdeint_frame->linesize[i] = pv->width[i];
1243 pv->mcdeint_avctx_enc->me_cmp = FF_CMP_SAD;
1244 pv->mcdeint_avctx_enc->me_sub_cmp = FF_CMP_SAD;
1245 pv->mcdeint_frame->quality = pv->mcdeint_qp * FF_QP2LAMBDA;
1247 out_size = avcodec_encode_video( pv->mcdeint_avctx_enc,
1249 pv->mcdeint_outbuf_size,
1250 pv->mcdeint_frame );
1252 pv->mcdeint_frame_dec = pv->mcdeint_avctx_enc->coded_frame;
1254 for( i = 0; i < 3; i++ )
1256 int w = pv->width[i];
1257 int h = pv->height[i];
1258 int fils = pv->mcdeint_frame_dec->linesize[i];
1259 int srcs = pv->width[i];
1261 for( y = 0; y < h; y++ )
1263 if( (y ^ parity) & 1 )
1265 for( x = 0; x < w; x++ )
1267 if( (x-2)+(y-1)*w >= 0 && (x+2)+(y+1)*w < w*h )
1270 &pv->mcdeint_frame_dec->data[i][x + y*fils];
1271 uint8_t * srcp = &src[i][x + y*srcs];
1273 int diff0 = filp[-fils] - srcp[-srcs];
1274 int diff1 = filp[+fils] - srcp[+srcs];
1277 ABS(srcp[-srcs-1] - srcp[+srcs-1])
1278 + ABS(srcp[-srcs ] - srcp[+srcs ])
1279 + ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
1283 #define MCDEINT_CHECK(j)\
1284 { int score = ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
1285 + ABS(srcp[-srcs +j] - srcp[+srcs -j])\
1286 + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
1287 if( score < spatial_score ) {\
1288 spatial_score = score;\
1289 diff0 = filp[-fils+j] - srcp[-srcs+j];\
1290 diff1 = filp[+fils-j] - srcp[+srcs-j];
1292 MCDEINT_CHECK(-1) MCDEINT_CHECK(-2) }} }}
1293 MCDEINT_CHECK( 1) MCDEINT_CHECK( 2) }} }}
1295 if(diff0 + diff1 > 0)
1297 temp -= (diff0 + diff1 -
1298 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1302 temp -= (diff0 + diff1 +
1303 ABS( ABS(diff0) - ABS(diff1) ) / 2) / 2;
1306 filp[0] = dst[i][x + y*w] =
1307 temp > 255U ? ~(temp>>31) : temp;
1312 pv->mcdeint_frame_dec->data[i][x + y*fils];
1318 for( y = 0; y < h; y++ )
1320 if( !((y ^ parity) & 1) )
1322 for( x = 0; x < w; x++ )
1324 pv->mcdeint_frame_dec->data[i][x + y*fils] =
1325 dst[i][x + y*w]= src[i][x + y*srcs];
1331 #ifdef SUPPRESS_AV_LOG
1332 /* TODO: restore previous log level */
1333 av_log_set_level(loglevel);
1337 hb_filter_private_t * hb_decomb_init( int pix_fmt,
1342 if( pix_fmt != PIX_FMT_YUV420P )
1347 hb_filter_private_t * pv = calloc( 1, sizeof(struct hb_filter_private_s) );
1349 pv->pix_fmt = pix_fmt;
1351 pv->width[0] = width;
1352 pv->height[0] = height;
1353 pv->width[1] = pv->width[2] = width >> 1;
1354 pv->height[1] = pv->height[2] = height >> 1;
1356 pv->buf_out[0] = hb_video_buffer_init( width, height );
1357 pv->buf_out[1] = hb_video_buffer_init( width, height );
1358 pv->buf_settings = hb_buffer_init( 0 );
1360 pv->yadif_deinterlaced_frames = 0;
1361 pv->blend_deinterlaced_frames = 0;
1362 pv->unfiltered_frames = 0;
1364 pv->yadif_ready = 0;
1366 pv->mode = MODE_DEFAULT;
1367 pv->spatial_metric = 2;
1368 pv->motion_threshold = 6;
1369 pv->spatial_threshold = 9;
1370 pv->block_threshold = 80;
1371 pv->block_width = 16;
1372 pv->block_height = 16;
1374 pv->magnitude_threshold = 10;
1375 pv->variance_threshold = 20;
1376 pv->laplacian_threshold = 20;
1377 pv->dilation_threshold = 4;
1378 pv->erosion_threshold = 2;
1379 pv->noise_threshold = 50;
1380 pv->maximum_search_distance = 24;
1381 pv->post_processing = 1;
1383 pv->parity = PARITY_DEFAULT;
1385 pv->mcdeint_mode = MCDEINT_MODE_DEFAULT;
1386 pv->mcdeint_qp = MCDEINT_QP_DEFAULT;
1390 sscanf( settings, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
1392 &pv->spatial_metric,
1393 &pv->motion_threshold,
1394 &pv->spatial_threshold,
1395 &pv->block_threshold,
1398 &pv->magnitude_threshold,
1399 &pv->variance_threshold,
1400 &pv->laplacian_threshold,
1401 &pv->dilation_threshold,
1402 &pv->erosion_threshold,
1403 &pv->noise_threshold,
1404 &pv->maximum_search_distance,
1405 &pv->post_processing );
1408 pv->cpu_count = hb_get_cpu_count();
1411 if( pv->mode == 2 || pv->mode == 3 )
1413 pv->mcdeint_mode = 0;
1416 /* Allocate yadif specific buffers */
1418 for( i = 0; i < 3; i++ )
1420 int is_chroma = !!i;
1421 int w = ((width + 31) & (~31))>>is_chroma;
1422 int h = ((height+6+ 31) & (~31))>>is_chroma;
1424 pv->ref_stride[i] = w;
1426 for( j = 0; j < 3; j++ )
1428 pv->ref[j][i] = malloc( w*h*sizeof(uint8_t) ) + 3*w;
1432 /* Allocate a buffer to store a comb mask. */
1433 for( i = 0; i < 3; i++ )
1435 int is_chroma = !!i;
1436 int w = ((pv->width[0] + 31) & (~31))>>is_chroma;
1437 int h = ((pv->height[0]+6+ 31) & (~31))>>is_chroma;
1439 pv->mask[i] = calloc( 1, w*h*sizeof(uint8_t) ) + 3*w;
1444 /* Allocate half-height eedi2 buffers */
1445 height = pv->height[0] / 2;
1446 for( i = 0; i < 3; i++ )
1448 int is_chroma = !!i;
1449 int w = ((width + 31) & (~31))>>is_chroma;
1450 int h = ((height+6+ 31) & (~31))>>is_chroma;
1452 for( j = 0; j < 4; j++ )
1454 pv->eedi_half[j][i] = malloc( w*h*sizeof(uint8_t) ) + 3*w;
1458 /* Allocate full-height eedi2 buffers */
1459 height = pv->height[0];
1460 for( i = 0; i < 3; i++ )
1462 int is_chroma = !!i;
1463 int w = ((width + 31) & (~31))>>is_chroma;
1464 int h = ((height+6+ 31) & (~31))>>is_chroma;
1466 for( j = 0; j < 5; j++ )
1468 pv->eedi_full[j][i] = malloc( w*h*sizeof(uint8_t) ) + 3*w;
1474 * Create yadif threads and locks.
1476 pv->yadif_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1477 pv->yadif_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1478 pv->yadif_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1479 pv->yadif_arguments = malloc( sizeof( yadif_arguments_t ) * pv->cpu_count );
1481 for( i = 0; i < pv->cpu_count; i++ )
1483 yadif_thread_arg_t *thread_args;
1485 thread_args = malloc( sizeof( yadif_thread_arg_t ) );
1489 thread_args->pv = pv;
1490 thread_args->segment = i;
1492 pv->yadif_begin_lock[i] = hb_lock_init();
1493 pv->yadif_complete_lock[i] = hb_lock_init();
1496 * Important to start off with the threads locked waiting
1499 hb_lock( pv->yadif_begin_lock[i] );
1501 pv->yadif_arguments[i].stop = 0;
1502 pv->yadif_arguments[i].dst = NULL;
1504 pv->yadif_threads[i] = hb_thread_init( "yadif_filter_segment",
1505 yadif_decomb_filter_thread,
1507 HB_NORMAL_PRIORITY );
1511 hb_error( "yadif could not create threads" );
1516 * Create decomb threads and locks.
1518 pv->decomb_threads = malloc( sizeof( hb_thread_t* ) * pv->cpu_count );
1519 pv->decomb_begin_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1520 pv->decomb_complete_lock = malloc( sizeof( hb_lock_t * ) * pv->cpu_count );
1521 pv->decomb_arguments = malloc( sizeof( decomb_arguments_t ) * pv->cpu_count );
1523 for( i = 0; i < pv->cpu_count; i++ )
1525 decomb_thread_arg_t *decomb_thread_args;
1527 decomb_thread_args = malloc( sizeof( decomb_thread_arg_t ) );
1529 if( decomb_thread_args )
1531 decomb_thread_args->pv = pv;
1532 decomb_thread_args->segment = i;
1534 pv->decomb_begin_lock[i] = hb_lock_init();
1535 pv->decomb_complete_lock[i] = hb_lock_init();
1538 * Important to start off with the threads locked waiting
1541 hb_lock( pv->decomb_begin_lock[i] );
1543 pv->decomb_arguments[i].stop = 0;
1545 pv->decomb_threads[i] = hb_thread_init( "decomb_filter_segment",
1546 decomb_filter_thread,
1548 HB_NORMAL_PRIORITY );
1552 hb_error( "decomb could not create threads" );
1559 * Create eedi2 threads and locks.
1561 pv->eedi2_threads = malloc( sizeof( hb_thread_t* ) * 3 );
1562 pv->eedi2_begin_lock = malloc( sizeof( hb_lock_t * ) * 3 );
1563 pv->eedi2_complete_lock = malloc( sizeof( hb_lock_t * ) * 3 );
1564 pv->eedi2_arguments = malloc( sizeof( eedi2_arguments_t ) * 3 );
1566 if( pv->post_processing > 1 )
1568 pv->cx2 = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1569 pv->cy2 = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1570 pv->cxy = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1571 pv->tmpc = (int*)eedi2_aligned_malloc(pv->height[0]*pv->ref_stride[0]*sizeof(int), 16);
1572 if( !pv->cx2 || !pv->cy2 || !pv->cxy || !pv->tmpc )
1573 hb_log("EEDI2: failed to malloc derivative arrays");
1575 hb_log("EEDI2: successfully mallloced derivative arrays");
1578 for( i = 0; i < 3; i++ )
1580 eedi2_thread_arg_t *eedi2_thread_args;
1582 eedi2_thread_args = malloc( sizeof( eedi2_thread_arg_t ) );
1584 if( eedi2_thread_args )
1586 eedi2_thread_args->pv = pv;
1587 eedi2_thread_args->plane = i;
1589 pv->eedi2_begin_lock[i] = hb_lock_init();
1590 pv->eedi2_complete_lock[i] = hb_lock_init();
1593 * Important to start off with the threads locked waiting
1596 hb_lock( pv->eedi2_begin_lock[i] );
1598 pv->eedi2_arguments[i].stop = 0;
1600 pv->eedi2_threads[i] = hb_thread_init( "eedi2_filter_segment",
1601 eedi2_filter_thread,
1603 HB_NORMAL_PRIORITY );
1607 hb_error( "eedi2 could not create threads" );
1613 /* Allocate mcdeint specific buffers */
1614 if( pv->mcdeint_mode >= 0 )
1617 avcodec_register_all();
1619 AVCodec * enc = avcodec_find_encoder( CODEC_ID_SNOW );
1622 for (i = 0; i < 3; i++ )
1624 AVCodecContext * avctx_enc;
1626 avctx_enc = pv->mcdeint_avctx_enc = avcodec_alloc_context();
1628 avctx_enc->width = width;
1629 avctx_enc->height = height;
1630 avctx_enc->time_base = (AVRational){1,25}; // meaningless
1631 avctx_enc->gop_size = 300;
1632 avctx_enc->max_b_frames = 0;
1633 avctx_enc->pix_fmt = PIX_FMT_YUV420P;
1634 avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
1635 avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
1636 avctx_enc->global_quality = 1;
1637 avctx_enc->flags2 = CODEC_FLAG2_MEMC_ONLY;
1638 avctx_enc->me_cmp = FF_CMP_SAD; //SSE;
1639 avctx_enc->me_sub_cmp = FF_CMP_SAD; //SSE;
1640 avctx_enc->mb_cmp = FF_CMP_SSE;
1642 switch( pv->mcdeint_mode )
1645 avctx_enc->refs = 3;
1647 avctx_enc->me_method = ME_UMH;
1649 avctx_enc->flags |= CODEC_FLAG_4MV;
1650 avctx_enc->dia_size =2;
1652 avctx_enc->flags |= CODEC_FLAG_QPEL;
1655 hb_avcodec_open(avctx_enc, enc);
1658 pv->mcdeint_frame = avcodec_alloc_frame();
1659 pv->mcdeint_outbuf_size = width * height * 10;
1660 pv->mcdeint_outbuf = malloc( pv->mcdeint_outbuf_size );
1666 void hb_decomb_close( hb_filter_private_t * pv )
1673 hb_log("decomb: %s deinterlaced %i | blend deinterlaced %i | unfiltered %i | total %i", pv->mode == 5 ? "yadif+eedi2" : "yadif", pv->yadif_deinterlaced_frames, pv->blend_deinterlaced_frames, pv->unfiltered_frames, pv->yadif_deinterlaced_frames + pv->blend_deinterlaced_frames + pv->unfiltered_frames);
1675 /* Cleanup frame buffers */
1676 if( pv->buf_out[0] )
1678 hb_buffer_close( &pv->buf_out[0] );
1680 if( pv->buf_out[1] )
1682 hb_buffer_close( &pv->buf_out[1] );
1684 if (pv->buf_settings )
1686 hb_buffer_close( &pv->buf_settings );
1689 /* Cleanup yadif specific buffers */
1691 for( i = 0; i<3*3; i++ )
1693 uint8_t **p = &pv->ref[i%3][i/3];
1696 free( *p - 3*pv->ref_stride[i/3] );
1701 /* Cleanup combing mask. */
1702 for( i = 0; i<3*3; i++ )
1704 uint8_t **p = &pv->mask[i/3];
1707 free( *p - 3*pv->ref_stride[i/3] );
1714 /* Cleanup eedi-half buffers */
1716 for( i = 0; i<3; i++ )
1718 for( j = 0; j < 4; j++ )
1720 uint8_t **p = &pv->eedi_half[j][i];
1723 free( *p - 3*pv->ref_stride[i] );
1729 /* Cleanup eedi-full buffers */
1730 for( i = 0; i<3; i++ )
1732 for( j = 0; j < 5; j++ )
1734 uint8_t **p = &pv->eedi_full[j][i];
1737 free( *p - 3*pv->ref_stride[i] );
1744 if( pv->post_processing > 1 && pv->mode == 5 )
1746 if (pv->cx2) eedi2_aligned_free(pv->cx2);
1747 if (pv->cy2) eedi2_aligned_free(pv->cy2);
1748 if (pv->cxy) eedi2_aligned_free(pv->cxy);
1749 if (pv->tmpc) eedi2_aligned_free(pv->tmpc);
1752 for( i = 0; i < pv->cpu_count; i++)
1755 * Tell each yadif thread to stop, and then cleanup.
1757 pv->yadif_arguments[i].stop = 1;
1758 hb_unlock( pv->yadif_begin_lock[i] );
1760 hb_thread_close( &pv->yadif_threads[i] );
1761 hb_lock_close( &pv->yadif_begin_lock[i] );
1762 hb_lock_close( &pv->yadif_complete_lock[i] );
1766 * free memory for yadif structs
1768 free( pv->yadif_threads );
1769 free( pv->yadif_begin_lock );
1770 free( pv->yadif_complete_lock );
1771 free( pv->yadif_arguments );
1773 for( i = 0; i < pv->cpu_count; i++)
1776 * Tell each decomb thread to stop, and then cleanup.
1778 pv->decomb_arguments[i].stop = 1;
1779 hb_unlock( pv->decomb_begin_lock[i] );
1781 hb_thread_close( &pv->decomb_threads[i] );
1782 hb_lock_close( &pv->decomb_begin_lock[i] );
1783 hb_lock_close( &pv->decomb_complete_lock[i] );
1787 * free memory for decomb structs
1789 free( pv->decomb_threads );
1790 free( pv->decomb_begin_lock );
1791 free( pv->decomb_complete_lock );
1792 free( pv->decomb_arguments );
1796 for( i = 0; i < 3; i++)
1799 * Tell each eedi2 thread to stop, and then cleanup.
1801 pv->eedi2_arguments[i].stop = 1;
1802 hb_unlock( pv->eedi2_begin_lock[i] );
1804 hb_thread_close( &pv->eedi2_threads[i] );
1805 hb_lock_close( &pv->eedi2_begin_lock[i] );
1806 hb_lock_close( &pv->eedi2_complete_lock[i] );
1810 * free memory for eedi2 structs
1812 free( pv->eedi2_threads );
1813 free( pv->eedi2_begin_lock );
1814 free( pv->eedi2_complete_lock );
1815 free( pv->eedi2_arguments );
1818 /* Cleanup mcdeint specific buffers */
1819 if( pv->mcdeint_mode >= 0 )
1821 if( pv->mcdeint_avctx_enc )
1823 hb_avcodec_close( pv->mcdeint_avctx_enc );
1824 av_freep( &pv->mcdeint_avctx_enc );
1826 if( pv->mcdeint_outbuf )
1828 free( pv->mcdeint_outbuf );
1835 int hb_decomb_work( const hb_buffer_t * cbuf_in,
1836 hb_buffer_t ** buf_out,
1840 hb_filter_private_t * pv )
1842 hb_buffer_t * buf_in = (hb_buffer_t *)cbuf_in;
1845 pix_fmt != pv->pix_fmt ||
1846 width != pv->width[0] ||
1847 height != pv->height[0] )
1849 return FILTER_FAILED;
1852 avpicture_fill( &pv->pic_in, buf_in->data,
1853 pix_fmt, width, height );
1855 /* Determine if top-field first layout */
1857 if( pv->parity < 0 )
1859 tff = !!(buf_in->flags & PIC_FLAG_TOP_FIELD_FIRST);
1863 tff = (pv->parity & 1) ^ 1;
1868 /* Store current frame in yadif cache */
1869 store_ref( (const uint8_t**)pv->pic_in.data, pv );
1871 /* If yadif is not ready, store another ref and return FILTER_DELAY */
1872 if( pv->yadif_ready == 0 )
1874 store_ref( (const uint8_t**)pv->pic_in.data, pv );
1876 hb_buffer_copy_settings( pv->buf_settings, buf_in );
1878 /* don't let 'work_loop' send a chapter mark upstream */
1879 buf_in->new_chap = 0;
1881 pv->yadif_ready = 1;
1883 return FILTER_DELAY;
1886 /* Perform yadif filtering */
1888 for( frame = 0; frame <= ( ( pv->mode == 2 || pv->mode == 3 )? 1 : 0 ) ; frame++ )
1890 int parity = frame ^ tff ^ 1;
1892 avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,
1893 pix_fmt, width, height );
1895 yadif_filter( pv->pic_out.data, parity, tff, pv );
1897 if( pv->mcdeint_mode >= 0 )
1899 /* Perform mcdeint filtering */
1900 avpicture_fill( &pv->pic_in, pv->buf_out[(frame^1)]->data,
1901 pix_fmt, width, height );
1903 mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );
1906 *buf_out = pv->buf_out[!(frame^1)];
1909 /* Copy buffered settings to output buffer settings */
1910 hb_buffer_copy_settings( *buf_out, pv->buf_settings );
1912 /* Replace buffered settings with input buffer settings */
1913 hb_buffer_copy_settings( pv->buf_settings, buf_in );
1915 /* don't let 'work_loop' send a chapter mark upstream */
1916 buf_in->new_chap = 0;