2 #include "ffmpeg/avcodec.h"
3 #include "mpeg2dec/mpeg2.h"
11 #define PULLUP_FMT_Y 1
12 #define PULLUP_HAVE_BREAKS 1
13 #define PULLUP_HAVE_AFFINITY 2
14 #define PULLUP_BREAK_LEFT 1
15 #define PULLUP_BREAK_RIGHT 2
17 #define PULLUP_ABS( a ) (((a)^((a)>>31))-((a)>>31))
19 #ifndef PIC_FLAG_REPEAT_FIRST_FIELD
20 #define PIC_FLAG_REPEAT_FIRST_FIELD 256
26 unsigned char **planes
;
32 struct pullup_buffer
*buffer
;
39 struct pullup_field
*prev
, *next
;
47 struct pullup_buffer
**ifields
, *ofields
[2];
48 struct pullup_buffer
*buffer
;
53 /* Public interface */
56 int *bpp
, *w
, *h
, *stride
, *background
;
58 int junk_left
, junk_right
, junk_top
, junk_bottom
;
64 struct pullup_field
*first
, *last
, *head
;
65 struct pullup_buffer
*buffers
;
67 int (*diff
)(unsigned char *, unsigned char *, int);
68 int (*comb
)(unsigned char *, unsigned char *, int);
69 int (*var
)(unsigned char *, unsigned char *, int);
70 int metric_w
, metric_h
, metric_len
, metric_offset
;
71 struct pullup_frame
*frame
;
76 * DETELECINE FILTER DEFINITIONS
80 struct hb_filter_private_s
86 struct pullup_context
* pullup_ctx
;
92 hb_buffer_t
* buf_out
;
95 hb_filter_private_t
* hb_detelecine_init( int pix_fmt
,
100 int hb_detelecine_work( const hb_buffer_t
* buf_in
,
101 hb_buffer_t
** buf_out
,
105 hb_filter_private_t
* pv
);
107 void hb_detelecine_close( hb_filter_private_t
* pv
);
109 hb_filter_object_t hb_filter_detelecine
=
112 "Detelecine (pullup)",
121 * PULLUP STATIC FUNCTIONS
125 static int pullup_diff_y( unsigned char *a
, unsigned char * b
, int s
)
130 for( j
= 0; j
< 8; j
++ )
132 diff
+= PULLUP_ABS( a
[j
]-b
[j
] );
139 static int pullup_licomb_y( unsigned char * a
, unsigned char * b
, int s
)
144 for( j
= 0; j
< 8; j
++ )
146 diff
+= PULLUP_ABS( (a
[j
]<<1) - b
[j
-s
] - b
[j
] )
147 + PULLUP_ABS( (b
[j
]<<1) - a
[j
] - a
[j
+s
] );
154 static int pullup_var_y( unsigned char * a
, unsigned char * b
, int s
)
159 for( j
= 0; j
< 8; j
++ )
161 var
+= PULLUP_ABS( a
[j
]-a
[j
+s
] );
168 static void pullup_alloc_metrics( struct pullup_context
* c
,
169 struct pullup_field
* f
)
171 f
->diffs
= calloc( c
->metric_len
, sizeof(int) );
172 f
->comb
= calloc( c
->metric_len
, sizeof(int) );
173 f
->var
= calloc( c
->metric_len
, sizeof(int) );
176 static void pullup_compute_metric( struct pullup_context
* c
,
177 struct pullup_field
* fa
, int pa
,
178 struct pullup_field
* fb
, int pb
,
179 int (* func
)( unsigned char *,
180 unsigned char *, int),
183 unsigned char *a
, *b
;
185 int mp
= c
->metric_plane
;
186 int xstep
= c
->bpp
[mp
];
187 int ystep
= c
->stride
[mp
]<<3;
188 int s
= c
->stride
[mp
]<<1; /* field stride */
189 int w
= c
->metric_w
*xstep
;
191 if( !fa
->buffer
|| !fb
->buffer
) return;
193 /* Shortcut for duplicate fields (e.g. from RFF flag) */
194 if( fa
->buffer
== fb
->buffer
&& pa
== pb
)
196 memset( dest
, 0, c
->metric_len
* sizeof(int) );
200 a
= fa
->buffer
->planes
[mp
] + pa
* c
->stride
[mp
] + c
->metric_offset
;
201 b
= fb
->buffer
->planes
[mp
] + pb
* c
->stride
[mp
] + c
->metric_offset
;
203 for( y
= c
->metric_h
; y
; y
-- )
205 for( x
= 0; x
< w
; x
+= xstep
)
207 *dest
++ = func( a
+ x
, b
+ x
, s
);
209 a
+= ystep
; b
+= ystep
;
213 static struct pullup_field
* pullup_make_field_queue( struct pullup_context
* c
,
216 struct pullup_field
* head
, * f
;
217 f
= head
= calloc( 1, sizeof(struct pullup_field
) );
218 pullup_alloc_metrics( c
, f
);
219 for ( ; len
> 0; len
-- )
221 f
->next
= calloc( 1, sizeof(struct pullup_field
) );
224 pullup_alloc_metrics( c
, f
);
231 static void pullup_check_field_queue( struct pullup_context
* c
)
233 if( c
->head
->next
== c
->first
)
235 struct pullup_field
*f
= calloc( 1, sizeof(struct pullup_field
) );
236 pullup_alloc_metrics( c
, f
);
244 static void pullup_copy_field( struct pullup_context
* c
,
245 struct pullup_buffer
* dest
,
246 struct pullup_buffer
* src
,
250 unsigned char *d
, *s
;
251 for( i
= 0; i
< c
->nplanes
; i
++ )
253 s
= src
->planes
[i
] + parity
*c
->stride
[i
];
254 d
= dest
->planes
[i
] + parity
*c
->stride
[i
];
255 for( j
= c
->h
[i
]>>1; j
; j
-- )
257 memcpy( d
, s
, c
->stride
[i
] );
258 s
+= c
->stride
[i
]<<1;
259 d
+= c
->stride
[i
]<<1;
265 static int pullup_queue_length( struct pullup_field
* begin
,
266 struct pullup_field
* end
)
269 struct pullup_field
* f
;
271 if( !begin
|| !end
) return 0;
272 for( f
= begin
; f
!= end
; f
= f
->next
) count
++;
276 static int pullup_find_first_break( struct pullup_field
* f
, int max
)
279 for( i
= 0; i
< max
; i
++ )
281 if( f
->breaks
& PULLUP_BREAK_RIGHT
||
282 f
->next
->breaks
& PULLUP_BREAK_LEFT
)
291 static void pullup_compute_breaks( struct pullup_context
* c
,
292 struct pullup_field
* f0
)
295 struct pullup_field
*f1
= f0
->next
;
296 struct pullup_field
*f2
= f1
->next
;
297 struct pullup_field
*f3
= f2
->next
;
298 int l
, max_l
=0, max_r
=0;
300 if( f0
->flags
& PULLUP_HAVE_BREAKS
) return;
301 f0
->flags
|= PULLUP_HAVE_BREAKS
;
303 /* Special case when fields are 100% identical */
304 if( f0
->buffer
== f2
->buffer
&& f1
->buffer
!= f3
->buffer
)
306 f2
->breaks
|= PULLUP_BREAK_RIGHT
;
309 if( f0
->buffer
!= f2
->buffer
&& f1
->buffer
== f3
->buffer
)
311 f1
->breaks
|= PULLUP_BREAK_LEFT
;
315 for( i
= 0; i
< c
->metric_len
; i
++ )
317 l
= f2
->diffs
[i
] - f3
->diffs
[i
];
318 if( l
> max_l
) max_l
= l
;
319 if( -l
> max_r
) max_r
= -l
;
322 /* Don't get tripped up when differences are mostly quant error */
323 if( max_l
+ max_r
< 128 ) return;
324 if( max_l
> 4*max_r
) f1
->breaks
|= PULLUP_BREAK_LEFT
;
325 if( max_r
> 4*max_l
) f2
->breaks
|= PULLUP_BREAK_RIGHT
;
328 static void pullup_compute_affinity( struct pullup_context
* c
,
329 struct pullup_field
* f
)
332 int max_l
= 0, max_r
= 0, l
;
334 if( f
->flags
& PULLUP_HAVE_AFFINITY
)
338 f
->flags
|= PULLUP_HAVE_AFFINITY
;
340 if( f
->buffer
== f
->next
->next
->buffer
)
343 f
->next
->affinity
= 0;
344 f
->next
->next
->affinity
= -1;
346 f
->next
->flags
|= PULLUP_HAVE_AFFINITY
;
347 f
->next
->next
->flags
|= PULLUP_HAVE_AFFINITY
;
352 for( i
= 0; i
< c
->metric_len
; i
++ )
354 int lv
= f
->prev
->var
[i
];
355 int rv
= f
->next
->var
[i
];
357 int lc
= f
->comb
[i
] - (v
+lv
) + PULLUP_ABS( v
-lv
);
358 int rc
= f
->next
->comb
[i
] - (v
+rv
) + PULLUP_ABS( v
-rv
);
360 lc
= (lc
> 0) ? lc
: 0;
361 rc
= (rc
> 0) ? rc
: 0;
363 if( l
> max_l
) max_l
= l
;
364 if( -l
> max_r
) max_r
= -l
;
367 if( max_l
+ max_r
< 64 )
372 if( max_r
> 6*max_l
)
376 else if( max_l
> 6*max_r
)
382 static void pullup_foo( struct pullup_context
* c
)
384 struct pullup_field
* f
= c
->first
;
385 int i
, n
= pullup_queue_length (f
, c
->last
);
386 for( i
= 0; i
< n
-1; i
++ )
388 if( i
< n
-3 ) pullup_compute_breaks( c
, f
);
389 pullup_compute_affinity( c
, f
);
394 static int pullup_decide_frame_length( struct pullup_context
* c
)
396 struct pullup_field
*f0
= c
->first
;
397 struct pullup_field
*f1
= f0
->next
;
398 struct pullup_field
*f2
= f1
->next
;
399 struct pullup_field
*f3
= f2
->next
;
402 if( pullup_queue_length( c
->first
, c
->last
) < 4 )
408 if( f0
->affinity
== -1 ) return 1;
410 l
= pullup_find_first_break( f0
, 3 );
411 if( l
== 1 && c
->strict_breaks
< 0 ) l
= 0;
416 if ( c
->strict_breaks
< 1 &&
428 /* FIXME: strictly speaking, f0->prev is no longer valid... :) */
429 if( c
->strict_pairs
&&
430 (f0
->prev
->breaks
& PULLUP_BREAK_RIGHT
) &&
431 (f2
->breaks
& PULLUP_BREAK_LEFT
) &&
432 (f0
->affinity
!= 1 || f1
->affinity
!= -1) )
436 if( f1
->affinity
== 1 )
446 if( f2
->affinity
== 1 )
456 /* 9 possibilities covered before switch */
457 if( f1
->affinity
== 1 )
459 return 1; /* covers 6 */
461 else if( f1
->affinity
== -1 )
463 return 2; /* covers 6 */
465 else if( f2
->affinity
== -1 )
468 if( f0
->affinity
== 1 )
479 return 2; /* the remaining 6 */
484 static void pullup_print_aff_and_breaks(struct pullup_context
* c
,
485 struct pullup_field
* f
)
488 struct pullup_field
* f0
= f
;
489 const char aff_l
[] = "+..", aff_r
[] = "..+";
490 printf( "\naffinity: " );
491 for( i
= 0; i
< 4; i
++ )
494 aff_l
[1+f
->affinity
],
496 aff_r
[1+f
->affinity
] );
501 printf("\nbreaks: ");
502 for( i
= 0; i
< 4; i
++ )
505 f
->breaks
& PULLUP_BREAK_LEFT
? '|' : '.',
507 f
->breaks
& PULLUP_BREAK_RIGHT
? '|' : '.' );
516 * PULLUP CONTEXT FUNCTIONS
520 struct pullup_context
* pullup_alloc_context( void )
522 struct pullup_context
* c
;
524 c
= calloc( 1, sizeof(struct pullup_context
)) ;
529 void pullup_preinit_context( struct pullup_context
* c
)
531 c
->bpp
= calloc( c
->nplanes
, sizeof(int) );
532 c
->w
= calloc( c
->nplanes
, sizeof(int) );
533 c
->h
= calloc( c
->nplanes
, sizeof(int) );
534 c
->stride
= calloc( c
->nplanes
, sizeof(int) );
535 c
->background
= calloc( c
->nplanes
, sizeof(int) );
538 void pullup_init_context( struct pullup_context
* c
)
540 int mp
= c
->metric_plane
;
541 if ( c
->nbuffers
< 10 )
545 c
->buffers
= calloc( c
->nbuffers
, sizeof (struct pullup_buffer
) );
547 c
->metric_w
= (c
->w
[mp
] - ((c
->junk_left
+ c
->junk_right
) << 3)) >> 3;
548 c
->metric_h
= (c
->h
[mp
] - ((c
->junk_top
+ c
->junk_bottom
) << 1)) >> 3;
549 c
->metric_offset
= c
->junk_left
*c
->bpp
[mp
] + (c
->junk_top
<<1)*c
->stride
[mp
];
550 c
->metric_len
= c
->metric_w
* c
->metric_h
;
552 c
->head
= pullup_make_field_queue( c
, 8 );
554 c
->frame
= calloc( 1, sizeof (struct pullup_frame
) );
555 c
->frame
->ifields
= calloc( 3, sizeof (struct pullup_buffer
*) );
557 if( c
->format
== PULLUP_FMT_Y
)
559 c
->diff
= pullup_diff_y
;
560 c
->comb
= pullup_licomb_y
;
561 c
->var
= pullup_var_y
;
565 void pullup_free_context( struct pullup_context
* c
)
567 struct pullup_field
* f
;
579 while( f
!= c
->head
);
587 * PULLUP BUFFER FUNCTIONS
591 static void pullup_alloc_buffer( struct pullup_context
* c
,
592 struct pullup_buffer
* b
)
595 if( b
->planes
) return;
596 b
->planes
= calloc( c
->nplanes
, sizeof(unsigned char *) );
597 for ( i
= 0; i
< c
->nplanes
; i
++ )
599 b
->planes
[i
] = malloc(c
->h
[i
]*c
->stride
[i
]);
600 /* Deal with idiotic 128=0 for chroma: */
601 memset( b
->planes
[i
], c
->background
[i
], c
->h
[i
]*c
->stride
[i
] );
605 struct pullup_buffer
* pullup_lock_buffer( struct pullup_buffer
* b
,
609 if( (parity
+1) & 1 ) b
->lock
[0]++;
610 if( (parity
+1) & 2 ) b
->lock
[1]++;
615 void pullup_release_buffer( struct pullup_buffer
* b
,
619 if( (parity
+1) & 1 ) b
->lock
[0]--;
620 if( (parity
+1) & 2 ) b
->lock
[1]--;
623 struct pullup_buffer
* pullup_get_buffer( struct pullup_context
* c
,
628 /* Try first to get the sister buffer for the previous field */
631 parity
!= c
->last
->parity
&&
632 !c
->last
->buffer
->lock
[parity
])
634 pullup_alloc_buffer( c
, c
->last
->buffer
);
635 return pullup_lock_buffer( c
->last
->buffer
, parity
);
638 /* Prefer a buffer with both fields open */
639 for( i
= 0; i
< c
->nbuffers
; i
++ )
641 if( c
->buffers
[i
].lock
[0] ) continue;
642 if( c
->buffers
[i
].lock
[1] ) continue;
643 pullup_alloc_buffer( c
, &c
->buffers
[i
] );
644 return pullup_lock_buffer( &c
->buffers
[i
], parity
);
647 if( parity
== 2 ) return 0;
649 /* Search for any half-free buffer */
650 for( i
= 0; i
< c
->nbuffers
; i
++ )
652 if( ((parity
+1) & 1) && c
->buffers
[i
].lock
[0] ) continue;
653 if( ((parity
+1) & 2) && c
->buffers
[i
].lock
[1] ) continue;
654 pullup_alloc_buffer( c
, &c
->buffers
[i
] );
655 return pullup_lock_buffer( &c
->buffers
[i
], parity
);
663 * PULLUP FRAME FUNCTIONS
667 struct pullup_frame
* pullup_get_frame( struct pullup_context
* c
)
670 struct pullup_frame
* fr
= c
->frame
;
671 int n
= pullup_decide_frame_length( c
);
672 int aff
= c
->first
->next
->affinity
;
675 if ( fr
->lock
) return 0;
679 pullup_print_aff_and_breaks(c
, c
->first
);
680 printf("duration: %d \n", n
);
685 fr
->parity
= c
->first
->parity
;
687 for( i
= 0; i
< n
; i
++ )
689 /* We cheat and steal the buffer without release+relock */
690 fr
->ifields
[i
] = c
->first
->buffer
;
691 c
->first
->buffer
= 0;
692 c
->first
= c
->first
->next
;
697 fr
->ofields
[fr
->parity
] = fr
->ifields
[0];
698 fr
->ofields
[fr
->parity
^1] = 0;
702 fr
->ofields
[fr
->parity
] = fr
->ifields
[0];
703 fr
->ofields
[fr
->parity
^1] = fr
->ifields
[1];
709 aff
= (fr
->ifields
[0] == fr
->ifields
[1]) ? -1 : 1;
711 fr
->ofields
[fr
->parity
] = fr
->ifields
[1+aff
];
712 fr
->ofields
[fr
->parity
^1] = fr
->ifields
[1];
714 pullup_lock_buffer( fr
->ofields
[0], 0 );
715 pullup_lock_buffer( fr
->ofields
[1], 1 );
717 if( fr
->ofields
[0] == fr
->ofields
[1] )
719 fr
->buffer
= fr
->ofields
[0];
720 pullup_lock_buffer(fr
->buffer
, 2);
726 void pullup_pack_frame( struct pullup_context
* c
, struct pullup_frame
* fr
)
729 if (fr
->buffer
) return;
730 if (fr
->length
< 2) return; /* FIXME: deal with this */
731 for( i
= 0; i
< 2; i
++ )
733 if( fr
->ofields
[i
]->lock
[i
^1] ) continue;
734 fr
->buffer
= fr
->ofields
[i
];
735 pullup_lock_buffer(fr
->buffer
, 2);
736 pullup_copy_field( c
, fr
->buffer
, fr
->ofields
[i
^1], i
^1 );
739 fr
->buffer
= pullup_get_buffer( c
, 2 );
740 pullup_copy_field( c
, fr
->buffer
, fr
->ofields
[0], 0 );
741 pullup_copy_field( c
, fr
->buffer
, fr
->ofields
[1], 1 );
744 void pullup_release_frame( struct pullup_frame
* fr
)
747 for( i
= 0; i
< fr
->length
; i
++ )
749 pullup_release_buffer( fr
->ifields
[i
], fr
->parity
^ (i
&1) );
751 pullup_release_buffer( fr
->ofields
[0], 0 );
752 pullup_release_buffer( fr
->ofields
[1], 1 );
753 if (fr
->buffer
) pullup_release_buffer( fr
->buffer
, 2 );
759 * PULLUP FIELD FUNCTIONS
763 void pullup_submit_field( struct pullup_context
* c
,
764 struct pullup_buffer
* b
,
767 struct pullup_field
* f
;
769 /* Grow the circular list if needed */
770 pullup_check_field_queue( c
);
772 /* Cannot have two fields of same parity in a row; drop the new one */
773 if( c
->last
&& c
->last
->parity
== parity
) return;
777 f
->buffer
= pullup_lock_buffer( b
, parity
);
782 pullup_compute_metric( c
, f
, parity
, f
->prev
->prev
,
783 parity
, c
->diff
, f
->diffs
);
784 pullup_compute_metric( c
, parity
?f
->prev
:f
, 0,
785 parity
?f
:f
->prev
, 1, c
->comb
, f
->comb
);
786 pullup_compute_metric( c
, f
, parity
, f
,
787 -1, c
->var
, f
->var
);
789 /* Advance the circular list */
790 if( !c
->first
) c
->first
= c
->head
;
792 c
->head
= c
->head
->next
;
795 void pullup_flush_fields( struct pullup_context
* c
)
797 struct pullup_field
* f
;
799 for( f
= c
->first
; f
&& f
!= c
->head
; f
= f
->next
)
801 pullup_release_buffer( f
->buffer
, f
->parity
);
804 c
->first
= c
->last
= 0;
809 * DETELECINE FILTER FUNCTIONS
813 hb_filter_private_t
* hb_detelecine_init( int pix_fmt
,
818 if( pix_fmt
!= PIX_FMT_YUV420P
)
823 hb_filter_private_t
* pv
= malloc( sizeof(struct hb_filter_private_s
) );
825 pv
->pix_fmt
= pix_fmt
;
826 pv
->width
[0] = width
;
827 pv
->height
[0] = height
;
828 pv
->width
[1] = pv
->width
[2] = width
>> 1;
829 pv
->height
[1] = pv
->height
[2] = height
>> 1;
831 int buf_size
= 3 * width
* height
/ 2;
832 pv
->buf_out
= hb_buffer_init( buf_size
);
834 struct pullup_context
* ctx
;
835 pv
->pullup_ctx
= ctx
= pullup_alloc_context();
837 ctx
->junk_left
= ctx
->junk_right
= 1;
838 ctx
->junk_top
= ctx
->junk_bottom
= 4;
839 ctx
->strict_breaks
= 0;
840 ctx
->metric_plane
= 0;
844 sscanf( settings
, "%d:%d:%d:%d:%d:%d",
850 &ctx
->metric_plane
);
853 ctx
->format
= PULLUP_FMT_Y
;
856 pullup_preinit_context( ctx
);
858 ctx
->bpp
[0] = ctx
->bpp
[1] = ctx
->bpp
[2] = 8;
859 ctx
->background
[1] = ctx
->background
[2] = 128;
861 ctx
->w
[0] = pv
->width
[0];
862 ctx
->h
[0] = pv
->height
[0];
863 ctx
->stride
[0] = pv
->width
[0];
865 ctx
->w
[1] = pv
->width
[1];
866 ctx
->h
[1] = pv
->height
[1];
867 ctx
->stride
[1] = pv
->width
[1];
869 ctx
->w
[2] = pv
->width
[2];
870 ctx
->h
[2] = pv
->height
[2];
871 ctx
->stride
[2] = pv
->width
[2];
873 ctx
->w
[3] = ((width
+15)/16) * ((height
+15)/16);
875 ctx
->stride
[3] = ctx
->w
[3];
881 pullup_init_context( ctx
);
883 pv
->pullup_fakecount
= 1;
884 pv
->pullup_skipflag
= 0;
889 void hb_detelecine_close( hb_filter_private_t
* pv
)
898 hb_buffer_close( &pv
->buf_out
);
903 pullup_free_context( pv
->pullup_ctx
);
909 int hb_detelecine_work( const hb_buffer_t
* buf_in
,
910 hb_buffer_t
** buf_out
,
914 hb_filter_private_t
* pv
)
917 pix_fmt
!= pv
->pix_fmt
||
918 width
!= pv
->width
[0] ||
919 height
!= pv
->height
[0] )
921 return FILTER_FAILED
;
924 struct pullup_context
* ctx
= pv
->pullup_ctx
;
925 struct pullup_buffer
* buf
;
926 struct pullup_frame
* frame
;
928 buf
= pullup_get_buffer( ctx
, 2 );
931 frame
= pullup_get_frame( ctx
);
932 pullup_release_frame( frame
);
933 hb_log( "Could not get buffer from pullup!" );
934 return FILTER_FAILED
;
937 /* Copy input buffer into pullup buffer */
938 avpicture_fill( &pv
->pic_in
, buf_in
->data
,
939 pix_fmt
, width
, height
);
941 hb_buffer_copy_settings( pv
->buf_out
, buf_in
);
943 memcpy( buf
->planes
[0], pv
->pic_in
.data
[0],
944 pv
->width
[0] * pv
->height
[0] * sizeof(uint8_t) );
945 memcpy( buf
->planes
[1], pv
->pic_in
.data
[1],
946 pv
->width
[1] * pv
->height
[1] * sizeof(uint8_t) );
947 memcpy( buf
->planes
[2], pv
->pic_in
.data
[2],
948 pv
->width
[2] * pv
->height
[2] * sizeof(uint8_t) );
950 /* Submit buffer fields based on buffer flags */
952 if( buf_in
->flags
& PIC_FLAG_TOP_FIELD_FIRST
)
956 pullup_submit_field( ctx
, buf
, parity
);
957 pullup_submit_field( ctx
, buf
, parity
^1 );
958 if( buf_in
->flags
& PIC_FLAG_REPEAT_FIRST_FIELD
)
960 pullup_submit_field( ctx
, buf
, parity
);
962 pullup_release_buffer( buf
, 2 );
964 /* Get frame and check if pullup is ready */
965 frame
= pullup_get_frame( ctx
);
968 if( pv
->pullup_fakecount
)
970 pv
->pullup_fakecount
--;
972 memcpy( pv
->buf_out
->data
, buf_in
->data
, buf_in
->size
);
982 /* Check to see if frame should be dropped */
983 if( frame
->length
< 2 )
985 pullup_release_frame( frame
);
986 frame
= pullup_get_frame( ctx
);
992 if( frame
->length
< 2 )
994 pullup_release_frame( frame
);
996 if( !(buf_in
->flags
& PIC_FLAG_REPEAT_FIRST_FIELD
) )
1001 frame
= pullup_get_frame( ctx
);
1007 if( frame
->length
< 2 )
1009 pullup_release_frame( frame
);
1015 /* Check to see if frame buffer is ready for export */
1016 if( !frame
->buffer
)
1018 pullup_pack_frame( ctx
, frame
);
1021 /* Copy pullup frame buffer into output buffer */
1022 avpicture_fill( &pv
->pic_out
, pv
->buf_out
->data
,
1023 pix_fmt
, width
, height
);
1025 memcpy( pv
->pic_out
.data
[0], frame
->buffer
->planes
[0],
1026 pv
->width
[0] * pv
->height
[0] * sizeof(uint8_t) );
1027 memcpy( pv
->pic_out
.data
[1], frame
->buffer
->planes
[1],
1028 pv
->width
[1] * pv
->height
[1] * sizeof(uint8_t) );
1029 memcpy( pv
->pic_out
.data
[2], frame
->buffer
->planes
[2],
1030 pv
->width
[2] * pv
->height
[2] * sizeof(uint8_t) );
1032 pullup_release_frame( frame
);
1035 *buf_out
= pv
->buf_out
;
1038 /* This and all discard_frame calls shown above are
1039 the result of me restoring the functionality in
1040 pullup that huevos_rancheros disabled because
1041 HB couldn't handle it. */
1043 *buf_out
= pv
->buf_out
;