2 * detect frames that are (almost) black
3 * search for black frames to detect scene transitions
6 * based on code designed for skipping commercials
7 * (c) 2002-2003 Brian J. Murrell
9 * cleanup, simplify, speedup (c) 2006 by Ivo van Poorten
11 * This file is part of MPlayer.
13 * MPlayer is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * MPlayer is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 #include "img_format.h"
40 unsigned int bamount
, bthresh
, frame
, lastkeyframe
;
43 static int config(struct vf_instance_s
* vf
, int width
, int height
, int d_width
,
44 int d_height
, unsigned int flags
, unsigned int outfmt
) {
45 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
48 static int query_format(struct vf_instance_s
*vf
, unsigned fmt
) {
64 return vf_next_query_format(vf
, fmt
);
69 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
72 int nblack
=0, pblack
=0;
73 unsigned char *yplane
= mpi
->planes
[0];
74 unsigned int ystride
= mpi
->stride
[0];
75 int pict_type
= mpi
->pict_type
;
76 int w
= mpi
->w
, h
= mpi
->h
;
77 int bthresh
= vf
->priv
->bthresh
;
78 int bamount
= vf
->priv
->bamount
;
79 static const char *const picttypes
[4] = { "unknown", "I", "P", "B" };
81 for (y
=1; y
<=h
; y
++) {
83 nblack
+= yplane
[x
] < bthresh
;
84 pblack
= nblack
*100/(w
*y
);
85 if (pblack
< bamount
) break;
89 if (pict_type
> 3 || pict_type
< 0) pict_type
= 0;
90 if (pict_type
== 1) vf
->priv
->lastkeyframe
= vf
->priv
->frame
;
92 if (pblack
>= bamount
)
93 mp_msg(MSGT_VFILTER
, MSGL_INFO
,"vf_blackframe: %u, %i%%, %s (I:%u)\n",
94 vf
->priv
->frame
, pblack
, picttypes
[pict_type
],
95 vf
->priv
->lastkeyframe
);
99 dmpi
= vf_get_image(vf
->next
, mpi
->imgfmt
, MP_IMGTYPE_EXPORT
, 0,
100 mpi
->width
, mpi
->height
);
101 dmpi
->planes
[0] = mpi
->planes
[0];
102 dmpi
->stride
[0] = mpi
->stride
[0];
103 dmpi
->planes
[1] = mpi
->planes
[1];
104 dmpi
->stride
[1] = mpi
->stride
[1];
105 dmpi
->planes
[2] = mpi
->planes
[2];
106 dmpi
->stride
[2] = mpi
->stride
[2];
108 vf_clone_mpi_attributes(dmpi
, mpi
);
110 return vf_next_put_image(vf
, dmpi
, pts
);
113 static int control(struct vf_instance_s
* vf
, int request
, void* data
){
114 return vf_next_control(vf
,request
,data
);
117 static void uninit(struct vf_instance_s
*vf
) {
118 if (vf
->priv
) free(vf
->priv
);
121 static int open(vf_instance_t
*vf
, char* args
){
122 vf
->priv
= malloc(sizeof(struct vf_priv_s
));
123 if (!vf
->priv
) return 0;
126 vf
->put_image
= put_image
;
127 vf
->control
= control
;
129 vf
->query_format
= query_format
;
131 vf
->priv
->bamount
= 98;
132 vf
->priv
->bthresh
= 0x20;
134 vf
->priv
->lastkeyframe
= 0;
137 sscanf(args
, "%u:%u", &vf
->priv
->bamount
, &vf
->priv
->bthresh
);
141 const vf_info_t vf_info_blackframe
= {
142 "detects black frames",
144 "Brian J. Murrell, Julian Hall, Ivo van Poorten",
145 "Useful for detecting scene transitions",