static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ int cw= mpi->w >> mpi->chroma_x_shift; int ch= mpi->h >> mpi->chroma_y_shift; int W = mpi->w, H = mpi->h; mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, MP_IMGTYPE_IP, MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_PRESERVE | MP_IMGFLAG_READABLE, mpi->w,mpi->h); if(!dmpi) return 0; if (!vf->priv->pmpi) vf->priv->pmpi=mpi; deNoise(mpi->planes[0], vf->priv->pmpi->planes[0], dmpi->planes[0], vf->priv->Line, W, H, mpi->stride[0], vf->priv->pmpi->stride[0], dmpi->stride[0], vf->priv->Coefs[0] + 256, vf->priv->Coefs[0] + 256, vf->priv->Coefs[1] + 256); deNoise(mpi->planes[1], vf->priv->pmpi->planes[1], dmpi->planes[1], vf->priv->Line, cw, ch, mpi->stride[1], vf->priv->pmpi->stride[1], dmpi->stride[1], vf->priv->Coefs[2] + 256, vf->priv->Coefs[2] + 256, vf->priv->Coefs[3] + 256); deNoise(mpi->planes[2], vf->priv->pmpi->planes[2], dmpi->planes[2], vf->priv->Line, cw, ch, mpi->stride[2], vf->priv->pmpi->stride[2], dmpi->stride[2], vf->priv->Coefs[2] + 256, vf->priv->Coefs[2] + 256, vf->priv->Coefs[3] + 256); vf->priv->pmpi=dmpi; // save reference image return vf_next_put_image(vf,dmpi, pts); }
int tc_filter(frame_list_t *vframe_, char * options) { vframe_list_t *vframe = (vframe_list_t *)vframe_; int instance; int tag = vframe->tag; dn3d_private_data_t * pd; if(tag & TC_AUDIO) return(0); instance = vframe->filter_id; pd = &dn3d_private_data[instance]; if(tag & TC_FILTER_GET_CONFIG) { char buf[128]; optstr_filter_desc(options, MOD_NAME, MOD_CAP, MOD_VERSION, MOD_AUTHOR, "VYMOE", "2"); tc_snprintf(buf, 128, "%f", DEFAULT_LUMA_SPATIAL); optstr_param(options, "luma", "spatial luma strength", "%f", buf, "0.0", "100.0" ); tc_snprintf(buf, 128, "%f", DEFAULT_CHROMA_SPATIAL); optstr_param(options, "chroma", "spatial chroma strength", "%f", buf, "0.0", "100.0" ); tc_snprintf(buf, 128, "%f", DEFAULT_LUMA_TEMPORAL); optstr_param(options, "luma_strength", "temporal luma strength", "%f", buf, "0.0", "100.0" ); tc_snprintf(buf, 128, "%f", DEFAULT_CHROMA_TEMPORAL); optstr_param(options, "chroma_strength", "temporal chroma strength", "%f", buf, "0.0", "100.0" ); tc_snprintf(buf, 128, "%d", dn3d_private_data[instance].prefilter); optstr_param(options, "pre", "run as a pre filter", "%d", buf, "0", "1" ); } if(tag & TC_FILTER_INIT) { int format_index, plane_index, found; const dn3d_layout_t * lp; size_t size; if(!(pd->vob = tc_get_vob())) return(TC_IMPORT_ERROR); pd->parameter.luma_spatial = 0; pd->parameter.luma_temporal = 0; pd->parameter.chroma_spatial = 0; pd->parameter.chroma_temporal = 0; if(!options) { tc_log_error(MOD_NAME, "options not set!"); return(TC_IMPORT_ERROR); } if(optstr_lookup(options, "help")) { help_optstr(); return(TC_IMPORT_ERROR); } optstr_get(options, "luma", "%lf", &pd->parameter.luma_spatial); optstr_get(options, "luma_strength", "%lf", &pd->parameter.luma_temporal); optstr_get(options, "chroma", "%lf", &pd->parameter.chroma_spatial); optstr_get(options, "chroma_strength", "%lf", &pd->parameter.chroma_temporal); optstr_get(options, "pre", "%d", &dn3d_private_data[instance].prefilter); if((pd->parameter.luma_spatial < 0) || (pd->parameter.luma_temporal < 0)) pd->enable_luma = 0; else { pd->enable_luma = 1; if(pd->parameter.luma_spatial == 0) { if(pd->parameter.luma_temporal == 0) { pd->parameter.luma_spatial = DEFAULT_LUMA_SPATIAL; pd->parameter.luma_temporal = DEFAULT_LUMA_TEMPORAL; } else { pd->parameter.luma_spatial = pd->parameter.luma_temporal * 3 / 2; } } else { if(pd->parameter.luma_temporal == 0) { pd->parameter.luma_temporal = pd->parameter.luma_spatial * 2 / 3; } } } if((pd->parameter.chroma_spatial < 0) || (pd->parameter.chroma_temporal < 0)) pd->enable_chroma = 0; else { pd->enable_chroma = 1; if(pd->parameter.chroma_spatial == 0) { if(pd->parameter.chroma_temporal == 0) { pd->parameter.chroma_spatial = DEFAULT_CHROMA_SPATIAL; pd->parameter.chroma_temporal = DEFAULT_CHROMA_TEMPORAL; } else { pd->parameter.chroma_spatial = pd->parameter.chroma_temporal * 3 / 2; } } else { if(pd->parameter.chroma_temporal == 0) { pd->parameter.chroma_temporal = pd->parameter.chroma_spatial * 2 / 3; } } } for(format_index = 0, found = 0; format_index < (sizeof(dn3d_layout) / sizeof(*dn3d_layout)); format_index++) { if(pd->vob->im_v_codec == dn3d_layout[format_index].tc_fmt) { found = 1; break; } } if(!found) { tc_log_error(MOD_NAME, "This filter is only capable of YUV, YUV422 and RGB mode"); return(TC_IMPORT_ERROR); } lp = &dn3d_layout[format_index]; pd->layout_data = *lp; for(plane_index = 0; plane_index < MAX_PLANES; plane_index++) { if((pd->layout_data.layout[plane_index].plane_type == dn3d_luma) && !pd->enable_luma) pd->layout_data.layout[plane_index].plane_type = dn3d_disabled; if((pd->layout_data.layout[plane_index].plane_type == dn3d_chroma) && !pd->enable_chroma) pd->layout_data.layout[plane_index].plane_type = dn3d_disabled; } size = pd->vob->im_v_width * MAX_PLANES * sizeof(char) * 2; pd->lineant = tc_zalloc(size); if(pd->lineant == NULL) tc_log_error(MOD_NAME, "Malloc failed"); size *= pd->vob->im_v_height * 2; pd->previous = tc_zalloc(size); if(pd->previous == NULL) tc_log_error(MOD_NAME, "Malloc failed"); PrecalcCoefs(pd->coefficients[0], pd->parameter.luma_spatial); PrecalcCoefs(pd->coefficients[1], pd->parameter.luma_temporal); PrecalcCoefs(pd->coefficients[2], pd->parameter.chroma_spatial); PrecalcCoefs(pd->coefficients[3], pd->parameter.chroma_temporal); if(verbose) { tc_log_info(MOD_NAME, "%s %s #%d", MOD_VERSION, MOD_CAP, instance); tc_log_info(MOD_NAME, "Settings luma (spatial): %.2f " "luma_strength (temporal): %.2f " "chroma (spatial): %.2f " "chroma_strength (temporal): %.2f", pd->parameter.luma_spatial, pd->parameter.luma_temporal, pd->parameter.chroma_spatial, pd->parameter.chroma_temporal); tc_log_info(MOD_NAME, "luma enabled: %s, chroma enabled: %s", pd->enable_luma ? "yes" : "no", pd->enable_chroma ? "yes" : "no"); } } if(((tag & TC_PRE_M_PROCESS && pd->prefilter) || (tag & TC_POST_M_PROCESS && !pd->prefilter)) && !(vframe->attributes & TC_FRAME_IS_SKIPPED)) { int plane_index, coef[2]; int offset = 0; const dn3d_single_layout_t * lp; for(plane_index = 0; plane_index < MAX_PLANES; plane_index++) { lp = &pd->layout_data.layout[plane_index]; if(lp->plane_type != dn3d_disabled) { // if(plane_index != 2) // debug // continue; coef[0] = (lp->plane_type == dn3d_luma) ? 0 : 2; coef[1] = coef[0] + 1; switch(lp->offset) { case(dn3d_off_r): offset = 0; break; case(dn3d_off_g): offset = 1; break; case(dn3d_off_b): offset = 2; break; case(dn3d_off_y420): offset = vframe->v_width * vframe->v_height * 0 / 4; break; case(dn3d_off_u420): offset = vframe->v_width * vframe->v_height * 4 / 4; break; case(dn3d_off_v420): offset = vframe->v_width * vframe->v_height * 5 / 4; break; case(dn3d_off_y422): offset = vframe->v_width * vframe->v_height * 0 / 2; break; case(dn3d_off_u422): offset = vframe->v_width * vframe->v_height * 2 / 2; break; case(dn3d_off_v422): offset = vframe->v_width * vframe->v_height * 3 / 2; break; } deNoise(vframe->video_buf, // frame pd->previous, // previous (saved) frame pd->lineant, // line buffer vframe->v_width / lp->scale_x, // width (pixels) vframe->v_height / lp->scale_y, // height (pixels) // debug pd->coefficients[coef[0]], // horizontal (spatial) strength pd->coefficients[coef[0]], // vertical (spatial) strength pd->coefficients[coef[1]], // temporal strength offset, // offset in bytes of first relevant pixel in frame lp->skip // skip this amount of bytes between two pixels ); } } } if(tag & TC_FILTER_CLOSE) { if(pd->previous) { free(pd->previous); pd->previous = 0; } if(pd->lineant) { free(pd->lineant); pd->lineant = 0; } } return(0); }
uint8_t ADMVideoMPD3D::getFrameNumberNoAlloc(uint32_t frame, uint32_t *len, ADMImage *data, uint32_t *flags) { UNUSED_ARG(flags); int cw= _info.width>>1; int ch= _info.height>>1; int W = _info.width; int H = _info.height; uint32_t dlen,dflags; if(frame> _info.nb_frames-1) return 0; *len=(W*H*3)>>1; // First and last frame we don"t modify. if(!frame || (frame!=_last+1)) { if(!_in->getFrameNumberNoAlloc(frame, &dlen,data,&dflags)) { return 0; } unsigned short* dst=_uncompressed; unsigned char* src=YPLANE(data); for (int Y = 0; Y < W*H; Y++) { *(dst++)=*(src++)<<8; } src=UPLANE(data); dst=_uncompressed+(W*H); for (int Y = 0; Y < (W*H)>>2; Y++) { *(dst++)=*(src++)<<8; } src=VPLANE(data); dst=_uncompressed+((5*W*H)>>2); for (int Y = 0; Y < (W*H)>>2; Y++) { *(dst++)=*(src++)<<8; } _last=frame; return 1; } ADM_assert(frame<_info.nb_frames); // read uncompressed frame // else we fill previous/current/next if(!_in->getFrameNumberNoAlloc(frame, &dlen,_storage,&dflags)) { return 0; } uint8_t *c,*n; unsigned short *ant; ant=(_uncompressed); n=YPLANE(data); c=YPLANE(_storage); // deNoise(c, n, Line,ant, W, H, W,W, (int *)Coefs[0], (int *)Coefs[0], (int *)Coefs[1]); ant=(_uncompressed)+W*H; n=UPLANE(data); c=UPLANE(_storage); deNoise(c, n, Line, ant, cw, ch, cw,cw, (int *)Coefs[2], (int *)Coefs[2], (int *)Coefs[3]); ant=_uncompressed+((W*H*5)>>2); n=VPLANE(data); c=VPLANE(_storage); deNoise(c, n, Line, ant, cw, ch, cw,cw, (int *)Coefs[2], (int *)Coefs[2], (int *)Coefs[3]); // n is out.... _last=frame; data->copyInfo(_storage); return 1; }
uint8_t ADMVideoMPD3Dlow::getFrameNumberNoAlloc(uint32_t frame, uint32_t *len, ADMImage *data, uint32_t *flags) { UNUSED_ARG(flags); int cw= _info.width>>1; int ch= _info.height>>1; int W = _info.width; int H = _info.height; uint32_t dlen,dflags; if(frame> _info.nb_frames-1) return 0; *len=(W*H*3)>>1; // First and last frame we don"t modify. if(!frame || (frame!=_last+1)) { aprintf("D3D: First /last frame\n"); if(!_in->getFrameNumberNoAlloc(frame, &dlen,data,&dflags)) { return 0; } // store for future use memcpy(_stored->data,data->data,*len); _last=frame; return 1; } ADM_assert(frame<_info.nb_frames); aprintf("D3D: next frame\n"); // read uncompressed frame if(!_in->getFrameNumberNoAlloc(frame, &dlen,_uncompressed,&dflags)) { return 0; } uint8_t *c,*d,*p; d=YPLANE(data); c=YPLANE(_uncompressed); p=YPLANE(_stored); // deNoise(c,p, d, Line, W, H, W,W,W, Coefs[0] + 256, Coefs[0] + 256, Coefs[1] + 256); uint32_t page=W*H; d=UPLANE(data); c=UPLANE(_uncompressed); p=UPLANE(_stored); deNoise(c,p, d, Line, cw, ch, cw,cw,cw, Coefs[2] + 256, Coefs[2] + 256, Coefs[3] + 256); page=page>>2; d=VPLANE(data); c=VPLANE(_uncompressed); p=VPLANE(_stored); deNoise(c,p, d, Line, cw, ch, cw,cw,cw, Coefs[2] + 256, Coefs[2] + 256, Coefs[3] + 256); _last=frame; memcpy(YPLANE(_stored),YPLANE(data),W*H); memcpy(UPLANE(_stored),UPLANE(data),(W*H)>>2); memcpy(VPLANE(_stored),VPLANE(data),(W*H)>>2); data->copyInfo(_uncompressed); return 1; }
// main filter routine int tc_filter(frame_list_t *ptr_, char *options) { vframe_list_t *ptr = (vframe_list_t *)ptr_; static vob_t *vob=NULL; /* FIXME: these use the filter ID as an index--the ID can grow * arbitrarily large, so this needs to be fixed */ static MyFilterData *mfd[100]; static char *buffer[100]; int instance = ptr->filter_id; if(ptr->tag & TC_AUDIO) return 0; if(ptr->tag & TC_FILTER_GET_CONFIG) { char buf[128]; optstr_filter_desc (options, MOD_NAME, MOD_CAP, MOD_VERSION, MOD_AUTHOR, "VYMOE", "2"); tc_snprintf(buf, 128, "%f", PARAM1_DEFAULT); optstr_param (options, "luma", "spatial luma strength", "%f", buf, "0.0", "100.0" ); tc_snprintf(buf, 128, "%f", PARAM2_DEFAULT); optstr_param (options, "chroma", "spatial chroma strength", "%f", buf, "0.0", "100.0" ); tc_snprintf(buf, 128, "%f", PARAM3_DEFAULT); optstr_param (options, "luma_strength", "temporal luma strength", "%f", buf, "0.0", "100.0" ); tc_snprintf(buf, 128, "%f", PARAM3_DEFAULT*PARAM2_DEFAULT/PARAM1_DEFAULT); optstr_param (options, "chroma_strength", "temporal chroma strength", "%f", buf, "0.0", "100.0" ); tc_snprintf(buf, 128, "%d", mfd[instance]->pre); optstr_param (options, "pre", "run as a pre filter", "%d", buf, "0", "1" ); return 0; } if(ptr->tag & TC_FILTER_INIT) { double LumSpac, LumTmp, ChromSpac, ChromTmp; double Param1=0.0, Param2=0.0, Param3=0.0, Param4=0.0; if((vob = tc_get_vob())==NULL) return(-1); if (vob->im_v_codec != TC_CODEC_YUV420P) { tc_log_error(MOD_NAME, "This filter is only capable of YUV 4:2:0 mode"); return -1; } mfd[instance] = tc_zalloc(sizeof(MyFilterData)); if (mfd[instance]) { mfd[instance]->Line = tc_zalloc(TC_MAX_V_FRAME_WIDTH*sizeof(int)); } buffer[instance] = tc_zalloc(SIZE_RGB_FRAME); if (!mfd[instance] || !mfd[instance]->Line || !buffer[instance]) { tc_log_error(MOD_NAME, "Malloc failed"); return -1; } // defaults LumSpac = PARAM1_DEFAULT; LumTmp = PARAM3_DEFAULT; ChromSpac = PARAM2_DEFAULT; ChromTmp = LumTmp * ChromSpac / LumSpac; if (options) { if (optstr_lookup (options, "help")) { help_optstr(); } optstr_get (options, "luma", "%lf", &Param1); optstr_get (options, "luma_strength", "%lf", &Param3); optstr_get (options, "chroma", "%lf", &Param2); optstr_get (options, "chroma_strength","%lf", &Param4); optstr_get (options, "pre", "%d", &mfd[instance]->pre); // recalculate only the needed params if (Param1!=0.0) { LumSpac = Param1; LumTmp = PARAM3_DEFAULT * Param1 / PARAM1_DEFAULT; ChromSpac = PARAM2_DEFAULT * Param1 / PARAM1_DEFAULT; ChromTmp = LumTmp * ChromSpac / LumSpac; } if (Param2!=0.0) { ChromSpac = Param2; ChromTmp = LumTmp * ChromSpac / LumSpac; } if (Param3!=0.0) { LumTmp = Param3; ChromTmp = LumTmp * ChromSpac / LumSpac; } if (Param4!=0.0) { ChromTmp = Param4; } } PrecalcCoefs(mfd[instance]->Coefs[0], LumSpac); PrecalcCoefs(mfd[instance]->Coefs[1], LumTmp); PrecalcCoefs(mfd[instance]->Coefs[2], ChromSpac); PrecalcCoefs(mfd[instance]->Coefs[3], ChromTmp); if(verbose) { tc_log_info(MOD_NAME, "%s %s #%d", MOD_VERSION, MOD_CAP, instance); tc_log_info(MOD_NAME, "Settings luma=%.2f chroma=%.2f luma_strength=%.2f chroma_strength=%.2f", LumSpac, ChromSpac, LumTmp, ChromTmp); } return 0; } //---------------------------------- // // filter close // //---------------------------------- if(ptr->tag & TC_FILTER_CLOSE) { if (buffer[instance]) {free(buffer[instance]); buffer[instance]=NULL;} if (mfd[instance]) { if(mfd[instance]->Line){free(mfd[instance]->Line);mfd[instance]->Line=NULL;} if(mfd[instance]->Frame[0]){free(mfd[instance]->Frame[0]);mfd[instance]->Frame[0]=NULL;} if(mfd[instance]->Frame[1]){free(mfd[instance]->Frame[1]);mfd[instance]->Frame[1]=NULL;} if(mfd[instance]->Frame[2]){free(mfd[instance]->Frame[2]);mfd[instance]->Frame[2]=NULL;} free(mfd[instance]); } mfd[instance]=NULL; return(0); } /* filter close */ //actually do the filter if(((ptr->tag & TC_PRE_M_PROCESS && mfd[instance]->pre) || (ptr->tag & TC_POST_M_PROCESS && !mfd[instance]->pre)) && !(ptr->attributes & TC_FRAME_IS_SKIPPED)) { ac_memcpy (buffer[instance], ptr->video_buf, ptr->video_size); deNoise(buffer[instance], ptr->video_buf, mfd[instance]->Line, &mfd[instance]->Frame[0], ptr->v_width, ptr->v_height, ptr->v_width, ptr->v_width, mfd[instance]->Coefs[0], mfd[instance]->Coefs[0], mfd[instance]->Coefs[1]); deNoise(buffer[instance] + ptr->v_width*ptr->v_height, ptr->video_buf + ptr->v_width*ptr->v_height, mfd[instance]->Line, &mfd[instance]->Frame[1], ptr->v_width>>1, ptr->v_height>>1, ptr->v_width>>1, ptr->v_width>>1, mfd[instance]->Coefs[2], mfd[instance]->Coefs[2], mfd[instance]->Coefs[3]); deNoise(buffer[instance] + 5*ptr->v_width*ptr->v_height/4, ptr->video_buf + 5*ptr->v_width*ptr->v_height/4, mfd[instance]->Line, &mfd[instance]->Frame[2], ptr->v_width>>1, ptr->v_height>>1, ptr->v_width>>1, ptr->v_width>>1, mfd[instance]->Coefs[2], mfd[instance]->Coefs[2], mfd[instance]->Coefs[3]); }