avfilter: remove av_opt_set_defaults() from process_options()
[ffmpeg.git] / libavfilter / vf_mp.c
1 /*
2  * Copyright (c) 2011 Michael Niedermayer
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg 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  * FFmpeg 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
17  * along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  *
20  * Parts of this file have been stolen from mplayer
21  */
22
23 /**
24  * @file
25  */
26
27 #include "avfilter.h"
28 #include "video.h"
29 #include "formats.h"
30 #include "internal.h"
31 #include "libavutil/avassert.h"
32 #include "libavutil/pixdesc.h"
33 #include "libavutil/intreadwrite.h"
34 #include "libavutil/imgutils.h"
35 #include "libavutil/opt.h"
36
37 #include "libmpcodecs/vf.h"
38 #include "libmpcodecs/img_format.h"
39 #include "libmpcodecs/cpudetect.h"
40 #include "libmpcodecs/av_helpers.h"
41 #include "libmpcodecs/vf_scale.h"
42 #include "libmpcodecs/libvo/fastmemcpy.h"
43
44 #include "libswscale/swscale.h"
45
46
47 //FIXME maybe link the orig in
48 //XXX: identical pix_fmt must be following with each others
49 static const struct {
50     int fmt;
51     enum AVPixelFormat pix_fmt;
52 } conversion_map[] = {
53     {IMGFMT_ARGB, AV_PIX_FMT_ARGB},
54     {IMGFMT_BGRA, AV_PIX_FMT_BGRA},
55     {IMGFMT_BGR24, AV_PIX_FMT_BGR24},
56     {IMGFMT_BGR16BE, AV_PIX_FMT_RGB565BE},
57     {IMGFMT_BGR16LE, AV_PIX_FMT_RGB565LE},
58     {IMGFMT_BGR15BE, AV_PIX_FMT_RGB555BE},
59     {IMGFMT_BGR15LE, AV_PIX_FMT_RGB555LE},
60     {IMGFMT_BGR12BE, AV_PIX_FMT_RGB444BE},
61     {IMGFMT_BGR12LE, AV_PIX_FMT_RGB444LE},
62     {IMGFMT_BGR8,  AV_PIX_FMT_RGB8},
63     {IMGFMT_BGR4,  AV_PIX_FMT_RGB4},
64     {IMGFMT_BGR1,  AV_PIX_FMT_MONOBLACK},
65     {IMGFMT_RGB1,  AV_PIX_FMT_MONOBLACK},
66     {IMGFMT_RG4B,  AV_PIX_FMT_BGR4_BYTE},
67     {IMGFMT_BG4B,  AV_PIX_FMT_RGB4_BYTE},
68     {IMGFMT_RGB48LE, AV_PIX_FMT_RGB48LE},
69     {IMGFMT_RGB48BE, AV_PIX_FMT_RGB48BE},
70     {IMGFMT_ABGR, AV_PIX_FMT_ABGR},
71     {IMGFMT_RGBA, AV_PIX_FMT_RGBA},
72     {IMGFMT_RGB24, AV_PIX_FMT_RGB24},
73     {IMGFMT_RGB16BE, AV_PIX_FMT_BGR565BE},
74     {IMGFMT_RGB16LE, AV_PIX_FMT_BGR565LE},
75     {IMGFMT_RGB15BE, AV_PIX_FMT_BGR555BE},
76     {IMGFMT_RGB15LE, AV_PIX_FMT_BGR555LE},
77     {IMGFMT_RGB12BE, AV_PIX_FMT_BGR444BE},
78     {IMGFMT_RGB12LE, AV_PIX_FMT_BGR444LE},
79     {IMGFMT_RGB8,  AV_PIX_FMT_BGR8},
80     {IMGFMT_RGB4,  AV_PIX_FMT_BGR4},
81     {IMGFMT_BGR8,  AV_PIX_FMT_PAL8},
82     {IMGFMT_YUY2,  AV_PIX_FMT_YUYV422},
83     {IMGFMT_UYVY,  AV_PIX_FMT_UYVY422},
84     {IMGFMT_NV12,  AV_PIX_FMT_NV12},
85     {IMGFMT_NV21,  AV_PIX_FMT_NV21},
86     {IMGFMT_Y800,  AV_PIX_FMT_GRAY8},
87     {IMGFMT_Y8,    AV_PIX_FMT_GRAY8},
88     {IMGFMT_YVU9,  AV_PIX_FMT_YUV410P},
89     {IMGFMT_IF09,  AV_PIX_FMT_YUV410P},
90     {IMGFMT_YV12,  AV_PIX_FMT_YUV420P},
91     {IMGFMT_I420,  AV_PIX_FMT_YUV420P},
92     {IMGFMT_IYUV,  AV_PIX_FMT_YUV420P},
93     {IMGFMT_411P,  AV_PIX_FMT_YUV411P},
94     {IMGFMT_422P,  AV_PIX_FMT_YUV422P},
95     {IMGFMT_444P,  AV_PIX_FMT_YUV444P},
96     {IMGFMT_440P,  AV_PIX_FMT_YUV440P},
97
98     {IMGFMT_420A,  AV_PIX_FMT_YUVA420P},
99
100     {IMGFMT_420P16_LE,  AV_PIX_FMT_YUV420P16LE},
101     {IMGFMT_420P16_BE,  AV_PIX_FMT_YUV420P16BE},
102     {IMGFMT_422P16_LE,  AV_PIX_FMT_YUV422P16LE},
103     {IMGFMT_422P16_BE,  AV_PIX_FMT_YUV422P16BE},
104     {IMGFMT_444P16_LE,  AV_PIX_FMT_YUV444P16LE},
105     {IMGFMT_444P16_BE,  AV_PIX_FMT_YUV444P16BE},
106
107     // YUVJ are YUV formats that use the full Y range and not just
108     // 16 - 235 (see colorspaces.txt).
109     // Currently they are all treated the same way.
110     {IMGFMT_YV12,  AV_PIX_FMT_YUVJ420P},
111     {IMGFMT_422P,  AV_PIX_FMT_YUVJ422P},
112     {IMGFMT_444P,  AV_PIX_FMT_YUVJ444P},
113     {IMGFMT_440P,  AV_PIX_FMT_YUVJ440P},
114
115     {IMGFMT_XVMC_MOCO_MPEG2, AV_PIX_FMT_XVMC_MPEG2_MC},
116     {IMGFMT_XVMC_IDCT_MPEG2, AV_PIX_FMT_XVMC_MPEG2_IDCT},
117     {IMGFMT_VDPAU_MPEG1,     AV_PIX_FMT_VDPAU_MPEG1},
118     {IMGFMT_VDPAU_MPEG2,     AV_PIX_FMT_VDPAU_MPEG2},
119     {IMGFMT_VDPAU_H264,      AV_PIX_FMT_VDPAU_H264},
120     {IMGFMT_VDPAU_WMV3,      AV_PIX_FMT_VDPAU_WMV3},
121     {IMGFMT_VDPAU_VC1,       AV_PIX_FMT_VDPAU_VC1},
122     {IMGFMT_VDPAU_MPEG4,     AV_PIX_FMT_VDPAU_MPEG4},
123     {0, AV_PIX_FMT_NONE}
124 };
125
126 extern const vf_info_t ff_vf_info_dint;
127 extern const vf_info_t ff_vf_info_eq2;
128 extern const vf_info_t ff_vf_info_eq;
129 extern const vf_info_t ff_vf_info_fil;
130 extern const vf_info_t ff_vf_info_fspp;
131 extern const vf_info_t ff_vf_info_ilpack;
132 extern const vf_info_t ff_vf_info_mcdeint;
133 extern const vf_info_t ff_vf_info_perspective;
134 extern const vf_info_t ff_vf_info_phase;
135 extern const vf_info_t ff_vf_info_pp7;
136 extern const vf_info_t ff_vf_info_pullup;
137 extern const vf_info_t ff_vf_info_qp;
138 extern const vf_info_t ff_vf_info_sab;
139 extern const vf_info_t ff_vf_info_softpulldown;
140 extern const vf_info_t ff_vf_info_spp;
141 extern const vf_info_t ff_vf_info_uspp;
142
143
144 static const vf_info_t* const filters[]={
145     &ff_vf_info_dint,
146     &ff_vf_info_eq2,
147     &ff_vf_info_eq,
148     &ff_vf_info_fil,
149     &ff_vf_info_fspp,
150     &ff_vf_info_ilpack,
151     &ff_vf_info_mcdeint,
152     &ff_vf_info_perspective,
153     &ff_vf_info_phase,
154     &ff_vf_info_pp7,
155     &ff_vf_info_pullup,
156     &ff_vf_info_qp,
157     &ff_vf_info_sab,
158     &ff_vf_info_softpulldown,
159     &ff_vf_info_spp,
160     &ff_vf_info_uspp,
161
162     NULL
163 };
164
165 /*
166 Unsupported filters
167 1bpp
168 ass
169 bmovl
170 crop
171 dvbscale
172 flip
173 expand
174 format
175 halfpack
176 lavc
177 lavcdeint
178 noformat
179 pp
180 scale
181 tfields
182 vo
183 yadif
184 zrmjpeg
185 */
186
187 CpuCaps ff_gCpuCaps; //FIXME initialize this so optims work
188
189 enum AVPixelFormat ff_mp2ff_pix_fmt(int mp){
190     int i;
191     for(i=0; conversion_map[i].fmt && mp != conversion_map[i].fmt; i++)
192         ;
193     return mp == conversion_map[i].fmt ? conversion_map[i].pix_fmt : AV_PIX_FMT_NONE;
194 }
195
196 static void ff_sws_getFlagsAndFilterFromCmdLine(int *flags, SwsFilter **srcFilterParam, SwsFilter **dstFilterParam)
197 {
198         static int firstTime=1;
199         *flags=0;
200
201 #if ARCH_X86
202         if(ff_gCpuCaps.hasMMX)
203                 __asm__ volatile("emms\n\t"::: "memory"); //FIXME this should not be required but it IS (even for non-MMX versions)
204 #endif
205         if(firstTime)
206         {
207                 firstTime=0;
208                 *flags= SWS_PRINT_INFO;
209         }
210         else if( ff_mp_msg_test(MSGT_VFILTER,MSGL_DBG2) ) *flags= SWS_PRINT_INFO;
211
212         switch(SWS_BILINEAR)
213         {
214                 case 0: *flags|= SWS_FAST_BILINEAR; break;
215                 case 1: *flags|= SWS_BILINEAR; break;
216                 case 2: *flags|= SWS_BICUBIC; break;
217                 case 3: *flags|= SWS_X; break;
218                 case 4: *flags|= SWS_POINT; break;
219                 case 5: *flags|= SWS_AREA; break;
220                 case 6: *flags|= SWS_BICUBLIN; break;
221                 case 7: *flags|= SWS_GAUSS; break;
222                 case 8: *flags|= SWS_SINC; break;
223                 case 9: *flags|= SWS_LANCZOS; break;
224                 case 10:*flags|= SWS_SPLINE; break;
225                 default:*flags|= SWS_BILINEAR; break;
226         }
227
228         *srcFilterParam= NULL;
229         *dstFilterParam= NULL;
230 }
231
232 //exact copy from vf_scale.c
233 // will use sws_flags & src_filter (from cmd line)
234 struct SwsContext *ff_sws_getContextFromCmdLine(int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat)
235 {
236         int flags, i;
237         SwsFilter *dstFilterParam, *srcFilterParam;
238         enum AVPixelFormat dfmt, sfmt;
239
240         for(i=0; conversion_map[i].fmt && dstFormat != conversion_map[i].fmt; i++);
241         dfmt= conversion_map[i].pix_fmt;
242         for(i=0; conversion_map[i].fmt && srcFormat != conversion_map[i].fmt; i++);
243         sfmt= conversion_map[i].pix_fmt;
244
245         if (srcFormat == IMGFMT_RGB8 || srcFormat == IMGFMT_BGR8) sfmt = AV_PIX_FMT_PAL8;
246         ff_sws_getFlagsAndFilterFromCmdLine(&flags, &srcFilterParam, &dstFilterParam);
247
248         return sws_getContext(srcW, srcH, sfmt, dstW, dstH, dfmt, flags , srcFilterParam, dstFilterParam, NULL);
249 }
250
251 typedef struct {
252     const AVClass *class;
253     vf_instance_t vf;
254     vf_instance_t next_vf;
255     AVFilterContext *avfctx;
256     int frame_returned;
257     char *filter;
258 } MPContext;
259
260 #define OFFSET(x) offsetof(MPContext, x)
261 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
262 static const AVOption mp_options[] = {
263     { "filter", "set MPlayer filter name and parameters", OFFSET(filter), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
264     { NULL }
265 };
266
267 AVFILTER_DEFINE_CLASS(mp);
268
269 void ff_mp_msg(int mod, int lev, const char *format, ... ){
270     va_list va;
271     va_start(va, format);
272     //FIXME convert lev/mod
273     av_vlog(NULL, AV_LOG_DEBUG, format, va);
274     va_end(va);
275 }
276
277 int ff_mp_msg_test(int mod, int lev){
278     return 123;
279 }
280
281 void ff_init_avcodec(void)
282 {
283     //we maybe should init but its kinda 1. unneeded 2. a bit inpolite from here
284 }
285
286 //Exact copy of vf.c
287 void ff_vf_clone_mpi_attributes(mp_image_t* dst, mp_image_t* src){
288     dst->pict_type= src->pict_type;
289     dst->fields = src->fields;
290     dst->qscale_type= src->qscale_type;
291     if(dst->width == src->width && dst->height == src->height){
292         dst->qstride= src->qstride;
293         dst->qscale= src->qscale;
294     }
295 }
296
297 //Exact copy of vf.c
298 void ff_vf_next_draw_slice(struct vf_instance *vf,unsigned char** src, int * stride,int w, int h, int x, int y){
299     if (vf->next->draw_slice) {
300         vf->next->draw_slice(vf->next,src,stride,w,h,x,y);
301         return;
302     }
303     if (!vf->dmpi) {
304         ff_mp_msg(MSGT_VFILTER,MSGL_ERR,"draw_slice: dmpi not stored by vf_%s\n", vf->info->name);
305         return;
306     }
307     if (!(vf->dmpi->flags & MP_IMGFLAG_PLANAR)) {
308         memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+vf->dmpi->bpp/8*x,
309             src[0], vf->dmpi->bpp/8*w, h, vf->dmpi->stride[0], stride[0]);
310         return;
311     }
312     memcpy_pic(vf->dmpi->planes[0]+y*vf->dmpi->stride[0]+x, src[0],
313         w, h, vf->dmpi->stride[0], stride[0]);
314     memcpy_pic(vf->dmpi->planes[1]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[1]+(x>>vf->dmpi->chroma_x_shift),
315         src[1], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[1], stride[1]);
316     memcpy_pic(vf->dmpi->planes[2]+(y>>vf->dmpi->chroma_y_shift)*vf->dmpi->stride[2]+(x>>vf->dmpi->chroma_x_shift),
317         src[2], w>>vf->dmpi->chroma_x_shift, h>>vf->dmpi->chroma_y_shift, vf->dmpi->stride[2], stride[2]);
318 }
319
320 //Exact copy of vf.c
321 void ff_vf_mpi_clear(mp_image_t* mpi,int x0,int y0,int w,int h){
322     int y;
323     if(mpi->flags&MP_IMGFLAG_PLANAR){
324         y0&=~1;h+=h&1;
325         if(x0==0 && w==mpi->width){
326             // full width clear:
327             memset(mpi->planes[0]+mpi->stride[0]*y0,0,mpi->stride[0]*h);
328             memset(mpi->planes[1]+mpi->stride[1]*(y0>>mpi->chroma_y_shift),128,mpi->stride[1]*(h>>mpi->chroma_y_shift));
329             memset(mpi->planes[2]+mpi->stride[2]*(y0>>mpi->chroma_y_shift),128,mpi->stride[2]*(h>>mpi->chroma_y_shift));
330         } else
331         for(y=y0;y<y0+h;y+=2){
332             memset(mpi->planes[0]+x0+mpi->stride[0]*y,0,w);
333             memset(mpi->planes[0]+x0+mpi->stride[0]*(y+1),0,w);
334             memset(mpi->planes[1]+(x0>>mpi->chroma_x_shift)+mpi->stride[1]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift));
335             memset(mpi->planes[2]+(x0>>mpi->chroma_x_shift)+mpi->stride[2]*(y>>mpi->chroma_y_shift),128,(w>>mpi->chroma_x_shift));
336         }
337         return;
338     }
339     // packed:
340     for(y=y0;y<y0+h;y++){
341         unsigned char* dst=mpi->planes[0]+mpi->stride[0]*y+(mpi->bpp>>3)*x0;
342         if(mpi->flags&MP_IMGFLAG_YUV){
343             unsigned int* p=(unsigned int*) dst;
344             int size=(mpi->bpp>>3)*w/4;
345             int i;
346 #if HAVE_BIGENDIAN
347 #define CLEAR_PACKEDYUV_PATTERN 0x00800080
348 #define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x80008000
349 #else
350 #define CLEAR_PACKEDYUV_PATTERN 0x80008000
351 #define CLEAR_PACKEDYUV_PATTERN_SWAPPED 0x00800080
352 #endif
353             if(mpi->flags&MP_IMGFLAG_SWAPPED){
354                 for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN_SWAPPED;
355                 for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN_SWAPPED;
356             } else {
357                 for(i=0;i<size-3;i+=4) p[i]=p[i+1]=p[i+2]=p[i+3]=CLEAR_PACKEDYUV_PATTERN;
358                 for(;i<size;i++) p[i]=CLEAR_PACKEDYUV_PATTERN;
359             }
360         } else
361             memset(dst,0,(mpi->bpp>>3)*w);
362     }
363 }
364
365 int ff_vf_next_query_format(struct vf_instance *vf, unsigned int fmt){
366     return 1;
367 }
368
369 //used by delogo
370 unsigned int ff_vf_match_csp(vf_instance_t** vfp,const unsigned int* list,unsigned int preferred){
371     return preferred;
372 }
373
374 mp_image_t* ff_vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h){
375     MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, next_vf));
376   mp_image_t* mpi=NULL;
377   int w2;
378   int number = mp_imgtype >> 16;
379
380   av_assert0(vf->next == NULL); // all existing filters call this just on next
381
382   //vf_dint needs these as it calls ff_vf_get_image() before configuring the output
383   if(vf->w==0 && w>0) vf->w=w;
384   if(vf->h==0 && h>0) vf->h=h;
385
386   av_assert0(w == -1 || w >= vf->w);
387   av_assert0(h == -1 || h >= vf->h);
388   av_assert0(vf->w > 0);
389   av_assert0(vf->h > 0);
390
391   av_log(m->avfctx, AV_LOG_DEBUG, "get_image: %d:%d, vf: %d:%d\n", w,h,vf->w,vf->h);
392
393   if (w == -1) w = vf->w;
394   if (h == -1) h = vf->h;
395
396   w2=(mp_imgflag&MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE)?((w+15)&(~15)):w;
397
398   // Note: we should call libvo first to check if it supports direct rendering
399   // and if not, then fallback to software buffers:
400   switch(mp_imgtype & 0xff){
401   case MP_IMGTYPE_EXPORT:
402     if(!vf->imgctx.export_images[0]) vf->imgctx.export_images[0]=ff_new_mp_image(w2,h);
403     mpi=vf->imgctx.export_images[0];
404     break;
405   case MP_IMGTYPE_STATIC:
406     if(!vf->imgctx.static_images[0]) vf->imgctx.static_images[0]=ff_new_mp_image(w2,h);
407     mpi=vf->imgctx.static_images[0];
408     break;
409   case MP_IMGTYPE_TEMP:
410     if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=ff_new_mp_image(w2,h);
411     mpi=vf->imgctx.temp_images[0];
412     break;
413   case MP_IMGTYPE_IPB:
414     if(!(mp_imgflag&MP_IMGFLAG_READABLE)){ // B frame:
415       if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=ff_new_mp_image(w2,h);
416       mpi=vf->imgctx.temp_images[0];
417       break;
418     }
419   case MP_IMGTYPE_IP:
420     if(!vf->imgctx.static_images[vf->imgctx.static_idx]) vf->imgctx.static_images[vf->imgctx.static_idx]=ff_new_mp_image(w2,h);
421     mpi=vf->imgctx.static_images[vf->imgctx.static_idx];
422     vf->imgctx.static_idx^=1;
423     break;
424   case MP_IMGTYPE_NUMBERED:
425     if (number == -1) {
426       int i;
427       for (i = 0; i < NUM_NUMBERED_MPI; i++)
428         if (!vf->imgctx.numbered_images[i] || !vf->imgctx.numbered_images[i]->usage_count)
429           break;
430       number = i;
431     }
432     if (number < 0 || number >= NUM_NUMBERED_MPI) return NULL;
433     if (!vf->imgctx.numbered_images[number]) vf->imgctx.numbered_images[number] = ff_new_mp_image(w2,h);
434     mpi = vf->imgctx.numbered_images[number];
435     mpi->number = number;
436     break;
437   }
438   if(mpi){
439     mpi->type=mp_imgtype;
440     mpi->w=vf->w; mpi->h=vf->h;
441     // keep buffer allocation status & color flags only:
442 //    mpi->flags&=~(MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE|MP_IMGFLAG_DIRECT);
443     mpi->flags&=MP_IMGFLAG_ALLOCATED|MP_IMGFLAG_TYPE_DISPLAYED|MP_IMGFLAGMASK_COLORS;
444     // accept restrictions, draw_slice and palette flags only:
445     mpi->flags|=mp_imgflag&(MP_IMGFLAGMASK_RESTRICTIONS|MP_IMGFLAG_DRAW_CALLBACK|MP_IMGFLAG_RGB_PALETTE);
446     if(!vf->draw_slice) mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;
447     if(mpi->width!=w2 || mpi->height!=h){
448 //      printf("vf.c: MPI parameters changed!  %dx%d -> %dx%d   \n", mpi->width,mpi->height,w2,h);
449         if(mpi->flags&MP_IMGFLAG_ALLOCATED){
450             if(mpi->width<w2 || mpi->height<h){
451                 // need to re-allocate buffer memory:
452                 av_free(mpi->planes[0]);
453                 mpi->flags&=~MP_IMGFLAG_ALLOCATED;
454                 ff_mp_msg(MSGT_VFILTER,MSGL_V,"vf.c: have to REALLOCATE buffer memory :(\n");
455             }
456 //      } else {
457         } {
458             mpi->width=w2; mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift;
459             mpi->height=h; mpi->chroma_height=(h + (1<<mpi->chroma_y_shift) - 1)>>mpi->chroma_y_shift;
460         }
461     }
462     if(!mpi->bpp) ff_mp_image_setfmt(mpi,outfmt);
463     if(!(mpi->flags&MP_IMGFLAG_ALLOCATED) && mpi->type>MP_IMGTYPE_EXPORT){
464
465         av_assert0(!vf->get_image);
466         // check libvo first!
467         if(vf->get_image) vf->get_image(vf,mpi);
468
469         if(!(mpi->flags&MP_IMGFLAG_DIRECT)){
470           // non-direct and not yet allocated image. allocate it!
471           if (!mpi->bpp) { // no way we can allocate this
472               ff_mp_msg(MSGT_DECVIDEO, MSGL_FATAL,
473                      "ff_vf_get_image: Tried to allocate a format that can not be allocated!\n");
474               return NULL;
475           }
476
477           // check if codec prefer aligned stride:
478           if(mp_imgflag&MP_IMGFLAG_PREFER_ALIGNED_STRIDE){
479               int align=(mpi->flags&MP_IMGFLAG_PLANAR &&
480                          mpi->flags&MP_IMGFLAG_YUV) ?
481                          (8<<mpi->chroma_x_shift)-1 : 15; // -- maybe FIXME
482               w2=((w+align)&(~align));
483               if(mpi->width!=w2){
484 #if 0
485                   // we have to change width... check if we CAN co it:
486                   int flags=vf->query_format(vf,outfmt); // should not fail
487                   if(!(flags&3)) ff_mp_msg(MSGT_DECVIDEO,MSGL_WARN,"??? ff_vf_get_image{vf->query_format(outfmt)} failed!\n");
488 //                printf("query -> 0x%X    \n",flags);
489                   if(flags&VFCAP_ACCEPT_STRIDE){
490 #endif
491                       mpi->width=w2;
492                       mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift;
493 //                  }
494               }
495           }
496
497           ff_mp_image_alloc_planes(mpi);
498 //        printf("clearing img!\n");
499           ff_vf_mpi_clear(mpi,0,0,mpi->width,mpi->height);
500         }
501     }
502     av_assert0(!vf->start_slice);
503     if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)
504         if(vf->start_slice) vf->start_slice(vf,mpi);
505     if(!(mpi->flags&MP_IMGFLAG_TYPE_DISPLAYED)){
506             ff_mp_msg(MSGT_DECVIDEO,MSGL_V,"*** [%s] %s%s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",
507                   "NULL"/*vf->info->name*/,
508                   (mpi->type==MP_IMGTYPE_EXPORT)?"Exporting":
509                   ((mpi->flags&MP_IMGFLAG_DIRECT)?"Direct Rendering":"Allocating"),
510                   (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)?" (slices)":"",
511                   mpi->width,mpi->height,mpi->bpp,
512                   (mpi->flags&MP_IMGFLAG_YUV)?"YUV":((mpi->flags&MP_IMGFLAG_SWAPPED)?"BGR":"RGB"),
513                   (mpi->flags&MP_IMGFLAG_PLANAR)?"planar":"packed",
514                   mpi->bpp*mpi->width*mpi->height/8);
515             ff_mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"(imgfmt: %x, planes: %p,%p,%p strides: %d,%d,%d, chroma: %dx%d, shift: h:%d,v:%d)\n",
516                 mpi->imgfmt, mpi->planes[0], mpi->planes[1], mpi->planes[2],
517                 mpi->stride[0], mpi->stride[1], mpi->stride[2],
518                 mpi->chroma_width, mpi->chroma_height, mpi->chroma_x_shift, mpi->chroma_y_shift);
519             mpi->flags|=MP_IMGFLAG_TYPE_DISPLAYED;
520     }
521
522   mpi->qscale = NULL;
523   mpi->usage_count++;
524   }
525 //    printf("\rVF_MPI: %p %p %p %d %d %d    \n",
526 //      mpi->planes[0],mpi->planes[1],mpi->planes[2],
527 //      mpi->stride[0],mpi->stride[1],mpi->stride[2]);
528   return mpi;
529 }
530
531 int ff_vf_next_put_image(struct vf_instance *vf,mp_image_t *mpi, double pts){
532     MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, vf));
533     AVFilterLink *outlink     = m->avfctx->outputs[0];
534     AVFrame *picref = av_frame_alloc();
535     int i;
536
537     av_assert0(vf->next);
538
539     av_log(m->avfctx, AV_LOG_DEBUG, "ff_vf_next_put_image\n");
540
541     if (!picref)
542         goto fail;
543
544     picref->width  = mpi->w;
545     picref->height = mpi->h;
546
547     picref->type = AVMEDIA_TYPE_VIDEO;
548
549     for(i=0; conversion_map[i].fmt && mpi->imgfmt != conversion_map[i].fmt; i++);
550     picref->format = conversion_map[i].pix_fmt;
551
552     memcpy(picref->linesize, mpi->stride, FFMIN(sizeof(picref->linesize), sizeof(mpi->stride)));
553
554     for(i=0; i<4 && mpi->stride[i]; i++){
555         picref->data[i] = mpi->planes[i];
556     }
557
558     if(pts != MP_NOPTS_VALUE)
559         picref->pts= pts * av_q2d(outlink->time_base);
560
561     if(1) { // mp buffers are currently unsupported in libavfilter, we thus must copy
562         AVFrame *tofree = picref;
563         picref = av_frame_clone(picref);
564         av_frame_free(&tofree);
565     }
566
567     ff_filter_frame(outlink, picref);
568     m->frame_returned++;
569
570     return 1;
571 fail:
572     av_frame_free(&picref);
573     return 0;
574 }
575
576 int ff_vf_next_config(struct vf_instance *vf,
577         int width, int height, int d_width, int d_height,
578         unsigned int voflags, unsigned int outfmt){
579
580     av_assert0(width>0 && height>0);
581     vf->next->w = width; vf->next->h = height;
582
583     return 1;
584 #if 0
585     int flags=vf->next->query_format(vf->next,outfmt);
586     if(!flags){
587         // hmm. colorspace mismatch!!!
588         //this is fatal for us ATM
589         return 0;
590     }
591     ff_mp_msg(MSGT_VFILTER,MSGL_V,"REQ: flags=0x%X  req=0x%X  \n",flags,vf->default_reqs);
592     miss=vf->default_reqs - (flags&vf->default_reqs);
593     if(miss&VFCAP_ACCEPT_STRIDE){
594         // vf requires stride support but vf->next doesn't support it!
595         // let's insert the 'expand' filter, it does the job for us:
596         vf_instance_t* vf2=vf_open_filter(vf->next,"expand",NULL);
597         if(!vf2) return 0; // shouldn't happen!
598         vf->next=vf2;
599     }
600     vf->next->w = width; vf->next->h = height;
601     return 1;
602 #endif
603 }
604
605 int ff_vf_next_control(struct vf_instance *vf, int request, void* data){
606     MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, vf));
607     av_log(m->avfctx, AV_LOG_DEBUG, "Received control %d\n", request);
608     return 0;
609 }
610
611 static int vf_default_query_format(struct vf_instance *vf, unsigned int fmt){
612     MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, vf));
613     int i;
614     av_log(m->avfctx, AV_LOG_DEBUG, "query %X\n", fmt);
615
616     for(i=0; conversion_map[i].fmt; i++){
617         if(fmt==conversion_map[i].fmt)
618             return 1; //we suport all
619     }
620     return 0;
621 }
622
623
624 static av_cold int init(AVFilterContext *ctx)
625 {
626     MPContext *m = ctx->priv;
627     int cpu_flags = av_get_cpu_flags();
628     char name[256];
629     const char *args;
630     int i;
631
632     ff_gCpuCaps.hasMMX      = cpu_flags & AV_CPU_FLAG_MMX;
633     ff_gCpuCaps.hasMMX2     = cpu_flags & AV_CPU_FLAG_MMX2;
634     ff_gCpuCaps.hasSSE      = cpu_flags & AV_CPU_FLAG_SSE;
635     ff_gCpuCaps.hasSSE2     = cpu_flags & AV_CPU_FLAG_SSE2;
636     ff_gCpuCaps.hasSSE3     = cpu_flags & AV_CPU_FLAG_SSE3;
637     ff_gCpuCaps.hasSSSE3    = cpu_flags & AV_CPU_FLAG_SSSE3;
638     ff_gCpuCaps.hasSSE4     = cpu_flags & AV_CPU_FLAG_SSE4;
639     ff_gCpuCaps.hasSSE42    = cpu_flags & AV_CPU_FLAG_SSE42;
640     ff_gCpuCaps.hasAVX      = cpu_flags & AV_CPU_FLAG_AVX;
641     ff_gCpuCaps.has3DNow    = cpu_flags & AV_CPU_FLAG_3DNOW;
642     ff_gCpuCaps.has3DNowExt = cpu_flags & AV_CPU_FLAG_3DNOWEXT;
643
644     m->avfctx= ctx;
645
646     args = m->filter;
647     if(!args || 1!=sscanf(args, "%255[^:=]", name)){
648         av_log(ctx, AV_LOG_ERROR, "Invalid parameter.\n");
649         return AVERROR(EINVAL);
650     }
651     args += strlen(name);
652     if (args[0] == '=')
653         args++;
654
655     for(i=0; ;i++){
656         if(!filters[i] || !strcmp(name, filters[i]->name))
657             break;
658     }
659
660     if(!filters[i]){
661         av_log(ctx, AV_LOG_ERROR, "Unknown filter %s\n", name);
662         return AVERROR(EINVAL);
663     }
664
665     av_log(ctx, AV_LOG_WARNING,
666            "'%s' is a wrapped MPlayer filter (libmpcodecs). This filter may be removed\n"
667            "once it has been ported to a native libavfilter.\n", name);
668
669     memset(&m->vf,0,sizeof(m->vf));
670     m->vf.info= filters[i];
671
672     m->vf.next        = &m->next_vf;
673     m->vf.put_image   = ff_vf_next_put_image;
674     m->vf.config      = ff_vf_next_config;
675     m->vf.query_format= vf_default_query_format;
676     m->vf.control     = ff_vf_next_control;
677     m->vf.default_caps=VFCAP_ACCEPT_STRIDE;
678     m->vf.default_reqs=0;
679     if(m->vf.info->opts)
680         av_log(ctx, AV_LOG_ERROR, "opts / m_struct_set is unsupported\n");
681 #if 0
682     if(vf->info->opts) { // vf_vo get some special argument
683       const m_struct_t* st = vf->info->opts;
684       void* vf_priv = m_struct_alloc(st);
685       int n;
686       for(n = 0 ; args && args[2*n] ; n++)
687         m_struct_set(st,vf_priv,args[2*n],args[2*n+1]);
688       vf->priv = vf_priv;
689       args = NULL;
690     } else // Otherwise we should have the '_oldargs_'
691       if(args && !strcmp(args[0],"_oldargs_"))
692         args = (char**)args[1];
693       else
694         args = NULL;
695 #endif
696     if(m->vf.info->vf_open(&m->vf, (char*)args)<=0){
697         av_log(ctx, AV_LOG_ERROR, "vf_open() of %s with arg=%s failed\n", name, args);
698         return -1;
699     }
700
701     return 0;
702 }
703
704 static av_cold void uninit(AVFilterContext *ctx)
705 {
706     MPContext *m = ctx->priv;
707     vf_instance_t *vf = &m->vf;
708
709     while(vf){
710         vf_instance_t *next = vf->next;
711         if(vf->uninit)
712             vf->uninit(vf);
713         ff_free_mp_image(vf->imgctx.static_images[0]);
714         ff_free_mp_image(vf->imgctx.static_images[1]);
715         ff_free_mp_image(vf->imgctx.temp_images[0]);
716         ff_free_mp_image(vf->imgctx.export_images[0]);
717         vf = next;
718     }
719 }
720
721 static int query_formats(AVFilterContext *ctx)
722 {
723     AVFilterFormats *avfmts=NULL;
724     MPContext *m = ctx->priv;
725     enum AVPixelFormat lastpixfmt = AV_PIX_FMT_NONE;
726     int i;
727
728     for(i=0; conversion_map[i].fmt; i++){
729         av_log(ctx, AV_LOG_DEBUG, "query: %X\n", conversion_map[i].fmt);
730         if(m->vf.query_format(&m->vf, conversion_map[i].fmt)){
731             av_log(ctx, AV_LOG_DEBUG, "supported,adding\n");
732             if (conversion_map[i].pix_fmt != lastpixfmt) {
733                 ff_add_format(&avfmts, conversion_map[i].pix_fmt);
734                 lastpixfmt = conversion_map[i].pix_fmt;
735             }
736         }
737     }
738
739     if (!avfmts)
740         return -1;
741
742     //We assume all allowed input formats are also allowed output formats
743     ff_set_common_formats(ctx, avfmts);
744     return 0;
745 }
746
747 static int config_inprops(AVFilterLink *inlink)
748 {
749     MPContext *m = inlink->dst->priv;
750     int i;
751     for(i=0; conversion_map[i].fmt && conversion_map[i].pix_fmt != inlink->format; i++);
752
753     av_assert0(conversion_map[i].fmt && inlink->w && inlink->h);
754
755     m->vf.fmt.have_configured = 1;
756     m->vf.fmt.orig_height     = inlink->h;
757     m->vf.fmt.orig_width      = inlink->w;
758     m->vf.fmt.orig_fmt        = conversion_map[i].fmt;
759
760     if(m->vf.config(&m->vf, inlink->w, inlink->h, inlink->w, inlink->h, 0, conversion_map[i].fmt)<=0)
761         return -1;
762
763     return 0;
764 }
765
766 static int config_outprops(AVFilterLink *outlink)
767 {
768     MPContext *m = outlink->src->priv;
769
770     outlink->w = m->next_vf.w;
771     outlink->h = m->next_vf.h;
772
773     return 0;
774 }
775
776 static int request_frame(AVFilterLink *outlink)
777 {
778     MPContext *m = outlink->src->priv;
779     int ret;
780
781     av_log(m->avfctx, AV_LOG_DEBUG, "mp request_frame\n");
782
783     for(m->frame_returned=0; !m->frame_returned;){
784         ret=ff_request_frame(outlink->src->inputs[0]);
785         if(ret<0)
786             break;
787     }
788
789     av_log(m->avfctx, AV_LOG_DEBUG, "mp request_frame ret=%d\n", ret);
790     return ret;
791 }
792
793 static int filter_frame(AVFilterLink *inlink, AVFrame *inpic)
794 {
795     MPContext *m = inlink->dst->priv;
796     int i;
797     double pts= MP_NOPTS_VALUE;
798     mp_image_t* mpi = ff_new_mp_image(inpic->width, inpic->height);
799
800     if(inpic->pts != AV_NOPTS_VALUE)
801         pts= inpic->pts / av_q2d(inlink->time_base);
802
803     for(i=0; conversion_map[i].fmt && conversion_map[i].pix_fmt != inlink->format; i++);
804     ff_mp_image_setfmt(mpi,conversion_map[i].fmt);
805
806     memcpy(mpi->planes, inpic->data,     FFMIN(sizeof(inpic->data)    , sizeof(mpi->planes)));
807     memcpy(mpi->stride, inpic->linesize, FFMIN(sizeof(inpic->linesize), sizeof(mpi->stride)));
808
809     if (inpic->interlaced_frame)
810         mpi->fields |= MP_IMGFIELD_INTERLACED;
811     if (inpic->top_field_first)
812         mpi->fields |= MP_IMGFIELD_TOP_FIRST;
813     if (inpic->repeat_pict)
814         mpi->fields |= MP_IMGFIELD_REPEAT_FIRST;
815
816     // mpi->flags|=MP_IMGFLAG_ALLOCATED; ?
817     mpi->flags |= MP_IMGFLAG_READABLE;
818     if(!av_frame_is_writable(inpic))
819         mpi->flags |= MP_IMGFLAG_PRESERVE;
820     if(m->vf.put_image(&m->vf, mpi, pts) == 0){
821         av_log(m->avfctx, AV_LOG_DEBUG, "put_image() says skip\n");
822     }else{
823         av_frame_free(&inpic);
824     }
825     ff_free_mp_image(mpi);
826     return 0;
827 }
828
829 static const AVFilterPad mp_inputs[] = {
830     {
831         .name         = "default",
832         .type         = AVMEDIA_TYPE_VIDEO,
833         .filter_frame = filter_frame,
834         .config_props = config_inprops,
835     },
836     { NULL }
837 };
838
839 static const AVFilterPad mp_outputs[] = {
840     {
841         .name          = "default",
842         .type          = AVMEDIA_TYPE_VIDEO,
843         .request_frame = request_frame,
844         .config_props  = config_outprops,
845     },
846     { NULL }
847 };
848
849 AVFilter avfilter_vf_mp = {
850     .name      = "mp",
851     .description = NULL_IF_CONFIG_SMALL("Apply a libmpcodecs filter to the input video."),
852     .init = init,
853     .uninit = uninit,
854     .priv_size = sizeof(MPContext),
855     .query_formats = query_formats,
856     .inputs        = mp_inputs,
857     .outputs       = mp_outputs,
858     .priv_class    = &mp_class,
859 };