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 int out_size;
00096
00097 for(i=0; i<3; i++){
00098 p->frame->data[i]= src[i];
00099 p->frame->linesize[i]= src_stride[i];
00100 }
00101
00102 p->avctx_enc->me_cmp=
00103 p->avctx_enc->me_sub_cmp= FF_CMP_SAD ;
00104 p->frame->quality= p->qp*FF_QP2LAMBDA;
00105 out_size = avcodec_encode_video(p->avctx_enc, p->outbuf, p->outbuf_size, p->frame);
00106 p->frame_dec = p->avctx_enc->coded_frame;
00107
00108 for(i=0; i<3; i++){
00109 int is_chroma= !!i;
00110 int w= width >>is_chroma;
00111 int h= height>>is_chroma;
00112 int fils= p->frame_dec->linesize[i];
00113 int srcs= src_stride[i];
00114
00115 for(y=0; y<h; y++){
00116 if((y ^ p->parity) & 1){
00117 for(x=0; x<w; x++){
00118 if((x-2)+(y-1)*w>=0 && (x+2)+(y+1)*w<w*h){
00119 uint8_t *filp= &p->frame_dec->data[i][x + y*fils];
00120 uint8_t *srcp= &src[i][x + y*srcs];
00121 int diff0= filp[-fils] - srcp[-srcs];
00122 int diff1= filp[+fils] - srcp[+srcs];
00123 int spatial_score= ABS(srcp[-srcs-1] - srcp[+srcs-1])
00124 +ABS(srcp[-srcs ] - srcp[+srcs ])
00125 +ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
00126 int temp= filp[0];
00127
00128 #define CHECK(j)\
00129 { int score= ABS(srcp[-srcs-1+j] - srcp[+srcs-1-j])\
00130 + ABS(srcp[-srcs +j] - srcp[+srcs -j])\
00131 + ABS(srcp[-srcs+1+j] - srcp[+srcs+1-j]);\
00132 if(score < spatial_score){\
00133 spatial_score= score;\
00134 diff0= filp[-fils+j] - srcp[-srcs+j];\
00135 diff1= filp[+fils-j] - srcp[+srcs-j];
00136
00137 CHECK(-1) CHECK(-2) }} }}
00138 CHECK( 1) CHECK( 2) }} }}
00139 #if 0
00140 if((diff0 ^ diff1) > 0){
00141 int mindiff= ABS(diff0) > ABS(diff1) ? diff1 : diff0;
00142 temp-= mindiff;
00143 }
00144 #elif 1
00145 if(diff0 + diff1 > 0)
00146 temp-= (diff0 + diff1 - ABS( ABS(diff0) - ABS(diff1) )/2)/2;
00147 else
00148 temp-= (diff0 + diff1 + ABS( ABS(diff0) - ABS(diff1) )/2)/2;
00149 #else
00150 temp-= (diff0 + diff1)/2;
00151 #endif
00152 #if 1
00153 filp[0]=
00154 dst[i][x + y*dst_stride[i]]= temp > 255U ? ~(temp>>31) : temp;
00155 #else
00156 dst[i][x + y*dst_stride[i]]= filp[0];
00157 filp[0]= temp > 255U ? ~(temp>>31) : temp;
00158 #endif
00159 }else
00160 dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils];
00161 }
00162 }
00163 }
00164 for(y=0; y<h; y++){
00165 if(!((y ^ p->parity) & 1)){
00166 for(x=0; x<w; x++){
00167 #if 1
00168 p->frame_dec->data[i][x + y*fils]=
00169 dst[i][x + y*dst_stride[i]]= src[i][x + y*srcs];
00170 #else
00171 dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils];
00172 p->frame_dec->data[i][x + y*fils]= src[i][x + y*srcs];
00173 #endif
00174 }
00175 }
00176 }
00177 }
00178 p->parity ^= 1;
00179
00180 }
00181
00182 static int config(struct vf_instance *vf,
00183 int width, int height, int d_width, int d_height,
00184 unsigned int flags, unsigned int outfmt){
00185 int i;
00186 AVCodec *enc= avcodec_find_encoder(CODEC_ID_SNOW);
00187
00188 for(i=0; i<3; i++){
00189 AVCodecContext *avctx_enc;
00190 #if 0
00191 int is_chroma= !!i;
00192 int w= ((width + 31) & (~31))>>is_chroma;
00193 int h= ((height + 31) & (~31))>>is_chroma;
00194
00195 vf->priv->temp_stride[i]= w;
00196 vf->priv->temp[i]= malloc(vf->priv->temp_stride[i]*h*sizeof(int16_t));
00197 vf->priv->src [i]= malloc(vf->priv->temp_stride[i]*h*sizeof(uint8_t));
00198 #endif
00199 avctx_enc=
00200 vf->priv->avctx_enc= avcodec_alloc_context();
00201 avctx_enc->width = width;
00202 avctx_enc->height = height;
00203 avctx_enc->time_base= (AVRational){1,25};
00204 avctx_enc->gop_size = 300;
00205 avctx_enc->max_b_frames= 0;
00206 avctx_enc->pix_fmt = PIX_FMT_YUV420P;
00207 avctx_enc->flags = CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
00208 avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
00209 avctx_enc->global_quality= 1;
00210 avctx_enc->flags2= CODEC_FLAG2_MEMC_ONLY;
00211 avctx_enc->me_cmp=
00212 avctx_enc->me_sub_cmp= FF_CMP_SAD;
00213 avctx_enc->mb_cmp= FF_CMP_SSE;
00214
00215 switch(vf->priv->mode){
00216 case 3:
00217 avctx_enc->refs= 3;
00218 case 2:
00219 avctx_enc->me_method= ME_ITER;
00220 case 1:
00221 avctx_enc->flags |= CODEC_FLAG_4MV;
00222 avctx_enc->dia_size=2;
00223
00224 case 0:
00225 avctx_enc->flags |= CODEC_FLAG_QPEL;
00226 }
00227
00228 avcodec_open(avctx_enc, enc);
00229
00230 }
00231 vf->priv->frame= avcodec_alloc_frame();
00232
00233 vf->priv->outbuf_size= width*height*10;
00234 vf->priv->outbuf= malloc(vf->priv->outbuf_size);
00235
00236 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
00237 }
00238
00239 static void get_image(struct vf_instance *vf, mp_image_t *mpi){
00240 if(mpi->flags&MP_IMGFLAG_PRESERVE) return;
00241 return;
00242
00243 vf->dmpi=vf_get_image(vf->next,mpi->imgfmt,
00244 mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
00245 mpi->planes[0]=vf->dmpi->planes[0];
00246 mpi->stride[0]=vf->dmpi->stride[0];
00247 mpi->width=vf->dmpi->width;
00248 if(mpi->flags&MP_IMGFLAG_PLANAR){
00249 mpi->planes[1]=vf->dmpi->planes[1];
00250 mpi->planes[2]=vf->dmpi->planes[2];
00251 mpi->stride[1]=vf->dmpi->stride[1];
00252 mpi->stride[2]=vf->dmpi->stride[2];
00253 }
00254 mpi->flags|=MP_IMGFLAG_DIRECT;
00255 }
00256
00257 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
00258 mp_image_t *dmpi;
00259
00260 if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
00261
00262 dmpi=vf_get_image(vf->next,mpi->imgfmt,
00263 MP_IMGTYPE_TEMP,
00264 MP_IMGFLAG_ACCEPT_STRIDE|MP_IMGFLAG_PREFER_ALIGNED_STRIDE,
00265 mpi->width,mpi->height);
00266 vf_clone_mpi_attributes(dmpi, mpi);
00267 }else{
00268 dmpi=vf->dmpi;
00269 }
00270
00271 filter(vf->priv, dmpi->planes, mpi->planes, dmpi->stride, mpi->stride, mpi->w, mpi->h);
00272
00273 return vf_next_put_image(vf,dmpi, pts);
00274 }
00275
00276 static void uninit(struct vf_instance *vf){
00277 if(!vf->priv) return;
00278
00279 #if 0
00280 for(i=0; i<3; i++){
00281 free(vf->priv->temp[i]);
00282 vf->priv->temp[i]= NULL;
00283 free(vf->priv->src[i]);
00284 vf->priv->src[i]= NULL;
00285 }
00286 #endif
00287 if (vf->priv->avctx_enc) {
00288 avcodec_close(vf->priv->avctx_enc);
00289 av_freep(&vf->priv->avctx_enc);
00290 }
00291
00292 free(vf->priv->outbuf);
00293 free(vf->priv);
00294 vf->priv=NULL;
00295 }
00296
00297
00298 static int query_format(struct vf_instance *vf, unsigned int fmt){
00299 switch(fmt){
00300 case IMGFMT_YV12:
00301 case IMGFMT_I420:
00302 case IMGFMT_IYUV:
00303 case IMGFMT_Y800:
00304 case IMGFMT_Y8:
00305 return vf_next_query_format(vf,fmt);
00306 }
00307 return 0;
00308 }
00309
00310 static int vf_open(vf_instance_t *vf, char *args){
00311
00312 vf->config=config;
00313 vf->put_image=put_image;
00314 vf->get_image=get_image;
00315 vf->query_format=query_format;
00316 vf->uninit=uninit;
00317 vf->priv=malloc(sizeof(struct vf_priv_s));
00318 memset(vf->priv, 0, sizeof(struct vf_priv_s));
00319
00320 init_avcodec();
00321
00322 vf->priv->mode=0;
00323 vf->priv->parity= -1;
00324 vf->priv->qp=1;
00325
00326 if (args) sscanf(args, "%d:%d:%d", &vf->priv->mode, &vf->priv->parity, &vf->priv->qp);
00327
00328 return 1;
00329 }
00330
00331 const vf_info_t vf_info_mcdeint = {
00332 "motion compensating deinterlacer",
00333 "mcdeint",
00334 "Michael Niedermayer",
00335 "",
00336 vf_open,
00337 NULL
00338 };