3 Copyright (c) 2003-2015 HandBrake Team
4 This file is part of the HandBrake source code
5 Homepage: <http://handbrake.fr/>.
6 It may be used under the terms of the GNU General Public License v2.
7 For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
19 #define PULLUP_FMT_Y 1
20 #define PULLUP_HAVE_BREAKS 1
21 #define PULLUP_HAVE_AFFINITY 2
22 #define PULLUP_BREAK_LEFT 1
23 #define PULLUP_BREAK_RIGHT 2
25 #define PULLUP_ABS( a ) (((a)^((a)>>31))-((a)>>31))
27 #ifndef PIC_FLAG_REPEAT_FIRST_FIELD
28 #define PIC_FLAG_REPEAT_FIRST_FIELD 256
34 unsigned char **planes
;
41 struct pullup_buffer
*buffer
;
48 struct pullup_field
*prev
, *next
;
56 struct pullup_buffer
**ifields
, *ofields
[2];
57 struct pullup_buffer
*buffer
;
62 /* Public interface */
65 int *bpp
, *w
, *h
, *stride
, *background
;
67 int junk_left
, junk_right
, junk_top
, junk_bottom
;
74 struct pullup_field
*first
, *last
, *head
;
75 struct pullup_buffer
*buffers
;
77 int (*diff
)(unsigned char *, unsigned char *, int);
78 int (*comb
)(unsigned char *, unsigned char *, int);
79 int (*var
)(unsigned char *, unsigned char *, int);
80 int metric_w
, metric_h
, metric_len
, metric_offset
;
81 struct pullup_frame
*frame
;
86 * DETELECINE FILTER DEFINITIONS
90 struct hb_filter_private_s
92 struct pullup_context
* pullup_ctx
;
97 static int hb_detelecine_init( hb_filter_object_t
* filter
,
98 hb_filter_init_t
* init
);
100 static int hb_detelecine_work( hb_filter_object_t
* filter
,
101 hb_buffer_t
** buf_in
,
102 hb_buffer_t
** buf_out
);
104 static void hb_detelecine_close( hb_filter_object_t
* filter
);
106 hb_filter_object_t hb_filter_detelecine
=
108 .id
= HB_FILTER_DETELECINE
,
110 .name
= "Detelecine (pullup)",
112 .init
= hb_detelecine_init
,
113 .work
= hb_detelecine_work
,
114 .close
= hb_detelecine_close
,
119 * PULLUP STATIC FUNCTIONS
123 static int pullup_diff_y( unsigned char *a
, unsigned char * b
, int s
)
128 for( j
= 0; j
< 8; j
++ )
130 diff
+= PULLUP_ABS( a
[j
]-b
[j
] );
137 static int pullup_licomb_y( unsigned char * a
, unsigned char * b
, int s
)
142 for( j
= 0; j
< 8; j
++ )
144 diff
+= PULLUP_ABS( (a
[j
]<<1) - b
[j
-s
] - b
[j
] )
145 + PULLUP_ABS( (b
[j
]<<1) - a
[j
] - a
[j
+s
] );
152 static int pullup_var_y( unsigned char * a
, unsigned char * b
, int s
)
157 for( j
= 0; j
< 8; j
++ )
159 var
+= PULLUP_ABS( a
[j
]-a
[j
+s
] );
166 static void pullup_alloc_metrics( struct pullup_context
* c
,
167 struct pullup_field
* f
)
169 f
->diffs
= calloc( c
->metric_len
, sizeof(int) );
170 f
->comb
= calloc( c
->metric_len
, sizeof(int) );
171 f
->var
= calloc( c
->metric_len
, sizeof(int) );
174 static void pullup_compute_metric( struct pullup_context
* c
,
175 struct pullup_field
* fa
, int pa
,
176 struct pullup_field
* fb
, int pb
,
177 int (* func
)( unsigned char *,
178 unsigned char *, int),
181 unsigned char *a
, *b
;
183 int mp
= c
->metric_plane
;
184 int xstep
= c
->bpp
[mp
];
185 int ystep
= c
->stride
[mp
]<<3;
186 int s
= c
->stride
[mp
]<<1; /* field stride */
187 int w
= c
->metric_w
*xstep
;
189 if( !fa
->buffer
|| !fb
->buffer
) return;
191 /* Shortcut for duplicate fields (e.g. from RFF flag) */
192 if( fa
->buffer
== fb
->buffer
&& pa
== pb
)
194 memset( dest
, 0, c
->metric_len
* sizeof(int) );
198 a
= fa
->buffer
->planes
[mp
] + pa
* c
->stride
[mp
] + c
->metric_offset
;
199 b
= fb
->buffer
->planes
[mp
] + pb
* c
->stride
[mp
] + c
->metric_offset
;
201 for( y
= c
->metric_h
; y
; y
-- )
203 for( x
= 0; x
< w
; x
+= xstep
)
205 *dest
++ = func( a
+ x
, b
+ x
, s
);
207 a
+= ystep
; b
+= ystep
;
211 static struct pullup_field
* pullup_make_field_queue( struct pullup_context
* c
,
214 struct pullup_field
* head
, * f
;
215 f
= head
= calloc( 1, sizeof(struct pullup_field
) );
216 pullup_alloc_metrics( c
, f
);
217 for ( ; len
> 0; len
-- )
219 f
->next
= calloc( 1, sizeof(struct pullup_field
) );
222 pullup_alloc_metrics( c
, f
);
229 static void pullup_check_field_queue( struct pullup_context
* c
)
231 if( c
->head
->next
== c
->first
)
233 struct pullup_field
*f
= calloc( 1, sizeof(struct pullup_field
) );
234 pullup_alloc_metrics( c
, f
);
242 static void pullup_copy_field( struct pullup_context
* c
,
243 struct pullup_buffer
* dest
,
244 struct pullup_buffer
* src
,
248 unsigned char *d
, *s
;
249 for( i
= 0; i
< c
->nplanes
; i
++ )
251 s
= src
->planes
[i
] + parity
*c
->stride
[i
];
252 d
= dest
->planes
[i
] + parity
*c
->stride
[i
];
253 for( j
= c
->h
[i
]>>1; j
; j
-- )
255 memcpy( d
, s
, c
->stride
[i
] );
256 s
+= c
->stride
[i
]<<1;
257 d
+= c
->stride
[i
]<<1;
263 static int pullup_queue_length( struct pullup_field
* begin
,
264 struct pullup_field
* end
)
267 struct pullup_field
* f
;
269 if( !begin
|| !end
) return 0;
270 for( f
= begin
; f
!= end
; f
= f
->next
) count
++;
274 static int pullup_find_first_break( struct pullup_field
* f
, int max
)
277 for( i
= 0; i
< max
; i
++ )
279 if( f
->breaks
& PULLUP_BREAK_RIGHT
||
280 f
->next
->breaks
& PULLUP_BREAK_LEFT
)
289 static void pullup_compute_breaks( struct pullup_context
* c
,
290 struct pullup_field
* f0
)
293 struct pullup_field
*f1
= f0
->next
;
294 struct pullup_field
*f2
= f1
->next
;
295 struct pullup_field
*f3
= f2
->next
;
296 int l
, max_l
=0, max_r
=0;
298 if( f0
->flags
& PULLUP_HAVE_BREAKS
) return;
299 f0
->flags
|= PULLUP_HAVE_BREAKS
;
301 /* Special case when fields are 100% identical */
302 if( f0
->buffer
== f2
->buffer
&& f1
->buffer
!= f3
->buffer
)
304 f2
->breaks
|= PULLUP_BREAK_RIGHT
;
307 if( f0
->buffer
!= f2
->buffer
&& f1
->buffer
== f3
->buffer
)
309 f1
->breaks
|= PULLUP_BREAK_LEFT
;
313 for( i
= 0; i
< c
->metric_len
; i
++ )
315 l
= f2
->diffs
[i
] - f3
->diffs
[i
];
316 if( l
> max_l
) max_l
= l
;
317 if( -l
> max_r
) max_r
= -l
;
320 /* Don't get tripped up when differences are mostly quant error */
321 if( max_l
+ max_r
< 128 ) return;
322 if( max_l
> 4*max_r
) f1
->breaks
|= PULLUP_BREAK_LEFT
;
323 if( max_r
> 4*max_l
) f2
->breaks
|= PULLUP_BREAK_RIGHT
;
326 static void pullup_compute_affinity( struct pullup_context
* c
,
327 struct pullup_field
* f
)
330 int max_l
= 0, max_r
= 0, l
;
332 if( f
->flags
& PULLUP_HAVE_AFFINITY
)
336 f
->flags
|= PULLUP_HAVE_AFFINITY
;
338 if( f
->buffer
== f
->next
->next
->buffer
)
341 f
->next
->affinity
= 0;
342 f
->next
->next
->affinity
= -1;
344 f
->next
->flags
|= PULLUP_HAVE_AFFINITY
;
345 f
->next
->next
->flags
|= PULLUP_HAVE_AFFINITY
;
350 for( i
= 0; i
< c
->metric_len
; i
++ )
352 int lv
= f
->prev
->var
[i
];
353 int rv
= f
->next
->var
[i
];
355 int lc
= f
->comb
[i
] - (v
+lv
) + PULLUP_ABS( v
-lv
);
356 int rc
= f
->next
->comb
[i
] - (v
+rv
) + PULLUP_ABS( v
-rv
);
358 lc
= (lc
> 0) ? lc
: 0;
359 rc
= (rc
> 0) ? rc
: 0;
361 if( l
> max_l
) max_l
= l
;
362 if( -l
> max_r
) max_r
= -l
;
365 if( max_l
+ max_r
< 64 )
370 if( max_r
> 6*max_l
)
374 else if( max_l
> 6*max_r
)
380 static void pullup_foo( struct pullup_context
* c
)
382 struct pullup_field
* f
= c
->first
;
383 int i
, n
= pullup_queue_length (f
, c
->last
);
384 for( i
= 0; i
< n
-1; i
++ )
386 if( i
< n
-3 ) pullup_compute_breaks( c
, f
);
387 pullup_compute_affinity( c
, f
);
392 static int pullup_decide_frame_length( struct pullup_context
* c
)
394 struct pullup_field
*f0
= c
->first
;
395 struct pullup_field
*f1
= f0
->next
;
396 struct pullup_field
*f2
= f1
->next
;
399 if( pullup_queue_length( c
->first
, c
->last
) < 4 )
405 if( f0
->affinity
== -1 ) return 1;
407 l
= pullup_find_first_break( f0
, 3 );
408 if( l
== 1 && c
->strict_breaks
< 0 ) l
= 0;
413 if ( c
->strict_breaks
< 1 &&
425 /* FIXME: strictly speaking, f0->prev is no longer valid... :) */
426 if( c
->strict_pairs
&&
427 (f0
->prev
->breaks
& PULLUP_BREAK_RIGHT
) &&
428 (f2
->breaks
& PULLUP_BREAK_LEFT
) &&
429 (f0
->affinity
!= 1 || f1
->affinity
!= -1) )
433 if( f1
->affinity
== 1 )
443 if( f2
->affinity
== 1 )
453 /* 9 possibilities covered before switch */
454 if( f1
->affinity
== 1 )
456 return 1; /* covers 6 */
458 else if( f1
->affinity
== -1 )
460 return 2; /* covers 6 */
462 else if( f2
->affinity
== -1 )
465 if( f0
->affinity
== 1 )
476 return 2; /* the remaining 6 */
481 static void pullup_print_aff_and_breaks(struct pullup_context
* c
,
482 struct pullup_field
* f
)
485 struct pullup_field
* f0
= f
;
486 const char aff_l
[] = "+..", aff_r
[] = "..+";
487 hb_log( "affinity: " );
488 for( i
= 0; i
< 4; i
++ )
491 aff_l
[1+f
->affinity
],
493 aff_r
[1+f
->affinity
] );
498 printf("\nbreaks: ");
499 for( i
= 0; i
< 4; i
++ )
502 f
->breaks
& PULLUP_BREAK_LEFT
? '|' : '.',
504 f
->breaks
& PULLUP_BREAK_RIGHT
? '|' : '.' );
513 * PULLUP CONTEXT FUNCTIONS
517 struct pullup_context
* pullup_alloc_context( void )
519 struct pullup_context
* c
;
521 c
= calloc( 1, sizeof(struct pullup_context
)) ;
526 void pullup_preinit_context( struct pullup_context
* c
)
528 c
->bpp
= calloc( c
->nplanes
, sizeof(int) );
529 c
->w
= calloc( c
->nplanes
, sizeof(int) );
530 c
->h
= calloc( c
->nplanes
, sizeof(int) );
531 c
->stride
= calloc( c
->nplanes
, sizeof(int) );
532 c
->background
= calloc( c
->nplanes
, sizeof(int) );
535 void pullup_init_context( struct pullup_context
* c
)
537 int mp
= c
->metric_plane
;
538 if ( c
->nbuffers
< 10 )
542 c
->buffers
= calloc( c
->nbuffers
, sizeof (struct pullup_buffer
) );
544 c
->metric_w
= (c
->w
[mp
] - ((c
->junk_left
+ c
->junk_right
) << 3)) >> 3;
545 c
->metric_h
= (c
->h
[mp
] - ((c
->junk_top
+ c
->junk_bottom
) << 1)) >> 3;
546 c
->metric_offset
= c
->junk_left
*c
->bpp
[mp
] + (c
->junk_top
<<1)*c
->stride
[mp
];
547 c
->metric_len
= c
->metric_w
* c
->metric_h
;
549 c
->head
= pullup_make_field_queue( c
, 8 );
551 c
->frame
= calloc( 1, sizeof (struct pullup_frame
) );
552 c
->frame
->ifields
= calloc( 3, sizeof (struct pullup_buffer
*) );
554 if( c
->format
== PULLUP_FMT_Y
)
556 c
->diff
= pullup_diff_y
;
557 c
->comb
= pullup_licomb_y
;
558 c
->var
= pullup_var_y
;
562 void pullup_free_context( struct pullup_context
* c
)
564 struct pullup_field
* f
;
569 while( f
!= c
->head
)
586 * PULLUP BUFFER FUNCTIONS
590 static void pullup_alloc_buffer( struct pullup_context
* c
,
591 struct pullup_buffer
* b
)
594 if( b
->planes
) return;
595 b
->planes
= calloc( c
->nplanes
, sizeof(unsigned char *) );
596 b
->size
= calloc( c
->nplanes
, sizeof(int) );
597 for ( i
= 0; i
< c
->nplanes
; i
++ )
599 b
->size
[i
] = c
->h
[i
] * c
->stride
[i
];
600 b
->planes
[i
] = malloc(b
->size
[i
]);
601 /* Deal with idiotic 128=0 for chroma: */
602 memset( b
->planes
[i
], c
->background
[i
], b
->size
[i
] );
606 struct pullup_buffer
* pullup_lock_buffer( struct pullup_buffer
* b
,
610 if( (parity
+1) & 1 ) b
->lock
[0]++;
611 if( (parity
+1) & 2 ) b
->lock
[1]++;
616 void pullup_release_buffer( struct pullup_buffer
* b
,
620 if( (parity
+1) & 1 ) b
->lock
[0]--;
621 if( (parity
+1) & 2 ) b
->lock
[1]--;
624 struct pullup_buffer
* pullup_get_buffer( struct pullup_context
* c
,
629 /* Try first to get the sister buffer for the previous field */
632 parity
!= c
->last
->parity
&&
633 !c
->last
->buffer
->lock
[parity
])
635 pullup_alloc_buffer( c
, c
->last
->buffer
);
636 return pullup_lock_buffer( c
->last
->buffer
, parity
);
639 /* Prefer a buffer with both fields open */
640 for( i
= 0; i
< c
->nbuffers
; i
++ )
642 if( c
->buffers
[i
].lock
[0] ) continue;
643 if( c
->buffers
[i
].lock
[1] ) continue;
644 pullup_alloc_buffer( c
, &c
->buffers
[i
] );
645 return pullup_lock_buffer( &c
->buffers
[i
], parity
);
648 if( parity
== 2 ) return 0;
650 /* Search for any half-free buffer */
651 for( i
= 0; i
< c
->nbuffers
; i
++ )
653 if( ((parity
+1) & 1) && c
->buffers
[i
].lock
[0] ) continue;
654 if( ((parity
+1) & 2) && c
->buffers
[i
].lock
[1] ) continue;
655 pullup_alloc_buffer( c
, &c
->buffers
[i
] );
656 return pullup_lock_buffer( &c
->buffers
[i
], parity
);
664 * PULLUP FRAME FUNCTIONS
668 struct pullup_frame
* pullup_get_frame( struct pullup_context
* c
)
671 struct pullup_frame
* fr
= c
->frame
;
672 int n
= pullup_decide_frame_length( c
);
673 int aff
= c
->first
->next
->affinity
;
676 if ( fr
->lock
) return 0;
680 pullup_print_aff_and_breaks(c
, c
->first
);
681 printf("duration: %d \n", n
);
686 fr
->parity
= c
->first
->parity
;
688 for( i
= 0; i
< n
; i
++ )
690 /* We cheat and steal the buffer without release+relock */
691 fr
->ifields
[i
] = c
->first
->buffer
;
692 c
->first
->buffer
= 0;
693 c
->first
= c
->first
->next
;
698 fr
->ofields
[fr
->parity
] = fr
->ifields
[0];
699 fr
->ofields
[fr
->parity
^1] = 0;
703 fr
->ofields
[fr
->parity
] = fr
->ifields
[0];
704 fr
->ofields
[fr
->parity
^1] = fr
->ifields
[1];
710 aff
= (fr
->ifields
[0] == fr
->ifields
[1]) ? -1 : 1;
712 fr
->ofields
[fr
->parity
] = fr
->ifields
[1+aff
];
713 fr
->ofields
[fr
->parity
^1] = fr
->ifields
[1];
715 pullup_lock_buffer( fr
->ofields
[0], 0 );
716 pullup_lock_buffer( fr
->ofields
[1], 1 );
718 if( fr
->ofields
[0] == fr
->ofields
[1] )
720 fr
->buffer
= fr
->ofields
[0];
721 pullup_lock_buffer(fr
->buffer
, 2);
727 void pullup_pack_frame( struct pullup_context
* c
, struct pullup_frame
* fr
)
730 if (fr
->buffer
) return;
731 if (fr
->length
< 2) return; /* FIXME: deal with this */
732 for( i
= 0; i
< 2; i
++ )
734 if( fr
->ofields
[i
]->lock
[i
^1] ) continue;
735 fr
->buffer
= fr
->ofields
[i
];
736 pullup_lock_buffer(fr
->buffer
, 2);
737 pullup_copy_field( c
, fr
->buffer
, fr
->ofields
[i
^1], i
^1 );
740 fr
->buffer
= pullup_get_buffer( c
, 2 );
741 pullup_copy_field( c
, fr
->buffer
, fr
->ofields
[0], 0 );
742 pullup_copy_field( c
, fr
->buffer
, fr
->ofields
[1], 1 );
745 void pullup_release_frame( struct pullup_frame
* fr
)
748 for( i
= 0; i
< fr
->length
; i
++ )
750 pullup_release_buffer( fr
->ifields
[i
], fr
->parity
^ (i
&1) );
752 pullup_release_buffer( fr
->ofields
[0], 0 );
753 pullup_release_buffer( fr
->ofields
[1], 1 );
754 if (fr
->buffer
) pullup_release_buffer( fr
->buffer
, 2 );
760 * PULLUP FIELD FUNCTIONS
764 void pullup_submit_field( struct pullup_context
* c
,
765 struct pullup_buffer
* b
,
768 struct pullup_field
* f
;
770 /* Grow the circular list if needed */
771 pullup_check_field_queue( c
);
773 /* Cannot have two fields of same parity in a row; drop the new one */
774 if( c
->last
&& c
->last
->parity
== parity
) return;
778 f
->buffer
= pullup_lock_buffer( b
, parity
);
783 pullup_compute_metric( c
, f
, parity
, f
->prev
->prev
,
784 parity
, c
->diff
, f
->diffs
);
785 pullup_compute_metric( c
, parity
?f
->prev
:f
, 0,
786 parity
?f
:f
->prev
, 1, c
->comb
, f
->comb
);
787 pullup_compute_metric( c
, f
, parity
, f
,
788 -1, c
->var
, f
->var
);
790 /* Advance the circular list */
791 if( !c
->first
) c
->first
= c
->head
;
793 c
->head
= c
->head
->next
;
796 void pullup_flush_fields( struct pullup_context
* c
)
798 struct pullup_field
* f
;
800 for( f
= c
->first
; f
&& f
!= c
->head
; f
= f
->next
)
802 pullup_release_buffer( f
->buffer
, f
->parity
);
805 c
->first
= c
->last
= 0;
810 * DETELECINE FILTER FUNCTIONS
814 static int hb_detelecine_init( hb_filter_object_t
* filter
,
815 hb_filter_init_t
* init
)
817 filter
->private_data
= calloc( sizeof(struct hb_filter_private_s
), 1 );
818 hb_filter_private_t
* pv
= filter
->private_data
;
820 struct pullup_context
* ctx
;
821 pv
->pullup_ctx
= ctx
= pullup_alloc_context();
823 ctx
->junk_left
= ctx
->junk_right
= 1;
824 ctx
->junk_top
= ctx
->junk_bottom
= 4;
825 ctx
->strict_breaks
= -1;
826 ctx
->metric_plane
= 0;
829 if( filter
->settings
)
831 sscanf( filter
->settings
, "%d:%d:%d:%d:%d:%d:%d",
841 ctx
->format
= PULLUP_FMT_Y
;
844 pullup_preinit_context( ctx
);
846 ctx
->bpp
[0] = ctx
->bpp
[1] = ctx
->bpp
[2] = 8;
847 ctx
->background
[1] = ctx
->background
[2] = 128;
849 ctx
->w
[0] = init
->geometry
.width
;
850 ctx
->h
[0] = hb_image_height( init
->pix_fmt
, init
->geometry
.height
, 0 );
851 ctx
->stride
[0] = hb_image_stride( init
->pix_fmt
, init
->geometry
.width
, 0 );
853 ctx
->w
[1] = init
->geometry
.width
>> 1;
854 ctx
->h
[1] = hb_image_height( init
->pix_fmt
, init
->geometry
.height
, 1 );
855 ctx
->stride
[1] = hb_image_stride( init
->pix_fmt
, init
->geometry
.width
, 1 );
857 ctx
->w
[1] = init
->geometry
.width
>> 1;
858 ctx
->h
[2] = hb_image_height( init
->pix_fmt
, init
->geometry
.height
, 2 );
859 ctx
->stride
[2] = hb_image_stride( init
->pix_fmt
, init
->geometry
.width
, 2 );
861 ctx
->w
[3] = ((init
->geometry
.width
+ 15) / 16) *
862 ((init
->geometry
.height
+ 15) / 16);
864 ctx
->stride
[3] = ctx
->w
[3];
870 pullup_init_context( ctx
);
872 pv
->pullup_fakecount
= 1;
873 pv
->pullup_skipflag
= 0;
875 init
->job
->use_detelecine
= 1;
880 static void hb_detelecine_close( hb_filter_object_t
* filter
)
882 hb_filter_private_t
* pv
= filter
->private_data
;
891 pullup_free_context( pv
->pullup_ctx
);
895 filter
->private_data
= NULL
;
899 static int hb_detelecine_work( hb_filter_object_t
* filter
,
900 hb_buffer_t
** buf_in
,
901 hb_buffer_t
** buf_out
)
903 hb_filter_private_t
* pv
= filter
->private_data
;
904 hb_buffer_t
* in
= *buf_in
, * out
;
906 if (in
->s
.flags
& HB_BUF_FLAG_EOF
)
910 return HB_FILTER_DONE
;
913 struct pullup_context
* ctx
= pv
->pullup_ctx
;
914 struct pullup_buffer
* buf
;
915 struct pullup_frame
* frame
;
917 buf
= pullup_get_buffer( ctx
, 2 );
920 frame
= pullup_get_frame( ctx
);
921 pullup_release_frame( frame
);
922 hb_log( "Could not get buffer from pullup!" );
923 return HB_FILTER_FAILED
;
926 /* Copy input buffer into pullup buffer */
927 memcpy( buf
->planes
[0], in
->plane
[0].data
, buf
->size
[0] );
928 memcpy( buf
->planes
[1], in
->plane
[1].data
, buf
->size
[1] );
929 memcpy( buf
->planes
[2], in
->plane
[2].data
, buf
->size
[2] );
931 /* Submit buffer fields based on buffer flags.
932 Detelecine assumes BFF when the TFF flag isn't present. */
934 if( in
->s
.flags
& PIC_FLAG_TOP_FIELD_FIRST
)
936 /* Source signals TFF */
939 else if( ctx
->parity
== 0 )
941 /* Many non-MPEG-2 sources lack parity flags even though
942 they are TFF, so this allow users to override. */
945 if( ctx
->parity
== 1 )
947 /* Override autodetected parity with BFF */
950 pullup_submit_field( ctx
, buf
, parity
);
951 pullup_submit_field( ctx
, buf
, parity
^1 );
952 if( in
->s
.flags
& PIC_FLAG_REPEAT_FIRST_FIELD
)
954 pullup_submit_field( ctx
, buf
, parity
);
956 pullup_release_buffer( buf
, 2 );
958 /* Get frame and check if pullup is ready */
959 frame
= pullup_get_frame( ctx
);
962 if( pv
->pullup_fakecount
)
964 pv
->pullup_fakecount
--;
977 /* Check to see if frame should be dropped */
978 if( frame
->length
< 2 )
980 pullup_release_frame( frame
);
981 frame
= pullup_get_frame( ctx
);
987 if( frame
->length
< 2 )
989 pullup_release_frame( frame
);
991 if( !(in
->s
.flags
& PIC_FLAG_REPEAT_FIRST_FIELD
) )
996 frame
= pullup_get_frame( ctx
);
1002 if( frame
->length
< 2 )
1004 pullup_release_frame( frame
);
1010 /* Check to see if frame buffer is ready for export */
1011 if( !frame
->buffer
)
1013 pullup_pack_frame( ctx
, frame
);
1016 out
= hb_video_buffer_init( in
->f
.width
, in
->f
.height
);
1018 /* Copy pullup frame buffer into output buffer */
1019 memcpy( out
->plane
[0].data
, frame
->buffer
->planes
[0], frame
->buffer
->size
[0] );
1020 memcpy( out
->plane
[1].data
, frame
->buffer
->planes
[1], frame
->buffer
->size
[1] );
1021 memcpy( out
->plane
[2].data
, frame
->buffer
->planes
[2], frame
->buffer
->size
[2] );
1023 pullup_release_frame( frame
);
1026 hb_buffer_move_subs( out
, in
);
1032 return HB_FILTER_OK
;
1034 /* This and all discard_frame calls shown above are
1035 the result of me restoring the functionality in
1036 pullup that huevos_rancheros disabled because
1037 HB couldn't handle it. */
1039 return HB_FILTER_OK
;