[FFmpeg-devel] [PATCH v2 2/2] avcodec/noise: allow various cadence for dropping packets

Gyan Doshi ffmpeg at gyani.pro
Fri Jul 23 13:34:50 EEST 2021


Packets can now be dropped at fixed intervals or
with varying degrees of irregularity
---
 doc/bitstream_filters.texi                    | 22 +++++++
 libavcodec/noise_bsf.c                        | 65 +++++++++++++++----
 libavcodec/version.h                          |  2 +-
 .../fate/matroska-mastering-display-metadata  |  5 +-
 4 files changed, 76 insertions(+), 18 deletions(-)

diff --git a/doc/bitstream_filters.texi b/doc/bitstream_filters.texi
index 2b84bda1fc..4ab6cc15ab 100644
--- a/doc/bitstream_filters.texi
+++ b/doc/bitstream_filters.texi
@@ -539,6 +539,22 @@ with @var{1} meaning every byte is modified. Default is @var{0}.
 @item dropamount
 Accepts a positive integer. Lower the value, more frequently packets will be dropped,
 with @var{1} meaning every packet is dropped. Default is @var{0}.
+ at item drop_pattern
+Regulate how packets are dropped, starting with packet index of @var{drop_offset}.
+Possible values are
+ at table @option
+ at item 0 (@emph{default})
+Drop at fixed intervals of @var{dropamount}, e.g. with dropamount @var{5} and drop_offset @var{2},
+packets no. @code{2, 7, 12...} will be dropped.
+ at item 1
+Drop a random packet in each interval of size @var{dropamount}.
+ at item 2
+Drop a random packet in roughly inverse frequency to @var{dropamount}. Over a short range of packets,
+the drop frequency is less stable than pattern value @var{1}.
+ at end table
+ at item drop_offset
+Accepts a positive integer. Represents the index of the first packet at which drop evaluations
+start. Default is @var{0}.
 @end table
 
 The following example applies the modification to every byte but does not drop
@@ -547,6 +563,12 @@ any packets.
 ffmpeg -i INPUT -c copy -bsf noise=amount=1 output.mkv
 @end example
 
+The following example drops one random packet every 5 packets starting with packet #2 and modifies
+roughly every 3rd byte of remaining packets.
+ at example
+ffmpeg -i INPUT -c copy -bsf noise=amount=3:dropamount=5:drop_pattern=1:drop_offset=2 output.mkv
+ at end example
+
 @section null
 This bitstream filter passes the packets through unchanged.
 
diff --git a/libavcodec/noise_bsf.c b/libavcodec/noise_bsf.c
index c1b0203442..83118c12cf 100644
--- a/libavcodec/noise_bsf.c
+++ b/libavcodec/noise_bsf.c
@@ -30,7 +30,12 @@ typedef struct NoiseContext {
     const AVClass *class;
     int amount;
     int dropamount;
+    int drop_pattern;
+    int drop_offset;
+
     unsigned int state;
+    unsigned int pkt_idx;
+    unsigned int drop_idx;
 } NoiseContext;
 
 static int noise_init(AVBSFContext *ctx)
