[FFmpeg-devel] [PATCH 1/2] avcodec: add realtime bitstream filter
Moritz Barsnick
barsnick at gmx.net
Tue Dec 25 22:41:38 EET 2018
Works for video and audio streams.
Similar to the -re option in ffmpeg that only works for input files,
and is only implemented for the command line tool, not available in
the libraries.
Implementation mostly taken from libavfilter/f_realtime.c.
Signed-off-by: Moritz Barsnick <barsnick at gmx.net>
---
doc/bitstream_filters.texi | 16 ++++++++
libavcodec/Makefile | 1 +
libavcodec/bitstream_filters.c | 1 +
libavcodec/realtime_bsf.c | 90 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 108 insertions(+)
create mode 100644 libavcodec/realtime_bsf.c
diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index b779265f58..8c71100460 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -596,6 +596,22 @@ Set Rec709 colorspace for each frame of the file
ffmpeg -i INPUT -c copy -bsf:v prores_metadata=color_primaries=bt709:color_trc=bt709:colorspace=bt709 output.mov
@end example
+ at section realtime
+
+Slow down output processing to match real time approximately.
+
+This filter will pause the filtering for a variable amount of time to
+match the output rate with the input timestamps.
+It is similar to the @option{re} option to @code{ffmpeg}.
+
+It accepts the following options:
+
+ at table @option
+ at item limit
+Time limit for the pauses. Any pause longer than that will be considered
+a timestamp discontinuity and reset the timer. Default is 2 seconds.
+ at end table
+
@section remove_extra
Remove extradata from packets.
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 08f89ae0b2..a85a5e1fa2 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1085,6 +1085,7 @@ OBJS-$(CONFIG_MPEG2_METADATA_BSF) += mpeg2_metadata_bsf.o
OBJS-$(CONFIG_NOISE_BSF) += noise_bsf.o
OBJS-$(CONFIG_NULL_BSF) += null_bsf.o
OBJS-$(CONFIG_PRORES_METADATA_BSF) += prores_metadata_bsf.o
+OBJS-$(CONFIG_REALTIME_BSF) += realtime_bsf.o
OBJS-$(CONFIG_REMOVE_EXTRADATA_BSF) += remove_extradata_bsf.o
OBJS-$(CONFIG_TEXT2MOVSUB_BSF) += movsub_bsf.o
OBJS-$(CONFIG_TRACE_HEADERS_BSF) += trace_headers_bsf.o
diff --git a/libavcodec/bitstream_filters.c b/libavcodec/bitstream_filters.c
index 2c999d3c1d..ba7d3224c4 100644
--- a/libavcodec/bitstream_filters.c
+++ b/libavcodec/bitstream_filters.c
@@ -48,6 +48,7 @@ extern const AVBitStreamFilter ff_mov2textsub_bsf;
extern const AVBitStreamFilter ff_noise_bsf;
extern const AVBitStreamFilter ff_null_bsf;
extern const AVBitStreamFilter ff_prores_metadata_bsf;
+extern const AVBitStreamFilter ff_realtime_bsf;
extern const AVBitStreamFilter ff_remove_extradata_bsf;
extern const AVBitStreamFilter ff_text2movsub_bsf;
extern const AVBitStreamFilter ff_trace_headers_bsf;
diff --git a/libavcodec/realtime_bsf.c b/libavcodec/realtime_bsf.c
new file mode 100644
index 0000000000..eb4b0b69ed
--- /dev/null
+++ b/libavcodec/realtime_bsf.c
@@ -0,0 +1,90 @@
+/*
+ * Realtime filter
+ * Copyright (c) 2015 Nicolas George
+ * Copyright (c) 2018 Moritz Barsnick
+ *
+ * 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/time.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "bsf.h"
+
+typedef struct RealtimeContext {
+ const AVClass *class;
+ int64_t delta;
+ int64_t limit;
+ unsigned inited;
+} RealtimeContext;
+
+static int realtime_filter(AVBSFContext *bsf, AVPacket *pkt)
+{
+ int ret;
+ RealtimeContext *ctx = bsf->priv_data;
+
+ ret = ff_bsf_get_packet_ref(bsf, pkt);
+ if (ret < 0)
+ return ret;
+
+ if (pkt->pts != AV_NOPTS_VALUE) {
+ int64_t pts = av_rescale_q(pkt->pts, bsf->time_base_in, AV_TIME_BASE_Q);
+ int64_t now = av_gettime_relative();
+ int64_t sleep = pts - now + ctx->delta;
+ if (!ctx->inited) {
+ ctx->inited = 1;
+ sleep = 0;
+ ctx->delta = now - pts;
+ }
+ if (sleep > ctx->limit || sleep < -ctx->limit) {
+ av_log(ctx, AV_LOG_WARNING,
+ "time discontinuity detected: %"PRIi64" us, resetting\n",
+ sleep);
+ sleep = 0;
+ ctx->delta = now - pts;
+ }
+ if (sleep > 0) {
+ av_log(ctx, AV_LOG_DEBUG, "sleeping %"PRIi64" us\n", sleep);
+ for (; sleep > 600000000; sleep -= 600000000)
+ av_usleep(600000000);
+ av_usleep(sleep);
+ }
+ }
+
+ return 0;
+}
+
+#define OFFSET(x) offsetof(RealtimeContext, x)
+#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_BSF_PARAM)
+static const AVOption options[] = {
+ { "limit", "sleep time limit", OFFSET(limit), AV_OPT_TYPE_DURATION, { .i64 = 2000000 }, 0, INT64_MAX, FLAGS },
+ { NULL },
+};
+
+static const AVClass realtime_class = {
+ .class_name = "realtime_bsf",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+const AVBitStreamFilter ff_realtime_bsf = {
+ .name = "realtime",
+ .priv_data_size = sizeof(RealtimeContext),
+ .priv_class = &realtime_class,
+ .filter = realtime_filter,
+};
--
2.14.5
More information about the ffmpeg-devel
mailing list