libmpcodecs/vf_tinterlace.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003 Michael Zucchi <notzed@ximian.com>
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 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include "config.h"
26 #include "mp_msg.h"
27 
28 #include "img_format.h"
29 #include "mp_image.h"
30 #include "vf.h"
31 
32 #include "libvo/fastmemcpy.h"
33 
34 struct vf_priv_s {
35  int mode;
36  int frame;
38 };
39 
40 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
41 {
42  int ret = 0;
44 
45  switch (vf->priv->mode) {
46  case 0:
47  dmpi = vf->priv->dmpi;
48  if (dmpi == NULL) {
49  dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
52  mpi->width, mpi->height*2);
53 
54  vf->priv->dmpi = dmpi;
55 
56  memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
57  dmpi->stride[0]*2, mpi->stride[0]);
58  if (mpi->flags & MP_IMGFLAG_PLANAR) {
59  memcpy_pic(dmpi->planes[1], mpi->planes[1],
60  mpi->chroma_width, mpi->chroma_height,
61  dmpi->stride[1]*2, mpi->stride[1]);
62  memcpy_pic(dmpi->planes[2], mpi->planes[2],
63  mpi->chroma_width, mpi->chroma_height,
64  dmpi->stride[2]*2, mpi->stride[2]);
65  }
66  } else {
67  vf->priv->dmpi = NULL;
68 
69  memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h,
70  dmpi->stride[0]*2, mpi->stride[0]);
71  if (mpi->flags & MP_IMGFLAG_PLANAR) {
72  memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1],
73  mpi->chroma_width, mpi->chroma_height,
74  dmpi->stride[1]*2, mpi->stride[1]);
75  memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2],
76  mpi->chroma_width, mpi->chroma_height,
77  dmpi->stride[2]*2, mpi->stride[2]);
78  }
79  ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
80  }
81  break;
82  case 1:
83  if (vf->priv->frame & 1)
84  ret = ff_vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
85  break;
86  case 2:
87  if ((vf->priv->frame & 1) == 0)
88  ret = ff_vf_next_put_image(vf, mpi, MP_NOPTS_VALUE);
89  break;
90  case 3:
91  dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
93  mpi->width, mpi->height*2);
94  /* fixme, just clear alternate lines */
95  ff_vf_mpi_clear(dmpi, 0, 0, dmpi->w, dmpi->h);
96  if ((vf->priv->frame & 1) == 0) {
97  memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h,
98  dmpi->stride[0]*2, mpi->stride[0]);
99  if (mpi->flags & MP_IMGFLAG_PLANAR) {
100  memcpy_pic(dmpi->planes[1], mpi->planes[1],
101  mpi->chroma_width, mpi->chroma_height,
102  dmpi->stride[1]*2, mpi->stride[1]);
103  memcpy_pic(dmpi->planes[2], mpi->planes[2],
104  mpi->chroma_width, mpi->chroma_height,
105  dmpi->stride[2]*2, mpi->stride[2]);
106  }
107  } else {
108  memcpy_pic(dmpi->planes[0]+dmpi->stride[0], mpi->planes[0], mpi->w, mpi->h,
109  dmpi->stride[0]*2, mpi->stride[0]);
110  if (mpi->flags & MP_IMGFLAG_PLANAR) {
111  memcpy_pic(dmpi->planes[1]+dmpi->stride[1], mpi->planes[1],
112  mpi->chroma_width, mpi->chroma_height,
113  dmpi->stride[1]*2, mpi->stride[1]);
114  memcpy_pic(dmpi->planes[2]+dmpi->stride[2], mpi->planes[2],
115  mpi->chroma_width, mpi->chroma_height,
116  dmpi->stride[2]*2, mpi->stride[2]);
117  }
118  }
119  ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
120  break;
121  case 4:
122  // Interleave even lines (only) from Frame 'i' with odd
123  // lines (only) from Frame 'i+1', halving the Frame
124  // rate and preserving image height.
125 
126  dmpi = vf->priv->dmpi;
127 
128  // @@ Need help: Should I set dmpi->fields to indicate
129  // that the (new) frame will be interlaced!? E.g. ...
130  // dmpi->fields |= MP_IMGFIELD_INTERLACED;
131  // dmpi->fields |= MP_IMGFIELD_TOP_FIRST;
132  // etc.
133 
134  if (dmpi == NULL) {
135  dmpi = ff_vf_get_image(vf->next, mpi->imgfmt,
138  mpi->width, mpi->height);
139 
140  vf->priv->dmpi = dmpi;
141 
142  my_memcpy_pic(dmpi->planes[0], mpi->planes[0], mpi->w, mpi->h/2,
143  dmpi->stride[0]*2, mpi->stride[0]*2);
144  if (mpi->flags & MP_IMGFLAG_PLANAR) {
145  my_memcpy_pic(dmpi->planes[1], mpi->planes[1],
146  mpi->chroma_width, mpi->chroma_height/2,
147  dmpi->stride[1]*2, mpi->stride[1]*2);
148  my_memcpy_pic(dmpi->planes[2], mpi->planes[2],
149  mpi->chroma_width, mpi->chroma_height/2,
150  dmpi->stride[2]*2, mpi->stride[2]*2);
151  }
152  } else {
153  vf->priv->dmpi = NULL;
154 
155  my_memcpy_pic(dmpi->planes[0]+dmpi->stride[0],
156  mpi->planes[0]+mpi->stride[0],
157  mpi->w, mpi->h/2,
158  dmpi->stride[0]*2, mpi->stride[0]*2);
159  if (mpi->flags & MP_IMGFLAG_PLANAR) {
160  my_memcpy_pic(dmpi->planes[1]+dmpi->stride[1],
161  mpi->planes[1]+mpi->stride[1],
162  mpi->chroma_width, mpi->chroma_height/2,
163  dmpi->stride[1]*2, mpi->stride[1]*2);
164  my_memcpy_pic(dmpi->planes[2]+dmpi->stride[2],
165  mpi->planes[2]+mpi->stride[2],
166  mpi->chroma_width, mpi->chroma_height/2,
167  dmpi->stride[2]*2, mpi->stride[2]*2);
168  }
169  ret = ff_vf_next_put_image(vf, dmpi, MP_NOPTS_VALUE);
170  }
171  break;
172  }
173 
174  vf->priv->frame++;
175 
176  return ret;
177 }
178 
179 static int query_format(struct vf_instance *vf, unsigned int fmt)
180 {
181  /* FIXME - figure out which other formats work */
182  switch (fmt) {
183  case IMGFMT_YV12:
184  case IMGFMT_IYUV:
185  case IMGFMT_I420:
186  return ff_vf_next_query_format(vf, fmt);
187  }
188  return 0;
189 }
190 
191 static int config(struct vf_instance *vf,
192  int width, int height, int d_width, int d_height,
193  unsigned int flags, unsigned int outfmt)
194 {
195  switch (vf->priv->mode) {
196  case 0:
197  case 3:
198  return ff_vf_next_config(vf,width,height*2,d_width,d_height*2,flags,outfmt);
199  case 1: /* odd frames */
200  case 2: /* even frames */
201  case 4: /* alternate frame (height-preserving) interlacing */
202  return ff_vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
203  }
204  return 0;
205 }
206 
207 static void uninit(struct vf_instance *vf)
208 {
209  free(vf->priv);
210 }
211 
212 static int vf_open(vf_instance_t *vf, char *args)
213 {
214  struct vf_priv_s *p;
215  vf->config = config;
216  vf->put_image = put_image;
218  vf->uninit = uninit;
220  vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
221  p->mode = 0;
222  if (args)
223  sscanf(args, "%d", &p->mode);
224  p->frame = 0;
225  return 1;
226 }
227 
229  "temporal field interlacing",
230  "tinterlace",
231  "Michael Zucchi",
232  "",
233  vf_open,
234  NULL
235 };
static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height, unsigned int flags, unsigned int outfmt)
unsigned int imgfmt
Definition: mp_image.h:130
const char * fmt
Definition: avisynth_c.h:669
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
#define MP_IMGFLAG_PRESERVE
Definition: mp_image.h:46
#define IMGFMT_YV12
Definition: img_format.h:119
void(* uninit)(struct vf_instance *vf)
Definition: vf.h:74
AVFrame * frame
Definition: vf_mcdeint.c:90
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
int width
Definition: mp_image.h:131
int(* put_image)(struct vf_instance *vf, mp_image_t *mpi, double pts)
Definition: vf.h:68
Definition: vf.h:31
unsigned char * planes[MP_MAX_PLANES]
Definition: mp_image.h:133
int stride[MP_MAX_PLANES]
Definition: mp_image.h:134
int width
Definition: vf_fil.c:32
int mode
Definition: vf_ilpack.c:38
int chroma_height
Definition: mp_image.h:143
#define MP_IMGTYPE_TEMP
Definition: mp_image.h:104
int(* query_format)(struct vf_instance *vf, unsigned int fmt)
Definition: vf.h:64
#define MP_IMGTYPE_STATIC
Definition: mp_image.h:102
#define IMGFMT_IYUV
Definition: img_format.h:121
ret
Definition: avfilter.c:821
unsigned int default_reqs
Definition: vf.h:79
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
struct vf_instance * next
Definition: vf.h:84
NULL
Definition: eval.c:55
#define memcpy_pic(d, s, b, h, ds, ss)
Definition: fastmemcpy.h:62
int chroma_width
Definition: mp_image.h:142
int w
Definition: mp_image.h:132
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 int flags
Definition: cpu.c:23
static int vf_open(vf_instance_t *vf, char *args)
int height
Definition: mp_image.h:131
#define my_memcpy_pic(d, s, b, h, ds, ss)
Definition: fastmemcpy.h:63
static int query_format(struct vf_instance *vf, unsigned int fmt)
#define MP_IMGFLAG_PLANAR
Definition: mp_image.h:76
int ff_vf_next_put_image(struct vf_instance *vf, mp_image_t *mpi, double pts)
Definition: vf_mp.c:539
void ff_vf_mpi_clear(mp_image_t *mpi, int x0, int y0, int w, int h)
Definition: vf_mp.c:327
const vf_info_t ff_vf_info_tinterlace
#define MP_IMGFLAG_ACCEPT_STRIDE
Definition: mp_image.h:63
struct vf_priv_s * priv
Definition: vf.h:86
#define IMGFMT_I420
Definition: img_format.h:120
int h
Definition: mp_image.h:132
#define VFCAP_ACCEPT_STRIDE
Definition: vfcap.h:44
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
static void uninit(struct vf_instance *vf)
#define MP_NOPTS_VALUE
Definition: vf.h:118
int height
Definition: vf_fil.c:31
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