diff options
Diffstat (limited to 'filters')
-rw-r--r-- | filters/f_auto_filters.c | 55 | ||||
-rw-r--r-- | filters/f_output_chain.c | 20 | ||||
-rw-r--r-- | filters/f_output_chain.h | 2 | ||||
-rw-r--r-- | filters/filter.h | 1 | ||||
-rw-r--r-- | filters/user_filters.c | 1 | ||||
-rw-r--r-- | filters/user_filters.h | 1 |
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; |