diff mbox series

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

Message ID 20210723103450.11265-2-ffmpeg@gyani.pro
State New
Headers show
Series [FFmpeg-devel,v2,1/2] avcodec/noise: don't force non-zero value for amount
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Gyan Doshi July 23, 2021, 10:34 a.m. UTC
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(-)

Comments

Michael Niedermayer July 23, 2021, 7:49 p.m. UTC | #1
On Fri, Jul 23, 2021 at 04:04:50PM +0530, Gyan Doshi wrote:
> 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}.
> +@item drop_pattern
> +Regulate how packets are dropped, starting with packet index of @var{drop_offset}.
> +Possible values are
> +@table @option
> +@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.
> +@item 1
> +Drop a random packet in each interval of size @var{dropamount}.
> +@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}.
> +@end table
> +@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

I suggest that if a more powerful& fancy logic is added then libavutil/eval is
used, its more generic and it uses the same syntax&functions used in many other
places in ffmpeg.
it could do all kinds of interresting things like droping packets based on
their number, size, content, timestamp, duration

thx

[...]
diff mbox series

Patch

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}.
+@item drop_pattern
+Regulate how packets are dropped, starting with packet index of @var{drop_offset}.
+Possible values are
+@table @option
+@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.
+@item 1
+Drop a random packet in each interval of size @var{dropamount}.
+@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}.
+@end table
+@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.
+@example
+ffmpeg -i INPUT -c copy -bsf noise=amount=3:dropamount=5:drop_pattern=1:drop_offset=2 output.mkv
+@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