changeset 7571:8819fdf88b5d

Adding support for multiple audio streams and removing annoying message from resample and format
author anders
date Tue, 01 Oct 2002 12:53:30 +0000
parents a0bba1b6c458
children f46967928779
files libaf/af.c libaf/af.h libaf/af_format.c libaf/af_resample.c
diffstat 4 files changed, 122 insertions(+), 124 deletions(-) [+]
line wrap: on
line diff
--- a/libaf/af.c	Tue Oct 01 09:20:27 2002 +0000
+++ b/libaf/af.c	Tue Oct 01 12:53:30 2002 +0000
@@ -27,28 +27,6 @@
    NULL \
 };
 
-// Command line config switches
-af_cfg_t af_cfg={\
-   0,\
-   0,\
-   0,\
-   0,\
-   NULL,\
-};
-
-
-// Initialization types
-#define SLOW  1
-#define FAST  2
-#define FORCE 3
-
-// The first and last filter in the list
-static af_instance_t* first=NULL;
-static af_instance_t* last=NULL;
-// Storage for input and output data formats (set by init)
-static af_data_t input;
-static af_data_t output;
-
 /* Find a filter in the static list of filters using it's name. This
    function is used internally */
 af_info_t* af_find(char*name)
@@ -89,9 +67,9 @@
 /* Create and insert a new filter of type name before the filter in the
    argument. This function can be called during runtime, the return
    value is the new filter */
-af_instance_t* af_prepend(af_instance_t* af, char* name)
+af_instance_t* af_prepend(af_stream_t* s, af_instance_t* af, char* name)
 {
-  // Create the new filter and make sure it is ok
+  // Create the new filter and make sure it is OK
   af_instance_t* new=af_create(name);
   if(!new)
     return NULL;
@@ -102,18 +80,18 @@
     af->prev=new;
   }
   else
-    last=new;
+    s->last=new;
   if(new->prev)
     new->prev->next=new;
   else
-    first=new;
+    s->first=new;
   return new;
 }
 
 /* Create and insert a new filter of type name after the filter in the
    argument. This function can be called during runtime, the return
    value is the new filter */
-af_instance_t* af_append(af_instance_t* af, char* name)
+af_instance_t* af_append(af_stream_t* s, af_instance_t* af, char* name)
 {
   // Create the new filter and make sure it is OK
   af_instance_t* new=af_create(name);
@@ -126,16 +104,16 @@
     af->next=new;
   }
   else
-    first=new;
+    s->first=new;
   if(new->next)
     new->next->prev=new;
   else
-    last=new;
+    s->last=new;
   return new;
 }
 
 // Uninit and remove the filter "af"
-void af_remove(af_instance_t* af)
+void af_remove(af_stream_t* s, af_instance_t* af)
 {
   if(!af) return;
 
@@ -143,11 +121,11 @@
   if(af->prev)
     af->prev->next=af->next;
   else
-    first=af->next;
+    s->first=af->next;
   if(af->next)
     af->next->prev=af->prev;
   else
-    last=af->prev;
+    s->last=af->prev;
 
   // Uninitialize af and free memory   
   af->uninit(af);
@@ -155,7 +133,7 @@
 }
 
 /* Reinitializes all filters downstream from the filter given in the argument */
