[FFmpeg-devel] [PATCH v2] avcodec: add realtime bitstream filter

Moritz Barsnick barsnick at gmx.net
Wed May 1 17:13:16 EEST 2019


Works for video and audio streams.

Similar to the "-re" option in ffmpeg, but unlike that option does not
only work for input files, and is not only implemented for the
command line tool. This filter is available through the libraries,
and unlike the "realtime" filter also works when using the "copy"
encoder.

Implementation mostly taken from libavfilter/f_realtime.c.
---
 doc/bitstream_filters.texi     | 24 +++++++++++
 libavcodec/Makefile            |  1 +
 libavcodec/bitstream_filters.c |  1 +
 libavcodec/realtime_bsf.c      | 93 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 119 insertions(+)
 create mode 100644 libavcodec/realtime_bsf.c

diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index 25bbf8372b..18ddb2e52b 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -599,6 +599,30 @@ 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 bitstream 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
+ at 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 item speed
+Speed factor for processing. The value must be a float larger than zero.
+Values larger than 1.0 will result in faster than realtime processing,
+smaller will slow processing down. The @var{limit} is automatically adapted
+accordingly. Default is 1.0.
+
+A processing speed faster than what is possible without this bitstream
+filter cannot be achieved.
+ at end table
+
 @section remove_extra

 Remove extradata from packets.
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index f37135fc07..83f143922f 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -1094,6 +1094,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 463003966a..741a240380 100644
--- a/libavcodec/bitstream_filters.c
+++ b/libavcodec/bitstream_filters.c
@@ -49,6 +49,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..b9abda90a4
--- /dev/null
+++ b/libavcodec/realtime_bsf.c
@@ -0,0 +1,93 @@
+/*
+ * 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"
+#include <float.h>
+
+typedef struct RealtimeContext {
+    const AVClass *class;
+    int64_t delta;
+    int64_t limit;
+    double speed;
+    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) / ctx->speed;
+        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 (FFABS(sleep) > ctx->limit / ctx->speed) {
+            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 },
+    { "speed", "speed factor", OFFSET(speed), AV_OPT_TYPE_DOUBLE, { .dbl = 1.0 }, DBL_MIN, DBL_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