[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