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.
28 #include "img_format.h"
32 float sense
; // first parameter
33 float level
; // second parameter
40 mp_image_t
*pmpi
; // previous mpi
43 #define MAXROWSIZE 1200
45 static int config (struct vf_instance
*vf
,
46 int width
, int height
, int d_width
, int d_height
,
47 unsigned int flags
, unsigned int outfmt
)
51 vf
->priv
->pmpi
= vf_get_image (vf
->next
, outfmt
, MP_IMGTYPE_TEMP
,
53 if (!(vf
->priv
->pmpi
->flags
& MP_IMGFLAG_PLANAR
) &&
54 outfmt
!= IMGFMT_RGB32
&& outfmt
!= IMGFMT_BGR32
&&
55 outfmt
!= IMGFMT_RGB24
&& outfmt
!= IMGFMT_BGR24
&&
56 outfmt
!= IMGFMT_RGB16
&& outfmt
!= IMGFMT_BGR16
)
58 mp_msg (MSGT_VFILTER
, MSGL_WARN
, "Drop-interlaced filter doesn't support this outfmt :(\n");
61 vf
->priv
->imgfmt
= outfmt
;
62 // recalculate internal values
63 rowsize
= vf
->priv
->pmpi
->width
;
64 if (rowsize
> MAXROWSIZE
) rowsize
= MAXROWSIZE
;
65 vf
->priv
->max
= vf
->priv
->level
* vf
->priv
->pmpi
->height
* rowsize
/ 2;
66 if (vf
->priv
->pmpi
->flags
& MP_IMGFLAG_PLANAR
) // planar YUV
67 vf
->priv
->diff
= vf
->priv
->sense
* 256;
69 vf
->priv
->diff
= vf
->priv
->sense
* (1 << (vf
->priv
->pmpi
->bpp
/3));
70 if (vf
->priv
->diff
< 0) vf
->priv
->diff
= 0;
71 if (!(vf
->priv
->pmpi
->flags
& MP_IMGFLAG_PLANAR
) &&
72 vf
->priv
->pmpi
->bpp
< 24 && vf
->priv
->diff
> 31)
74 mp_msg (MSGT_VFILTER
, MSGL_INFO
, "Drop-interlaced: %dx%d diff %d / level %u\n",
75 vf
->priv
->pmpi
->width
, vf
->priv
->pmpi
->height
,
76 (int)vf
->priv
->diff
, (unsigned int)vf
->priv
->max
);
77 // vf->priv->rdfr = vf->priv->dfr = 0;
78 vf
->priv
->was_dint
= 0;
79 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
82 static int put_image (struct vf_instance
*vf
, mp_image_t
*mpi
, double pts
)
84 char rrow0
[MAXROWSIZE
];
85 char rrow1
[MAXROWSIZE
];
86 char rrow2
[MAXROWSIZE
];
87 char *row0
= rrow0
, *row1
= rrow1
, *row2
= rrow2
/*, *row3 = rrow3*/;
88 int rowsize
= mpi
->width
;
89 uint32_t nok
= 0, max
= vf
->priv
->max
;
90 int diff
= vf
->priv
->diff
;
93 unsigned char *cur0
, *prv0
;
94 register unsigned char *cur
, *prv
;
96 if (rowsize
> MAXROWSIZE
) rowsize
= MAXROWSIZE
;
97 // check if nothing to do
98 if (mpi
->imgfmt
== vf
->priv
->imgfmt
)
100 cur0
= mpi
->planes
[0] + mpi
->stride
[0];
101 prv0
= mpi
->planes
[0];
102 for (j
= 1; j
< mpi
->height
&& nok
<= max
; j
++)
106 // analyse row (row0)
107 if (mpi
->flags
& MP_IMGFLAG_PLANAR
) // planar YUV - check luminance
108 for (i
= 0; i
< rowsize
; i
++)
110 if (cur
[0] - prv
[0] > diff
)
112 else if (cur
[0] - prv
[0] < -diff
)
118 // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
119 // but row3 is 1 so it's interlaced ptr (nok++)
120 if (j
> 2 && row0
[i
] > 0 && (row1
[i
] < 0 || (!row1
[i
] && row2
[i
] < 0)) &&
124 else if (mpi
->bpp
< 24) // RGB/BGR 16 - check all colors
125 for (i
= 0; i
< rowsize
; i
++)
127 n1
= cur
[0] + (cur
[1]<<8);
128 n2
= prv
[0] + (prv
[1]<<8);
129 if ((n1
&0x1f) - (n2
&0x1f) > diff
||
130 ((n1
>>5)&0x3f) - ((n2
>>5)&0x3f) > diff
||
131 ((n1
>>11)&0x1f) - ((n2
>>11)&0x1f) > diff
)
133 else if ((n1
&0x1f) - (n2
&0x1f) < -diff
||
134 ((n1
>>5)&0x3f) - ((n2
>>5)&0x3f) < -diff
||
135 ((n1
>>11)&0x1f) - ((n2
>>11)&0x1f) < -diff
)
141 // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
142 // but row3 is 1 so it's interlaced ptr (nok++)
143 if (j
> 2 && row0
[i
] > 0 && (row1
[i
] < 0 || (!row1
[i
] && row2
[i
] < 0)) &&
147 else // RGB/BGR 24/32
148 for (i
= 0; i
< rowsize
; i
++)
150 if (cur
[0] - prv
[0] > diff
||
151 cur
[1] - prv
[1] > diff
||
152 cur
[2] - prv
[2] > diff
)
154 else if (prv
[0] - cur
[0] > diff
||
155 prv
[1] - cur
[1] > diff
||
156 prv
[2] - cur
[2] > diff
)
162 // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
163 // but row3 is 1 so it's interlaced ptr (nok++)
164 if (j
> 2 && row0
[i
] > 0 && (row1
[i
] < 0 || (!row1
[i
] && row2
[i
] < 0)) &&
168 cur0
+= mpi
->stride
[0];
169 prv0
+= mpi
->stride
[0];
177 // check if number of interlaced is above of max
181 if (vf
->priv
->was_dint
< 1) // can skip at most one frame!
183 vf
->priv
->was_dint
++;
185 // mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
189 vf
->priv
->was_dint
= 0;
190 // mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
191 return vf_next_put_image (vf
, mpi
, pts
);
194 static int vf_open(vf_instance_t
*vf
, char *args
){
196 vf
->put_image
= put_image
;
197 // vf->default_reqs=VFCAP_ACCEPT_STRIDE;
198 vf
->priv
= malloc (sizeof(struct vf_priv_s
));
199 vf
->priv
->sense
= 0.1;
200 vf
->priv
->level
= 0.15;
201 vf
->priv
->pmpi
= NULL
;
203 sscanf (args
, "%f:%f", &vf
->priv
->sense
, &vf
->priv
->level
);
207 const vf_info_t vf_info_dint
= {
208 "drop interlaced frames",