• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavfilter/vf_blackframe.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2010 Stefano Sabatini
00003  * Copyright (c) 2006 Ivo van Poorten
00004  * Copyright (c) 2006 Julian Hall
00005  * Copyright (c) 2002-2003 Brian J. Murrell
00006  *
00007  * This file is part of FFmpeg.
00008  *
00009  * FFmpeg is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * FFmpeg is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License along
00020  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
00021  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00022  */
00023 
00030 #include "avfilter.h"
00031 
00032 typedef struct {
00033     unsigned int bamount; 
00034     unsigned int bthresh; 
00035     unsigned int frame;   
00036     unsigned int nblack;  
00037 } BlackFrameContext;
00038 
00039 static int query_formats(AVFilterContext *ctx)
00040 {
00041     static const enum PixelFormat pix_fmts[] = {
00042         PIX_FMT_YUV410P, PIX_FMT_YUV420P, PIX_FMT_GRAY8, PIX_FMT_NV12,
00043         PIX_FMT_NV21, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV411P,
00044         PIX_FMT_NONE
00045     };
00046 
00047     avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts));
00048     return 0;
00049 }
00050 
00051 static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
00052 {
00053     BlackFrameContext *blackframe = ctx->priv;
00054 
00055     blackframe->bamount = 98;
00056     blackframe->bthresh = 32;
00057     blackframe->nblack = 0;
00058     blackframe->frame = 0;
00059 
00060     if (args)
00061         sscanf(args, "%u:%u", &blackframe->bamount, &blackframe->bthresh);
00062 
00063     av_log(ctx, AV_LOG_INFO, "bamount:%u bthresh:%u\n",
00064            blackframe->bamount, blackframe->bthresh);
00065 
00066     if (blackframe->bamount > 100 || blackframe->bthresh > 255) {
00067         av_log(ctx, AV_LOG_ERROR, "Too big value for bamount (max is 100) or bthresh (max is 255)\n");
00068         return AVERROR(EINVAL);
00069     }
00070 
00071     return 0;
00072 }
00073 
00074 static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
00075 {
00076     AVFilterContext *ctx = inlink->dst;
00077     BlackFrameContext *blackframe = ctx->priv;
00078     AVFilterBufferRef *picref = inlink->cur_buf;
00079     int x, i;
00080     uint8_t *p = picref->data[0] + y * picref->linesize[0];
00081 
00082     for (i = 0; i < h; i++) {
00083         for (x = 0; x < inlink->w; x++)
00084             blackframe->nblack += p[x] < blackframe->bthresh;
00085         p += picref->linesize[0];
00086     }
00087 
00088     avfilter_draw_slice(ctx->outputs[0], y, h, slice_dir);
00089 }
00090 
00091 static void end_frame(AVFilterLink *inlink)
00092 {
00093     AVFilterContext *ctx = inlink->dst;
00094     BlackFrameContext *blackframe = ctx->priv;
00095     AVFilterBufferRef *picref = inlink->cur_buf;
00096     int pblack = 0;
00097 
00098     pblack = blackframe->nblack * 100 / (inlink->w * inlink->h);
00099     if (pblack >= blackframe->bamount)
00100         av_log(ctx, AV_LOG_INFO, "frame:%u pblack:%u pos:%"PRId64" pts:%"PRId64" t:%f\n",
00101                blackframe->frame, pblack, picref->pos, picref->pts,
00102                picref->pts == AV_NOPTS_VALUE ? -1 : picref->pts * av_q2d(inlink->time_base));
00103 
00104     blackframe->frame++;
00105     blackframe->nblack = 0;
00106     avfilter_end_frame(inlink->dst->outputs[0]);
00107 }
00108 
00109 AVFilter avfilter_vf_blackframe = {
00110     .name        = "blackframe",
00111     .description = NULL_IF_CONFIG_SMALL("Detect frames that are (almost) black."),
00112 
00113     .priv_size = sizeof(BlackFrameContext),
00114     .init      = init,
00115 
00116     .query_formats = query_formats,
00117 
00118     .inputs    = (AVFilterPad[]) {{ .name = "default",
00119                                     .type             = AVMEDIA_TYPE_VIDEO,
00120                                     .draw_slice       = draw_slice,
00121                                     .get_video_buffer = avfilter_null_get_video_buffer,
00122                                     .start_frame      = avfilter_null_start_frame,
00123                                     .end_frame        = end_frame, },
00124                                   { .name = NULL}},
00125 
00126     .outputs   = (AVFilterPad[]) {{ .name             = "default",
00127                                     .type             = AVMEDIA_TYPE_VIDEO },
00128                                   { .name = NULL}},
00129 };

Generated on Wed Apr 11 2012 07:31:35 for FFmpeg by  doxygen 1.7.1