vf_mcdeint.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006 Michael Niedermayer <michaelni@gmx.at>
3  *
4  * This file is part of MPlayer.
5  *
6  * MPlayer is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * MPlayer is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 
22 /*
23 Known Issues:
24 * The motion estimation is somewhat at the mercy of the input, if the input
25  frames are created purely based on spatial interpolation then for example
26  a thin black line or another random and not interpolateable pattern
27  will cause problems
28  Note: completly ignoring the "unavailable" lines during motion estimation
29  didnt look any better, so the most obvious solution would be to improve
30  tfields or penalize problematic motion vectors ...
31 
32 * If non iterative ME is used then snow currently ignores the OBMC window
33  and as a result sometimes creates artifacts
34 
35 * only past frames are used, we should ideally use future frames too, something
36  like filtering the whole movie in forward and then backward direction seems
37  like a interresting idea but the current filter framework is FAR from
38  supporting such things
39 
40 * combining the motion compensated image with the input image also isnt
41  as trivial as it seems, simple blindly taking even lines from one and
42  odd ones from the other doesnt work at all as ME/MC sometimes simple
43  has nothing in the previous frames which matches the current, the current
44  algo has been found by trial and error and almost certainly can be
45  improved ...
46 */
47 
48 #include <stdio.h>
49 #include <stdlib.h>
50 #include <string.h>
51 #include <inttypes.h>
52 #include <math.h>
53 
54 #include "mp_msg.h"
55 #include "cpudetect.h"
56 
57 #include "libavutil/common.h"
58 #include "libavutil/internal.h"
59 #include "libavutil/intreadwrite.h"
60 #include "libavcodec/avcodec.h"
61 #include "libavcodec/dsputil.h"
62 
63 #undef fprintf
64 #undef free
65 #undef malloc
66 
67 #include "img_format.h"
68 #include "mp_image.h"
69 #include "vf.h"
70 #include "av_helpers.h"
71 
72 #define MIN(a,b) ((a) > (b) ? (b) : (a))
73 #define MAX(a,b) ((a) < (b) ? (b) : (a))
74 #define ABS(a) ((a) > 0 ? (a) : (-(a)))
75 
76 //===========================================================================//
77 
78 struct vf_priv_s {
79  int mode;
80  int qp;
81  int parity;
82 #if 0
83  int temp_stride[3];
84  uint8_t *src[3];
85  int16_t *temp[3];
86 #endif
92 };
93 
94 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){
95  int x, y, i;
96 
97  for(i=0; i<3; i++){
98  p->frame->data[i]= src[i];
99  p->frame->linesize[i]= src_stride[i];
100  }
101 
102  p->avctx_enc->me_cmp=
103  p->avctx_enc->me_sub_cmp= FF_CMP_SAD /*| (p->parity ? FF_CMP_ODD : FF_CMP_EVEN)*/;
104  p->frame->quality= p->qp*FF_QP2LAMBDA;
107 
108  for(i=0; i<3; i++){
109  int is_chroma= !!i;
110  int w= width >>is_chroma;
111  int h= height>>is_chroma;
112  int fils= p->frame_dec->linesize[i];
113  int srcs= src_stride[i];
114 
115  for(y=0; y<h; y++){
116  if((y ^ p->parity) & 1){
117  for(x=0; x<w; x++){
118  if((x-2)+(y-1)*w>=0 && (x+2)+(y+1)*w<w*h){ //FIXME either alloc larger images or optimize this
119  uint8_t *filp= &p->frame_dec->data[i][x + y*fils];
120  uint8_t *srcp= &src[i][x + y*srcs];
121  int diff0= filp[-fils] - srcp[-srcs];
122  int diff1= filp[+fils] - srcp[+srcs];
123  int spatial_score= ABS(srcp[-srcs-1] - srcp[+srcs-1])
124  +ABS(srcp[-srcs ] - srcp[+srcs ])
125  +ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;
126  int temp= filp[0];
127 
128 #define CHECK(j)\
129  { int score= ABS(srcp[-srcs-1+(j)] - srcp[+srcs-1-(j)])\
130  + ABS(srcp[-srcs +(j)] - srcp[+srcs -(j)])\
131  + ABS(srcp[-srcs+1+(j)] - srcp[+srcs+1-(j)]);\
132  if(score < spatial_score){\
133  spatial_score= score;\
134  diff0= filp[-fils+(j)] - srcp[-srcs+(j)];\
135  diff1= filp[+fils-(j)] - srcp[+srcs-(j)];
136 
137  CHECK(-1) CHECK(-2) }} }}
138  CHECK( 1) CHECK( 2) }} }}
139 #if 0
140  if((diff0 ^ diff1) > 0){
141  int mindiff= ABS(diff0) > ABS(diff1) ? diff1 : diff0;
142  temp-= mindiff;
143  }
144 #elif 1
145  if(diff0 + diff1 > 0)
146  temp-= (diff0 + diff1 - ABS( ABS(diff0) - ABS(diff1) )/2)/2;
147  else
148  temp-= (diff0 + diff1 + ABS( ABS(diff0) - ABS(diff1) )/2)/2;
149 #else
150  temp-= (diff0 + diff1)/2;
151 #endif
152 #if 1
153  filp[0]=
154  dst[i][x + y*dst_stride[i]]= temp > 255U ? ~(temp>>31) : temp;
155 #else
156  dst[i][x + y*dst_stride[i]]= filp[0];
157  filp[0]= temp > 255U ? ~(temp>>31) : temp;
158 #endif
159  }else
160  dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils];
161  }
162  }
163  }
164  for(y=0; y<h; y++){
165  if(!((y ^ p->parity) & 1)){
166  for(x=0; x<w; x++){
167 #if 1
168  p->frame_dec->data[i][x + y*fils]=
169  dst[i][x + y*dst_stride[i]]= src[i][x + y*srcs];
170 #else
171  dst[i][x + y*dst_stride[i]]= p->frame_dec->data[i][x + y*fils];
172  p->frame_dec->data[i][x + y*fils]= src[i][x + y*srcs];
173 #endif
174  }
175  }
176  }
177  }
178  p->parity ^= 1;
179 
180 }
181 
182 static int config(struct vf_instance *vf,
183  int width, int height, int d_width, int d_height,
184  unsigned int flags, unsigned int outfmt){
185  int i;
187 
188  for(i=0; i<3; i++){
190  AVDictionary *opts = NULL;
191 #if 0
192  int is_chroma= !!i;
193  int w= ((width + 31) & (~31))>>is_chroma;
194  int h= ((height + 31) & (~31))>>is_chroma;
195 
196  vf->priv->temp_stride[i]= w;
197  vf->priv->temp[i]= malloc(vf->priv->temp_stride[i]*h*sizeof(int16_t));
198  vf->priv->src [i]= malloc(vf->priv->temp_stride[i]*h*sizeof(uint8_t));
199 #endif
200  avctx_enc=
202  avctx_enc->width = width;
203  avctx_enc->height = height;
204  avctx_enc->time_base= (AVRational){1,25}; // meaningless
205  avctx_enc->gop_size = 300;
206  avctx_enc->max_b_frames= 0;
207  avctx_enc->pix_fmt = AV_PIX_FMT_YUV420P;
210  avctx_enc->global_quality= 1;
211  av_dict_set(&opts, "memc_only", "1", 0);
212  avctx_enc->me_cmp=
213  avctx_enc->me_sub_cmp= FF_CMP_SAD; //SSE;
214  avctx_enc->mb_cmp= FF_CMP_SSE;
215 
216  switch(vf->priv->mode){
217  case 3:
218  avctx_enc->refs= 3;
219  case 2:
220  avctx_enc->me_method= ME_ITER;
221  case 1:
222  avctx_enc->flags |= CODEC_FLAG_4MV;
223  avctx_enc->dia_size=2;
224 // avctx_enc->mb_decision = MB_DECISION_RD;
225  case 0:
226  avctx_enc->flags |= CODEC_FLAG_QPEL;
227  }
228 
229  avcodec_open2(avctx_enc, enc, &opts);
230  av_dict_free(&opts);
231 
232  }
234 
235  vf->priv->outbuf_size= width*height*10;
236  vf->priv->outbuf= malloc(vf->priv->outbuf_size);
237 
238  return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
239 }
240 
241 static void get_image(struct vf_instance *vf, mp_image_t *mpi){
242  if(mpi->flags&MP_IMGFLAG_PRESERVE) return; // don't change
243 return; //caused problems, dunno why
244  // ok, we can do pp in-place (or pp disabled):
245  vf->dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
246  mpi->type, mpi->flags | MP_IMGFLAG_READABLE, mpi->width, mpi->height);
247  mpi->planes[0]=vf->dmpi->planes[0];
248  mpi->stride[0]=vf->dmpi->stride[0];
249  mpi->width=vf->dmpi->width;
250  if(mpi->flags&MP_IMGFLAG_PLANAR){
251  mpi->planes[1]=vf->dmpi->planes[1];
252  mpi->planes[2]=vf->dmpi->planes[2];
253  mpi->stride[1]=vf->dmpi->stride[1];
254  mpi->stride[2]=vf->dmpi->stride[2];
255  }
256  mpi->flags|=MP_IMGFLAG_DIRECT;
257 }
258 
259 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
260  mp_image_t *dmpi;
261 
262  if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
263  // no DR, so get a new image! hope we'll get DR buffer:
264  dmpi=ff_vf_get_image(vf->next,mpi->imgfmt,
267  mpi->width,mpi->height);
268  ff_vf_clone_mpi_attributes(dmpi, mpi);
269  }else{
270  dmpi=vf->dmpi;
271  }
272 
273  filter(vf->priv, dmpi->planes, mpi->planes, dmpi->stride, mpi->stride, mpi->w, mpi->h);
274 
275  return ff_vf_next_put_image(vf,dmpi, pts);
276 }
277 
278 static void uninit(struct vf_instance *vf){
279  if(!vf->priv) return;
280 
281 #if 0
282  for(i=0; i<3; i++){
283  free(vf->priv->temp[i]);
284  vf->priv->temp[i]= NULL;
285  free(vf->priv->src[i]);
286  vf->priv->src[i]= NULL;
287  }
288 #endif
289  if (vf->priv->avctx_enc) {
291  av_freep(&vf->priv->avctx_enc);
292  }
293 
294  free(vf->priv->outbuf);
295  free(vf->priv);
296  vf->priv=NULL;
297 }
298 
299 //===========================================================================//
300 static int query_format(struct vf_instance *vf, unsigned int fmt){
301  switch(fmt){
302  case IMGFMT_YV12:
303  case IMGFMT_I420:
304  case IMGFMT_IYUV:
305  case IMGFMT_Y800:
306  case IMGFMT_Y8:
307  return ff_vf_next_query_format(vf,fmt);
308  }
309  return 0;
310 }
311 
312 static int vf_open(vf_instance_t *vf, char *args){
313 
314  vf->config=config;
315  vf->put_image=put_image;
316  vf->get_image=get_image;
318  vf->uninit=uninit;
319  vf->priv=malloc(sizeof(struct vf_priv_s));
320  memset(vf->priv, 0, sizeof(struct vf_priv_s));
321 
322  ff_init_avcodec();
323 
324  vf->priv->mode=0;
325  vf->priv->parity= -1;
326  vf->priv->qp=1;
327 
328  if (args) sscanf(args, "%d:%d:%d", &vf->priv->mode, &vf->priv->parity, &vf->priv->qp);
329 
330  return 1;
331 }
332 
334  "motion compensating deinterlacer",
335  "mcdeint",
336  "Michael Niedermayer",
337  "",
338  vf_open,
339  NULL
340 };
unsigned int imgfmt
Definition: mp_image.h:130
static void uninit(struct vf_instance *vf)
Definition: vf_mcdeint.c:278
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
void(* get_image)(struct vf_instance *vf, mp_image_t *mpi)
Definition: vf.h:66
int parity
Definition: vf_mcdeint.c:81
AVCodec * avcodec_find_encoder(enum AVCodecID id)
Find a registered encoder with a matching codec ID.
const char * fmt
Definition: avisynth_c.h:669
AVFrame * coded_frame
the picture in the bitstream
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
#define FF_CMP_SSE
mp_image_t * ff_vf_get_image(vf_instance_t *vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h)
Definition: vf_mp.c:380
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
#define MP_IMGFLAG_PRESERVE
Definition: mp_image.h:46
int temp_stride
Definition: vf_fspp.c:94
#define IMGFMT_YV12
Definition: img_format.h:119
void(* uninit)(struct vf_instance *vf)
Definition: vf.h:74
#define MP_IMGFLAG_READABLE
Definition: mp_image.h:55
#define IMGFMT_Y8
Definition: img_format.h:124
AVFrame * frame
Definition: vf_mcdeint.c:90
output residual component w
#define CODEC_FLAG_QPEL
Use qpel MC.
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
int ff_vf_next_config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt)
Definition: vf_mp.c:584
BYTE int const BYTE * srcp
Definition: avisynth_c.h:713
int width
Definition: mp_image.h:131
filp[0]
Definition: vf_mcdeint.c:153
int(* put_image)(struct vf_instance *vf, mp_image_t *mpi, double pts)
Definition: vf.h:68
uint8_t
int outbuf_size
Definition: vf_mcdeint.c:87
Definition: vf.h:31
static void get_image(struct vf_instance *vf, mp_image_t *mpi)
Definition: vf_mcdeint.c:241
unsigned char * planes[MP_MAX_PLANES]
Definition: mp_image.h:133
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
Definition: vf_mcdeint.c:259
int me_cmp
motion estimation comparison function
int stride[MP_MAX_PLANES]
Definition: mp_image.h:134
int width
Definition: vf_fil.c:32
static int query_format(struct vf_instance *vf, unsigned int fmt)
Definition: vf_mcdeint.c:300
int mode
Definition: vf_ilpack.c:38
Discrete Time axis x
#define U(x)
int avcodec_close(AVCodecContext *avctx)
Close a given AVCodecContext and free all the data associated with it (but not the AVCodecContext its...
int16_t * temp
Definition: vf_fspp.c:99
#define MP_IMGTYPE_TEMP
Definition: mp_image.h:104
int(* query_format)(struct vf_instance *vf, unsigned int fmt)
Definition: vf.h:64
int qp
Definition: vf_fspp.c:95
int me_sub_cmp
subpixel motion estimation comparison function
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
Definition: dict.c:162
int flags
CODEC_FLAG_*.
#define IMGFMT_IYUV
Definition: img_format.h:121
#define CODEC_FLAG_QSCALE
Use fixed qscale.
external API header
#define CODEC_FLAG_LOW_DELAY
Force low delay.
uint8_t * src
Definition: vf_fspp.c:98
#define ABS(a)
Definition: vf_mcdeint.c:74
uint8_t * outbuf
Definition: vf_mcdeint.c:88
common internal API header
AVFrame * avcodec_alloc_frame(void)
Allocate an AVFrame and set its fields to default values.
int refs
number of reference frames
struct AVRational AVRational
rational number numerator/denominator
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
const vf_info_t ff_vf_info_mcdeint
Definition: vf_mcdeint.c:333
#define MP_IMGFLAG_PREFER_ALIGNED_STRIDE
Definition: mp_image.h:61
iterative search
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
int width
picture width / height.
AVFrame * frame_dec
Definition: vf_mcdeint.c:91
int quality
quality (between 1 (good) and FF_LAMBDA_MAX (bad))
Definition: frame.h:185
void ff_init_avcodec(void)
Definition: vf_mp.c:287
void ff_vf_clone_mpi_attributes(mp_image_t *dst, mp_image_t *src)
Definition: vf_mp.c:293
struct vf_instance * next
Definition: vf.h:84
int attribute_align_arg avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVFrame *pict)
NULL
Definition: eval.c:55
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
#define CHECK(j)
main external API structure.
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:62
synthesis window for stochastic i
#define IMGFMT_Y800
Definition: img_format.h:123
int w
Definition: mp_image.h:132
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt)
Definition: vf_mcdeint.c:182
int(* config)(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt)
Definition: vf.h:59
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)
Definition: vf_mcdeint.c:94
int global_quality
Global quality for codecs which cannot change it per frame.
static int vf_open(vf_instance_t *vf, char *args)
Definition: vf_mcdeint.c:312
static int flags
Definition: cpu.c:23
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
int height
Definition: mp_image.h:131
unsigned char type
Definition: mp_image.h:127
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
#define FF_CMP_SAD
AVCodecContext * avctx_enc
Definition: vf_mcdeint.c:89
int mb_cmp
macroblock comparison function (not supported yet)
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:68
common internal and external API header
#define MP_IMGFLAG_PLANAR
Definition: mp_image.h:76
function y
Definition: D.m:1
int ff_vf_next_put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
Definition: vf_mp.c:539
DSP utils.
int dia_size
ME diamond size & shape.
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition: avutil.h:169
#define MP_IMGFLAG_ACCEPT_STRIDE
Definition: mp_image.h:63
struct vf_priv_s * priv
Definition: vf.h:86
#define MP_IMGFLAG_DIRECT
Definition: mp_image.h:91
#define IMGFMT_I420
Definition: img_format.h:120
int h
Definition: mp_image.h:132
int me_method
Motion estimation algorithm used for video coding.
#define CODEC_FLAG_4MV
4 MV per MB allowed / advanced prediction for H.263.
int strict_std_compliance
strictly follow the standard (MPEG4, ...).
int ff_vf_next_query_format(struct vf_instance *vf, unsigned int fmt)
Definition: vf_mp.c:371
Definition: vf.h:56
unsigned int flags
Definition: mp_image.h:126
int height
Definition: vf_fil.c:31
mp_image_t * dmpi
Definition: vf.h:85
MUSIC TECHNOLOGY GROUP UNIVERSITAT POMPEU FABRA Free Non Commercial Binary License Agreement UNIVERSITAT POMPEU OR INDICATING ACCEPTANCE BY SELECTING THE ACCEPT BUTTON ON ANY DOWNLOAD OR INSTALL YOU ACCEPT THE TERMS OF THE LICENSE SUMMARY TABLE Software MELODIA Melody Extraction vamp plug in Licensor Music Technology Group Universitat Pompeu Plaça de la Spain Permitted purposes Non commercial internal research and validation and educational purposes only All commercial uses in a production either internal or are prohibited by this license and require an additional commercial exploitation license TERMS AND CONDITIONS SOFTWARE Software means the software programs identified herein in binary any other machine readable any updates or error corrections provided by and any user programming guides and other documentation provided to you by UPF under this Agreement LICENSE Subject to the terms and conditions of this UPF grants you a royalty free