2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include "cpudetect.h"
33 #include "img_format.h"
36 #include "libavutil/internal.h"
37 #include "libpostproc/postprocess.h"
39 #ifdef CONFIG_LIBPOSTPROC_A
41 #include "libpostproc/postprocess_internal.h"
48 pp_mode_t
*ppMode
[PP_QUALITY_MAX
+1];
53 //===========================================================================//
55 static int config(struct vf_instance
*vf
,
56 int width
, int height
, int d_width
, int d_height
,
57 unsigned int voflags
, unsigned int outfmt
){
59 (gCpuCaps
.hasMMX
? PP_CPU_CAPS_MMX
: 0)
60 | (gCpuCaps
.hasMMX2
? PP_CPU_CAPS_MMX2
: 0)
61 | (gCpuCaps
.has3DNow
? PP_CPU_CAPS_3DNOW
: 0);
64 case IMGFMT_444P
: flags
|= PP_FORMAT_444
; break;
65 case IMGFMT_422P
: flags
|= PP_FORMAT_422
; break;
66 case IMGFMT_411P
: flags
|= PP_FORMAT_411
; break;
67 default: flags
|= PP_FORMAT_420
; break;
70 if(vf
->priv
->context
) pp_free_context(vf
->priv
->context
);
71 vf
->priv
->context
= pp_get_context(width
, height
, flags
);
73 return vf_next_config(vf
,width
,height
,d_width
,d_height
,voflags
,outfmt
);
76 static void uninit(struct vf_instance
*vf
){
78 for(i
=0; i
<=PP_QUALITY_MAX
; i
++){
79 if(vf
->priv
->ppMode
[i
])
80 pp_free_mode(vf
->priv
->ppMode
[i
]);
82 if(vf
->priv
->context
) pp_free_context(vf
->priv
->context
);
85 static int query_format(struct vf_instance
*vf
, unsigned int fmt
){
93 return vf_next_query_format(vf
,fmt
);
98 static int control(struct vf_instance
*vf
, int request
, void* data
){
100 case VFCTRL_QUERY_MAX_PP_LEVEL
:
101 return PP_QUALITY_MAX
;
102 case VFCTRL_SET_PP_LEVEL
:
103 vf
->priv
->pp
= *((unsigned int*)data
);
106 return vf_next_control(vf
,request
,data
);
109 static void get_image(struct vf_instance
*vf
, mp_image_t
*mpi
){
110 if(vf
->priv
->pp
&0xFFFF) return; // non-local filters enabled
111 if((mpi
->type
==MP_IMGTYPE_IPB
|| vf
->priv
->pp
) &&
112 mpi
->flags
&MP_IMGFLAG_PRESERVE
) return; // don't change
113 if(!(mpi
->flags
&MP_IMGFLAG_ACCEPT_STRIDE
) && mpi
->imgfmt
!=vf
->priv
->outfmt
)
114 return; // colorspace differ
115 // ok, we can do pp in-place (or pp disabled):
116 vf
->dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
117 mpi
->type
, mpi
->flags
| MP_IMGFLAG_READABLE
, mpi
->width
, mpi
->height
);
118 mpi
->planes
[0]=vf
->dmpi
->planes
[0];
119 mpi
->stride
[0]=vf
->dmpi
->stride
[0];
120 mpi
->width
=vf
->dmpi
->width
;
121 if(mpi
->flags
&MP_IMGFLAG_PLANAR
){
122 mpi
->planes
[1]=vf
->dmpi
->planes
[1];
123 mpi
->planes
[2]=vf
->dmpi
->planes
[2];
124 mpi
->stride
[1]=vf
->dmpi
->stride
[1];
125 mpi
->stride
[2]=vf
->dmpi
->stride
[2];
127 mpi
->flags
|=MP_IMGFLAG_DIRECT
;
130 static int put_image(struct vf_instance
*vf
, mp_image_t
*mpi
, double pts
){
131 if(!(mpi
->flags
&MP_IMGFLAG_DIRECT
)){
132 // no DR, so get a new image! hope we'll get DR buffer:
133 vf
->dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
134 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
|
135 MP_IMGFLAG_PREFER_ALIGNED_STRIDE
| MP_IMGFLAG_READABLE
,
136 // MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
138 (mpi
->width
+7)&(~7),(mpi
->height
+7)&(~7));
139 vf
->dmpi
->w
=mpi
->w
; vf
->dmpi
->h
=mpi
->h
; // display w;h
142 if(vf
->priv
->pp
|| !(mpi
->flags
&MP_IMGFLAG_DIRECT
)){
143 // do the postprocessing! (or copy if no DR)
144 pp_postprocess(mpi
->planes
,mpi
->stride
,
145 vf
->dmpi
->planes
,vf
->dmpi
->stride
,
146 (mpi
->w
+7)&(~7),mpi
->h
,
147 mpi
->qscale
, mpi
->qstride
,
148 vf
->priv
->ppMode
[ vf
->priv
->pp
], vf
->priv
->context
,
149 #ifdef PP_PICT_TYPE_QP2
150 mpi
->pict_type
| (mpi
->qscale_type
? PP_PICT_TYPE_QP2
: 0));
155 return vf_next_put_image(vf
,vf
->dmpi
, pts
);
158 //===========================================================================//
160 extern int divx_quality
;
162 static const unsigned int fmt_list
[]={
172 static int vf_open(vf_instance_t
*vf
, char *args
){
177 vf
->query_format
=query_format
;
180 vf
->get_image
=get_image
;
181 vf
->put_image
=put_image
;
183 vf
->default_caps
=VFCAP_ACCEPT_STRIDE
|VFCAP_POSTPROC
;
184 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
185 vf
->priv
->context
=NULL
;
188 vf
->priv
->outfmt
=vf_match_csp(&vf
->next
,fmt_list
,IMGFMT_YV12
);
189 if(!vf
->priv
->outfmt
) return 0; // no csp match :(
192 hex_mode
= strtol(args
, &endptr
, 0);
204 for(i
=0; i
<=PP_QUALITY_MAX
; i
++){
205 vf
->priv
->ppMode
[i
]= pp_get_mode_by_name_and_quality(name
, i
);
206 if(vf
->priv
->ppMode
[i
]==NULL
) return -1;
210 /* hex mode for compatibility */
211 for(i
=0; i
<=PP_QUALITY_MAX
; i
++){
214 ppMode
= (PPMode
*)memalign(8, sizeof(PPMode
));
216 ppMode
->lumMode
= hex_mode
;
217 ppMode
->chromMode
= ((hex_mode
&0xFF)>>4) | (hex_mode
&0xFFFFFF00);
218 ppMode
->maxTmpNoise
[0]= 700;
219 ppMode
->maxTmpNoise
[1]= 1500;
220 ppMode
->maxTmpNoise
[2]= 3000;
221 ppMode
->maxAllowedY
= 234;
222 ppMode
->minAllowedY
= 16;
223 ppMode
->baseDcDiff
= 256/4;
224 ppMode
->flatnessThreshold
=40;
226 vf
->priv
->ppMode
[i
]= ppMode
;
231 vf
->priv
->pp
=PP_QUALITY_MAX
;
235 const vf_info_t vf_info_pp
= {
244 //===========================================================================//