This imposes a global maximum volume scale of 8388607 to keep
volume_i <= INT_MAX. Also, different functions are used depending on the
scale in order to avoid doing 64-bit multiplication when possible.
---
libavfilter/af_volume.c | 32 ++++++++++++++++++++++++++++----
1 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/libavfilter/af_volume.c b/libavfilter/af_volume.c
index e88d9ca..230dfd7 100644
--- a/libavfilter/af_volume.c
+++ b/libavfilter/af_volume.c
@@ -114,7 +114,7 @@ static av_cold int init(AVFilterContext *ctx, const char
*args)
goto init_end;
}
- if (d < 0 || d > 65536) { /* 65536 = INT_MIN / (128 * 256) */
+ if (d < 0 || d > 8388607) { /* INT_MAX / 256 */
av_log(ctx, AV_LOG_ERROR,
"Negative or too big volume value %f\n", d);
ret = AVERROR(EINVAL);
@@ -193,6 +193,15 @@ static inline void scale_samples_u8(uint8_t *data, int
nb_samples, int volume)
int i;
uint8_t *smp = data;
for (i = 0; i < nb_samples; i++)
+ smp[i] = av_clip_uint8(((((int64_t)smp[i] - 128) * volume + 128) >> 8)
+ 128);
+}
+
+static inline void scale_samples_u8_small(VolumeContext *vol, uint8_t *data,
+ int nb_samples, int volume)
+{
+ int i;
+ uint8_t *smp = data;
+ for (i = 0; i < nb_samples; i++)
smp[i] = av_clip_uint8((((smp[i] - 128) * volume + 128) >> 8) + 128);
}
@@ -204,6 +213,15 @@ static inline void scale_samples_s16(uint8_t *data, int
nb_samples, int volume)
smp[i] = av_clip_int16(((int64_t)smp[i] * volume + 128) >> 8);
}
+static inline void scale_samples_s16_small(VolumeContext *vol, uint8_t *data,
+ int nb_samples, int volume)
+{
+ int i;
+ int16_t *smp = (int16_t *)data;
+ for (i = 0; i < nb_samples; i++)
+ smp[i] = av_clip_int16((smp[i] * volume + 128) >> 8);
+}
+
static inline void scale_samples_s32(uint8_t *data, int nb_samples, int volume)
{
int i;
@@ -233,12 +251,18 @@ static inline void scale_samples_dbl(uint8_t *data, int
nb_samples,
static void volume_init(VolumeContext *vol, enum AVSampleFormat sample_fmt)
{
- switch (sample_fmt) {
+ switch (av_get_packed_sample_fmt(sample_fmt)) {
case AV_SAMPLE_FMT_U8:
- vol->scale_samples_int = scale_samples_u8;
+ if (vol->volume_i < 16777216)
+ vol->scale_samples_int = scale_samples_u8_small;
+ else
+ vol->scale_samples_int = scale_samples_u8;
break;
case AV_SAMPLE_FMT_S16:
- vol->scale_samples_int = scale_samples_s16;
+ if (vol->volume_i < 65536)
+ vol->scale_samples_int = scale_samples_s16_small;
+ else
+ vol->scale_samples_int = scale_samples_s16;
break;
case AV_SAMPLE_FMT_S32:
vol->scale_samples_int = scale_samples_s32;
--
1.7.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel