[MPlayer-dev-eng] [PATCH 1/7] af_scale*: af_playback_speed_change

Robert Juliano juliano.1 at osu.edu
Mon Jun 11 06:39:10 CEST 2007


af_playback_speed_change

Moves code handling changes in playback_speed to libaf.  Adds
libaf/af.h:af_playback_speed_change() to handle changes in
playback_speed.  This is needed by later patches.

Files:
  mplayer.c
  mencoder.c
  command.c
  mp_core.h
  libaf/af.c
  libaf/af.h
  libaf/control.h

Index: mplayer-HEAD/command.c
===================================================================
--- mplayer-HEAD.orig/command.c	2007-06-10 11:18:40.000000000 -0400
+++ mplayer-HEAD/command.c	2007-06-10 11:41:59.000000000 -0400
@@ -160,20 +160,27 @@
 static int mp_property_playback_speed(m_option_t * prop, int action,
 				      void *arg, MPContext * mpctx)
 {
+    float prev = playback_speed;
     switch (action) {
     case M_PROPERTY_SET:
 	if (!arg)
 	    return M_PROPERTY_ERROR;
 	M_PROPERTY_CLAMP(prop, *(float *) arg);
 	playback_speed = *(float *) arg;
-	build_afilter_chain(mpctx->sh_audio, &ao_data);
+        if (mpctx->sh_audio && !af_playback_speed_change(mpctx->sh_audio->afilter, playback_speed, mpctx->sh_audio->samplerate)) {
+            playback_speed = prev;
+            return M_PROPERTY_ERROR;
+        }
 	return M_PROPERTY_OK;
     case M_PROPERTY_STEP_UP:
     case M_PROPERTY_STEP_DOWN:
 	playback_speed += (arg ? *(float *) arg : 0.1) *
 	    (action == M_PROPERTY_STEP_DOWN ? -1 : 1);
 	M_PROPERTY_CLAMP(prop, playback_speed);
-	build_afilter_chain(mpctx->sh_audio, &ao_data);
+        if (mpctx->sh_audio && !af_playback_speed_change(mpctx->sh_audio->afilter, playback_speed, mpctx->sh_audio->samplerate)) {
+            playback_speed = prev;
+            return M_PROPERTY_ERROR;
+        }
 	return M_PROPERTY_OK;
     }
     return m_property_float_range(prop, action, arg, &playback_speed);
@@ -1974,24 +1981,36 @@
 
 	case MP_CMD_SPEED_INCR:{
 		float v = cmd->args[0].v.f;
+                float prev = playback_speed;
 		playback_speed += v;
-		build_afilter_chain(sh_audio, &ao_data);
+                if (mpctx->sh_audio && !af_playback_speed_change(mpctx->sh_audio->afilter, playback_speed, mpctx->sh_audio->samplerate)) {
+                    af_msg(AF_MSG_WARN, "speed changed failed!\n");
+                    playback_speed = prev;
+                }
 		set_osd_msg(OSD_MSG_SPEED, 1, osd_duration, MSGTR_OSDSpeed,
 			    playback_speed);
 	    } break;
 
 	case MP_CMD_SPEED_MULT:{
 		float v = cmd->args[0].v.f;
+                float prev = playback_speed;
 		playback_speed *= v;
-		build_afilter_chain(sh_audio, &ao_data);
+                if (mpctx->sh_audio && !af_playback_speed_change(mpctx->sh_audio->afilter, playback_speed, mpctx->sh_audio->samplerate)) {
+                    af_msg(AF_MSG_WARN, "speed changed failed!\n");
+                    playback_speed = prev;
+                }
 		set_osd_msg(OSD_MSG_SPEED, 1, osd_duration, MSGTR_OSDSpeed,
 			    playback_speed);
 	    } break;
 
 	case MP_CMD_SPEED_SET:{
 		float v = cmd->args[0].v.f;
+                float prev = playback_speed;
 		playback_speed = v;
-		build_afilter_chain(sh_audio, &ao_data);
+                if (mpctx->sh_audio && !af_playback_speed_change(mpctx->sh_audio->afilter, playback_speed, mpctx->sh_audio->samplerate)) {
+                    af_msg(AF_MSG_WARN, "speed changed failed!\n");
+                    playback_speed = prev;
+                }
 		set_osd_msg(OSD_MSG_SPEED, 1, osd_duration, MSGTR_OSDSpeed,
 			    playback_speed);
 	    } break;
Index: mplayer-HEAD/libaf/af.c
===================================================================
--- mplayer-HEAD.orig/libaf/af.c	2007-06-10 11:21:55.000000000 -0400
+++ mplayer-HEAD/libaf/af.c	2007-06-10 12:27:59.000000000 -0400
@@ -648,6 +648,16 @@
   return NULL;
 }
 
