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
20 #include "ffmpeg/avcodec.h"
21 #include "mpeg2dec/mpeg2.h"
23 #define SUPPRESS_AV_LOG
25 #define YADIF_MODE_DEFAULT -1
26 #define YADIF_PARITY_DEFAULT -1
28 #define MCDEINT_MODE_DEFAULT -1
29 #define MCDEINT_QP_DEFAULT 1
31 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
32 #define MIN3(a,b,c) MIN(MIN(a,b),c)
33 #define MAX3(a,b,c) MAX(MAX(a,b),c)
35 struct hb_filter_private_s
45 uint8_t * yadif_ref
[4][3];
46 int yadif_ref_stride
[3];
51 int mcdeint_outbuf_size
;
52 uint8_t * mcdeint_outbuf
;
53 AVCodecContext
* mcdeint_avctx_enc
;
54 AVFrame
* mcdeint_frame
;
55 AVFrame
* mcdeint_frame_dec
;
59 hb_buffer_t
* buf_out
[2];
60 hb_buffer_t
* buf_settings
;
63 hb_filter_private_t
* hb_deinterlace_init( int pix_fmt
,
68 int hb_deinterlace_work( const hb_buffer_t
* buf_in
,
69 hb_buffer_t
** buf_out
,
73 hb_filter_private_t
* pv
);
75 void hb_deinterlace_close( hb_filter_private_t
* pv
);
77 hb_filter_object_t hb_filter_deinterlace
=
80 "Deinterlace (ffmpeg or yadif/mcdeint)",
87 static void yadif_store_ref( const uint8_t ** pic
,
88 hb_filter_private_t
* pv
)
90 memcpy( pv
->yadif_ref
[3],
92 sizeof(uint8_t *)*3 );
94 memmove( pv
->yadif_ref
[0],
96 sizeof(uint8_t *)*3*3 );
99 for( i
= 0; i
< 3; i
++ )
101 const uint8_t * src
= pic
[i
];
102 uint8_t * ref
= pv
->yadif_ref
[2][i
];
104 int w
= pv
->width
[i
];
105 int h
= pv
->height
[i
];
106 int ref_stride
= pv
->yadif_ref_stride
[i
];
109 for( y
= 0; y
< pv
->height
[i
]; y
++ )
112 src
= (uint8_t*)src
+ w
;
113 ref
= (uint8_t*)ref
+ ref_stride
;
118 static void yadif_filter_line( uint8_t *dst
,
124 hb_filter_private_t
* pv
)
126 uint8_t *prev2
= parity
? prev
: cur
;
127 uint8_t *next2
= parity
? cur
: next
;
129 int w
= pv
->width
[plane
];
130 int refs
= pv
->yadif_ref_stride
[plane
];
133 for( x
= 0; x
< w
; x
++)
136 int d
= (prev2
[0] + next2
[0])>>1;
138 int temporal_diff0
= ABS(prev2
[0] - next2
[0]);
139 int temporal_diff1
= ( ABS(prev
[-refs
] - c
) + ABS(prev
[+refs
] - e
) ) >> 1;
140 int temporal_diff2
= ( ABS(next
[-refs
] - c
) + ABS(next
[+refs
] - e
) ) >> 1;
141 int diff
= MAX3(temporal_diff0
>>1, temporal_diff1
, temporal_diff2
);
142 int spatial_pred
= (c
+e
)>>1;
143 int spatial_score
= ABS(cur
[-refs
-1] - cur
[+refs
-1]) + ABS(c
-e
) +
144 ABS(cur
[-refs
+1] - cur
[+refs
+1]) - 1;
146 #define YADIF_CHECK(j)\
147 { int score = ABS(cur[-refs-1+j] - cur[+refs-1-j])\
148 + ABS(cur[-refs +j] - cur[+refs -j])\
149 + ABS(cur[-refs+1+j] - cur[+refs+1-j]);\
150 if( score < spatial_score ){\
151 spatial_score = score;\
152 spatial_pred = (cur[-refs +j] + cur[+refs -j])>>1;\
154 YADIF_CHECK(-1) YADIF_CHECK(-2) }} }}
155 YADIF_CHECK( 1) YADIF_CHECK( 2) }} }}
157 if( pv
->yadif_mode
< 2 )
159 int b
= (prev2
[-2*refs
] + next2
[-2*refs
])>>1;
160 int f
= (prev2
[+2*refs
] + next2
[+2*refs
])>>1;
162 int max
= MAX3(d
-e
, d
-c
, MIN(b
-c
, f
-e
));
163 int min
= MIN3(d
-e
, d
-c
, MAX(b
-c
, f
-e
));
165 diff
= MAX3( diff
, min
, -max
);
168 if( spatial_pred
> d
+ diff
)
170 spatial_pred
= d
+ diff
;
172 else if( spatial_pred
< d
- diff
)
174 spatial_pred
= d
- diff
;
177 dst
[0] = spatial_pred
;
188 static void yadif_filter( uint8_t ** dst
,
191 hb_filter_private_t
* pv
)
194 for( i
= 0; i
< 3; i
++ )
196 int w
= pv
->width
[i
];
197 int h
= pv
->height
[i
];
198 int ref_stride
= pv
->yadif_ref_stride
[i
];
201 for( y
= 0; y
< h
; y
++ )
203 if( (y
^ parity
) & 1 )
205 uint8_t *prev
= &pv
->yadif_ref
[0][i
][y
*ref_stride
];
206 uint8_t *cur
= &pv
->yadif_ref
[1][i
][y
*ref_stride
];
207 uint8_t *next
= &pv
->yadif_ref
[2][i
][y
*ref_stride
];
208 uint8_t *dst2
= &dst
[i
][y
*w
];
210 yadif_filter_line( dst2
, prev
, cur
, next
, i
, parity
^ tff
, pv
);
214 memcpy( &dst
[i
][y
*w
],
215 &pv
->yadif_ref
[1][i
][y
*ref_stride
],
216 w
* sizeof(uint8_t) );
222 static void mcdeint_filter( uint8_t ** dst
,
225 hb_filter_private_t
* pv
)
230 #ifdef SUPPRESS_AV_LOG
231 /* TODO: temporarily change log level to suppress obnoxious debug output */
232 int loglevel
= av_log_get_level();
233 av_log_set_level( AV_LOG_QUIET
);
238 pv
->mcdeint_frame
->data
[i
] = src
[i
];
239 pv
->mcdeint_frame
->linesize
[i
] = pv
->width
[i
];
241 pv
->mcdeint_avctx_enc
->me_cmp
= FF_CMP_SAD
;
242 pv
->mcdeint_avctx_enc
->me_sub_cmp
= FF_CMP_SAD
;
243 pv
->mcdeint_frame
->quality
= pv
->mcdeint_qp
* FF_QP2LAMBDA
;
245 out_size
= avcodec_encode_video( pv
->mcdeint_avctx_enc
,
247 pv
->mcdeint_outbuf_size
,
250 pv
->mcdeint_frame_dec
= pv
->mcdeint_avctx_enc
->coded_frame
;
252 for( i
= 0; i
< 3; i
++ )
254 int w
= pv
->width
[i
];
255 int h
= pv
->height
[i
];
256 int fils
= pv
->mcdeint_frame_dec
->linesize
[i
];
257 int srcs
= pv
->width
[i
];
259 for( y
= 0; y
< h
; y
++ )
261 if( (y
^ parity
) & 1 )
263 for( x
= 0; x
< w
; x
++ )
265 if( (x
-2)+(y
-1)*w
>= 0 && (x
+2)+(y
+1)*w
< w
*h
)
268 &pv
->mcdeint_frame_dec
->data
[i
][x
+ y
*fils
];
269 uint8_t * srcp
= &src
[i
][x
+ y
*srcs
];
271 int diff0
= filp
[-fils
] - srcp
[-srcs
];
272 int diff1
= filp
[+fils
] - srcp
[+srcs
];
275 ABS(srcp
[-srcs
-1] - srcp
[+srcs
-1])
276 + ABS(srcp
[-srcs
] - srcp
[+srcs
])
277 + ABS(srcp
[-srcs
+1] - srcp
[+srcs
+1]) - 1;
281 #define MCDEINT_CHECK(j)\
282 { int score = ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
283 + ABS(srcp[-srcs +j] - srcp[+srcs -j])\
284 + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
285 if( score < spatial_score ) {\
286 spatial_score = score;\
287 diff0 = filp[-fils+j] - srcp[-srcs+j];\
288 diff1 = filp[+fils-j] - srcp[+srcs-j];
290 MCDEINT_CHECK(-1) MCDEINT_CHECK(-2) }} }}
291 MCDEINT_CHECK( 1) MCDEINT_CHECK( 2) }} }}
293 if(diff0
+ diff1
> 0)
295 temp
-= (diff0
+ diff1
-
296 ABS( ABS(diff0
) - ABS(diff1
) ) / 2) / 2;
300 temp
-= (diff0
+ diff1
+
301 ABS( ABS(diff0
) - ABS(diff1
) ) / 2) / 2;
304 filp
[0] = dst
[i
][x
+ y
*w
] =
305 temp
> 255U ? ~(temp
>>31) : temp
;
310 pv
->mcdeint_frame_dec
->data
[i
][x
+ y
*fils
];
316 for( y
= 0; y
< h
; y
++ )
318 if( !((y
^ parity
) & 1) )
320 for( x
= 0; x
< w
; x
++ )
322 pv
->mcdeint_frame_dec
->data
[i
][x
+ y
*fils
] =
323 dst
[i
][x
+ y
*w
]= src
[i
][x
+ y
*srcs
];
329 #ifdef SUPPRESS_AV_LOG
330 /* TODO: restore previous log level */
331 av_log_set_level(loglevel
);
335 hb_filter_private_t
* hb_deinterlace_init( int pix_fmt
,
340 if( pix_fmt
!= PIX_FMT_YUV420P
)
345 hb_filter_private_t
* pv
= calloc( 1, sizeof(struct hb_filter_private_s
) );
347 pv
->pix_fmt
= pix_fmt
;
349 pv
->width
[0] = width
;
350 pv
->height
[0] = height
;
351 pv
->width
[1] = pv
->width
[2] = width
>> 1;
352 pv
->height
[1] = pv
->height
[2] = height
>> 1;
354 int buf_size
= 3 * width
* height
/ 2;
355 pv
->buf_out
[0] = hb_buffer_init( buf_size
);
356 pv
->buf_out
[1] = hb_buffer_init( buf_size
);
357 pv
->buf_settings
= hb_buffer_init( 0 );
360 pv
->yadif_mode
= YADIF_MODE_DEFAULT
;
361 pv
->yadif_parity
= YADIF_PARITY_DEFAULT
;
363 pv
->mcdeint_mode
= MCDEINT_MODE_DEFAULT
;
364 pv
->mcdeint_qp
= MCDEINT_QP_DEFAULT
;
368 sscanf( settings
, "%d:%d:%d:%d",
375 /* Allocate yadif specific buffers */
376 if( pv
->yadif_mode
>= 0 )
379 for( i
= 0; i
< 3; i
++ )
382 int w
= ((width
+ 31) & (~31))>>is_chroma
;
383 int h
= ((height
+6+ 31) & (~31))>>is_chroma
;
385 pv
->yadif_ref_stride
[i
] = w
;
387 for( j
= 0; j
< 3; j
++ )
389 pv
->yadif_ref
[j
][i
] = malloc( w
*h
*sizeof(uint8_t) ) + 3*w
;
394 /* Allocate mcdeint specific buffers */
395 if( pv
->mcdeint_mode
>= 0 )
398 avcodec_register_all();
400 AVCodec
* enc
= avcodec_find_encoder( CODEC_ID_SNOW
);
403 for (i
= 0; i
< 3; i
++ )
405 AVCodecContext
* avctx_enc
;
407 avctx_enc
= pv
->mcdeint_avctx_enc
= avcodec_alloc_context();
409 avctx_enc
->width
= width
;
410 avctx_enc
->height
= height
;
411 avctx_enc
->time_base
= (AVRational
){1,25}; // meaningless
412 avctx_enc
->gop_size
= 300;
413 avctx_enc
->max_b_frames
= 0;
414 avctx_enc
->pix_fmt
= PIX_FMT_YUV420P
;
415 avctx_enc
->flags
= CODEC_FLAG_QSCALE
| CODEC_FLAG_LOW_DELAY
;
416 avctx_enc
->strict_std_compliance
= FF_COMPLIANCE_EXPERIMENTAL
;
417 avctx_enc
->global_quality
= 1;
418 avctx_enc
->flags2
= CODEC_FLAG2_MEMC_ONLY
;
419 avctx_enc
->me_cmp
= FF_CMP_SAD
; //SSE;
420 avctx_enc
->me_sub_cmp
= FF_CMP_SAD
; //SSE;
421 avctx_enc
->mb_cmp
= FF_CMP_SSE
;
423 switch( pv
->mcdeint_mode
)
428 avctx_enc
->me_method
= ME_ITER
;
430 avctx_enc
->flags
|= CODEC_FLAG_4MV
;
431 avctx_enc
->dia_size
=2;
433 avctx_enc
->flags
|= CODEC_FLAG_QPEL
;
436 avcodec_open(avctx_enc
, enc
);
439 pv
->mcdeint_frame
= avcodec_alloc_frame();
440 pv
->mcdeint_outbuf_size
= width
* height
* 10;
441 pv
->mcdeint_outbuf
= malloc( pv
->mcdeint_outbuf_size
);
447 void hb_deinterlace_close( hb_filter_private_t
* pv
)
454 /* Cleanup frame buffers */
457 hb_buffer_close( &pv
->buf_out
[0] );
461 hb_buffer_close( &pv
->buf_out
[1] );
463 if (pv
->buf_settings
)
465 hb_buffer_close( &pv
->buf_settings
);
468 /* Cleanup yadif specific buffers */
469 if( pv
->yadif_mode
>= 0 )
472 for( i
= 0; i
<3*3; i
++ )
474 uint8_t **p
= &pv
->yadif_ref
[i
%3][i
/3];
477 free( *p
- 3*pv
->yadif_ref_stride
[i
/3] );
483 /* Cleanup mcdeint specific buffers */
484 if( pv
->mcdeint_mode
>= 0 )
486 if( pv
->mcdeint_avctx_enc
)
488 avcodec_close( pv
->mcdeint_avctx_enc
);
489 av_freep( &pv
->mcdeint_avctx_enc
);
491 if( pv
->mcdeint_outbuf
)
493 free( pv
->mcdeint_outbuf
);
500 int hb_deinterlace_work( const hb_buffer_t
* buf_in
,
501 hb_buffer_t
** buf_out
,
505 hb_filter_private_t
* pv
)
508 pix_fmt
!= pv
->pix_fmt
||
509 width
!= pv
->width
[0] ||
510 height
!= pv
->height
[0] )
512 return FILTER_FAILED
;
515 avpicture_fill( &pv
->pic_in
, buf_in
->data
,
516 pix_fmt
, width
, height
);
518 /* Use libavcodec deinterlace if yadif_mode < 0 */
519 if( pv
->yadif_mode
< 0 )
521 avpicture_fill( &pv
->pic_out
, pv
->buf_out
[0]->data
,
522 pix_fmt
, width
, height
);
524 avpicture_deinterlace( &pv
->pic_out
, &pv
->pic_in
,
525 pix_fmt
, width
, height
);
527 hb_buffer_copy_settings( pv
->buf_out
[0], buf_in
);
529 *buf_out
= pv
->buf_out
[0];
534 /* Determine if top-field first layout */
536 if( pv
->yadif_parity
< 0 )
538 tff
= !!(buf_in
->flags
& PIC_FLAG_TOP_FIELD_FIRST
);
542 tff
= (pv
->yadif_parity
& 1) ^ 1;
545 /* Store current frame in yadif cache */
546 yadif_store_ref( (const uint8_t**)pv
->pic_in
.data
, pv
);
548 /* If yadif is not ready, store another ref and return FILTER_DELAY */
549 if( pv
->yadif_ready
== 0 )
551 yadif_store_ref( (const uint8_t**)pv
->pic_in
.data
, pv
);
553 hb_buffer_copy_settings( pv
->buf_settings
, buf_in
);
560 /* Perform yadif and mcdeint filtering */
562 for( frame
= 0; frame
<= (pv
->yadif_mode
& 1); frame
++ )
564 int parity
= frame
^ tff
^ 1;
566 avpicture_fill( &pv
->pic_out
, pv
->buf_out
[!(frame
^1)]->data
,
567 pix_fmt
, width
, height
);
569 yadif_filter( pv
->pic_out
.data
, parity
, tff
, pv
);
571 if( pv
->mcdeint_mode
>= 0 )
573 avpicture_fill( &pv
->pic_in
, pv
->buf_out
[(frame
^1)]->data
,
574 pix_fmt
, width
, height
);
576 mcdeint_filter( pv
->pic_in
.data
, pv
->pic_out
.data
, parity
, pv
);
578 *buf_out
= pv
->buf_out
[ (frame
^1)];
582 *buf_out
= pv
->buf_out
[!(frame
^1)];
586 /* Copy buffered settings to output buffer settings */
587 hb_buffer_copy_settings( *buf_out
, pv
->buf_settings
);
589 /* Replace buffered settings with input buffer settings */
590 hb_buffer_copy_settings( pv
->buf_settings
, buf_in
);