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 + -
显示快捷键?