@@ -48,31 +53,61 @@ static int noise_init(AVBSFContext *ctx)
 static int noise(AVBSFContext *ctx, AVPacket *pkt)
 {
     NoiseContext *s = ctx->priv_data;
-    int i, ret;
+    int i, ret, interval_pos, drop;
 
     ret = ff_bsf_get_packet_ref(ctx, pkt);
     if (ret < 0)
         return ret;
 
-    if (s->dropamount && s->state % s->dropamount == 0) {
-        s->state++;
-        av_packet_unref(pkt);
-        return AVERROR(EAGAIN);
+    if (s->dropamount && s->pkt_idx >= s->drop_offset) {
+
+        interval_pos = (s->pkt_idx - s->drop_offset) % s->dropamount;
+
+        switch (s->drop_pattern) {
+        case 0:
+            drop = interval_pos == 0;
+            break;
+        case 1:
+            if (interval_pos == 0)
+                s->drop_idx = s->pkt_idx + s->state % s->dropamount;
+            drop = s->pkt_idx == s->drop_idx;
+            break;
+        case 2:
+            drop = s->state % s->dropamount == 0;
+            break;
+        }
+
+        if (drop) {
+            av_log(ctx, AV_LOG_VERBOSE, "Stream #%d packet #%d with pts %"PRId64" dropped.\n", pkt->stream_index, s->pkt_idx, pkt->pts);
+            s->state++;
+            av_packet_unref(pkt);
+            ret = AVERROR(EAGAIN);
+            goto done;
+        }
     }
 
-    ret = av_packet_make_writable(pkt);
-    if (ret < 0) {
-        av_packet_unref(pkt);
-        return ret;
+    if (s->amount) {
+        ret = av_packet_make_writable(pkt);
+        if (ret < 0) {
+            av_packet_unref(pkt);
+            goto done;
+        }
     }
 
-    for (i = 0; i < pkt->size; i++) {
-        s->state += pkt->data[i] + 1;
-        if (s->amount && s->state % s->amount == 0)
-            pkt->data[i] = s->state;
+    if (s->amount || s->drop_pattern) {
+
+        for (i = 0; i < pkt->size; i++) {
+            s->state += pkt->data[i] + 1;
+            if (s->amount && s->state % s->amount == 0)
+                pkt->data[i] = s->state;
+        }
     }
 
-    return 0;
+    ret = 0;
+
+done:
+    s->pkt_idx++;
+    return ret;
 }
 
 #define OFFSET(x) offsetof(NoiseContext, x)
@@ -80,6 +115,8 @@ static int noise(AVBSFContext *ctx, AVPacket *pkt)
 static const AVOption options[] = {
     { "amount", NULL, OFFSET(amount), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
     { "dropamount", NULL, OFFSET(dropamount), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
+    { "drop_pattern",  NULL, OFFSET(drop_pattern),  AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2,       FLAGS },
+    { "drop_offset",  NULL,  OFFSET(drop_offset),   AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
     { NULL },
 };
 
diff --git a/libavcodec/version.h b/libavcodec/version.h
index c660f70669..91325ce4e7 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
 
 #define LIBAVCODEC_VERSION_MAJOR  59
 #define LIBAVCODEC_VERSION_MINOR   3
-#define LIBAVCODEC_VERSION_MICRO 101
+#define LIBAVCODEC_VERSION_MICRO 102
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
                                                LIBAVCODEC_VERSION_MINOR, \
diff --git a/tests/ref/fate/matroska-mastering-display-metadata b/tests/ref/fate/matroska-mastering-display-metadata
index bd8d7cb2c9..a891a65a0d 100644
--- a/tests/ref/fate/matroska-mastering-display-metadata
+++ b/tests/ref/fate/matroska-mastering-display-metadata
@@ -1,5 +1,5 @@
-61c080b57ef81a6e3bc971857a6973dc *tests/data/fate/matroska-mastering-display-metadata.matroska
-1669695 tests/data/fate/matroska-mastering-display-metadata.matroska
+d288bd70ef60206734130e8e9df3d016 *tests/data/fate/matroska-mastering-display-metadata.matroska
+1668086 tests/data/fate/matroska-mastering-display-metadata.matroska
 #extradata 0:        4, 0x040901a3
 #extradata 3:      200, 0x506463a8
 #tb 0: 1/1000
@@ -41,7 +41,6 @@
 3,         50,         50,       16,   271465, 0x251b9cbe, F=0x0
 0,         67,         67,       16,    56960, 0x431d5189
 1,         67,         67,       16,     2403, 0x61cd96cb
-2,         67,         67,       16,     1602, 0x58ca0720
 3,         67,         67,       16,   270800, 0x8fb2e217, F=0x0
 [STREAM]
 index=0
-- 
2.32.0



More information about the ffmpeg-devel mailing list