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

U. Artie Eoff ullysses.a.eoff at intel.com
Wed Jul 10 04:44:51 EEST 2019


This filter enables raw frames to be dumped to a
file before they are sent through the auto-inserted
scaler filter and useful when you want unscaled
raw frames in an output file.

Signed-off-by: U. Artie Eoff <ullysses.a.eoff at intel.com>
---
 Changelog                |   1 +
 doc/filters.texi         |  20 +++++
 libavfilter/Makefile     |   1 +
 libavfilter/allfilters.c |   1 +
 libavfilter/version.h    |   4 +-
 libavfilter/vf_rawdump.c | 157 +++++++++++++++++++++++++++++++++++++++
 6 files changed, 182 insertions(+), 2 deletions(-)
 create mode 100644 libavfilter/vf_rawdump.c

diff --git a/Changelog b/Changelog
index 86167b76a13c..7fdd3789f26d 100644
--- a/Changelog
+++ b/Changelog
@@ -35,6 +35,7 @@ version <next>:
 - IFV demuxer
 - derain filter
 - deesser filter
+- rawdump filter
 
 
 version 4.1:
diff --git a/doc/filters.texi b/doc/filters.texi
index b0c49265e296..710100486e14 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -14631,6 +14631,26 @@ less than @code{0}, the filter will try to use a good random seed on a
 best effort basis.
 @end table
 
+ at anchor{rawdump}
+ at section rawdump
+
+Dump raw video frames to a file.
+
+The filter is especially useful when you want to dump raw frames to a file
+before scaling is applied by the auto-inserted scaler in the graph (e.g. for
+multi-resolution input streams).
+
+The input must be in non-hardware format.  It may be necessary to insert an
+additional @option{format} filter immediately preceding in the graph to get
+the input in a supported format for dumping to the file.
+
+The following parameters are required:
+
+ at table @option
+ at item file @var{filename}
+Specify the filename to dump the data to.
+ at end table
+
 @section readeia608
 
 Read closed captioning (EIA-608) information from the top lines of a video frame.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 455c809b151e..f8e02f382af9 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -334,6 +334,7 @@ OBJS-$(CONFIG_PSNR_FILTER)                   += vf_psnr.o framesync.o
 OBJS-$(CONFIG_PULLUP_FILTER)                 += vf_pullup.o
 OBJS-$(CONFIG_QP_FILTER)                     += vf_qp.o
 OBJS-$(CONFIG_RANDOM_FILTER)                 += vf_random.o
+OBJS-$(CONFIG_RAWDUMP_FILTER)                += vf_rawdump.o
 OBJS-$(CONFIG_READEIA608_FILTER)             += vf_readeia608.o
 OBJS-$(CONFIG_READVITC_FILTER)               += vf_readvitc.o
 OBJS-$(CONFIG_REALTIME_FILTER)               += f_realtime.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 04a3df7d56d6..565e2a73cc82 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -317,6 +317,7 @@ extern AVFilter ff_vf_psnr;
 extern AVFilter ff_vf_pullup;
 extern AVFilter ff_vf_qp;
 extern AVFilter ff_vf_random;
+extern AVFilter ff_vf_rawdump;
 extern AVFilter ff_vf_readeia608;
 extern AVFilter ff_vf_readvitc;
 extern AVFilter ff_vf_realtime;
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 5bf37fa8b407..cc5b23b70bbe 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -30,8 +30,8 @@
 #include "libavutil/version.h"
 
 #define LIBAVFILTER_VERSION_MAJOR   7
