summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--audio/filter/af_scaletempo.c3
-rw-r--r--player/audio.c123
2 files changed, 66 insertions, 60 deletions
diff --git a/audio/filter/af_scaletempo.c b/audio/filter/af_scaletempo.c
index 131dc5d511..4f0eb13091 100644
--- a/audio/filter/af_scaletempo.c
+++ b/audio/filter/af_scaletempo.c
@@ -286,9 +286,6 @@ static void update_speed(struct af_instance *af, float speed)
s->frames_stride_scaled = s->scale * s->frames_stride;
s->frames_stride_error = MPMIN(s->frames_stride_error, s->frames_stride_scaled);
-
- MP_VERBOSE(af, "%.3f speed * %.3f scale_nominal = %.3f\n",
- s->speed, s->scale_nominal, s->scale);
}
// Initialization and runtime control
diff --git a/player/audio.c b/player/audio.c
index 260c4fead4..0121dfb9e2 100644
--- a/player/audio.c
+++ b/player/audio.c
@@ -43,16 +43,23 @@
#include "core.h"
#include "command.h"
-static int update_playback_speed_filters(struct MPContext *mpctx)
+// Use pitch correction only for speed adjustments by the user, not minor sync
+// correction ones.
+static int get_speed_method(struct MPContext *mpctx)
+{
+ return mpctx->opts->pitch_correction && mpctx->opts->playback_speed != 1.0
+ ? AF_CONTROL_SET_PLAYBACK_SPEED : AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE;
+}
+
+// Try to reuse the existing filters to change playback speed. If it works,
+// return true; if filter recreation is needed, return false.
+static bool update_speed_filters(struct MPContext *mpctx)
{
- struct MPOpts *opts = mpctx->opts;
- double speed = mpctx->audio_speed;
struct af_stream *afs = mpctx->d_audio->afilter;
+ double speed = mpctx->audio_speed;
- // Use pitch correction only for speed adjustments by the user, not minor
- // sync correction ones.
- bool use_pitch_correction = opts->pitch_correction &&
- opts->playback_speed != 1.0;
+ if (afs->initialized < 1)
+ return false;
// Make sure only exactly one filter changes speed; resetting them all
// and setting 1 filter is the easiest way to achieve this.
@@ -60,54 +67,69 @@ static int update_playback_speed_filters(struct MPContext *mpctx)
af_control_all(afs, AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE, &(double){1});
if (speed == 1.0)
- return af_remove_by_label(afs, "playback-speed");
+ return !af_find_by_label(afs, "playback-speed");
// Compatibility: if the user uses --af=scaletempo, always use this
// filter to change speed. Don't insert a second filter (any) either.
if (!af_find_by_label(afs, "playback-speed") &&
af_control_any_rev(afs, AF_CONTROL_SET_PLAYBACK_SPEED, &speed))
- return 0;
+ return true;
- int method = AF_CONTROL_SET_PLAYBACK_SPEED_RESAMPLE;
- if (use_pitch_correction)
- method = AF_CONTROL_SET_PLAYBACK_SPEED;
-
- if (!af_control_any_rev(afs, method, &speed)) {
- if (af_remove_by_label(afs, "playback-speed") < 0)
- return -1;
-
- char *filter = method == AF_CONTROL_SET_PLAYBACK_SPEED
- ? "scaletempo" : "lavrresample";
- if (af_add(afs, filter, "playback-speed", NULL) < 0)
- return -1;
- // Try again.
- if (!af_control_any_rev(afs, method, &speed))
- return -1;
- }
+ return !!af_control_any_rev(afs, get_speed_method(mpctx), &speed);
+}
- return 0;
+// Update speed, and insert/remove filters if necessary.
+static void recreate_speed_filters(struct MPContext *mpctx)
+{
+ struct af_stream *afs = mpctx->d_audio->afilter;
+
+ if (update_speed_filters(mpctx))
+ return;
+
+ if (af_remove_by_label(afs, "playback-speed") < 0)
+ goto fail;
+
+ if (mpctx->audio_speed == 1.0)
+ return;
+
+ int method = get_speed_method(mpctx);
+ char *filter = method == AF_CONTROL_SET_PLAYBACK_SPEED
+ ? "scaletempo" : "lavrresample";
+
+ if (!af_add(afs, filter, "playback-speed", NULL))
+ goto fail;
+
+ if (!update_speed_filters(mpctx))
+ goto fail;
+
+ return;
+
+fail:
+ mpctx->opts->playback_speed = 1.0;
+ mpctx->speed_factor_a = 1.0;
+ mpctx->audio_speed = 1.0;
+ mp_notify(mpctx, MP_EVENT_CHANGE_ALL, NULL);
}
static int recreate_audio_filters(struct MPContext *mpctx)
{
assert(mpctx->d_audio);
- if (update_playback_speed_filters(mpctx) < 0) {
- mpctx->opts->playback_speed = 1.0;
- mpctx->speed_factor_a = 1.0;
- mpctx->audio_speed = 1.0;
- mp_notify(mpctx, MP_EVENT_CHANGE_ALL, NULL);
- }
-
struct af_stream *afs = mpctx->d_audio->afilter;
- if (afs->initialized < 1 && af_init(afs) < 0) {
- MP_ERR(mpctx, "Couldn't find matching filter/ao format!\n");
- return -1;
- }
+ if (afs->initialized < 1 && af_init(afs) < 0)
+ goto fail;
+
+ recreate_speed_filters(mpctx);
+ if (afs->initialized < 1 && af_init(afs) < 0)
+ goto fail;
mixer_reinit_audio(mpctx->mixer, mpctx->ao, afs);
return 0;
+
+fail:
+ MP_ERR(mpctx, "Couldn't find matching filter/ao format!\n");
+ return -1;
}
int reinit_audio_filters(struct MPContext *mpctx)
@@ -117,33 +139,20 @@ int reinit_audio_filters(struct MPContext *mpctx)
return 0;
af_uninit(mpctx->d_audio->afilter);
- if (af_init(mpctx->d_audio->afilter) < 0)
- return -1;
- if (recreate_audio_filters(mpctx) < 0)
- return -1;
-
- return 1;
+ return recreate_audio_filters(mpctx) < 0 ? -1 : 1;
}
-// Call this if opts->playback_speed or mpctx->speed_correction changes.
+// Call this if opts->playback_speed or mpctx->speed_factor_* change.
void update_playback_speed(struct MPContext *mpctx)
{
- struct MPOpts *opts = mpctx->opts;
-
- double old_speed_factor_a = mpctx->speed_factor_a;
- double old_audio_speed = mpctx->audio_speed;
-
- mpctx->audio_speed = opts->playback_speed * mpctx->speed_factor_a;
- mpctx->video_speed = opts->playback_speed * mpctx->speed_factor_v;
-
- if (mpctx->speed_factor_a == old_speed_factor_a &&
- mpctx->audio_speed == old_audio_speed)
- return;
+ mpctx->audio_speed = mpctx->opts->playback_speed * mpctx->speed_factor_a;
+ mpctx->video_speed = mpctx->opts->playback_speed * mpctx->speed_factor_v;
- if (!mpctx->d_audio || mpctx->d_audio->afilter->initialized < 1)
+ if (!mpctx->d_audio)
return;
- recreate_audio_filters(mpctx);
+ if (!update_speed_filters(mpctx))
+ recreate_audio_filters(mpctx);
}
void reset_audio_state(struct MPContext *mpctx)