~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libmpcodecs/vf_blackframe.c

  • Committer: William Grant
  • Date: 2007-02-03 03:16:07 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: william.grant@ubuntu.org.au-20070203031607-08gc2ompbz6spt9i
Update to 1.0rc1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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, lastkeyframe;
 
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 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 *picttypes[4] = { "unknown", "I", "P", "B" };
 
80
 
 
81
    for (y=1; y<=h; y++) {
 
82
            for (x=0; x<w; x++)
 
83
            nblack += yplane[x] < bthresh;
 
84
            pblack = nblack*100/(w*y);
 
85
            if (pblack < bamount) break;
 
86
        yplane += ystride;
 
87
    }
 
88
 
 
89
    if (pict_type > 3 || pict_type < 0) pict_type = 0;
 
90
    if (pict_type == 1) vf->priv->lastkeyframe = vf->priv->frame;
 
91
 
 
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);
 
96
 
 
97
    vf->priv->frame++;
 
98
 
 
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];
 
107
 
 
108
    vf_clone_mpi_attributes(dmpi, mpi);
 
109
 
 
110
    return vf_next_put_image(vf, dmpi, pts);
 
111
}
 
112
 
 
113
static int control(struct vf_instance_s* vf, int request, void* data){
 
114
    return vf_next_control(vf,request,data);
 
115
}
 
116
 
 
117
static void uninit(struct vf_instance_s *vf) {
 
118
    if (vf->priv) free(vf->priv);
 
119
}
 
120
 
 
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;
 
124
 
 
125
    vf->config = config;
 
126
    vf->put_image = put_image;
 
127
    vf->control = control;
 
128
    vf->uninit = uninit;
 
129
    vf->query_format = query_format;
 
130
 
 
131
    vf->priv->bamount = 98;
 
132
    vf->priv->bthresh = 0x20;
 
133
    vf->priv->frame = 0;
 
134
    vf->priv->lastkeyframe = 0;
 
135
 
 
136
    if (args)
 
137
            sscanf(args, "%u:%u", &vf->priv->bamount, &vf->priv->bthresh);
 
138
    return 1;
 
139
}
 
140
 
 
141
vf_info_t vf_info_blackframe = {
 
142
    "detects black frames",
 
143
    "blackframe",
 
144
    "Brian J. Murrell, Julian Hall, Ivo van Poorten",
 
145
    "Useful for detecting scene transitions",
 
146
    open,
 
147
    NULL
 
148
};