2 Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 // yadif_mode is a bit vector with the following flags
24 #define MODE_YADIF_ENABLE 1
25 #define MODE_YADIF_SPATIAL 2
26 #define MODE_YADIF_2PASS 4
27 #define MODE_YADIF_BOB 8
29 #define YADIF_MODE_DEFAULT 0
30 #define YADIF_PARITY_DEFAULT -1
32 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
33 #define MIN3(a,b,c) MIN(MIN(a,b),c)
34 #define MAX3(a,b,c) MAX(MAX(a,b),c)
36 typedef struct yadif_arguments_s
{
42 typedef struct deint_arguments_s
{
47 typedef struct deint_thread_arg_s
{
48 hb_filter_private_t
*pv
;
52 struct hb_filter_private_s
61 hb_buffer_t
* yadif_ref
[3];
68 taskset_t deint_taskset
; // Threads for fast deint
69 taskset_t yadif_taskset
; // Threads for Yadif
71 deint_arguments_t
*deint_arguments
; // Arguments to thread for work
72 yadif_arguments_t
*yadif_arguments
; // Arguments to thread for work
75 static int hb_deinterlace_init( hb_filter_object_t
* filter
,
76 hb_filter_init_t
* init
);
78 static int hb_deinterlace_work( hb_filter_object_t
* filter
,
79 hb_buffer_t
** buf_in
,
80 hb_buffer_t
** buf_out
);
82 static void hb_deinterlace_close( hb_filter_object_t
* filter
);
84 hb_filter_object_t hb_filter_deinterlace
=
86 .id
= HB_FILTER_DEINTERLACE
,
88 .name
= "Deinterlace",
90 .init
= hb_deinterlace_init
,
91 .work
= hb_deinterlace_work
,
92 .close
= hb_deinterlace_close
,
96 static void yadif_store_ref(hb_filter_private_t
*pv
, hb_buffer_t
*b
)
99 hb_buffer_close(&pv
->yadif_ref
[0]);
100 memmove(&pv
->yadif_ref
[0], &pv
->yadif_ref
[1], sizeof(hb_buffer_t
*) * 2 );
101 pv
->yadif_ref
[2] = b
;
104 static void yadif_filter_line(
105 hb_filter_private_t
* pv
,
114 uint8_t *prev2
= parity
? prev
: cur
;
115 uint8_t *next2
= parity
? cur
: next
;
118 for( x
= 0; x
< width
; x
++)
120 int c
= cur
[-stride
];
121 int d
= (prev2
[0] + next2
[0])>>1;
122 int e
= cur
[+stride
];
123 int temporal_diff0
= ABS(prev2
[0] - next2
[0]);
124 int temporal_diff1
= ( ABS(prev
[-stride
] - c
) + ABS(prev
[+stride
] - e
) ) >> 1;
125 int temporal_diff2
= ( ABS(next
[-stride
] - c
) + ABS(next
[+stride
] - e
) ) >> 1;
126 int diff
= MAX3(temporal_diff0
>>1, temporal_diff1
, temporal_diff2
);
127 int spatial_pred
= (c
+e
)>>1;
128 int spatial_score
= ABS(cur
[-stride
-1] - cur
[+stride
-1]) + ABS(c
-e
) +
129 ABS(cur
[-stride
+1] - cur
[+stride
+1]) - 1;
131 #define YADIF_CHECK(j)\
132 { int score = ABS(cur[-stride-1+j] - cur[+stride-1-j])\
133 + ABS(cur[-stride +j] - cur[+stride -j])\
134 + ABS(cur[-stride+1+j] - cur[+stride+1-j]);\
135 if( score < spatial_score ){\
136 spatial_score = score;\
137 spatial_pred = (cur[-stride +j] + cur[+stride -j])>>1;\
139 YADIF_CHECK(-1) YADIF_CHECK(-2) }} }}
140 YADIF_CHECK( 1) YADIF_CHECK( 2) }} }}
142 if( pv
->yadif_mode
& MODE_YADIF_SPATIAL
)
144 int b
= (prev2
[-2*stride
] + next2
[-2*stride
])>>1;
145 int f
= (prev2
[+2*stride
] + next2
[+2*stride
])>>1;
147 int max
= MAX3(d
-e
, d
-c
, MIN(b
-c
, f
-e
));
148 int min
= MIN3(d
-e
, d
-c
, MAX(b
-c
, f
-e
));
150 diff
= MAX3( diff
, min
, -max
);
153 if( spatial_pred
> d
+ diff
)
155 spatial_pred
= d
+ diff
;
157 else if( spatial_pred
< d
- diff
)
159 spatial_pred
= d
- diff
;
162 dst
[0] = spatial_pred
;
173 typedef struct yadif_thread_arg_s
{
174 hb_filter_private_t
*pv
;
176 } yadif_thread_arg_t
;
179 * deinterlace this segment of all three planes in a single thread.
181 void yadif_filter_thread( void *thread_args_v
)
183 yadif_arguments_t
*yadif_work
= NULL
;
184 hb_filter_private_t
* pv
;
186 int segment
, segment_start
, segment_stop
;
187 yadif_thread_arg_t
*thread_args
= thread_args_v
;
189 pv
= thread_args
->pv
;
190 segment
= thread_args
->segment
;
192 hb_log("Yadif Deinterlace thread started for segment %d", segment
);
197 * Wait here until there is work to do.
199 taskset_thread_wait4start( &pv
->yadif_taskset
, segment
);
202 if( taskset_thread_stop( &pv
->yadif_taskset
, segment
) )
205 * No more work to do, exit this thread.
208 goto report_completion
;
211 yadif_work
= &pv
->yadif_arguments
[segment
];
213 if( yadif_work
->dst
== NULL
)
215 hb_error( "Thread started when no work available" );
216 goto report_completion
;
220 * Process all three planes, but only this segment of it.
223 for(pp
= 0; pp
< 3; pp
++)
225 hb_buffer_t
*dst
= yadif_work
->dst
;
226 int w
= dst
->plane
[pp
].width
;
227 int s
= dst
->plane
[pp
].stride
;
228 int h
= dst
->plane
[pp
].height
;
230 int parity
= yadif_work
->parity
;
231 int tff
= yadif_work
->tff
;
232 int penultimate
= h
- 2;
234 int segment_height
= (h
/ pv
->segments
) & ~1;
235 segment_start
= segment_height
* segment
;
236 if( segment
== pv
->segments
- 1 )
243 segment_stop
= segment_height
* ( segment
+ 1 );
246 uint8_t *dst2
= &dst
->plane
[pp
].data
[segment_start
* s
];
247 uint8_t *prev
= &pv
->yadif_ref
[0]->plane
[pp
].data
[segment_start
* s
];
248 uint8_t *cur
= &pv
->yadif_ref
[1]->plane
[pp
].data
[segment_start
* s
];
249 uint8_t *next
= &pv
->yadif_ref
[2]->plane
[pp
].data
[segment_start
* s
];
250 for( yy
= segment_start
; yy
< segment_stop
; yy
++ )
252 if(((yy
^ parity
) & 1))
254 /* This is the bottom field when TFF and vice-versa.
255 It's the field that gets filtered. Because yadif
256 needs 2 lines above and below the one being filtered,
257 we need to mirror the edges. When TFF, this means
258 replacing the 2nd line with a copy of the 1st,
259 and the last with the second-to-last. */
260 if( yy
> 1 && yy
< penultimate
)
262 /* This isn't the top or bottom,
263 * proceed as normal to yadif. */
264 yadif_filter_line(pv
, dst2
, prev
, cur
, next
, w
, s
,
269 // parity == 0 (TFF), y1 = y0
270 // parity == 1 (BFF), y0 = y1
271 // parity == 0 (TFF), yu = yp
272 // parity == 1 (BFF), yp = yu
273 uint8_t *src
= &pv
->yadif_ref
[1]->plane
[pp
].data
[(yy
^parity
)*s
];
274 memcpy(dst2
, src
, w
);
279 /* Preserve this field unfiltered */
280 memcpy(dst2
, cur
, w
);
291 * Finished this segment, let everyone know.
293 taskset_thread_complete( &pv
->yadif_taskset
, segment
);
299 * threaded yadif - each thread deinterlaces a single segment of all
300 * three planes. Where a segment is defined as the frame divided by
301 * the number of CPUs.
303 * This function blocks until the frame is deinterlaced.
305 static void yadif_filter( hb_filter_private_t
* pv
,
306 hb_buffer_t
* dst
, int parity
, int tff
)
311 for( segment
= 0; segment
< pv
->segments
; segment
++ )
314 * Setup the work for this plane.
316 pv
->yadif_arguments
[segment
].parity
= parity
;
317 pv
->yadif_arguments
[segment
].tff
= tff
;
318 pv
->yadif_arguments
[segment
].dst
= dst
;
321 /* Allow the taskset threads to make one pass over the data. */
322 taskset_cycle( &pv
->yadif_taskset
);
325 * Entire frame is now deinterlaced.
330 * deinterlace a frame in a single thread.
332 void deint_filter_thread( void *thread_args_v
)
334 deint_arguments_t
*args
= NULL
;
335 hb_filter_private_t
* pv
;
338 deint_thread_arg_t
*thread_args
= thread_args_v
;
340 pv
= thread_args
->pv
;
341 segment
= thread_args
->segment
;
343 hb_log("Fast Deinterlace thread started for segment %d", segment
);
348 * Wait here until there is work to do.
350 taskset_thread_wait4start( &pv
->deint_taskset
, segment
);
353 if( taskset_thread_stop( &pv
->deint_taskset
, segment
) )
356 * No more work to do, exit this thread.
359 goto report_completion
;
362 args
= &pv
->deint_arguments
[segment
];
364 if( args
->dst
== NULL
)
366 // This can happen when flushing final buffers.
367 goto report_completion
;
371 * Process all three planes, but only this segment of it.
373 hb_deinterlace(args
->dst
, args
->src
);
377 * Finished this segment, let everyone know.
379 taskset_thread_complete( &pv
->deint_taskset
, segment
);
384 * threaded fast deint - each thread deinterlaces a single frame.
386 * This function blocks until all frames are deinterlaced.
388 static hb_buffer_t
* deint_fast(hb_filter_private_t
* pv
, hb_buffer_t
* in
)
392 hb_buffer_t
*dst
, *src
;
396 dst
= hb_frame_buffer_init(in
->f
.fmt
, in
->f
.width
, in
->f
.height
);
397 pv
->deint_arguments
[pv
->deint_nsegs
].src
= in
;
398 pv
->deint_arguments
[pv
->deint_nsegs
].dst
= dst
;
401 if (in
!= NULL
&& pv
->deint_nsegs
< pv
->segments
)
406 if (pv
->deint_nsegs
> 0)
408 /* Allow the taskset threads to make one pass over the data. */
409 taskset_cycle( &pv
->deint_taskset
);
412 hb_buffer_t
*first
= NULL
, *last
= NULL
;
413 for (ii
= 0; ii
< pv
->deint_nsegs
; ii
++)
415 src
= pv
->deint_arguments
[ii
].src
;
416 dst
= pv
->deint_arguments
[ii
].dst
;
417 pv
->deint_arguments
[ii
].src
= NULL
;
418 pv
->deint_arguments
[ii
].dst
= NULL
;
430 hb_buffer_move_subs(dst
, src
);
431 hb_buffer_close(&src
);
435 // Flushing final buffers. Append EOS marker buffer.
436 dst
= hb_buffer_eof_init();
451 static int hb_deinterlace_init( hb_filter_object_t
* filter
,
452 hb_filter_init_t
* init
)
454 filter
->private_data
= calloc( 1, sizeof(struct hb_filter_private_s
) );
455 hb_filter_private_t
* pv
= filter
->private_data
;
457 pv
->width
= init
->geometry
.width
;
458 pv
->height
= init
->geometry
.height
;
461 pv
->yadif_mode
= YADIF_MODE_DEFAULT
;
462 pv
->yadif_parity
= YADIF_PARITY_DEFAULT
;
464 if( filter
->settings
)
466 sscanf( filter
->settings
, "%d:%d",
471 pv
->cpu_count
= hb_get_cpu_count();
473 /* Allocate yadif specific buffers */
474 if( pv
->yadif_mode
& MODE_YADIF_ENABLE
)
477 * Setup yadif taskset.
479 pv
->segments
= pv
->cpu_count
;
480 pv
->yadif_arguments
= malloc( sizeof( yadif_arguments_t
) * pv
->segments
);
481 if( pv
->yadif_arguments
== NULL
||
482 taskset_init( &pv
->yadif_taskset
, /*thread_count*/pv
->segments
,
483 sizeof( yadif_thread_arg_t
) ) == 0 )
485 hb_error( "yadif could not initialize taskset" );
489 for( ii
= 0; ii
< pv
->segments
; ii
++ )
491 yadif_thread_arg_t
*thread_args
;
493 thread_args
= taskset_thread_args( &pv
->yadif_taskset
, ii
);
495 thread_args
->pv
= pv
;
496 thread_args
->segment
= ii
;
497 pv
->yadif_arguments
[ii
].dst
= NULL
;
499 if( taskset_thread_spawn( &pv
->yadif_taskset
, ii
,
500 "yadif_filter_segment",
502 HB_NORMAL_PRIORITY
) == 0 )
504 hb_error( "yadif could not spawn thread" );
511 * Setup fast deint taskset.
513 pv
->segments
= pv
->cpu_count
;
514 pv
->deint_arguments
= malloc( sizeof( deint_arguments_t
) * pv
->segments
);
515 if( pv
->deint_arguments
== NULL
||
516 taskset_init( &pv
->deint_taskset
, pv
->segments
,
517 sizeof( deint_thread_arg_t
) ) == 0 )
519 hb_error( "deint could not initialize taskset" );
523 for( ii
= 0; ii
< pv
->segments
; ii
++ )
525 deint_thread_arg_t
*thread_args
;
527 thread_args
= taskset_thread_args( &pv
->deint_taskset
, ii
);
529 thread_args
->pv
= pv
;
530 thread_args
->segment
= ii
;
531 pv
->deint_arguments
[ii
].dst
= NULL
;
533 if( taskset_thread_spawn( &pv
->deint_taskset
, ii
,
534 "deint_filter_segment",
536 HB_NORMAL_PRIORITY
) == 0 )
538 hb_error( "deint could not spawn thread" );
546 static void hb_deinterlace_close( hb_filter_object_t
* filter
)
548 hb_filter_private_t
* pv
= filter
->private_data
;
555 /* Cleanup yadif specific buffers */
556 if( pv
->yadif_mode
& MODE_YADIF_ENABLE
)
558 taskset_fini( &pv
->yadif_taskset
);
561 for(ii
= 0; ii
< 3; ii
++)
563 hb_buffer_close(&pv
->yadif_ref
[ii
]);
566 free( pv
->yadif_arguments
);
570 taskset_fini( &pv
->deint_taskset
);
571 free( pv
->deint_arguments
);
575 filter
->private_data
= NULL
;
578 static int hb_deinterlace_work( hb_filter_object_t
* filter
,
579 hb_buffer_t
** buf_in
,
580 hb_buffer_t
** buf_out
)
582 hb_filter_private_t
* pv
= filter
->private_data
;
583 hb_buffer_t
* in
= *buf_in
;
584 hb_buffer_t
* last
= NULL
, * out
= NULL
;
586 if (in
->s
.flags
& HB_BUF_FLAG_EOF
)
590 if( !( pv
->yadif_mode
& MODE_YADIF_ENABLE
) )
592 // Flush final frames
593 *buf_out
= deint_fast(pv
, NULL
);
595 return HB_FILTER_DONE
;
598 /* Use libavcodec deinterlace if yadif_mode < 0 */
599 if( !( pv
->yadif_mode
& MODE_YADIF_ENABLE
) )
602 *buf_out
= deint_fast(pv
, in
);
606 /* Store current frame in yadif cache */
608 yadif_store_ref(pv
, in
);
610 // yadif requires 3 buffers, prev, cur, and next. For the first
611 // frame, there can be no prev, so we duplicate the first frame.
612 if (!pv
->yadif_ready
)
614 // If yadif is not ready, store another ref and return HB_FILTER_DELAY
615 yadif_store_ref(pv
, hb_buffer_dup(in
));
618 return HB_FILTER_DELAY
;
621 /* Determine if top-field first layout */
623 if( pv
->yadif_parity
< 0 )
625 tff
= !!(in
->s
.flags
& PIC_FLAG_TOP_FIELD_FIRST
);
629 tff
= (pv
->yadif_parity
& 1) ^ 1;
632 /* deinterlace both fields if yadif 2 pass or bob */
633 int frame
, num_frames
= 1;
634 if ((pv
->yadif_mode
& MODE_YADIF_2PASS
) ||
635 (pv
->yadif_mode
& MODE_YADIF_BOB
))
640 // Will need up to 2 buffers simultaneously
642 hb_buffer_t
* o_buf
[2] = {NULL
,};
644 /* Perform yadif filtering */
645 for( frame
= 0; frame
< num_frames
; frame
++ )
647 int parity
= frame
^ tff
^ 1;
649 if (o_buf
[idx
] == NULL
)
651 o_buf
[idx
] = hb_frame_buffer_init(in
->f
.fmt
, in
->f
.width
, in
->f
.height
);
653 yadif_filter(pv
, o_buf
[idx
], parity
, tff
);
655 // If bob, add both frames
656 // else, add only final frame
657 if (( pv
->yadif_mode
& MODE_YADIF_BOB
) || frame
== num_frames
- 1)
661 last
= out
= o_buf
[idx
];
665 last
->next
= o_buf
[idx
];
670 // Indicate that buffer was consumed
673 /* Copy buffered settings to output buffer settings */
674 last
->s
= pv
->yadif_ref
[1]->s
;
679 // Copy subs only to first output buffer
680 hb_buffer_move_subs( out
, pv
->yadif_ref
[1] );
682 hb_buffer_close(&o_buf
[0]);
683 hb_buffer_close(&o_buf
[1]);
685 /* if bob mode is engaged, halve the duration of the
687 if (pv
->yadif_mode
& MODE_YADIF_BOB
)
689 out
->s
.stop
-= (out
->s
.stop
- out
->s
.start
) / 2LL;
690 last
->s
.start
= out
->s
.stop
;
691 last
->s
.new_chap
= 0;