comparison libmpcodecs/vf_blackframe.c @ 19094:e84360ee61c9

new black frame detection filter by Brian J. Murrell, Julian Hall and me.
author ivo
date Sat, 15 Jul 2006 09:18:44 +0000
parents
children 30084f256717
comparison
equal deleted inserted replaced
19093:aca5ce3701e9 19094:e84360ee61c9
1 /* vf_blackframe.c - detect frames that are (almost) black
2 *
3 * $Id$
4 *
5 * search for black frames to detect scene transitions
6 * (c) 2006 Julian Hall
7 *
8 * based on code designed for skipping commercials
9 * (c) 2002-2003 Brian J. Murrell
10 *
11 * cleanup, simplify, speedup (c) 2006 by Ivo van Poorten
12 *
13 * This program 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.
17 *
18 * This program 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.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "config.h"
33 #include "mp_msg.h"
34
35 #include "img_format.h"
36 #include "mp_image.h"
37 #include "vf.h"
38
39 struct vf_priv_s {
40 unsigned int bamount, bthresh, frame;
41 };
42
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);
46 }
47
48 static int query_format(struct vf_instance_s *vf, unsigned fmt) {
49 switch(fmt) {
50 case IMGFMT_YVU9:
51 case IMGFMT_IF09:
52 case IMGFMT_YV12:
53 case IMGFMT_I420:
54 case IMGFMT_IYUV:
55 case IMGFMT_CLPL:
56 case IMGFMT_Y800:
57 case IMGFMT_Y8:
58 case IMGFMT_NV12:
59 case IMGFMT_NV21:
60 case IMGFMT_444P:
61 case IMGFMT_422P:
62 case IMGFMT_411P:
63 case IMGFMT_HM12:
64 return vf_next_query_format(vf, fmt);
65 }
66 return 0;
67 }
68
69 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){
70 mp_image_t *dmpi;
71 int x, y;
72 int nblack=0, pblack=0;
73 unsigned char *yplane = mpi->planes[0];
74 unsigned int ystride = mpi->stride[0];
75 int w = mpi->w, h = mpi->h;
76 int bthresh = vf->priv->bthresh;
77 int bamount = vf->priv->bamount;
78
79 for (y=1; y<=h; y++) {
80 for (x=0; x<w; x++)
81 nblack += yplane[x] < bthresh;
82 pblack = nblack*100/(w*y);
83 if (pblack < bamount) break;
84 yplane += ystride;
85 }
86
87 if (pblack >= bamount)
88 mp_msg(MSGT_VFILTER, MSGL_INFO,"\nBlack frame: frame %u (%2d%%)\n",
89 vf->priv->frame, pblack);
90
91 vf->priv->frame++;
92
93 dmpi = vf_get_image(vf->next, mpi->imgfmt, MP_IMGTYPE_EXPORT, 0,
94 mpi->width, mpi->height);
95 dmpi->planes[0] = mpi->planes[0];
96 dmpi->stride[0] = mpi->stride[0];
97 dmpi->planes[1] = mpi->planes[1];
98 dmpi->stride[1] = mpi->stride[1];
99 dmpi->planes[2] = mpi->planes[2];
100 dmpi->stride[2] = mpi->stride[2];
101
102 vf_clone_mpi_attributes(dmpi, mpi);
103
104 return vf_next_put_image(vf, dmpi, pts);
105 }
106
107 static int control(struct vf_instance_s* vf, int request, void* data){
108 return vf_next_control(vf,request,data);
109 }
110
111 static void uninit(struct vf_instance_s *vf) {
112 if (vf->priv) free(vf->priv);
113 }
114
115 static int open(vf_instance_t *vf, char* args){
116 vf->priv = malloc(sizeof(struct vf_priv_s));
117 if (!vf->priv) return 0;
118
119 vf->config = config;
120 vf->put_image = put_image;
121 vf->control = control;
122 vf->uninit = uninit;
123 vf->query_format = query_format;
124
125 vf->priv->bamount = 98;
126 vf->priv->bthresh = 0x20;
127 vf->priv->frame = 0;
128
129 if (args)
130 sscanf(args, "%u:%u", &vf->priv->bamount, &vf->priv->bthresh);
131 return 1;
132 }
133
134 vf_info_t vf_info_blackframe = {
135 "detects black frames",
136 "blackframe",
137 "Brian J. Murrell, Julian Hall, Ivo van Poorten",
138 "Useful for detecting scene transitions",
139 open,
140 NULL
141 };