[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