summaryrefslogtreecommitdiffstats
path: root/filters
diff options
context:
space:
mode:
Diffstat (limited to 'filters')
-rw-r--r--filters/f_auto_filters.c55
-rw-r--r--filters/f_output_chain.c20
-rw-r--r--filters/f_output_chain.h2
-rw-r--r--filters/filter.h1
-rw-r--r--filters/user_filters.c1
-rw-r--r--filters/user_filters.h1
6 files changed, 60 insertions, 20 deletions
diff --git a/filters/f_auto_filters.c b/filters/f_auto_filters.c
index 944fe89eab..a5394dd35a 100644
--- a/filters/f_auto_filters.c
+++ b/filters/f_auto_filters.c
@@ -1,5 +1,7 @@
#include <math.h>
+#include "audio/aframe.h"
+#include "audio/format.h"
#include "common/common.h"
#include "common/msg.h"
#include "options/m_config.h"
@@ -295,7 +297,8 @@ struct mp_filter *mp_autorotate_create(struct mp_filter *parent)
struct aspeed_priv {
struct mp_subfilter sub;
- double cur_speed;
+ double cur_speed, cur_speed_drop;
+ int current_filter;
};
static void aspeed_process(struct mp_filter *f)
@@ -305,26 +308,48 @@ static void aspeed_process(struct mp_filter *f)
if (!mp_subfilter_read(&p->sub))
return;
- if (fabs(p->cur_speed - 1.0) < 1e-8) {
+ if (!p->sub.filter)
+ p->current_filter = 0;
+
+ double speed = p->cur_speed * p->cur_speed_drop;
+
+ int req_filter = 0;
+ if (fabs(speed - 1.0) >= 1e-8) {
+ req_filter = p->cur_speed_drop == 1.0 ? 1 : 2;
+ if (p->sub.frame.type == MP_FRAME_AUDIO &&
+ !af_fmt_is_pcm(mp_aframe_get_format(p->sub.frame.data)))
+ req_filter = 2;
+ }
+
+ if (req_filter != p->current_filter) {
if (p->sub.filter)
- MP_VERBOSE(f, "removing scaletempo\n");
+ MP_VERBOSE(f, "removing audio speed filter\n");
if (!mp_subfilter_drain_destroy(&p->sub))
return;
- } else if (!p->sub.filter) {
- MP_VERBOSE(f, "adding scaletempo\n");
- p->sub.filter =
- mp_create_user_filter(f, MP_OUTPUT_CHAIN_AUDIO, "scaletempo", NULL);
- if (!p->sub.filter) {
- MP_ERR(f, "could not create scaletempo filter\n");
- mp_subfilter_continue(&p->sub);
- return;
+
+ if (req_filter) {
+ if (req_filter == 1) {
+ MP_VERBOSE(f, "adding scaletempo\n");
+ p->sub.filter = mp_create_user_filter(f, MP_OUTPUT_CHAIN_AUDIO,
+ "scaletempo", NULL);
+ } else if (req_filter == 2) {
+ MP_VERBOSE(f, "adding drop\n");
+ p->sub.filter = mp_create_user_filter(f, MP_OUTPUT_CHAIN_AUDIO,
+ "drop", NULL);
+ }
+ if (!p->sub.filter) {
+ MP_ERR(f, "could not create filter\n");
+ mp_subfilter_continue(&p->sub);
+ return;
+ }
+ p->current_filter = req_filter;
}
}
if (p->sub.filter) {
struct mp_filter_command cmd = {
.type = MP_FILTER_COMMAND_SET_SPEED,
- .speed = p->cur_speed,
+ .speed = speed,
};
mp_filter_command(p->sub.filter, &cmd);
}
@@ -341,6 +366,11 @@ static bool aspeed_command(struct mp_filter *f, struct mp_filter_command *cmd)
return true;
}
+ if (cmd->type == MP_FILTER_COMMAND_SET_SPEED_DROP) {
+ p->cur_speed_drop = cmd->speed;
+ return true;
+ }
+
if (cmd->type == MP_FILTER_COMMAND_IS_ACTIVE) {
cmd->is_active = !!p->sub.filter;
return true;
@@ -381,6 +411,7 @@ struct mp_filter *mp_autoaspeed_create(struct mp_filter *parent)
struct aspeed_priv *p = f->priv;
p->cur_speed = 1.0;
+ p->cur_speed_drop = 1.0;
p->sub.in = mp_filter_add_pin(f, MP_PIN_IN, "in");
p->sub.out = mp_filter_add_pin(f, MP_PIN_OUT, "out");
diff --git a/filters/f_output_chain.c b/filters/f_output_chain.c
index cf16dcbf47..468bfe6466 100644
--- a/filters/f_output_chain.c
+++ b/filters/f_output_chain.c
@@ -454,13 +454,12 @@ bool mp_output_chain_command(struct mp_output_chain *c, const char *target,
// supports it, reset *speed, then keep setting the speed on the other filters.
// The purpose of this is to make sure only 1 filter changes speed.
static void set_speed_any(struct mp_user_filter **filters, int num_filters,
- bool resample, double *speed)
+ int command, double *speed)
{
for (int n = num_filters - 1; n >= 0; n--) {
assert(*speed);
struct mp_filter_command cmd = {
- .type = resample ? MP_FILTER_COMMAND_SET_SPEED_RESAMPLE
- : MP_FILTER_COMMAND_SET_SPEED,
+ .type = command,
.speed = *speed,
};
if (mp_filter_command(filters[n]->f, &cmd))
@@ -469,17 +468,24 @@ static void set_speed_any(struct mp_user_filter **filters, int num_filters,
}
void mp_output_chain_set_audio_speed(struct mp_output_chain *c,
- double speed, double resample)
+ double speed, double resample, double drop)
{
struct chain *p = c->f->priv;
// We always resample with the final libavresample instance.
- set_speed_any(p->post_filters, p->num_post_filters, true, &resample);
+ set_speed_any(p->post_filters, p->num_post_filters,
+ MP_FILTER_COMMAND_SET_SPEED_RESAMPLE, &resample);
// If users have filters like "scaletempo" insert anywhere, use that,
// otherwise use the builtin ones.
- set_speed_any(p->user_filters, p->num_user_filters, false, &speed);
- set_speed_any(p->post_filters, p->num_post_filters, false, &speed);
+ set_speed_any(p->user_filters, p->num_user_filters,
+ MP_FILTER_COMMAND_SET_SPEED, &speed);
+ set_speed_any(p->post_filters, p->num_post_filters,
+ MP_FILTER_COMMAND_SET_SPEED, &speed);
+ set_speed_any(p->user_filters, p->num_user_filters,
+ MP_FILTER_COMMAND_SET_SPEED_DROP, &drop);
+ set_speed_any(p->post_filters, p->num_post_filters,
+ MP_FILTER_COMMAND_SET_SPEED_DROP, &drop);
}
double mp_output_get_measured_total_delay(struct mp_output_chain *c)
diff --git a/filters/f_output_chain.h b/filters/f_output_chain.h
index 980b117d00..f06769cdd9 100644
--- a/filters/f_output_chain.h
+++ b/filters/f_output_chain.h
@@ -77,7 +77,7 @@ bool mp_output_chain_update_filters(struct mp_output_chain *p,
// Desired audio speed, with resample being strict resampling.
void mp_output_chain_set_audio_speed(struct mp_output_chain *p,
- double speed, double resample);
+ double speed, double resample, double drop);
// Total delay incurred by the filter chain, as measured by the recent filtered
// frames. The intention is that this sums the measured delays for each filter,
diff --git a/filters/filter.h b/filters/filter.h
index ddd3f27c3c..34cfcf0f54 100644
--- a/filters/filter.h
+++ b/filters/filter.h
@@ -364,6 +364,7 @@ enum mp_filter_command_type {
MP_FILTER_COMMAND_GET_META,
MP_FILTER_COMMAND_SET_SPEED,
MP_FILTER_COMMAND_SET_SPEED_RESAMPLE,
+ MP_FILTER_COMMAND_SET_SPEED_DROP,
MP_FILTER_COMMAND_IS_ACTIVE,
};
diff --git a/filters/user_filters.c b/filters/user_filters.c
index 72a2ab892c..57021adc7c 100644
--- a/filters/user_filters.c
+++ b/filters/user_filters.c
@@ -39,6 +39,7 @@ const struct mp_user_filter_entry *af_list[] = {
&af_rubberband,
#endif
&af_lavcac3enc,
+ &af_drop,
};
static bool get_af_desc(struct m_obj_desc *dst, int index)
diff --git a/filters/user_filters.h b/filters/user_filters.h
index a79e17030b..cecf0b52cd 100644
--- a/filters/user_filters.h
+++ b/filters/user_filters.h
@@ -24,6 +24,7 @@ extern const struct mp_user_filter_entry af_scaletempo;
extern const struct mp_user_filter_entry af_format;
extern const struct mp_user_filter_entry af_rubberband;
extern const struct mp_user_filter_entry af_lavcac3enc;
+extern const struct mp_user_filter_entry af_drop;
extern const struct mp_user_filter_entry vf_lavfi;
extern const struct mp_user_filter_entry vf_lavfi_bridge;