[MPlayer-users] Re: Video Filter for Black Frame Detect
Brian J. Murrell
brian at interlinx.bc.ca
Thu May 1 22:08:23 CEST 2003
On Thu, 01 May 2003 11:57:41 -0700, usene wrote:
> I was thinking of doing a commercial detect for mplayer to skip through
> commercials during playback. One method seems to be doing black frame
> detect.
Been there done that. Abandoned the idea. The reason is that you still
need to decode and analyse _every_ frame after you have detected a black
frame (group), looking for the next black frame (group) to know where the
end of the commercial is.
On my machine, this only ran about 2-3 times normal frame rate, which
meant it still took 10-15 seconds to find the end of a 30 second
commercial block. I can do better with just ffwd/rew by 10 and 1 second
increments.
> I was thinking of writing a video filter to do black frame
> detect. Anyone done something like this before? Something I can
borrow?
Here is mine. It's old code, so it may or may not work. Let me know how
you make out.
/* vf_blackframe.c
*
* search for black frames to mark the beginning and end of commercial
* blocks
*
* (c) 2002-2003 Brian J. Murrell
*
* Can be used and reproduced under the terms of the GPL, version 2
*
*/
#ifdef BFSEARCH
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "../config.h"
#include "../mp_msg.h"
#include "img_format.h"
#include "mp_image.h"
#include "vf.h"
#include "../libvo/fastmemcpy.h"
#include "../postproc/rgb2rgb.h"
//===========================================================================//
struct vf_priv_s {
unsigned int black_amount, black_thresh, is_black, searching;
};
static int config(struct vf_instance_s* vf,
int width, int height, int d_width, int d_height,
unsigned int flags, unsigned int outfmt){
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
}
static void put_image(struct vf_instance_s* vf, mp_image_t *mpi){
int x, y;
unsigned int num_black=0, pct_black=0, lines=0;
// last frame was black, so stop searching and reset is_black
//fprintf(stderr, "black=%d search=%d ", vf->priv->is_black, vf->priv->searching);
if (vf->priv->is_black) {
//fprintf(stderr, "\n\n%d clear is_black\n\n", __LINE__);
vf->priv->is_black=0;
//fprintf(stderr, "\n\n%d clear searching\n\n", __LINE__);
vf->priv->searching=0;
}
if (!vf->priv->searching) {
vf_next_put_image(vf,mpi);
fprintf(stderr, "\nnot searching for black frames, returning\n");
return;
}
else
fprintf(stderr, "\nsearching for black frames\n");
// vf->priv->searching=0;
// vf->priv->is_black=0;
for (y=mpi->h/2; y<mpi->h; y++) {
for (x=0; x<mpi->w; x++) {
if (mpi->planes[0][y*mpi->w+x]<vf->priv->black_thresh) {
num_black++;
}
}
lines++;
pct_black=num_black*100/(mpi->w*lines);
if (pct_black<vf->priv->black_amount)
goto done;
}
for (y=mpi->h/2-1; y>-1; y--) {
for (x=0; x<mpi->w; x++) {
if (mpi->planes[0][y*mpi->w+x]<vf->priv->black_thresh) {
num_black++;
}
}
lines++;
pct_black=num_black*100/(mpi->w*lines);
if (pct_black<vf->priv->black_amount)
goto done;
}
done:
fprintf(stderr, "\nlines=%3u, %x %3u \n", lines, mpi->planes[0][mpi->w*10+10],
pct_black);
if (pct_black>=vf->priv->black_amount)
vf->priv->is_black=1;
// skip all other image processing steps
//vf_next_put_image(vf,mpi);
return;
}
//===========================================================================//
static int control(struct vf_instance_s* vf, int request, void* data){
switch(request){
case VFCTRL_QUERY_IS_BLACK:
*(unsigned int *)data = vf->priv->is_black;
return CONTROL_TRUE;
case VFCTRL_SEARCH_FOR_BLACK:
vf->priv->searching=1;
return CONTROL_TRUE;
case VFCTRL_QUERY_IS_SEARCHING:
*(unsigned int *)data = vf->priv->searching;
return CONTROL_TRUE;
}
return vf_next_control(vf,request,data);
}
static int open(vf_instance_t *vf, char* args){
vf->config=config;
vf->put_image=put_image;
vf->control=control;
vf->priv=malloc(sizeof(struct vf_priv_s));
vf->priv->black_amount=98;
vf->priv->black_thresh=0x40;
vf->priv->searching=0;
if (args)
sscanf(args, "%d:%d", &vf->priv->black_amount, &vf->priv->black_thresh);
return 1;
}
vf_info_t vf_info_blackframe = {
"detects black frames",
"blackframe",
"Brian J. Murrell",
"Very useful for skipping commercials. :-)",
open
};
//===========================================================================//
#endif
More information about the MPlayer-users
mailing list