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 "libavcodec/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( 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_UMH;
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( 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 );
555 /* don't let 'work_loop' send a chapter mark upstream */
556 buf_in->new_chap = 0;
563 /* Perform yadif and mcdeint filtering */
565 for( frame = 0; frame <= (pv->yadif_mode & 1); frame++ )
567 int parity = frame ^ tff ^ 1;
569 avpicture_fill( &pv->pic_out, pv->buf_out[!(frame^1)]->data,
570 pix_fmt, width, height );
572 yadif_filter( pv->pic_out.data, parity, tff, pv );
574 if( pv->mcdeint_mode >= 0 )
576 avpicture_fill( &pv->pic_in, pv->buf_out[(frame^1)]->data,
577 pix_fmt, width, height );
579 mcdeint_filter( pv->pic_in.data, pv->pic_out.data, parity, pv );
581 *buf_out = pv->buf_out[ (frame^1)];
585 *buf_out = pv->buf_out[!(frame^1)];
589 /* Copy buffered settings to output buffer settings */
590 hb_buffer_copy_settings( *buf_out, pv->buf_settings );
592 /* Replace buffered settings with input buffer settings */
593 hb_buffer_copy_settings( pv->buf_settings, buf_in );
595 /* don't let 'work_loop' send a chapter mark upstream */
596 buf_in->new_chap = 0;