-#define LIBAVFILTER_VERSION_MINOR  56
-#define LIBAVFILTER_VERSION_MICRO 101
+#define LIBAVFILTER_VERSION_MINOR  57
+#define LIBAVFILTER_VERSION_MICRO 100
 
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
diff --git a/libavfilter/vf_rawdump.c b/libavfilter/vf_rawdump.c
new file mode 100644
index 000000000000..fe8a8a692603
--- /dev/null
+++ b/libavfilter/vf_rawdump.c
@@ -0,0 +1,157 @@
+/*
+ * 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/buffer.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "video.h"
+
+typedef struct RawDumpContext {
+    const AVClass *class;
+    FILE *rawdump_file;
+    char *rawdump_file_str;
+} RawDumpContext;
+
+static int rawdump_query_formats(AVFilterContext *avctx)
+{
+    AVFilterFormats *formats = NULL;
+    const AVPixFmtDescriptor *desc;
+    int err;
+
+    for (desc = av_pix_fmt_desc_next(NULL); desc;
+         desc = av_pix_fmt_desc_next(desc)) {
+        if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
+            continue;
+        err = ff_add_format(&formats, av_pix_fmt_desc_get_id(desc));
+        if (err < 0)
+            return err;
+    }
+
+    return ff_set_common_formats(avctx, formats);
+}
+
+static int rawdump_filter_frame(AVFilterLink *inlink, AVFrame *frame)
+{
+    AVFilterContext *avctx = inlink->dst;
+    RawDumpContext *ctx = avctx->priv;
+    uint8_t *buffer = NULL;
+    int size, err;
+
+    size = av_image_get_buffer_size(frame->format, frame->width,
+                                    frame->height, 1);
+    buffer = av_malloc(size);
+
+    err = av_image_copy_to_buffer(buffer, size,
+                                  (const uint8_t * const *) frame->data,
+                                  (const int *) frame->linesize, frame->format,
+                                  frame->width, frame->height, 1);
+    if (err < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Failed to copy image to buffer: %d.\n", err);
+        goto fail;
+    }
+
+    err = fwrite(buffer, 1, size, ctx->rawdump_file);
+    if (err < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Failed to dump buffer to file: %d.\n", err);
+        goto fail;
+    }
+
+    av_log(ctx, AV_LOG_DEBUG, "Dumped %d bytes to file.\n", size);
+
+    av_freep(&buffer);
+
+    return ff_filter_frame(inlink->dst->outputs[0], frame);
+
+fail:
+    av_freep(&buffer);
+    return err;
+}
+
+static av_cold int rawdump_init(AVFilterContext *avctx)
+{
+    RawDumpContext *ctx = avctx->priv;
+    static char *mode = "w";
+
+    ctx->rawdump_file = fopen(ctx->rawdump_file_str, mode);
+
+    if (ctx->rawdump_file == NULL) {
+        int err = AVERROR(errno);
+        char buf[128];
+        av_strerror(err, buf, sizeof(buf));
+        av_log(ctx, AV_LOG_ERROR, "Failed to open %s for dumping: %s\n",
+               ctx->rawdump_file_str, buf);
+        return err;
+    }
+
+    av_log(ctx, AV_LOG_DEBUG, "Opened %s (mode:%s) for dumping.\n",
+           ctx->rawdump_file_str, mode);
+
+    mode = "a";
+
+    return 0;
+}
+
+static av_cold void rawdump_uninit(AVFilterContext *avctx)
+{
+    RawDumpContext *ctx = avctx->priv;
+
+    if (ctx->rawdump_file != NULL)
+        fclose(ctx->rawdump_file);
+}
+
+#define OFFSET(x) offsetof(RawDumpContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption rawdump_options[] = {
+    {"file", "Set file where to dump raw frames", OFFSET(rawdump_file_str), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, FLAGS },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(rawdump);
+
+static const AVFilterPad rawdump_inputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+        .filter_frame = rawdump_filter_frame,
+    },
+    { NULL }
+};
+
+static const AVFilterPad rawdump_outputs[] = {
+    {
+        .name         = "default",
+        .type         = AVMEDIA_TYPE_VIDEO,
+    },
+    { NULL }
+};
+
+AVFilter ff_vf_rawdump = {
+    .name          = "rawdump",
+    .description   = NULL_IF_CONFIG_SMALL("Dump frames to file"),
+    .init          = rawdump_init,
+    .uninit        = rawdump_uninit,
+    .query_formats = rawdump_query_formats,
+    .priv_size     = sizeof(RawDumpContext),
+    .priv_class    = &rawdump_class,
+    .inputs        = rawdump_inputs,
+    .outputs       = rawdump_outputs,
+};
-- 
2.20.1



More information about the ffmpeg-devel mailing list