[FFmpeg-devel] [PATCH] avfilter: add shuffleframes filter

2015-10-20 Thread Paul B Mahol
Signed-off-by: Paul B Mahol 
---
 libavfilter/Makefile   |   1 +
 libavfilter/allfilters.c   |   1 +
 libavfilter/vf_shuffleframes.c | 157 +
 3 files changed, 159 insertions(+)
 create mode 100644 libavfilter/vf_shuffleframes.c

diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index a095a10..8e776c1 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -215,6 +215,7 @@ OBJS-$(CONFIG_SETSAR_FILTER) += vf_aspect.o
 OBJS-$(CONFIG_SETTB_FILTER)  += settb.o
 OBJS-$(CONFIG_SHOWINFO_FILTER)   += vf_showinfo.o
 OBJS-$(CONFIG_SHOWPALETTE_FILTER)+= vf_showpalette.o
+OBJS-$(CONFIG_SHUFFLEFRAMES_FILTER)  += vf_shuffleframes.o
 OBJS-$(CONFIG_SHUFFLEPLANES_FILTER)  += vf_shuffleplanes.o
 OBJS-$(CONFIG_SIGNALSTATS_FILTER)+= vf_signalstats.o
 OBJS-$(CONFIG_SMARTBLUR_FILTER)  += vf_smartblur.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 3ab9a48..9385fdf 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -236,6 +236,7 @@ void avfilter_register_all(void)
 REGISTER_FILTER(SETTB,  settb,  vf);
 REGISTER_FILTER(SHOWINFO,   showinfo,   vf);
 REGISTER_FILTER(SHOWPALETTE,showpalette,vf);
+REGISTER_FILTER(SHUFFLEFRAMES,  shuffleframes,  vf);
 REGISTER_FILTER(SHUFFLEPLANES,  shuffleplanes,  vf);
 REGISTER_FILTER(SIGNALSTATS,signalstats,vf);
 REGISTER_FILTER(SMARTBLUR,  smartblur,  vf);
