00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include <stdio.h>
00049 #include <stdlib.h>
00050 #include <string.h>
00051 #include <inttypes.h>
00052 #include <math.h>
00053
00054 #include "mp_msg.h"
00055 #include "cpudetect.h"
00056
00057 #include "libavutil/internal.h"
00058 #include "libavutil/intreadwrite.h"
00059 #include "libavcodec/avcodec.h"
00060 #include "libavcodec/dsputil.h"
00061
00062 #undef fprintf
00063 #undef free
00064 #undef malloc
00065
00066 #include "img_format.h"
00067 #include "mp_image.h"
00068 #include "vf.h"
00069 #include "vd_ffmpeg.h"
00070
00071 #define MIN(a,b) ((a) > (b) ? (b) : (a))
00072 #define MAX(a,b) ((a) < (b) ? (b) : (a))
00073 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
00074
00075
00076
00077 struct vf_priv_s {
00078 int mode;
00079 int qp;
00080 int parity;
00081 #if 0
00082 int temp_stride[3];
00083 uint8_t *src[3];
00084 int16_t *temp[3];
00085 #endif
00086 int outbuf_size;
00087 uint8_t *outbuf;
00088 AVCodecContext *avctx_enc;
00089 AVFrame *frame;
00090 AVFrame *frame_dec;
00091 };
00092
00093 static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int dst_stride[3], int src_stride[3], int width, int height){
00094 int x, y, i;
00095
00096 for(i=0; i<3; i++){
00097 p->frame->data[i]= src[i];
00098 p->frame->linesize[i]= src_stride[i];
00099 }
00100
00101 p->avctx_enc->me_cmp=
00102 p->avctx_enc->me_sub_cmp= FF_CMP_SAD ;
00103 p->frame->quality= p->qp*FF_QP2LAMBDA;
00104 avcodec_encode_video(p->avctx_enc, p->outbuf, p->outbuf_size, p->frame);
00105 p->frame_dec = p->avctx_enc->coded_frame;
00106
00107 for(i=0; i<3; i++){
00108 int is_chroma= !!i;
00109 int w= width >>is_chroma;
00110 int h= height>>is_chroma;
00111 int fils= p->frame_dec->linesize[i];
00112 int srcs= src_stride[i];
00113
00114 for(y=0; y<h; y++){
00115 if((y ^ p->parity) & 1){
00116 for(x=0; x<w; x++){
00117 if((x-2)+(y-1)*w>=0 && (x+2)+(y+1)*w<w*h){
00118 uint8_t *filp= &p->frame_dec->data[i][x + y*fils];
00119 uint8_t *srcp= &src[i][x + y*srcs];
00120 int diff0= filp[-fils] - srcp[-srcs];
00121 int diff1= filp[+fils] - srcp[+srcs];
00122 int spatial_score= ABS(srcp[-srcs-1] - srcp[+srcs-1])
00123 +ABS(srcp[-srcs ] - srcp[+srcs ])
00124 +ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
00125 int temp= filp[0];
00126
00127 #define CHECK(j)\
00128 { int score= ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
00129 + ABS(srcp[-srcs +j] - srcp[+srcs -j])\
00130 + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
00131 if(score < spatial_score){\
00132 spatial_score= score;\
00133 diff0= filp[-fils+j] - srcp[-srcs+j];\
00134 diff1= filp[+fils-j] - srcp[+srcs-j];
00135
00136 CHECK(-1) CHECK(-2) }} }}
00137 CHECK( 1) CHECK( 2) }} }}
00138 #if 0
00139 if((diff0 ^ diff1) > 0){
00140 int mindiff= ABS(diff0) > ABS(diff1) ? diff1 : diff0;
00141 temp-= mindiff;
00142 }
00143 #elif 1
00144 if(diff0 + diff1 > 0)
00145 temp-= (diff0 + diff1 - ABS( ABS(diff0) - ABS(diff1) )/2)/2;
00146 else
00147 temp-= (diff0 + diff1 + ABS( ABS(diff0) - ABS(diff1) )/2)/2;
00148 #else
00149 temp-= (diff0 + diff1)/2;
00150 #endif
00151 #if 1
00152 filp[0]=
00153 dst[i][x + y*dst_stride[i]]= temp > 255U ? ~(temp>>31) : temp;
00154 #else
00155 dst[i][x + y*dst_stride[i]]= filp[0];
00156 filp[0]= temp > 255U ? ~(temp>>31) : temp;
00157 #endif
00158 }else
00159 dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils];
00160 }
00161 }
00162 }
00163 for(y=0; y<h; y++){
00164 if(!((y ^ p->parity) & 1)){
00165 for(x=0; x<w; x++){
00166 #if 1
00167 p->frame_dec->data[i][x + y*fils]=
00168 dst[i][x + y*dst_stride[i]]= src[i][x + y*srcs];
00169 #else
00170 dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils];
00171 p->frame_dec->data[i][x + y*fils]= src[i][x + y*srcs];
00172 #endif
00173 }
00174 }
00175 }
00176 }
00177 p->parity ^= 1;
00178
00179 }
00180
00181 static int config(struct vf_instance *vf,
00182 int width, int height, int d_width, int d_height,
00183 unsigned int flags, unsigned int outfmt){
00184 int i;
00185 AVCodec *enc= avcodec_find_encoder(CODEC_ID_SNOW);
00186
00187 for(i=0; i<3; i++){
00188 AVCodecContext *avctx_enc;
00189 #if 0
00190 int is_chroma= !!i;
00191 int w= ((width + 31) & (~31))>>is_chroma;
00192 int h= ((height + 31) & (~31))>>is_chroma;
00193
00194 vf->priv->temp_stride[i]= w;
00195 vf->priv->temp[i]= malloc(vf->priv->temp_stride[i]*h*sizeof(int16_t));
00196 vf->priv->src [i]= malloc(vf->priv->temp_stride[i]*h*sizeof(uint8_t));
00197 #endif
00198 avctx_enc=
00199 vf->priv->avctx_enc= avcodec_alloc_context();
00200 avctx_enc->width = width;
00201 avctx_enc->height = height;
00202 avctx_enc->time_base= (AVRational){1,25};
00203 avctx_enc->gop_size = 300;
00204 avctx_enc->max_b_frames= 0;
00205 avctx_enc->pix_fmt = PIX_FMT_YUV420P;
00206 avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
00207 avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
00208 avctx_enc->global_quality= 1;
00209 avctx_enc->flags2= CODEC_FLAG2_MEMC_ONLY;
00210 avctx_enc->me_cmp=
00211 avctx_enc->me_sub_cmp= FF_CMP_SAD;
00212 avctx_enc->mb_cmp= FF_CMP_SSE;
00213
00214 switch(vf->priv->mode){
00215 case 3:
00216 avctx_enc->refs= 3;
00217 case 2:
00218 avctx_enc->me_method= ME_ITER;
00219 case 1:
00220 avctx_enc->flags |= CODEC_FLAG_4MV;
00221 avctx_enc->dia_size=2;
00222
00223 case 0:
00224 avctx_enc->flags |= CODEC_FLAG_QPEL;
00225 }
00226
00227 avcodec_open(avctx_enc, enc);
00228
00229 }
00230 vf->priv->frame= avcodec_alloc_frame();
00231
00232 vf->priv->outbuf_size= width*height*10;
00233 vf->priv->outbuf= malloc(vf->priv->outbuf_size);
00234
00235 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
00236 }
00237
00238 static void get_image(struct vf_instance *vf, mp_image_t *mpi){
00239 if(mpi->flags&MP_IMGFLAG_PRESERVE) return;
00240 return;
00241
00242 vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
00243 mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
00244 mpi->planes[0]=vf->dmpi->planes[0];
00245 mpi->stride[0]=vf->dmpi->stride[0];
00246 mpi->width=vf->dmpi->width;
00247 if(mpi->flags&MP_IMGFLAG_PLANAR){
00248 mpi->planes[1]=vf->dmpi->planes[1];
00249 mpi->planes[2]=vf->dmpi->planes[2];
00250 mpi->stride[1]=vf->dmpi->stride[1];
00251 mpi->stride[2]=vf->dmpi->stride[2];
00252 }
00253 mpi->flags|=MP_IMGFLAG_DIRECT;
00254 }
00255
00256 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
00257 mp_image_t *dmpi;
00258
00259 if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
00260
00261 dmpi=vf_get_image(vf->next,mpi->imgfmt,
00262 MP_IMGTYPE_TEMP,
00263 MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
00264 mpi->width,mpi->height);
00265 vf_clone_mpi_attributes(dmpi, mpi);
00266 }else{
00267 dmpi=vf->dmpi;
00268 }
00269
00270 filter(vf->priv, dmpi->planes, mpi->planes, dmpi->stride, mpi->stride, mpi->w, mpi->h);
00271
00272 return vf_next_put_image(vf,dmpi, pts);
00273 }
00274
00275 static void uninit(struct vf_instance *vf){
00276 if(!vf->priv) return;
00277
00278 #if 0
00279 for(i=0; i<3; i++){
00280 free(vf->priv->temp[i]);
00281 vf->priv->temp[i]= NULL;
00282 free(vf->priv->src[i]);
00283 vf->priv->src[i]= NULL;
00284 }
00285 #endif
00286 if (vf->priv->avctx_enc) {
00287 avcodec_close(vf->priv->avctx_enc);
00288 av_freep(&vf->priv->avctx_enc);
00289 }
00290
00291 free(vf->priv->outbuf);
00292 free(vf->priv);
00293 vf->priv=NULL;
00294 }
00295
00296
00297 static int query_format(struct vf_instance *vf, unsigned int fmt){
00298 switch(fmt){
00299 case IMGFMT_YV12:
00300 case IMGFMT_I420:
00301 case IMGFMT_IYUV:
00302 case IMGFMT_Y800:
00303 case IMGFMT_Y8:
00304 return vf_next_query_format(vf,fmt);
00305 }
00306 return 0;
00307 }
00308
00309 static int vf_open(vf_instance_t *vf, char *args){
00310
00311 vf->config=config;
00312 vf->put_image=put_image;
00313 vf->get_image=get_image;
00314 vf->query_format=query_format;
00315 vf->uninit=uninit;
00316 vf->priv=malloc(sizeof(struct vf_priv_s));
00317 memset(vf->priv, 0, sizeof(struct vf_priv_s));
00318
00319 init_avcodec();
00320
00321 vf->priv->mode=0;
00322 vf->priv->parity= -1;
00323 vf->priv->qp=1;
00324
00325 if (args) sscanf(args, "%d:%d:%d", &vf->priv->mode, &vf->priv->parity, &vf->priv->qp);
00326
00327 return 1;
00328 }
00329
00330 const vf_info_t vf_info_mcdeint = {
00331 "motion compensating deinterlacer",
00332 "mcdeint",
00333 "Michael Niedermayer",
00334 "",
00335 vf_open,
00336 NULL
00337 };