+// called when playback speed changes
+int af_playback_speed_change(af_stream_t* s, float speed, int base_srate)
+{
+  if(!af_control_any_rev(s, AF_CONTROL_PLAYBACK_SPEED | AF_CONTROL_SET, &speed)) {
+    // revert to old behavior
+    s->input.rate = base_srate * speed;
+  }
+  return !af_init(s); // make 0 failure
+}
+
 /**
  * \brief calculate greatest common divisior of a and b.
  * \ingroup af_filter
Index: mplayer-HEAD/libaf/af.h
===================================================================
--- mplayer-HEAD.orig/libaf/af.h	2007-06-10 11:18:40.000000000 -0400
+++ mplayer-HEAD/libaf/af.h	2007-06-10 11:26:03.000000000 -0400
@@ -334,6 +334,13 @@
  */
 void af_fix_parameters(af_data_t *data);
 
+/**
+ * \brief responds to change in playback_speed
+ * \param speed of playback
+ * \param base_srate samplerate when speed = 1
+ */
+int af_playback_speed_change(af_stream_t* s, float speed, int base_srate);
+
 /** Memory reallocation macro: if a local buffer is used (i.e. if the
    filter doesn't operate on the incoming buffer this macro must be
    called to ensure the buffer is big enough.
Index: mplayer-HEAD/libaf/control.h
===================================================================
--- mplayer-HEAD.orig/libaf/control.h	2007-06-10 11:18:40.000000000 -0400
+++ mplayer-HEAD/libaf/control.h	2007-06-10 12:28:10.000000000 -0400
@@ -229,4 +229,7 @@
 #define AF_CONTROL_SS_FREQ		0x00002300 | AF_CONTROL_FILTER_SPECIFIC
 #define AF_CONTROL_SS_DECAY		0x00002400 | AF_CONTROL_FILTER_SPECIFIC
 
+// Generic: respond to change in playback_speed
+#define AF_CONTROL_PLAYBACK_SPEED	0x00002500 | AF_CONTROL_FILTER_SPECIFIC
+
 #endif /*__af_control_h */
Index: mplayer-HEAD/mencoder.c
===================================================================
--- mplayer-HEAD.orig/mencoder.c	2007-06-10 11:18:40.000000000 -0400
+++ mplayer-HEAD/mencoder.c	2007-06-10 11:46:53.000000000 -0400
@@ -403,7 +403,6 @@
 int decoded_frameno=0;
 int next_frameno=-1;
 int curfile=0;
-int new_srate=0;
 
 unsigned int timer_start=0;
 ao_data_t ao_data = {0,0,0,0,OUTBURST,-1,0};
@@ -633,7 +632,7 @@
     mencoder_exit(1,NULL);
   }
 
