10 #include "img_format.h"
14 float sense
; // first parameter
15 float level
; // second parameter
22 mp_image_t
*pmpi
; // previous mpi
25 #define MAXROWSIZE 1200
27 static int config (struct vf_instance_s
* vf
,
28 int width
, int height
, int d_width
, int d_height
,
29 unsigned int flags
, unsigned int outfmt
)
33 vf
->priv
->pmpi
= vf_get_image (vf
->next
, outfmt
, MP_IMGTYPE_TEMP
,
35 if (!(vf
->priv
->pmpi
->flags
& MP_IMGFLAG_PLANAR
) &&
36 outfmt
!= IMGFMT_RGB32
&& outfmt
!= IMGFMT_BGR32
&&
37 outfmt
!= IMGFMT_RGB24
&& outfmt
!= IMGFMT_BGR24
&&
38 outfmt
!= IMGFMT_RGB16
&& outfmt
!= IMGFMT_BGR16
)
40 mp_msg (MSGT_VFILTER
, MSGL_WARN
, "Drop-interlaced filter doesn't support this outfmt :(\n");
43 vf
->priv
->imgfmt
= outfmt
;
44 // recalculate internal values
45 rowsize
= vf
->priv
->pmpi
->width
;
46 if (rowsize
> MAXROWSIZE
) rowsize
= MAXROWSIZE
;
47 vf
->priv
->max
= vf
->priv
->level
* vf
->priv
->pmpi
->height
* rowsize
/ 2;
48 if (vf
->priv
->pmpi
->flags
& MP_IMGFLAG_PLANAR
) // planar YUV
49 vf
->priv
->diff
= vf
->priv
->sense
* 256;
51 vf
->priv
->diff
= vf
->priv
->sense
* (1 << (vf
->priv
->pmpi
->bpp
/3));
52 if (vf
->priv
->diff
< 0) vf
->priv
->diff
= 0;
53 if (!(vf
->priv
->pmpi
->flags
& MP_IMGFLAG_PLANAR
) &&
54 vf
->priv
->pmpi
->bpp
< 24 && vf
->priv
->diff
> 31)
56 mp_msg (MSGT_VFILTER
, MSGL_INFO
, "Drop-interlaced: %dx%d diff %d / level %u\n",
57 vf
->priv
->pmpi
->width
, vf
->priv
->pmpi
->height
,
58 (int)vf
->priv
->diff
, (unsigned int)vf
->priv
->max
);
59 // vf->priv->rdfr = vf->priv->dfr = 0;
60 vf
->priv
->was_dint
= 0;
61 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
64 static int put_image (struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
)
66 char rrow0
[MAXROWSIZE
];
67 char rrow1
[MAXROWSIZE
];
68 char rrow2
[MAXROWSIZE
];
69 char *row0
= rrow0
, *row1
= rrow1
, *row2
= rrow2
/*, *row3 = rrow3*/;
70 int rowsize
= mpi
->width
;
71 uint32_t nok
= 0, max
= vf
->priv
->max
;
72 int diff
= vf
->priv
->diff
;
75 unsigned char *cur0
, *prv0
;
76 register unsigned char *cur
, *prv
;
78 if (rowsize
> MAXROWSIZE
) rowsize
= MAXROWSIZE
;
79 // check if nothing to do
80 if (mpi
->imgfmt
== vf
->priv
->imgfmt
)
82 cur0
= mpi
->planes
[0] + mpi
->stride
[0];
83 prv0
= mpi
->planes
[0];
84 for (j
= 1; j
< mpi
->height
&& nok
<= max
; j
++)
89 if (mpi
->flags
& MP_IMGFLAG_PLANAR
) // planar YUV - check luminance
90 for (i
= 0; i
< rowsize
; i
++)
92 if (cur
[0] - prv
[0] > diff
)
94 else if (cur
[0] - prv
[0] < -diff
)
100 // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
101 // but row3 is 1 so it's interlaced ptr (nok++)
102 if (j
> 2 && row0
[i
] > 0 && (row1
[i
] < 0 || (!row1
[i
] && row2
[i
] < 0)) &&
106 else if (mpi
->bpp
< 24) // RGB/BGR 16 - check all colors
107 for (i
= 0; i
< rowsize
; i
++)
109 n1
= cur
[0] + (cur
[1]<<8);
110 n2
= prv
[0] + (prv
[1]<<8);
111 if ((n1
&0x1f) - (n2
&0x1f) > diff
||
112 ((n1
>>5)&0x3f) - ((n2
>>5)&0x3f) > diff
||
113 ((n1
>>11)&0x1f) - ((n2
>>11)&0x1f) > diff
)
115 else if ((n1
&0x1f) - (n2
&0x1f) < -diff
||
116 ((n1
>>5)&0x3f) - ((n2
>>5)&0x3f) < -diff
||
117 ((n1
>>11)&0x1f) - ((n2
>>11)&0x1f) < -diff
)
123 // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
124 // but row3 is 1 so it's interlaced ptr (nok++)
125 if (j
> 2 && row0
[i
] > 0 && (row1
[i
] < 0 || (!row1
[i
] && row2
[i
] < 0)) &&
129 else // RGB/BGR 24/32
130 for (i
= 0; i
< rowsize
; i
++)
132 if (cur
[0] - prv
[0] > diff
||
133 cur
[1] - prv
[1] > diff
||
134 cur
[2] - prv
[2] > diff
)
136 else if (prv
[0] - cur
[0] > diff
||
137 prv
[1] - cur
[1] > diff
||
138 prv
[2] - cur
[2] > diff
)
144 // check if row0 is 1 but row1 is 0, and row2 is 1 or row2 is 0
145 // but row3 is 1 so it's interlaced ptr (nok++)
146 if (j
> 2 && row0
[i
] > 0 && (row1
[i
] < 0 || (!row1
[i
] && row2
[i
] < 0)) &&
150 cur0
+= mpi
->stride
[0];
151 prv0
+= mpi
->stride
[0];
159 // check if number of interlaced is above of max
163 if (vf
->priv
->was_dint
< 1) // can skip at most one frame!
165 vf
->priv
->was_dint
++;
167 // mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
171 vf
->priv
->was_dint
= 0;
172 // mp_msg (MSGT_VFILTER, MSGL_INFO, "DI:%d/%d ", vf->priv->rdfr, vf->priv->dfr);
173 return vf_next_put_image (vf
, mpi
, pts
);
176 static int open (vf_instance_t
*vf
, char* args
){
178 vf
->put_image
= put_image
;
179 // vf->default_reqs=VFCAP_ACCEPT_STRIDE;
180 vf
->priv
= malloc (sizeof(struct vf_priv_s
));
181 vf
->priv
->sense
= 0.1;
182 vf
->priv
->level
= 0.15;
183 vf
->priv
->pmpi
= NULL
;
185 sscanf (args
, "%f:%f", &vf
->priv
->sense
, &vf
->priv
->level
);
189 const vf_info_t vf_info_dint
= {
190 "drop interlaced frames",