[FFmpeg-devel] [PATCH] lavfi/select/WIP: add scene detection.

Michael Niedermayer michaelni at gmx.at
Sat May 26 18:45:09 CEST 2012


On Sat, May 26, 2012 at 12:41:01PM +0200, Clément Bœsch wrote:
> eg: ffmpeg -i ~/samples/GoneNutty.avi -vf scale=160:120,select='gt(scene_score\,60)*gt(scene_diff\,60)',tile -frames:v 1 out.png
> 
> TODO: documentation
> 
> Based on the shotdetect algorithm.
> ---
>  libavfilter/vf_select.c |   63 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 63 insertions(+)
> 
> diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c
> index d3f649c..5a9bdce 100644
> --- a/libavfilter/vf_select.c
> +++ b/libavfilter/vf_select.c
> @@ -25,7 +25,9 @@
>  
>  #include "libavutil/eval.h"
>  #include "libavutil/fifo.h"
> +#include "libavutil/timestamp.h"
>  #include "avfilter.h"
> +#include "formats.h"
>  #include "video.h"
>  
>  static const char *const var_names[] = {
> @@ -62,6 +64,9 @@ static const char *const var_names[] = {
>      "key",               ///< tell if the frame is a key frame
>      "pos",               ///< original position in the file of the frame
>  
> +    "scene_diff",
> +    "scene_score",
> +
>      NULL
>  };
>  
> @@ -99,6 +104,9 @@ enum var_name {
>      VAR_KEY,
>      VAR_POS,
>  
> +    VAR_SCENE_DIFF,
> +    VAR_SCENE_SCORE,
> +
>      VAR_VARS_NB
>  };
>  
> @@ -107,6 +115,9 @@ enum var_name {
>  typedef struct {
>      AVExpr *expr;
>      double var_values[VAR_VARS_NB];
> +    int do_scene_detect;
> +    int64_t prev_score;             ///< score of the previous frame (scene detect only)
> +    AVFilterBufferRef *prev_picref; ///< previous frame
>      double select;
>      int cache_frames;
>      AVFifoBuffer *pending_frames; ///< FIFO buffer of video frames
> @@ -128,6 +139,8 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
>          av_log(ctx, AV_LOG_ERROR, "Failed to allocate pending frames buffer.\n");
>          return AVERROR(ENOMEM);
>      }
> +
> +    select->do_scene_detect = args && strstr(args, "scene_");
>      return 0;
>  }
>  
> @@ -166,12 +179,44 @@ static int config_input(AVFilterLink *inlink)
>  #define D2TS(d)  (isnan(d) ? AV_NOPTS_VALUE : (int64_t)(d))
>  #define TS2D(ts) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts))
>  
> +static void set_scene_values(AVFilterContext *ctx, AVFilterBufferRef *picref)
> +{
> +    SelectContext *select = ctx->priv;
> +    AVFilterBufferRef *prev_picref = select->prev_picref;
> +
> +    if (prev_picref &&
> +        picref->video->h == prev_picref->video->h &&
> +        picref->video->w == prev_picref->video->w) {
> +        int64_t score = 0, diff;
> +        int x, y;
> +

> +#define ABSSC(a) abs((int)p[a] - (int)q[a])
> +        for (y = 0; y < picref->video->h; y++) {
> +            for (x = 0; x < picref->video->w; x++) {
> +                const uint8_t *p =      picref->data[0] + y *      picref->linesize[0] + x*3;
> +                const uint8_t *q = prev_picref->data[0] + y * prev_picref->linesize[0] + x*3;
> +                score += ABSSC(0) + ABSSC(1) + ABSSC(2);
> +            }

theres some optimized code in dsputil to calculate sum of abs diff
not sure how easy it is to use from lavfi but above looks pretty
inefficient so a TODO/FIXME should be added at least

the patch LGTM otherwise

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Democracy is the form of government in which you can choose your dictator
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20120526/0d782142/attachment.asc>


More information about the ffmpeg-devel mailing list