-if(sh_audio && (out_audio_codec || seek_to_sec || !sh_audio->wf || playback_speed != 1.0)){
+if(sh_audio && (out_audio_codec || seek_to_sec || !sh_audio->wf)){
   // Go through the codec.conf and find the best codec...
   mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
   if(!init_best_audio_codec(sh_audio,audio_codec_list,audio_fm_list)){
@@ -642,17 +641,6 @@
   mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
 }
 
-  if (sh_audio) {
-    new_srate = sh_audio->samplerate;
-    if (playback_speed != 1.0) {
-        new_srate *= playback_speed;
-        // limits are taken from libaf/af_resample.c
-        if (new_srate < 8000) new_srate = 8000;
-        if (new_srate > 192000) new_srate = 192000;
-        playback_speed = (float)new_srate / (float)sh_audio->samplerate;
-    }
-  }
-
 // after reading video params we should load subtitles because
 // we know fps so now we can adjust subtitles time to ~6 seconds AST
 // check .sub
@@ -909,7 +897,7 @@
 ao_data.format = audio_output_format;
 if(!preinit_audio_filters(sh_audio,
    // input:
-   new_srate,
+   sh_audio->samplerate,
    sh_audio->channels, sh_audio->sample_format,
    // output:
    &ao_data.samplerate, &ao_data.channels, &ao_data.format)) {
@@ -925,12 +913,15 @@
     if(!aencoder)
         mencoder_exit(1, NULL);
     if(!init_audio_filters(sh_audio, 
-        new_srate, sh_audio->channels, sh_audio->sample_format,  
+        sh_audio->samplerate, sh_audio->channels, sh_audio->sample_format,
         &aparams.sample_rate, &aparams.channels, &aencoder->input_format, 
         aencoder->min_buffer_size, aencoder->max_buffer_size)) {
       mp_msg(MSGT_CPLAYER,MSGL_FATAL,MSGTR_NoMatchingFilter);
       mencoder_exit(1,NULL);
     }
+    if (playback_speed != 1.0) {
+      af_playback_speed_change(sh_audio->afilter, playback_speed, sh_audio->samplerate);
+    }
 }
 switch(mux_a->codec){
 case ACODEC_COPY:
@@ -1026,12 +1017,15 @@
 		int out_format = aencoder->input_format;
 		int out_minsize = aencoder->min_buffer_size;
 		int out_maxsize = aencoder->max_buffer_size;
-		if (!init_audio_filters(sh_audio, new_srate, sh_audio->channels,
+                if (!init_audio_filters(sh_audio, sh_audio->samplerate, sh_audio->channels,
 					sh_audio->sample_format, &out_srate, &out_channels,
 					&out_format, out_minsize, out_maxsize)) {
 			mp_msg(MSGT_CPLAYER, MSGL_FATAL, MSGTR_NoMatchingFilter);
 			mencoder_exit(1, NULL);
 		}
+                if (playback_speed != 1.0) {
+                    af_playback_speed_change(sh_audio->afilter, playback_speed, sh_audio->samplerate);
+                }
 		mux_a->wf->nSamplesPerSec = out_srate;
 		mux_a->wf->nChannels = out_channels;
 	}
Index: mplayer-HEAD/mp_core.h
===================================================================
--- mplayer-HEAD.orig/mp_core.h	2007-06-10 11:18:40.000000000 -0400
+++ mplayer-HEAD/mp_core.h	2007-06-10 11:26:03.000000000 -0400
@@ -124,7 +124,6 @@
 
 
 
-int build_afilter_chain(sh_audio_t *sh_audio, ao_data_t *ao_data);
 void uninit_player(unsigned int mask);
 void reinit_audio_chain(void);
 void init_vo_spudec(void);
Index: mplayer-HEAD/mplayer.c
===================================================================
--- mplayer-HEAD.orig/mplayer.c	2007-06-10 11:18:40.000000000 -0400
+++ mplayer-HEAD/mplayer.c	2007-06-10 11:26:03.000000000 -0400
@@ -1194,45 +1194,6 @@
   free(line);
 }
 
-/**
- * \brief build a chain of audio filters that converts the input format
- * to the ao's format, taking into account the current playback_speed.
- * \param sh_audio describes the requested input format of the chain.
- * \param ao_data describes the requested output format of the chain.
- */
-int build_afilter_chain(sh_audio_t *sh_audio, ao_data_t *ao_data)
-{
-  int new_srate;
-  int result;
-  if (!sh_audio)
-  {
-#ifdef HAVE_NEW_GUI
-    if (use_gui) guiGetEvent(guiSetAfilter, (char *)NULL);
-#endif
-    mpctx->mixer.afilter = NULL;
-    return 0;
-  }
-  new_srate = sh_audio->samplerate * playback_speed;
-  if (new_srate != ao_data->samplerate) {
-    // limits are taken from libaf/af_resample.c
-    if (new_srate < 8000)
-      new_srate = 8000;
-    if (new_srate > 192000)
-      new_srate = 192000;
-    playback_speed = (float)new_srate / (float)sh_audio->samplerate;
-  }
-  result =  init_audio_filters(sh_audio, new_srate,
-           sh_audio->channels, sh_audio->sample_format,
-           &ao_data->samplerate, &ao_data->channels, &ao_data->format,
-           ao_data->outburst * 4, ao_data->buffersize);
-  mpctx->mixer.afilter = sh_audio->afilter;
-#ifdef HAVE_NEW_GUI
-  if (use_gui) guiGetEvent(guiSetAfilter, (char *)sh_audio->afilter);
-#endif
-  return result;
-}
-
-
 typedef struct mp_osd_msg mp_osd_msg_t;
 struct mp_osd_msg {
     /// Previous message on the stack.
@@ -1494,7 +1455,7 @@
   // first init to detect best values
   if(!preinit_audio_filters(mpctx->sh_audio,
         // input:
-        (int)(mpctx->sh_audio->samplerate*playback_speed),
+        mpctx->sh_audio->samplerate,
 	mpctx->sh_audio->channels, mpctx->sh_audio->sample_format,
 	// output:
 	&ao_data.samplerate, &ao_data.channels, &ao_data.format)){
@@ -1529,14 +1490,24 @@
     // init audio filters:
 #if 1
     current_module="af_init";
-    if(!build_afilter_chain(mpctx->sh_audio, &ao_data)) {
+    if(!init_audio_filters(mpctx->sh_audio,
+           mpctx->sh_audio->samplerate,
+           mpctx->sh_audio->channels, mpctx->sh_audio->sample_format,
+           &ao_data.samplerate, &ao_data.channels, &ao_data.format,
+           ao_data.outburst * 4, ao_data.buffersize)){
       mp_msg(MSGT_CPLAYER,MSGL_ERR,MSGTR_NoMatchingFilter);
 //      mp_msg(MSGT_CPLAYER,MSGL_ERR,"Couldn't find matching filter / ao format! -> NOSOUND\n");
 //      uninit_player(INITED_ACODEC|INITED_AO); // close codec & ao
 //      sh_audio=mpctx->d_audio->sh=NULL; // -> nosound
     }
+    if (playback_speed != 1.0)
+      af_playback_speed_change(mpctx->sh_audio->afilter, playback_speed, mpctx->sh_audio->samplerate);
+    mpctx->mixer.afilter = mpctx->sh_audio->afilter;
+#ifdef HAVE_NEW_GUI
+    if (use_gui) guiGetEvent(guiSetAfilter, (char *)mpctx->sh_audio->afilter);
 #endif
   }
+#endif
   mpctx->mixer.audio_out = mpctx->audio_out;
   mpctx->mixer.volstep = volstep;
 }



More information about the MPlayer-dev-eng mailing list