vf_filmdint.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,447 行 · 第 1/3 页

C
1,447
字号
    long unit = ((x+y+err) >> e);    long ret = (diff > unit) - (diff < -unit);    unit >>= 1;    return ret + (diff > unit) - (diff < -unit);}static unsigned longfind_breaks(struct vf_priv_s *p, struct frame_stats *s){    struct frame_stats *ps = &p->stats[(p->inframes-1) & 1];    long notfilm = 5*p->in_inc - p->out_dec;    unsigned long n = s->num_blocks >> 8;    unsigned long sad_comb_cmp = cmpe(s->sad.temp, s->sad.noise, 512, 1);    unsigned long ret = 8;    if (cmpe(s->sad.temp, s->sad.even, 512, 1) > 0)	mp_msg(MSGT_VFILTER, MSGL_WARN,	       "@@@@@@@@ Bottom-first field??? @@@@@@@@\n");    if (s->sad.temp > 1000 && s->sad.noise > 1000)	return 3;    if (s->interlaced_high >= 2*n && s->sad.temp > 256 && s->sad.noise > 256)	return 3;    if (s->high.noise > s->num_blocks/4 && s->sad.noise > 10000 &&	s->sad.noise > 2*s->sad.even && s->sad.noise > 2*ps->sad.odd) {	// Mid-frame scene change	if (s->tiny.temp + s->interlaced_low  < n   ||	    s->low.temp  + s->interlaced_high < n/4 ||	    s->high.temp + s->interlaced_high < n/8 ||	    s->sad.temp < 160)	    return 1;	return 3;    }    if (s->high.temp > s->num_blocks/4 && s->sad.temp > 10000 &&	s->sad.temp > 2*ps->sad.odd && s->sad.temp > 2*ps->sad.even) {	// Start frame scene change	if (s->tiny.noise + s->interlaced_low  < n   ||	    s->low.noise  + s->interlaced_high < n/4 ||	    s->high.noise + s->interlaced_high < n/8 ||	    s->sad.noise < 160)	    return 2;	return 3;    }    if (sad_comb_cmp == 2)	return 2;    if (sad_comb_cmp == -2)	return 1;    if (s->tiny.odd > 3*MAX(n,s->tiny.even) + s->interlaced_low)	return 1;    if (s->tiny.even > 3*MAX(n,s->tiny.odd)+s->interlaced_low &&	(!sad_comb_cmp || (s->low.noise <= n/4 && s->low.temp <= n/4)))	return 4;    if (s->sad.noise < 64 && s->sad.temp < 64 &&	s->low.noise <= n/2 && s->high.noise <= n/4 &&	s->low.temp  <= n/2 && s->high.temp  <= n/4)	goto still;    if (s->tiny.temp > 3*MAX(n,s->tiny.noise) + s->interlaced_low)	return 2;    if (s->tiny.noise > 3*MAX(n,s->tiny.temp) + s->interlaced_low)	return 1;    if (s->low.odd > 3*MAX(n/4,s->low.even) + s->interlaced_high)	return 1;    if (s->low.even > 3*MAX(n/4,s->low.odd)+s->interlaced_high &&	s->sad.even > 2*s->sad.odd &&	(!sad_comb_cmp || (s->low.noise <= n/4 && s->low.temp <= n/4)))	return 4;    if (s->low.temp > 3*MAX(n/4,s->low.noise) + s->interlaced_high)	return 2;    if (s->low.noise > 3*MAX(n/4,s->low.temp) + s->interlaced_high)	return 1;    if (sad_comb_cmp == 1 && s->sad.noise < 64)	return 2;    if (sad_comb_cmp == -1 && s->sad.temp < 64)	return 1;    if (s->tiny.odd <= n || (s->tiny.noise <= n/2 && s->tiny.temp <= n/2)) {	if (s->interlaced_low <= n) {	    if (p->num_fields == 1)		goto still;	    if (s->tiny.even <= n || ps->tiny.noise <= n/2)		/* Still frame */		goto still;	    if (s->bigger.even >= 2*MAX(n,s->bigger.odd) + s->interlaced_low)		return 4;	    if (s->low.even >= 2*n + s->interlaced_low)		return 4;	    goto still;	}    }    if (s->low.odd <= n/4) {	if (s->interlaced_high <= n/4) {	    if (p->num_fields == 1)		goto still;	    if (s->low.even <= n/4)		/* Still frame */		goto still;	    if (s->bigger.even >= 2*MAX(n/4,s->bigger.odd)+s->interlaced_high)		return 4;	    if (s->low.even >= n/2 + s->interlaced_high)		return 4;	    goto still;	}    }    if (s->bigger.temp > 2*MAX(n,s->bigger.noise) + s->interlaced_low)	return 2;    if (s->bigger.noise > 2*MAX(n,s->bigger.temp) + s->interlaced_low)	return 1;    if (s->bigger.temp > 2*MAX(n,s->bigger.noise) + s->interlaced_high)	return 2;    if (s->bigger.noise > 2*MAX(n,s->bigger.temp) + s->interlaced_high)	return 1;    if (s->twox.temp > 2*MAX(n,s->twox.noise) + s->interlaced_high)	return 2;    if (s->twox.noise > 2*MAX(n,s->twox.temp) + s->interlaced_high)	return 1;    if (s->bigger.even > 2*MAX(n,s->bigger.odd) + s->interlaced_low &&	s->bigger.temp < n && s->bigger.noise < n)	return 4;    if (s->interlaced_low > MIN(2*n, s->tiny.odd))	return 3;    ret = 8 + (1 << (s->sad.temp > s->sad.noise));  still:    if (p->num_fields == 1 && p->prev_fields == 3 && notfilm >= 0 &&	(s->tiny.temp <= s->tiny.noise || s->sad.temp < s->sad.noise+16))	return 1;    if (p->notout < p->num_fields && p->iosync > 2*p->in_inc && notfilm < 0)	notfilm = 0;    if (p->num_fields < 2 ||	(p->num_fields == 2 && p->prev_fields == 2 && notfilm < 0))	return ret;    if (!notfilm && (p->prev_fields&~1) == 2) {	if (p->prev_fields + p->num_fields == 5) {	    if (s->tiny.noise <= s->tiny.temp ||		s->low.noise == 0 || s->low.noise < s->low.temp ||		s->sad.noise < s->sad.temp+16)		return 2;	}	if (p->prev_fields + p->num_fields == 4) {	    if (s->tiny.temp <= s->tiny.noise ||		s->low.temp == 0 || s->low.temp < s->low.noise ||		s->sad.temp < s->sad.noise+16)		return 1;	}    }    if (p->num_fields > 2 &&	ps->sad.noise > s->sad.noise && ps->sad.noise > s->sad.temp)	return 4;    return 2 >> (s->sad.noise > s->sad.temp);}#define ITOC(X) (!(X) ? ' ' : (X) + ((X)>9 ? 'a'-10 : '0'))static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){    mp_image_t *dmpi;    struct vf_priv_s *p = vf->priv;    unsigned char **planes, **old_planes;    struct frame_stats *s  = &p->stats[p->inframes & 1];    struct frame_stats *ps = &p->stats[(p->inframes-1) & 1];    int swapped = 0;    const int flags = mpi->fields;    int breaks, prev;    int show_fields = 0;    int dropped_fields = 0;    double start_time, diff_time;    char prev_chflag = p->chflag;    int keep_rate;    if (!p->planes[0][0]) init(p, mpi);    old_planes = p->old_planes;    if ((mpi->flags & MP_IMGFLAG_DIRECT) && mpi->priv) {	planes = mpi->priv;	mpi->priv = 0;    } else {	planes = p->planes[2 + (++p->temp_idx & 1)];	my_memcpy_pic(planes[0],		      mpi->planes[0] + p->crop_x + p->crop_y * mpi->stride[0],		      p->w, p->h, p->stride, mpi->stride[0]);	if (mpi->flags & MP_IMGFLAG_PLANAR) {	    my_memcpy_pic(planes[1],			  mpi->planes[1] + p->crop_cx + p->crop_cy * mpi->stride[1],			  p->cw, p->ch, p->chroma_stride, mpi->stride[1]);	    my_memcpy_pic(planes[2],			  mpi->planes[2] + p->crop_cx + p->crop_cy * mpi->stride[2],			  p->cw, p->ch, p->chroma_stride, mpi->stride[2]);	    p->num_copies++;	}    }    p->old_planes = planes;    p->chflag = ';';    if (flags & MP_IMGFIELD_ORDERED) {	swapped = !(flags & MP_IMGFIELD_TOP_FIRST);	p->chflag = (flags & MP_IMGFIELD_REPEAT_FIRST ? '|' :		     flags & MP_IMGFIELD_TOP_FIRST ? ':' : '.');    }    p->swapped = swapped;    start_time = get_time();    if (p->chflag == '|') {	*s = ppzs;	p->iosync += p->in_inc;    } else if ((p->fast & 1) && prev_chflag == '|')	*s = pprs;    else	diff_fields(p, s, old_planes, planes);    diff_time = get_time();    p->diff_time += diff_time - start_time;    breaks = p->inframes ? find_breaks(p, s) : 2;    p->inframes++;    keep_rate = 4*p->in_inc == p->out_dec;    switch (breaks) {      case 0:      case 8:      case 9:      case 10:	if (!keep_rate && p->notout < p->num_fields && p->iosync < 2*p->in_inc)	    break;	if (p->notout < p->num_fields)	    dropped_fields = -2;      case 4:	if (keep_rate || p->iosync >= -2*p->in_inc)	    show_fields = (4<<p->num_fields)-1;	break;      case 3:	if (keep_rate)	    show_fields = 2;	else if (p->iosync > 0) {	    if (p->notout >= p->num_fields && p->iosync > 2*p->in_inc) {		show_fields = 4; /* prev odd only */		if (p->num_fields > 1)		    show_fields |= 8; /* + prev even */	    } else {		show_fields = 2; /* even only */		if (p->notout >= p->num_fields)		    dropped_fields += p->num_fields;	    }	}	break;      case 2:	if (p->iosync <= -3*p->in_inc) {	    if (p->notout >= p->num_fields)		dropped_fields = p->num_fields;	    break;	}	if (p->num_fields == 1) {	    int prevbreak = ps->sad.noise >= 128;	    if (p->iosync < 4*p->in_inc) {		show_fields = 3;		dropped_fields = prevbreak;	    } else {		show_fields = 4 | (!prevbreak << 3);		if (p->notout < 1 + p->prev_fields)		    dropped_fields = -!prevbreak;	    }	    break;	}      default:	if (keep_rate)	    show_fields = 3 << (breaks & 1);	else if (p->notout >= p->num_fields &&	    p->iosync >= (breaks == 1 ? -p->in_inc :			  p->in_inc << (p->num_fields == 1))) {	    show_fields = (1 << (2 + p->num_fields)) - (1<<breaks);	} else {	    if (p->notout >= p->num_fields)		dropped_fields += p->num_fields + 2 - breaks;	    if (breaks == 1) {		if (p->iosync >= 4*p->in_inc)		    show_fields = 6;	    } else if (p->iosync > -3*p->in_inc)		show_fields = 3;  /* odd+even */	}	break;    }    show_fields &= 15;    prev = p->prev_fields;    if (breaks < 8) {	if (p->num_fields == 1)	    breaks &= ~4;	if (breaks)	    p->num_breaks++;	if (breaks == 3)	    p->prev_fields = p->num_fields = 1;	else if (breaks) {	    p->prev_fields = p->num_fields + (breaks==1) - (breaks==4);	    p->num_fields = breaks - (breaks == 4) + (p->chflag == '|');	} else	    p->num_fields += 2;    } else	p->num_fields += 2;    p->iosync += 4 * p->in_inc;    if (p->chflag == '|')	p->iosync += p->in_inc;    if (show_fields) {	p->iosync -= p->out_dec;	p->notout = !(show_fields & 1) + !(show_fields & 3);	if (((show_fields &  3) ==  3 &&	     (s->low.noise + s->interlaced_low < (s->num_blocks>>8) ||	      s->sad.noise < 160)) ||	    ((show_fields & 12) == 12 &&	     (ps->low.noise + ps->interlaced_low < (s->num_blocks>>8) ||	      ps->sad.noise < 160))) {	    p->export_count++;	    dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_EXPORT,				MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE,				p->w, p->h);	    if ((show_fields & 3) != 3) planes = old_planes;	    dmpi->planes[0] = planes[0];	    dmpi->stride[0] = p->stride;	    dmpi->width = mpi->width;	    if (mpi->flags & MP_IMGFLAG_PLANAR) {		dmpi->planes[1] = planes[1];		dmpi->planes[2] = planes[2];		dmpi->stride[1] = p->chroma_stride;		dmpi->stride[2] = p->chroma_stride;	    }	} else {	    p->merge_count++;	    dmpi = vf_get_image(vf->next, mpi->imgfmt,				MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,				p->w, p->h);	    copy_merge_fields(p, dmpi, old_planes, planes, show_fields);	}	p->outframes++;    } else	p->notout += 2;    if (p->verbose)	mp_msg(MSGT_VFILTER, MSGL_INFO, "%lu %lu: %x %c %c %lu%s%s%c%s\n",	       p->inframes, p->outframes,	       breaks, breaks<8 && breaks>0 ? (int) p->prev_fields+'0' : ' ',	       ITOC(show_fields),	       p->num_breaks, 5*p->in_inc == p->out_dec && breaks<8 &&	       breaks>0 && ((prev&~1)!=2 || prev+p->prev_fields!=5) ?	       " ######## bad telecine ########" : "",	       dropped_fields ? " ======== dropped ":"", ITOC(dropped_fields),	       !show_fields || (show_fields & (show_fields-1)) ?	       "" : " @@@@@@@@@@@@@@@@@");    p->merge_time += get_time() - diff_time;    return show_fields ? vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE) : 0;}static int query_format(struct vf_instance_s* vf, unsigned int fmt){    /* FIXME - support more formats */    switch (fmt) {      case IMGFMT_YV12:      case IMGFMT_IYUV:      case IMGFMT_I420:      case IMGFMT_411P:      case IMGFMT_422P:      case IMGFMT_444P:	return vf_next_query_format(vf, fmt);    }    return 0;}static int config(struct vf_instance_s* vf,		  int width, int height, int d_width, int d_height,		  unsigned int flags, unsigned int outfmt){    unsigned long cxm = 0;    unsigned long cym = 0;    struct vf_priv_s *p = vf->priv;    // rounding:    if(!IMGFMT_IS_RGB(outfmt) && !IMGFMT_IS_BGR(outfmt)){	switch(outfmt){	  case IMGFMT_444P:	  case IMGFMT_Y800:	  case IMGFMT_Y8:	    break;	  case IMGFMT_YVU9:	  case IMGFMT_IF09:	    cym = 3;	  case IMGFMT_411P:	    cxm = 3;	    break;	  case IMGFMT_YV12:	  case IMGFMT_I420:	  case IMGFMT_IYUV:	    cym = 1;	  default:	    cxm = 1;	}    }    p->chroma_swapped = !!(p->crop_y & (cym+1));    if (p->w) p->w += p->crop_x & cxm;    if (p->h) p->h += p->crop_y & cym;    p->crop_x &= ~cxm;    p->crop_y &= ~cym;    if (!p->w || p->w > width ) p->w = width;    if (!p->h || p->h > height) p->h = height;    if (p->crop_x + p->w > width ) p->crop_x = 0;    if (p->crop_y + p->h > height) p->crop_y = 0;    if(!opt_screen_size_x && !opt_screen_size_y){	d_width = d_width * p->w/width;	d_height = d_height * p->h/height;    }    return vf_next_config(vf, p->w, p->h, d_width, d_height, flags, outfmt);}static void uninit(struct vf_instance_s* vf){    struct vf_priv_s *p = vf->priv;    mp_msg(MSGT_VFILTER, MSGL_INFO, "diff_time: %.3f, merge_time: %.3f, "	   "export: %lu, merge: %lu, copy: %lu\n", p->diff_time, p->merge_time,	   p->export_count, p->merge_count, p->num_copies);    free(p->memory_allocated);    free(p);}static int open(vf_instance_t *vf, char* args){    struct vf_priv_s *p;    vf->get_image = get_image;    vf->put_image = put_image;    vf->config = config;    vf->query_format = query_format;    vf->uninit = uninit;    vf->default_reqs = VFCAP_ACCEPT_STRIDE;    vf->priv = p = calloc(1, sizeof(struct vf_priv_s));    p->out_dec = 5;    p->in_inc = 4;    p->thres.noise = 128;    p->thres.even  = 128;    p->sad_thres = 64;    p->dint_thres = 4;    p->luma_only = 0;    p->fast = 3;    p->mmx2 = gCpuCaps.hasMMX2 ? 1 : gCpuCaps.has3DNow ? 2 : 0;    if (args) {	const char *args_remain = parse_args(p, args);	if (args_remain) {	    mp_msg(MSGT_VFILTER, MSGL_FATAL,		   "filmdint: unknown suboption: %s\n", args_remain);	    return 0;	}	if (p->out_dec < p->in_inc) {	    mp_msg(MSGT_VFILTER, MSGL_FATAL,		   "filmdint: increasing the frame rate is not supported\n");	    return 0;	}    }    if (p->mmx2 > 2)	p->mmx2 = 0;#ifndef HAVE_MMX    p->mmx2 = 0;#endif#ifndef HAVE_3DNOW    p->mmx2 &= 1;#endif    p->thres.odd  = p->thres.even;    p->thres.temp = p->thres.noise;    p->diff_time = 0;    p->merge_time = 0;    return 1;}vf_info_t vf_info_filmdint = {    "Advanced inverse telecine filer",    "filmdint",    "Zoltan Hidvegi",    "",    open,    NULL};

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?