[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