]> git.sesse.net Git - vlc/commitdiff
playlist: add simple corking infrastructure for audio policy
authorRémi Denis-Courmont <remi@remlab.net>
Wed, 8 Aug 2012 15:48:35 +0000 (18:48 +0300)
committerRémi Denis-Courmont <remi@remlab.net>
Wed, 8 Aug 2012 14:39:53 +0000 (17:39 +0300)
Depending on the system, this can be called ducking, focus, policy...
But it basically boils down to pausing playback automatically when a
higher priority audio stream starts, typically a voice call.

Resuming playback automatically when communications are over would be
possible as well. But that seems unfriendly to me, so I skipped it.

include/vlc_aout.h
lib/media_player.c
src/audio_output/output.c
src/libvlc-module.c
src/playlist/engine.c

index 4c7a44da9b02268ca68d4e611ff90306020db8a7..47630274b6b1956206625e023d5b7b341da961eb 100644 (file)
@@ -155,6 +155,7 @@ struct audio_output
     struct {
         void (*volume_report)(audio_output_t *, float);
         void (*mute_report)(audio_output_t *, bool);
+        void (*policy_report)(audio_output_t *, bool);
         int (*gain_request)(audio_output_t *, float);
     } event;
 };
@@ -233,6 +234,11 @@ static inline void aout_MuteReport(audio_output_t *aout, bool mute)
     aout->event.mute_report(aout, mute);
 }
 
+static inline void aout_PolicyReport(audio_output_t *aout, bool cork)
+{
+    aout->event.policy_report(aout, cork);
+}
+
 static inline int aout_GainRequest(audio_output_t *aout, float gain)
 {
     return aout->event.gain_request(aout, gain);
index f30f18404f73e90308099fad6965f5041a1d619f..a41b8c7cc764a424456a967277089999735e13c2 100644 (file)
@@ -468,6 +468,7 @@ libvlc_media_player_new( libvlc_instance_t *instance )
     var_Create (mp, "volume", VLC_VAR_FLOAT);
     var_Create (mp, "find-input-callback", VLC_VAR_ADDRESS);
     var_SetAddress (mp, "find-input-callback", find_input);
+    var_Create (mp, "corks", VLC_VAR_INTEGER);
     var_Create (mp, "amem-data", VLC_VAR_ADDRESS);
     var_Create (mp, "amem-setup", VLC_VAR_ADDRESS);
     var_Create (mp, "amem-cleanup", VLC_VAR_ADDRESS);
index 4e81e160e6315faa450cd3f41f9d3f661ff999f1..a43473a307c587c840521ca2413ae61c8b078515 100644 (file)
@@ -56,6 +56,11 @@ static void aout_OutputMuteReport (audio_output_t *aout, bool mute)
     var_SetBool (aout, "mute", mute);
 }
 
+static void aout_OutputPolicyReport (audio_output_t *aout, bool cork)
+{
+    (cork ? var_IncInteger : var_DecInteger) (aout->p_parent, "corks");
+}
+
 static int aout_OutputGainRequest (audio_output_t *aout, float gain)
 {
     aout_owner_t *owner = aout_owner (aout);
@@ -82,6 +87,7 @@ int aout_OutputNew( audio_output_t *p_aout,
 
     p_aout->event.volume_report = aout_OutputVolumeReport;
     p_aout->event.mute_report = aout_OutputMuteReport;
+    p_aout->event.policy_report = aout_OutputPolicyReport;
     p_aout->event.gain_request = aout_OutputGainRequest;
 
     /* Find the best output plug-in. */
index 7b6e2f92cdc7b345f0ba971cc5ed94a59b5ed361..f1ef74ce45f9daa896c784280ef9876c2b911307 100644 (file)
@@ -1184,6 +1184,11 @@ static const char *const ppsz_albumart_descriptions[] =
 #define AUTOSTART_LONGTEXT N_( "Automatically start playing the playlist " \
                 "content once it's loaded." )
 
+#define CORK_TEXT N_("Pause on audio communication")
+#define CORK_LONGTEXT N_( \
+    "If pending audio communication is detected, playback will be paused " \
+    "automatically." )
+
 #define ML_TEXT N_("Use media library")
 #define ML_LONGTEXT N_( \
     "The media library is automatically saved and reloaded each time you " \
@@ -2048,6 +2053,7 @@ vlc_module_begin ()
         change_safe()
     add_bool( "playlist-autostart", true,
               AUTOSTART_TEXT, AUTOSTART_LONGTEXT, false )
+    add_bool( "playlist-cork", true, CORK_TEXT, CORK_LONGTEXT, false )
     add_bool( "media-library", 0, ML_TEXT, ML_LONGTEXT, false )
 #if defined( MEDIA_LIBRARY )
     add_bool( "load-media-library-on-startup", 1, LOAD_ML_TEXT,
index 66a73aeab0beff15df998b2c8028e5df535b2b4b..1aa8e80ed8587836322a5def522aafc4756dc96f 100644 (file)
@@ -68,6 +68,38 @@ static int RandomCallback( vlc_object_t *p_this, char const *psz_cmd,
     return VLC_SUCCESS;
 }
 
+/**
+ * When there are one or more pending corks, playback should be paused.
+ * This is used for audio policy.
+ * \warning Always add and remove a cork with var_IncInteger() and var_DecInteger().
+ * var_Get() and var_Set() are prone to race conditions.
+ */
+static int CorksCallback( vlc_object_t *obj, char const *var,
+                          vlc_value_t old, vlc_value_t cur, void *dummy )
+{
+    playlist_t *pl = (playlist_t *)obj;
+
+    msg_Dbg( obj, "corks count: %"PRId64" -> %"PRId64, old.i_int, cur.i_int );
+    if( !old.i_int == !cur.i_int )
+        return VLC_SUCCESS; /* nothing to do */
+
+    if( cur.i_int )
+    {
+        if( var_InheritBool( obj, "playlist-cork" ) )
+        {
+            msg_Dbg( obj, "corked" );
+            playlist_Pause( pl );
+        }
+        else
+            msg_Dbg( obj, "not corked" );
+    }
+    else
+        msg_Dbg( obj, "uncorked" );
+
+    (void) var; (void) dummy;
+    return VLC_SUCCESS;
+}
+
 static int RateCallback( vlc_object_t *p_this, char const *psz_cmd,
                          vlc_value_t oldval, vlc_value_t newval, void *p )
 {
@@ -416,6 +448,8 @@ static void VariablesInit( playlist_t *p_playlist )
     var_AddCallback( p_playlist, "random", RandomCallback, NULL );
     var_Create( p_playlist, "repeat", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
     var_Create( p_playlist, "loop", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
+    var_Create( p_playlist, "corks", VLC_VAR_INTEGER );
+    var_AddCallback( p_playlist, "corks", CorksCallback, NULL );
 
     var_Create( p_playlist, "rate", VLC_VAR_FLOAT | VLC_VAR_DOINHERIT );
     var_AddCallback( p_playlist, "rate", RateCallback, NULL );