[FFmpeg-devel] [PATCHv2 1/2] ffplay: add support for interactive volume control

Ganesh Ajjanagadde gajjanagadde at gmail.com
Sat Sep 26 17:36:42 CEST 2015


This is a feature heavily inspired by the mpv player. At the moment, methods
for adjusting volume in ffplay are rather clumsy: either one needs to set it
system-wide, or one needs to set it via the volume filter.

This patch adds key bindings identical to the mpv defaults for muting/unmuting
and increasing/decreasing the volume interactively without any introduction of
external dependencies.

TODO: doc update, possible mouse button bindings (mpv has this).

Signed-off-by: Ganesh Ajjanagadde <gajjanagadde at gmail.com>
---
 ffplay.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/ffplay.c b/ffplay.c
index d302793..eada863 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -73,6 +73,9 @@ const int program_birth_year = 2003;
 /* Calculate actual buffer size keeping in mind not cause too frequent audio callbacks */
 #define SDL_AUDIO_MAX_CALLBACKS_PER_SEC 30
 
+/* Step size for volume control */
+#define SDL_VOLUME_STEP 2
+
 /* no AV sync correction is done if below the minimum AV sync threshold */
 #define AV_SYNC_THRESHOLD_MIN 0.04
 /* AV sync correction is done if above the maximum AV sync threshold */
@@ -246,6 +249,8 @@ typedef struct VideoState {
     unsigned int audio_buf1_size;
     int audio_buf_index; /* in bytes */
     int audio_write_buf_size;
+    int audio_volume;
+    int muted;
     struct AudioParams audio_src;
 #if CONFIG_AVFILTER
     struct AudioParams audio_filter_src;
@@ -1348,6 +1353,17 @@ static void toggle_pause(VideoState *is)
     is->step = 0;
 }
 
+static void toggle_mute(VideoState *is)
+{
+    is->muted = !is->muted;
+}
+
+static void update_volume(VideoState *is, int sign, int step)
+{
+    is->audio_volume += sign * step;
+    is->audio_volume = av_clip(is->audio_volume, 0, SDL_MIX_MAXVOLUME);
+}
+
 static void step_to_next_frame(VideoState *is)
 {
     /* if the stream is paused unpause it, then step */
@@ -2447,7 +2463,10 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len)
         len1 = is->audio_buf_size - is->audio_buf_index;
         if (len1 > len)
             len1 = len;
-        memcpy(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1);
+        if (is->muted)
+            memset(stream, 0, len1);
+        else
+            SDL_MixAudio(stream, (uint8_t *)is->audio_buf + is->audio_buf_index, len1, is->audio_volume);
         len -= len1;
         stream += len1;
         is->audio_buf_index += len1;
@@ -2634,6 +2653,8 @@ static int stream_component_open(VideoState *is, int stream_index)
         is->audio_src = is->audio_tgt;
         is->audio_buf_size  = 0;
         is->audio_buf_index = 0;
+        is->audio_volume = SDL_MIX_MAXVOLUME;
+        is->muted = 0;
 
         /* init averaging filter */
         is->audio_diff_avg_coef  = exp(log(0.01) / AUDIO_DIFF_AVG_NB);
@@ -3311,6 +3332,17 @@ static void event_loop(VideoState *cur_stream)
             case SDLK_SPACE:
                 toggle_pause(cur_stream);
                 break;
+            case SDLK_m:
+                toggle_mute(cur_stream);
+                break;
+            case SDLK_ASTERISK:
+            case SDLK_0:
+                update_volume(cur_stream, 1, SDL_VOLUME_STEP);
+                break;
+            case SDLK_SLASH:
+            case SDLK_9:
+                update_volume(cur_stream, -1, SDL_VOLUME_STEP);
+                break;
             case SDLK_s: // S: Step to next frame
                 step_to_next_frame(cur_stream);
                 break;
-- 
2.5.3



More information about the ffmpeg-devel mailing list