summaryrefslogtreecommitdiffstats
path: root/libaf/af.c
diff options
context:
space:
mode:
authoranders <anders@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-10-01 12:53:30 +0000
committeranders <anders@b3059339-0415-0410-9bf9-f77b7e298cf2>2002-10-01 12:53:30 +0000
commit3ef4629545772e39aeed57195521e78fe5c08aaa (patch)
tree1cc82befde2639d514180fe5df43da3aa02ed4d1 /libaf/af.c
parent5cc92f1a4e7c7ef1141798ab341582727af9f1de (diff)
downloadmpv-3ef4629545772e39aeed57195521e78fe5c08aaa.tar.bz2
mpv-3ef4629545772e39aeed57195521e78fe5c08aaa.tar.xz
Adding support for multiple audio streams and removing annoying message from resample and format
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@7572 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libaf/af.c')
-rw-r--r--libaf/af.c182
1 files changed, 83 insertions, 99 deletions
diff --git a/libaf/af.c b/libaf/af.c
index 39b34d8ab5..85569efba6 100644
--- a/libaf/af.c
+++ b/libaf/af.c
@@ -27,28 +27,6 @@ static af_info_t* filter_list[]={ \
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 @@ af_instance_t* af_create(char* name)
/* 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_instance_t* af_prepend(af_instance_t* af, char* name)
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_instance_t* af_append(af_instance_t* af, char* name)
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 @@ void af_remove(af_instance_t* af)
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 @@ void af_remove(af_instance_t* af)
}
/* 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 @@ int af_reinit(af_instance_t* af)
// 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 @@ int af_reinit(af_instance_t* af)
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 @@ int af_reinit(af_instance_t* af)
}
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 @@ int af_reinit(af_instance_t* af)
/* 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 @@ af_instance_t* af_get(char* name)
}
// 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 @@ int af_init(af_data_t* in, af_data_t* out)
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 @@ int af_init(af_data_t* in, af_data_t* out)
}
// 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 @@ inline int af_lencalc(frac_t mul, int len){
/* 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 @@ int af_outputlen(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)
{
- af_instance_t* af=first;
+ af_instance_t* af=s->first;
frac_t mul = {1,1};
// Iterate through all filters
do{