Fix crash with partial fribidi conversion.
[mplayer/greg.git] / libmpcodecs / vf_lavcdeint.c
blob061a7d392e6b6f3941ce7e3bf7910e096d3025e8
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <inttypes.h>
6 #include "config.h"
7 #include "mp_msg.h"
8 #include "help_mp.h"
10 #include "img_format.h"
11 #include "mp_image.h"
12 #include "vf.h"
13 #include "libavcodec/avcodec.h"
15 extern int avcodec_initialized;
17 struct vf_priv_s
19 int width, height;
20 int pix_fmt;
23 /* Support for avcodec's built-in deinterlacer.
24 * Based on vf_lavc.c
27 //===========================================================================//
30 /* Convert mplayer's IMGFMT_* to avcodec's PIX_FMT_* for the supported
31 * IMGFMT's, and return -1 if the deinterlacer doesn't support
32 * that format (-1 because 0 is a valid PIX_FMT).
34 /* The deinterlacer supports planer 4:2:0, 4:2:2, and 4:4:4 YUV */
35 static int
36 imgfmt_to_pixfmt (int imgfmt)
38 switch(imgfmt)
40 /* I hope I got all the supported formats */
42 /* 4:2:0 */
43 case IMGFMT_YV12:
44 case IMGFMT_I420:
45 case IMGFMT_IYUV:
46 return PIX_FMT_YUV420P;
47 break;
49 #if 0
50 /* 4:2:2 */
51 case IMGFMT_UYVY:
52 case IMGFMT_UYNV:
53 case IMGFMT_Y422:
54 case IMGFMT_YUY2:
55 case IMGFMT_YUNV:
56 case IMGFMT_YVYU:
57 case IMGFMT_Y42T:
58 case IMGFMT_V422:
59 case IMGFMT_V655:
60 return PIX_FMT_YUV422P;
61 break;
62 #endif
64 /* Are there any _planar_ YUV 4:4:4 formats? */
66 default:
67 return -1;
72 static int
73 config (struct vf_instance_s* vf,
74 int width, int height, int d_width, int d_height,
75 unsigned int flags, unsigned int outfmt)
77 struct vf_priv_s *priv = vf->priv;
79 priv->pix_fmt = imgfmt_to_pixfmt(outfmt);
80 if(priv->pix_fmt == -1)
81 return 0;
83 /* The deinterlacer will fail if this is false */
84 if ((width & 3) != 0 || (height & 3) != 0)
85 return 0;
87 /* If we get here, the deinterlacer is guaranteed not to fail */
89 priv->width = width;
90 priv->height = height;
92 return vf_next_config(vf,
93 width, height,
94 d_width, d_height,
95 flags, outfmt);
98 static int
99 put_image (struct vf_instance_s* vf, mp_image_t *mpi, double pts)
101 struct vf_priv_s *priv = vf->priv;
102 mp_image_t* dmpi;
103 AVPicture pic;
104 AVPicture lavc_picture;
106 lavc_picture.data[0] = mpi->planes[0];
107 lavc_picture.data[1] = mpi->planes[1];
108 lavc_picture.data[2] = mpi->planes[2];
109 lavc_picture.linesize[0] = mpi->stride[0];
110 lavc_picture.linesize[1] = mpi->stride[1];
111 lavc_picture.linesize[2] = mpi->stride[2];
113 dmpi = vf_get_image(vf->next, mpi->imgfmt,
114 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
115 priv->width, priv->height);
117 pic.data[0] = dmpi->planes[0];
118 pic.data[1] = dmpi->planes[1];
119 pic.data[2] = dmpi->planes[2];
120 pic.linesize[0] = dmpi->stride[0];
121 pic.linesize[1] = dmpi->stride[1];
122 pic.linesize[2] = dmpi->stride[2];
124 if (avpicture_deinterlace(&pic, &lavc_picture,
125 priv->pix_fmt, priv->width, priv->height) < 0)
127 /* This should not happen -- see config() */
128 return 0;
131 return vf_next_put_image(vf, dmpi, pts);
135 static int
136 query_format (struct vf_instance_s* vf, unsigned int fmt)
138 if(imgfmt_to_pixfmt(fmt) == -1)
139 return 0;
141 return vf_next_query_format(vf,fmt);
145 static int
146 open (vf_instance_t *vf, char* args)
148 /* We don't have any args */
149 (void) args;
151 vf->config = config;
152 vf->put_image = put_image;
153 vf->query_format = query_format;
154 vf->priv = malloc(sizeof(struct vf_priv_s));
155 memset(vf->priv,0,sizeof(struct vf_priv_s));
157 /* This may not technically be necessary just for a deinterlace,
158 * but it seems like a good idea.
160 if(!avcodec_initialized)
162 avcodec_init();
163 avcodec_register_all();
164 avcodec_initialized=1;
167 return 1;
171 const vf_info_t vf_info_lavcdeint = {
172 "libavcodec's deinterlacing filter",
173 "lavcdeint",
174 "Joe Rabinoff",
175 "libavcodec's internal deinterlacer, in case you don't like "
176 "the builtin ones (invoked with -pp or -npp)",
177 open,
178 NULL
182 //===========================================================================//