annotate ffmpeg/libavfilter/vf_blackframe.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Copyright (c) 2010 Stefano Sabatini
yading@10 3 * Copyright (c) 2006 Ivo van Poorten
yading@10 4 * Copyright (c) 2006 Julian Hall
yading@10 5 * Copyright (c) 2002-2003 Brian J. Murrell
yading@10 6 *
yading@10 7 * This file is part of FFmpeg.
yading@10 8 *
yading@10 9 * FFmpeg is free software; you can redistribute it and/or modify
yading@10 10 * it under the terms of the GNU General Public License as published by
yading@10 11 * the Free Software Foundation; either version 2 of the License, or
yading@10 12 * (at your option) any later version.
yading@10 13 *
yading@10 14 * FFmpeg is distributed in the hope that it will be useful,
yading@10 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
yading@10 17 * GNU General Public License for more details.
yading@10 18 *
yading@10 19 * You should have received a copy of the GNU General Public License along
yading@10 20 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
yading@10 21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
yading@10 22 */
yading@10 23
yading@10 24 /**
yading@10 25 * @file
yading@10 26 * Search for black frames to detect scene transitions.
yading@10 27 * Ported from MPlayer libmpcodecs/vf_blackframe.c.
yading@10 28 */
yading@10 29
yading@10 30 #include <stdio.h>
yading@10 31 #include <inttypes.h>
yading@10 32
yading@10 33 #include "libavutil/internal.h"
yading@10 34 #include "libavutil/opt.h"
yading@10 35 #include "avfilter.h"
yading@10 36 #include "internal.h"
yading@10 37 #include "formats.h"
yading@10 38 #include "internal.h"
yading@10 39 #include "video.h"
yading@10 40
yading@10 41 typedef struct {
yading@10 42 const AVClass *class;
yading@10 43 int bamount; ///< black amount
yading@10 44 int bthresh; ///< black threshold
yading@10 45 unsigned int frame; ///< frame number
yading@10 46 unsigned int nblack; ///< number of black pixels counted so far
yading@10 47 unsigned int last_keyframe; ///< frame number of the last received key-frame
yading@10 48 } BlackFrameContext;
yading@10 49
yading@10 50 static int query_formats(AVFilterContext *ctx)
yading@10 51 {
yading@10 52 static const enum AVPixelFormat pix_fmts[] = {
yading@10 53 AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NV12,
yading@10 54 AV_PIX_FMT_NV21, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P,
yading@10 55 AV_PIX_FMT_NONE
yading@10 56 };
yading@10 57
yading@10 58 ff_set_common_formats(ctx, ff_make_format_list(pix_fmts));
yading@10 59 return 0;
yading@10 60 }
yading@10 61
yading@10 62 static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
yading@10 63 {
yading@10 64 AVFilterContext *ctx = inlink->dst;
yading@10 65 BlackFrameContext *blackframe = ctx->priv;
yading@10 66 int x, i;
yading@10 67 int pblack = 0;
yading@10 68 uint8_t *p = frame->data[0];
yading@10 69
yading@10 70 for (i = 0; i < frame->height; i++) {
yading@10 71 for (x = 0; x < inlink->w; x++)
yading@10 72 blackframe->nblack += p[x] < blackframe->bthresh;
yading@10 73 p += frame->linesize[0];
yading@10 74 }
yading@10 75
yading@10 76 if (frame->key_frame)
yading@10 77 blackframe->last_keyframe = blackframe->frame;
yading@10 78
yading@10 79 pblack = blackframe->nblack * 100 / (inlink->w * inlink->h);
yading@10 80 if (pblack >= blackframe->bamount)
yading@10 81 av_log(ctx, AV_LOG_INFO, "frame:%u pblack:%u pts:%"PRId64" t:%f "
yading@10 82 "type:%c last_keyframe:%d\n",
yading@10 83 blackframe->frame, pblack, frame->pts,
yading@10 84 frame->pts == AV_NOPTS_VALUE ? -1 : frame->pts * av_q2d(inlink->time_base),
yading@10 85 av_get_picture_type_char(frame->pict_type), blackframe->last_keyframe);
yading@10 86
yading@10 87 blackframe->frame++;
yading@10 88 blackframe->nblack = 0;
yading@10 89 return ff_filter_frame(inlink->dst->outputs[0], frame);
yading@10 90 }
yading@10 91
yading@10 92 #define OFFSET(x) offsetof(BlackFrameContext, x)
yading@10 93 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
yading@10 94 static const AVOption blackframe_options[] = {
yading@10 95 { "amount", "Percentage of the pixels that have to be below the threshold "
yading@10 96 "for the frame to be considered black.", OFFSET(bamount), AV_OPT_TYPE_INT, { .i64 = 98 }, 0, 100, FLAGS },
yading@10 97 { "threshold", "threshold below which a pixel value is considered black",
yading@10 98 OFFSET(bthresh), AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 255, FLAGS },
yading@10 99 { "thresh", "threshold below which a pixel value is considered black",
yading@10 100 OFFSET(bthresh), AV_OPT_TYPE_INT, { .i64 = 32 }, 0, 255, FLAGS },
yading@10 101 { NULL },
yading@10 102 };
yading@10 103
yading@10 104 AVFILTER_DEFINE_CLASS(blackframe);
yading@10 105
yading@10 106 static const AVFilterPad avfilter_vf_blackframe_inputs[] = {
yading@10 107 {
yading@10 108 .name = "default",
yading@10 109 .type = AVMEDIA_TYPE_VIDEO,
yading@10 110 .get_video_buffer = ff_null_get_video_buffer,
yading@10 111 .filter_frame = filter_frame,
yading@10 112 },
yading@10 113 { NULL }
yading@10 114 };
yading@10 115
yading@10 116 static const AVFilterPad avfilter_vf_blackframe_outputs[] = {
yading@10 117 {
yading@10 118 .name = "default",
yading@10 119 .type = AVMEDIA_TYPE_VIDEO
yading@10 120 },
yading@10 121 { NULL }
yading@10 122 };
yading@10 123
yading@10 124 AVFilter avfilter_vf_blackframe = {
yading@10 125 .name = "blackframe",
yading@10 126 .description = NULL_IF_CONFIG_SMALL("Detect frames that are (almost) black."),
yading@10 127
yading@10 128 .priv_size = sizeof(BlackFrameContext),
yading@10 129 .priv_class = &blackframe_class,
yading@10 130
yading@10 131 .query_formats = query_formats,
yading@10 132
yading@10 133 .inputs = avfilter_vf_blackframe_inputs,
yading@10 134
yading@10 135 .outputs = avfilter_vf_blackframe_outputs,
yading@10 136 };