From patchwork Wed Jul 10 01:44:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Eoff, Ullysses A" X-Patchwork-Id: 13883 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 0F1B44471E9 for ; Wed, 10 Jul 2019 04:45:03 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id E62B868A957; Wed, 10 Jul 2019 04:45:02 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B3D0C68A878 for ; Wed, 10 Jul 2019 04:44:56 +0300 (EEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Jul 2019 18:44:53 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.63,472,1557212400"; d="scan'208";a="167584062" Received: from uaeoff-desk.amr.corp.intel.com ([10.251.0.178]) by fmsmga007.fm.intel.com with ESMTP; 09 Jul 2019 18:44:53 -0700 From: "U. Artie Eoff" To: ffmpeg-devel@ffmpeg.org Date: Tue, 9 Jul 2019 18:44:51 -0700 Message-Id: <20190710014451.16132-1-ullysses.a.eoff@intel.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avfilter: add rawdump filter X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: "U. Artie Eoff" Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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 --- 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 : - 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 +@anchor{rawdump} +@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: + +@table @option +@item file @var{filename} +Specify the filename to dump the data to. +@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, +};