diff --git a/libavfilter/vf_shuffleframes.c b/libavfilter/vf_shuffleframes.c
new file mode 100644
index 000..97c4aa5
--- /dev/null
+++ b/libavfilter/vf_shuffleframes.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2015 Paul B Mahol
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/common.h"
+#include "libavutil/internal.h"
+#include "libavutil/opt.h"
+
+#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
+
+typedef struct ShuffleFramesContext {
+const AVClass *class;
+char *mapping;
+AVFrame **frames;
+int *map;
+int64_t *pts;
+int in_frames;
+int nb_frames;
+} ShuffleFramesContext;
+
+static av_cold int init(AVFilterContext *ctx)
+{
+ShuffleFramesContext *s = ctx->priv;
+char *mapping, *saveptr = NULL, *p;
+int n, nb_items;
+
+mapping = av_strdup(s->mapping);
+if (!mapping)
+return AVERROR(ENOMEM);
+
+nb_items = 1;
+for (p = mapping; *p; p++) {
+if (*p == '|' || *p == ' ')
+nb_items++;
+}
+
+s->map= av_calloc(nb_items, sizeof(*s->map));
+s->pts= av_calloc(nb_items, sizeof(*s->pts));
+s->frames = av_calloc(nb_items, sizeof(*s->frames));
+if (!s->map || !s->frames || !s->pts) {
+return AVERROR(ENOMEM);
+}
+
+for (n = 0; n < nb_items; n++) {
+s->map[n] = -1;
+}
+
+for (n = 0; n < nb_items; n++) {
+char *map = av_strtok(n == 0 ? mapping : NULL, " |", );
+if (!map || sscanf(map, "%d", >map[n]) != 1)
+return AVERROR(EINVAL);
+if (s->map[n] < 0 || s->map[n] >= nb_items)
+return AVERROR(EINVAL);
+}
+
+s->nb_frames = nb_items;
+av_free(mapping);
+return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+AVFilterContext*ctx = inlink->dst;
+ShuffleFramesContext *s = ctx->priv;
+int ret;
+
+if (s->in_frames < s->nb_frames) {
+s->frames[s->in_frames] = frame;
+s->pts[s->in_frames] = frame->pts;
+s->in_frames++;
+ret = 0;
+}
+
+if (s->in_frames == s->nb_frames) {
+int n, x;
+
+for (n = 0; n < s->nb_frames; n++) {
+AVFrame *out;
+
+x = s->map[n];
+out = av_frame_clone(s->frames[x]);
+out->pts = s->pts[n];
+ret = ff_filter_frame(ctx->outputs[0], out);
+s->in_frames--;
+}
+
+for (n = 0; n < s->nb_frames; n++)
+av_frame_free(>frames[n]);
+}
+
+return ret;
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ShuffleFramesContext *s = ctx->priv;
+
+

[FFmpeg-devel] [PATCH] avfilter: add shuffleframes filter

2015-10-20 Thread Paul B Mahol
Signed-off-by: Paul B Mahol 
---
 doc/filters.texi   |  20 ++
 libavfilter/Makefile   |   1 +
 libavfilter/allfilters.c   |   1 +
 libavfilter/vf_shuffleframes.c | 159 +
 4 files changed, 181 insertions(+)
 create mode 100644 libavfilter/vf_shuffleframes.c

diff --git a/doc/filters.texi b/doc/filters.texi
index 1af0a72..9ff5e24 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -9945,6 +9945,26 @@ Set the size of the box used to represent one palette 
color entry. Default is
 @code{30} (for a @code{30x30} pixel box).
 @end table
 
+@section shuffleframes
+
+Reorder and/or duplicate video frames.
+
+It accepts the following parameters:
+
+@table @option
+@item mapping
+Set the destination indexes of input frames.
+This is space or '|' separated list of indexes that maps input frames to output
+frames. Number of indexes also sets maximal value that each index may have.
+@end table
+
+The first frame has the index 0. The default is to keep the input unchanged.
+
+Swap second and third frame of every three frames of the input:
+@example
+ffmpeg -i INPUT -vf "shuffleframes=0 2 1" OUTPUT
+@end example
+
 @section shuffleplanes
 
 Reorder and/or duplicate video planes.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index a095a10..8e776c1 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -215,6 +215,7 @@ OBJS-$(CONFIG_SETSAR_FILTER) += vf_aspect.o
 OBJS-$(CONFIG_SETTB_FILTER)  += settb.o
 OBJS-$(CONFIG_SHOWINFO_FILTER)   += vf_showinfo.o
 OBJS-$(CONFIG_SHOWPALETTE_FILTER)+= vf_showpalette.o
+OBJS-$(CONFIG_SHUFFLEFRAMES_FILTER)  += vf_shuffleframes.o
 OBJS-$(CONFIG_SHUFFLEPLANES_FILTER)  += vf_shuffleplanes.o
 OBJS-$(CONFIG_SIGNALSTATS_FILTER)+= vf_signalstats.o
 OBJS-$(CONFIG_SMARTBLUR_FILTER)  += vf_smartblur.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 3ab9a48..9385fdf 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -236,6 +236,7 @@ void avfilter_register_all(void)
 REGISTER_FILTER(SETTB,  settb,  vf);
 REGISTER_FILTER(SHOWINFO,   showinfo,   vf);
 REGISTER_FILTER(SHOWPALETTE,showpalette,vf);
+REGISTER_FILTER(SHUFFLEFRAMES,  shuffleframes,  vf);
 REGISTER_FILTER(SHUFFLEPLANES,  shuffleplanes,  vf);
 REGISTER_FILTER(SIGNALSTATS,signalstats,vf);
 REGISTER_FILTER(SMARTBLUR,  smartblur,  vf);
diff --git a/libavfilter/vf_shuffleframes.c b/libavfilter/vf_shuffleframes.c
new file mode 100644
index 000..eb409c5
--- /dev/null
+++ b/libavfilter/vf_shuffleframes.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2015 Paul B Mahol
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/common.h"
+#include "libavutil/internal.h"
+#include "libavutil/opt.h"
+
+#include "avfilter.h"
+#include "internal.h"
+#include "video.h"
+
+typedef struct ShuffleFramesContext {
+const AVClass *class;
+char *mapping;
+AVFrame **frames;
+int *map;
+int64_t *pts;
+int in_frames;
+int nb_frames;
+} ShuffleFramesContext;
+
+static av_cold int init(AVFilterContext *ctx)
+{
+ShuffleFramesContext *s = ctx->priv;
+char *mapping, *saveptr = NULL, *p;
+int n, nb_items;
+
+nb_items = 1;
+for (p = s->mapping; *p; p++) {
+if (*p == '|' || *p == ' ')
+nb_items++;
+}
+
+s->map= av_calloc(nb_items, sizeof(*s->map));
+s->pts= av_calloc(nb_items, sizeof(*s->pts));
+s->frames = av_calloc(nb_items, sizeof(*s->frames));
+if (!s->map || !s->frames || !s->pts) {
+return AVERROR(ENOMEM);
+}
+
+mapping = av_strdup(s->mapping);
+if (!mapping)
+return AVERROR(ENOMEM);
+
+for (n = 0; n < nb_items; n++) {
+char *map = av_strtok(n == 0 ? mapping : NULL, " |", );
+if (!map || sscanf(map, "%d", >map[n]) != 1) {
+av_free(mapping);
+return AVERROR(EINVAL);
+}
+
+if (s->map[n] < 0 || s->map[n] >= nb_items) {
+av_log(ctx, AV_LOG_ERROR, "Index out of range.\n");
+

Re: [FFmpeg-devel] [PATCH] avfilter: add shuffleframes filter

2015-10-20 Thread Clément Bœsch
On Tue, Oct 20, 2015 at 08:10:55PM +0200, Paul B Mahol wrote:
> Signed-off-by: Paul B Mahol 
> ---
>  doc/filters.texi   |  20 ++
>  libavfilter/Makefile   |   1 +
>  libavfilter/allfilters.c   |   1 +
>  libavfilter/vf_shuffleframes.c | 159 
> +
>  4 files changed, 181 insertions(+)
>  create mode 100644 libavfilter/vf_shuffleframes.c
> 
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 1af0a72..9ff5e24 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -9945,6 +9945,26 @@ Set the size of the box used to represent one palette 
> color entry. Default is
>  @code{30} (for a @code{30x30} pixel box).
>  @end table
>  
> +@section shuffleframes
> +
> +Reorder and/or duplicate video frames.
> +
> +It accepts the following parameters:
> +
> +@table @option
> +@item mapping
> +Set the destination indexes of input frames.
> +This is space or '|' separated list of indexes that maps input frames to 
> output
> +frames. Number of indexes also sets maximal value that each index may have.
> +@end table
> +
> +The first frame has the index 0. The default is to keep the input unchanged.
> +
> +Swap second and third frame of every three frames of the input:
> +@example
> +ffmpeg -i INPUT -vf "shuffleframes=0 2 1" OUTPUT
> +@end example
> +

No random shuffle of batches of frames?

[...]

-- 
Clément B.


signature.asc
Description: PGP signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] avfilter: add shuffleframes filter

2015-10-20 Thread Clément Bœsch
On Tue, Oct 20, 2015 at 12:28:32PM +0200, Paul B Mahol wrote:
> Signed-off-by: Paul B Mahol 
> ---
>  libavfilter/Makefile   |   1 +
>  libavfilter/allfilters.c   |   1 +
>  libavfilter/vf_shuffleframes.c | 157 
> +

doc please

>  3 files changed, 159 insertions(+)
>  create mode 100644 libavfilter/vf_shuffleframes.c
> 
> diff --git a/libavfilter/Makefile b/libavfilter/Makefile
> index a095a10..8e776c1 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -215,6 +215,7 @@ OBJS-$(CONFIG_SETSAR_FILTER) += 
> vf_aspect.o
>  OBJS-$(CONFIG_SETTB_FILTER)  += settb.o
>  OBJS-$(CONFIG_SHOWINFO_FILTER)   += vf_showinfo.o
>  OBJS-$(CONFIG_SHOWPALETTE_FILTER)+= vf_showpalette.o
> +OBJS-$(CONFIG_SHUFFLEFRAMES_FILTER)  += vf_shuffleframes.o
>  OBJS-$(CONFIG_SHUFFLEPLANES_FILTER)  += vf_shuffleplanes.o
>  OBJS-$(CONFIG_SIGNALSTATS_FILTER)+= vf_signalstats.o
>  OBJS-$(CONFIG_SMARTBLUR_FILTER)  += vf_smartblur.o
> diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
> index 3ab9a48..9385fdf 100644
> --- a/libavfilter/allfilters.c
> +++ b/libavfilter/allfilters.c
> @@ -236,6 +236,7 @@ void avfilter_register_all(void)
>  REGISTER_FILTER(SETTB,  settb,  vf);
>  REGISTER_FILTER(SHOWINFO,   showinfo,   vf);
>  REGISTER_FILTER(SHOWPALETTE,showpalette,vf);
> +REGISTER_FILTER(SHUFFLEFRAMES,  shuffleframes,  vf);
>  REGISTER_FILTER(SHUFFLEPLANES,  shuffleplanes,  vf);
>  REGISTER_FILTER(SIGNALSTATS,signalstats,vf);
>  REGISTER_FILTER(SMARTBLUR,  smartblur,  vf);
> diff --git a/libavfilter/vf_shuffleframes.c b/libavfilter/vf_shuffleframes.c
> new file mode 100644
> index 000..97c4aa5
> --- /dev/null
> +++ b/libavfilter/vf_shuffleframes.c
> @@ -0,0 +1,157 @@
> +/*
> + * Copyright (c) 2015 Paul B Mahol
> + *
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +#include "libavutil/avstring.h"
> +#include "libavutil/common.h"
> +#include "libavutil/internal.h"
> +#include "libavutil/opt.h"
> +
> +#include "avfilter.h"
> +#include "internal.h"
> +#include "video.h"
> +
> +typedef struct ShuffleFramesContext {
> +const AVClass *class;
> +char *mapping;
> +AVFrame **frames;
> +int *map;
> +int64_t *pts;
> +int in_frames;
> +int nb_frames;
> +} ShuffleFramesContext;
> +
> +static av_cold int init(AVFilterContext *ctx)
> +{
> +ShuffleFramesContext *s = ctx->priv;
> +char *mapping, *saveptr = NULL, *p;
> +int n, nb_items;
> +
> +mapping = av_strdup(s->mapping);
> +if (!mapping)
> +return AVERROR(ENOMEM);
> +
> +nb_items = 1;
> +for (p = mapping; *p; p++) {
> +if (*p == '|' || *p == ' ')
> +nb_items++;
> +}
> +
> +s->map= av_calloc(nb_items, sizeof(*s->map));
> +s->pts= av_calloc(nb_items, sizeof(*s->pts));
> +s->frames = av_calloc(nb_items, sizeof(*s->frames));
> +if (!s->map || !s->frames || !s->pts) {
> +return AVERROR(ENOMEM);

leaks mapping

> +}
> +
> +for (n = 0; n < nb_items; n++) {
> +s->map[n] = -1;
> +}
> +
> +for (n = 0; n < nb_items; n++) {
> +char *map = av_strtok(n == 0 ? mapping : NULL, " |", );

> +if (!map || sscanf(map, "%d", >map[n]) != 1)
> +return AVERROR(EINVAL);
> +if (s->map[n] < 0 || s->map[n] >= nb_items)
> +return AVERROR(EINVAL);

ditto mapping leak

> +}
> +
> +s->nb_frames = nb_items;
> +av_free(mapping);
> +return 0;
> +}
> +
> +static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
> +{
> +AVFilterContext*ctx = inlink->dst;
> +ShuffleFramesContext *s = ctx->priv;
> +int ret;
> +
> +if (s->in_frames < s->nb_frames) {
> +s->frames[s->in_frames] = frame;
> +s->pts[s->in_frames] = frame->pts;
> +s->in_frames++;
> +ret = 0;
> +}
> +
> +if (s->in_frames == s->nb_frames) {
> +int n, x;
> +
> +for (n = 0; n < s->nb_frames; n++) {
> +AVFrame *out;
> +
> +x = s->map[n];
> +out =