-int af_reinit(af_instance_t* af)
+int af_reinit(af_stream_t* s, af_instance_t* af)
 {
   if(!af)
     return AF_ERROR;
@@ -166,7 +144,7 @@
 
     // Check if this is the first filter 
     if(!af->prev) 
-      memcpy(&in,&input,sizeof(af_data_t));
+      memcpy(&in,&(s->input),sizeof(af_data_t));
     else
       memcpy(&in,af->prev->data,sizeof(af_data_t));
     // Reset just in case...
@@ -180,33 +158,33 @@
     case AF_FALSE:{ // Configuration filter is needed
       af_instance_t* new = NULL;
       // Insert channels filter
-      if((af->prev?af->prev->data->nch:input.nch) != in.nch){
+      if((af->prev?af->prev->data->nch:s->input.nch) != in.nch){
 	// Create channels filter
-	if(NULL == (new = af_prepend(af,"channels")))
+	if(NULL == (new = af_prepend(s,af,"channels")))
 	  return AF_ERROR;
 	// Set number of output channels
 	if(AF_OK != (rv = new->control(new,AF_CONTROL_CHANNELS,&in.nch)))
 	  return rv;
 	// Initialize channels filter
 	if(!new->prev) 
-	  memcpy(&in,&input,sizeof(af_data_t));
+	  memcpy(&in,&(s->input),sizeof(af_data_t));
 	else
 	  memcpy(&in,new->prev->data,sizeof(af_data_t));
 	if(AF_OK != (rv = new->control(new,AF_CONTROL_REINIT,&in)))
 	  return rv;
       }
       // Insert format filter
-      if(((af->prev?af->prev->data->format:input.format) != in.format) || 
-	 ((af->prev?af->prev->data->bps:input.bps) != in.bps)){
+      if(((af->prev?af->prev->data->format:s->input.format) != in.format) || 
+	 ((af->prev?af->prev->data->bps:s->input.bps) != in.bps)){
 	// Create format filter
-	if(NULL == (new = af_prepend(af,"format")))
+	if(NULL == (new = af_prepend(s,af,"format")))
 	  return AF_ERROR;
 	// Set output format
 	if(AF_OK != (rv = new->control(new,AF_CONTROL_FORMAT,&in)))
 	  return rv;
 	// Initialize format filter
 	if(!new->prev) 
-	  memcpy(&in,&input,sizeof(af_data_t));
+	  memcpy(&in,&(s->input),sizeof(af_data_t));
 	else
 	  memcpy(&in,new->prev->data,sizeof(af_data_t));
 	if(AF_OK != (rv = new->control(new,AF_CONTROL_REINIT,&in)))
@@ -219,15 +197,15 @@
     }
     case AF_DETACH:{ // Filter is redundant and wants to be unloaded
       af_instance_t* aft=af->prev;
-      af_remove(af);
+      af_remove(s,af);
       if(aft)
 	af=aft;
       else
-	af=first; // Restart configuration
+	af=s->first; // Restart configuration
       break;
     }
     default:
-      mp_msg(MSGT_AFILTER,MSGL_ERR,"Reinit did not work, audio filter '%s' returned error code %i\n",af->info->name,rv);
+      mp_msg(MSGT_AFILTER,MSGL_ERR,"Reinitialization did not work, audio filter '%s' returned error code %i\n",af->info->name,rv);
       return AF_ERROR;
     }
     af=af->next;
@@ -237,9 +215,9 @@
 
 /* Find filter in the dynamic filter list using it's name This
    function is used for finding already initialized filters */
-af_instance_t* af_get(char* name)
+af_instance_t* af_get(af_stream_t* s, char* name)
 {
-  af_instance_t* af=first; 
+  af_instance_t* af=s->first; 
   while(af->next != NULL){
     if(!strcmp(af->info->name,name))
       return af;
@@ -249,27 +227,34 @@
 }
 
 // Uninit and remove all filters
-void af_uninit()
+void af_uninit(af_stream_t* s)
 {
-  while(first)
-    af_remove(first);
+  while(s->first)
+    af_remove(s,s->first);
 }
 
-/* Init read configuration and create filter list accordingly. In and
-   out contains the format of the current movie and the formate of the
-   preferred output respectively */
-int af_init(af_data_t* in, af_data_t* out)
+/* Initialize the stream "s". This function creates a new filter list
+   if necessary according to the values set in input and output. Input
+   and output should contain the format of the current movie and the
+   formate of the preferred output respectively. The function is
+   reentrant i.e. if called with an already initialized stream the
+   stream will be reinitialized. The return value is 0 if success and
+   -1 if failure */
+int af_init(af_stream_t* s)
 {
   int cfg=SLOW;  // configuration type
   int i=0;
 
+  // Sanity check
+  if(!s) return -1;
+
   // Precaution in case caller is misbehaving
-  in->audio  = out->audio  = NULL;
-  in->len    = out->len    = 0;
+  s->input.audio  = s->output.audio  = NULL;
+  s->input.len    = s->output.len    = 0;
 
   // Figure out how fast the machine is
-  if(af_cfg.force)
-    cfg=af_cfg.force;
+  if(s->cfg.force)
+    cfg=s->cfg.force;
   else{
 #    if defined(HAVE_SSE) || defined(HAVE_3DNOWEX)
       cfg=FAST;
@@ -277,92 +262,91 @@
       cfg=SLOW;
 #    endif
   }
-  
-  // Input and output configuration 
-  memcpy(&input,in,sizeof(af_data_t));
-  memcpy(&output,out,sizeof(af_data_t));
 
   // Check if this is the first call
-  if(!first){
+  if(!s->first){
     // Add all filters in the list (if there are any)
-    if(!af_cfg.list){
-      if(!af_append(first,"dummy")) // To make automatic format conversion work
+    if(!s->cfg.list){      // To make automatic format conversion work
+      if(!af_append(s,s->first,"dummy")) 
 	return -1; 
     }
     else{
-      while(af_cfg.list[i]){
-	if(!af_append(last,af_cfg.list[i++]))
+      while(s->cfg.list[i]){
+	if(!af_append(s,s->last,s->cfg.list[i++]))
 	  return -1;
       }
     }
   }
   
   // Init filters 
-  if(AF_OK != af_reinit(first))
+  if(AF_OK != af_reinit(s,s->first))
     return -1;
 
   // Check output format
   if(cfg!=FORCE){
     af_instance_t* af = NULL; // New filter
     // Check output frequency if not OK fix with resample
-    if(last->data->rate!=output.rate){
-      if(NULL==(af=af_get("resample"))){
+    if(s->last->data->rate!=s->output.rate){
+      if(NULL==(af=af_get(s,"resample"))){
 	if(cfg==SLOW){
-	  if(!strcmp(first->info->name,"format"))
-	    af = af_append(first,"resample");
+	  if(!strcmp(s->first->info->name,"format"))
+	    af = af_append(s,s->first,"resample");
 	  else
-	    af = af_prepend(first,"resample");
+	    af = af_prepend(s,s->first,"resample");
 	}		
 	else{
-	  if(!strcmp(last->info->name,"format"))
-	    af = af_prepend(last,"resample");
+	  if(!strcmp(s->last->info->name,"format"))
+	    af = af_prepend(s,s->last,"resample");
 	  else
-	    af = af_append(last,"resample");
+	    af = af_append(s,s->last,"resample");
 	}
       }
       // Init the new filter
-      if(!af || (AF_OK != af->control(af,AF_CONTROL_RESAMPLE,&output.rate)))
+      if(!af || (AF_OK != af->control(af,AF_CONTROL_RESAMPLE,&(s->output.rate))))
 	return -1;
-      if(AF_OK != af_reinit(af))
+      if(AF_OK != af_reinit(s,af))
       	return -1;
     }	
       
     // Check number of output channels fix if not OK
     // If needed always inserted last -> easy to screw up other filters
-    if(last->data->nch!=output.nch){
-      if(!strcmp(last->info->name,"format"))
-	af = af_prepend(last,"channels");
+    if(s->last->data->nch!=s->output.nch){
+      if(!strcmp(s->last->info->name,"format"))
+	af = af_prepend(s,s->last,"channels");
       else
-	af = af_append(last,"channels");
+	af = af_append(s,s->last,"channels");
       // Init the new filter
-      if(!af || (AF_OK != af->control(af,AF_CONTROL_CHANNELS,&output.nch)))
+      if(!af || (AF_OK != af->control(af,AF_CONTROL_CHANNELS,&(s->output.nch))))
 	return -1;
-      if(AF_OK != af_reinit(af))
+      if(AF_OK != af_reinit(s,af))
 	return -1;
     }
     
     // Check output format fix if not OK
-    if((last->data->format != output.format) || (last->data->bps != output.bps)){
-      if(strcmp(last->info->name,"format"))
-	af = af_append(last,"format");
+    if((s->last->data->format != s->output.format) || 
+       (s->last->data->bps != s->output.bps)){
+      if(strcmp(s->last->info->name,"format"))
+	af = af_append(s,s->last,"format");
       else
-	af = last;
+	af = s->last;
       // Init the new filter
-      if(!af ||(AF_OK != af->control(af,AF_CONTROL_FORMAT,&output)))
+      if(!af ||(AF_OK != af->control(af,AF_CONTROL_FORMAT,&(s->output))))
 	return -1;
-      if(AF_OK != af_reinit(af))
+      if(AF_OK != af_reinit(s,af))
 	return -1;
     }
 
     // Re init again just in case
-    if(AF_OK != af_reinit(first))
+    if(AF_OK != af_reinit(s,s->first))
       return -1;
 
-    if((last->data->format != output.format) || (last->data->bps != output.bps) ||
-       (last->data->nch!=output.nch) || (last->data->rate!=output.rate)){
+    if((s->last->data->format != s->output.format) || 
+       (s->last->data->bps    != s->output.bps)    ||
+       (s->last->data->nch    != s->output.nch)    || 
+       (s->last->data->rate   != s->output.rate))  {
       // Something is stuffed audio out will not work 
       mp_msg(MSGT_AFILTER,MSGL_ERR,"Unable to setup filter system can not meet sound-card demands, please report this error on MPlayer development mailing list. \n");
-      af_uninit();
+      af_uninit(s);
       return -1;
     }
   }
@@ -370,9 +354,9 @@
 }
 
 // Filter data chunk through the filters in the list
-af_data_t* af_play(af_data_t* data)
+af_data_t* af_play(af_stream_t* s, af_data_t* data)
 {
-  af_instance_t* af=first; 
+  af_instance_t* af=s->first; 
   // Iterate through all filters 
   do{
     data=af->play(af,data);
@@ -390,9 +374,9 @@
 
 /* Calculate how long the output from the filters will be given the
    input length "len" */
-int af_outputlen(int len)
+int af_outputlen(af_stream_t* s, int len)
 {
-  af_instance_t* af=first; 
+  af_instance_t* af=s->first; 
   frac_t mul = {1,1};
   // Iterate through all filters 
   do{
@@ -406,9 +390,9 @@
 /* Calculate how long the input to the filters should be to produce a
    certain output length, i.e. the return value of this function is
    the input length required to produce the output length "len". */
-int af_inputlen(int len)
+int af_inputlen(af_stream_t* s, int len)
 {
-  af_instance_t* af=first; 
+  af_instance_t* af=s->first; 
   frac_t mul = {1,1};
   // Iterate through all filters 
   do{
--- a/libaf/af.h	Tue Oct 01 09:20:27 2002 +0000
+++ b/libaf/af.h	Tue Oct 01 12:53:30 2002 +0000
@@ -47,6 +47,31 @@
 		 the length of the buffer. */
 }af_instance_t;
 
+// Initialization types
+#define SLOW  1
+#define FAST  2
+#define FORCE 3
+
+// Configuration switches
+typedef struct af_cfg_s{
+  int force;	// Initialization type
+  char** list;	/* list of names of plugins that are added to filter
+		   list during first initialization of stream */
+}af_cfg_t;
+
+// Current audio stream
+typedef struct af_stream_s
+{
+  // The first and last filter in the list
+  af_instance_t* first;
+  af_instance_t* last;
+  // Storage for input and output data formats
+  af_data_t input;
+  af_data_t output;
+  // Cofiguration for this stream
+  af_cfg_t cfg;
+}af_stream_t;
+
 /*********************************************
 // Control parameters 
 */
@@ -97,35 +122,28 @@
 #define AF_NA      -3
 
 
-/*********************************************
-// Command line configuration switches
-*/
-typedef struct af_cfg_s{
-  int rate;
-  int format;
-  int bps;
-  int force;
-  char** list;
-}af_cfg_t;
-
 
 // Export functions
 
-/* Init read configuration and create filter list accordingly. In and
-   out contains the format of the current movie and the formate of the
-   prefered output respectively */
-int af_init(af_data_t* in, af_data_t* out);
+/* Initialize the stream "s". This function creates a new fileterlist
+   if nessesary according to the values set in input and output. Input
+   and output should contain the format of the current movie and the
+   formate of the preferred output respectively. The function is
+   reentreant i.e. if called wit an already initialized stream the
+   stream will be reinitialized. The return value is 0 if sucess and
+   -1 if failure */
+int af_init(af_stream_t* s);
 // Uninit and remove all filters
-void af_uninit();
+void af_uninit(af_stream_t* s);
 // Filter data chunk through the filters in the list
-af_data_t* af_play(af_data_t* data);
+af_data_t* af_play(af_stream_t* s, af_data_t* data);
 /* Calculate how long the output from the filters will be given the
    input length "len" */
-int af_outputlen(int len);
+int af_outputlen(af_stream_t* s, int len);
 /* Calculate how long the input to the filters should be to produce a
    certain output length, i.e. the return value of this function is
    the input length required to produce the output length "len". */
-int af_inputlen(int len);
+int af_inputlen(af_stream_t* s, int len);
 
 
 
@@ -153,8 +171,4 @@
 #define max(a,b)(((a)>(b))?(a):(b))
 #endif
 
-#ifndef AUDIO_FILTER
-extern af_cfg_t af_cfg;
-#endif /* AUDIO_FILTER */
-
 #endif
--- a/libaf/af_format.c	Tue Oct 01 09:20:27 2002 +0000
+++ b/libaf/af_format.c	Tue Oct 01 12:53:30 2002 +0000
@@ -97,7 +97,7 @@
     }
     af->data->bps=((af_data_t*)arg)->bps; 
 
-    mp_msg(MSGT_AFILTER,MSGL_STATUS,"[format] Changing number sample format to 0x%08X and/or bytes per sample to %i \n",af->data->format,af->data->bps);
+    mp_msg(MSGT_AFILTER,MSGL_V,"[format] Changing number sample format to 0x%08X and/or bytes per sample to %i \n",af->data->format,af->data->bps);
     return AF_OK;
   }
   return AF_UNKNOWN;
--- a/libaf/af_resample.c	Tue Oct 01 09:20:27 2002 +0000
+++ b/libaf/af_resample.c	Tue Oct 01 12:53:30 2002 +0000
@@ -277,7 +277,7 @@
     }
 
     af->data->rate=((int*)arg)[0]; 
-    mp_msg(MSGT_AFILTER,MSGL_STATUS,"[resample] Changing sample rate to %iHz\n",af->data->rate);
+    mp_msg(MSGT_AFILTER,MSGL_V,"[resample] Changing sample rate to %iHz\n",af->data->rate);
     return AF_OK;
   }
   return AF_UNKNOWN;