⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 af.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 2 页
字号:
  // Check if this is the first call  if(!s->first){    // Add all filters in the list (if there are any)    if(!s->cfg.list){      // To make automatic format conversion work      if(!af_append(s,s->first,"dummy")) 	return -1;     }    else{      while(s->cfg.list[i]){	if(!af_append(s,s->last,s->cfg.list[i++]))	  return -1;      }    }  }  // Init filters   if(AF_OK != af_reinit(s,s->first))    return -1;  // If force_output isn't set do not compensate for output format  if(!force_output){    memcpy(&s->output, s->last->data, sizeof(af_data_t));    return 0;  }  // Check output format  if((AF_INIT_TYPE_MASK & s->cfg.force) != AF_INIT_FORCE){    af_instance_t* af = NULL; // New filter    // Check output frequency if not OK fix with resample    if(s->last->data->rate!=s->output.rate){      // try to find a filter that can change samplrate      af = af_control_any_rev(s, AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET,               &(s->output.rate));      if (!af) {        char *resampler = "resample";#ifdef USE_LIBAVCODEC        if ((AF_INIT_TYPE_MASK & s->cfg.force) == AF_INIT_SLOW)          resampler = "lavcresample";#endif	if((AF_INIT_TYPE_MASK & s->cfg.force) == AF_INIT_SLOW){	  if(!strcmp(s->first->info->name,"format"))	    af = af_append(s,s->first,resampler);	  else	    af = af_prepend(s,s->first,resampler);	}			else{	  if(!strcmp(s->last->info->name,"format"))	    af = af_prepend(s,s->last,resampler);	  else	    af = af_append(s,s->last,resampler);	}      // Init the new filter      if(!af || (AF_OK != af->control(af,AF_CONTROL_RESAMPLE_RATE | AF_CONTROL_SET,				      &(s->output.rate))))	return -1;      // Use lin int if the user wants fast      if ((AF_INIT_TYPE_MASK & s->cfg.force) == AF_INIT_FAST) {        char args[32];	sprintf(args, "%d", s->output.rate);#ifdef USE_LIBAVCODEC	if (strcmp(resampler, "lavcresample") == 0)	  strcat(args, ":1");	else#endif	strcat(args, ":0:0");	af->control(af, AF_CONTROL_COMMAND_LINE, args);      }      }      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(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(s,s->last,"channels");      // Init the new filter      if(!af || (AF_OK != af->control(af,AF_CONTROL_CHANNELS,&(s->output.nch))))	return -1;      if(AF_OK != af_reinit(s,af))	return -1;    }        // Check output format fix if not OK    if(s->last->data->format != s->output.format){      if(strcmp(s->last->info->name,"format"))	af = af_append(s,s->last,"format");      else	af = s->last;      // Init the new filter      s->output.format |= af_bits2fmt(s->output.bps*8);      if(!af || (AF_OK != af->control(af,AF_CONTROL_FORMAT_FMT,&(s->output.format))))	return -1;      if(AF_OK != af_reinit(s,af))	return -1;    }    // Re init again just in case    if(AF_OK != af_reinit(s,s->first))      return -1;    if((s->last->data->format != s->output.format) ||        (s->last->data->nch    != s->output.nch)    ||        (s->last->data->rate   != s->output.rate))  {      // Something is stuffed audio out will not work       af_msg(AF_MSG_ERROR,"[libaf] Unable to setup filter system can not" 	     " meet sound-card demands, please send bugreport. \n");      af_uninit(s);      return -1;    }  }  return 0;}/* Add filter during execution. This function adds the filter "name"   to the stream s. The filter will be inserted somewhere nice in the   list of filters. The return value is a pointer to the new filter,   If the filter couldn't be added the return value is NULL. */af_instance_t* af_add(af_stream_t* s, char* name){  af_instance_t* new;  // Sanity check  if(!s || !s->first || !name)    return NULL;  // Insert the filter somwhere nice  if(!strcmp(s->first->info->name,"format"))    new = af_append(s, s->first, name);  else    new = af_prepend(s, s->first, name);  if(!new)    return NULL;  // Reinitalize the filter list  if(AF_OK != af_reinit(s, s->first)){    free(new);    return NULL;  }  return new;}// Filter data chunk through the filters in the listaf_data_t* af_play(af_stream_t* s, af_data_t* data){  af_instance_t* af=s->first;   // Iterate through all filters   do{    data=af->play(af,data);    af=af->next;  }while(af);  return data;}/* Helper function used to calculate the exact buffer length needed   when buffers are resized. The returned length is >= than what is   needed */inline int af_lencalc(frac_t mul, af_data_t* d){  register int t = d->bps*d->nch;  return t*(((d->len/t)*mul.n)/mul.d + 1);}/* Calculate how long the output from the filters will be given the   input length "len". The calculated length is >= the actual   length. */int af_outputlen(af_stream_t* s, int len){  int t = s->input.bps*s->input.nch;  af_instance_t* af=s->first;   frac_t mul = {1,1};  // Iterate through all filters   do{    af_frac_mul(&mul, &af->mul);    af=af->next;  }while(af);  return t * (((len/t)*mul.n + 1)/mul.d);}/* 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". The   calculated length is <= the actual length */int af_inputlen(af_stream_t* s, int len){  int t = s->input.bps*s->input.nch;  af_instance_t* af=s->first;   frac_t mul = {1,1};  // Iterate through all filters   do{    af_frac_mul(&mul, &af->mul);    af=af->next;  }while(af);  return t * (((len/t) * mul.d - 1)/mul.n);}/* Calculate how long the input IN to the filters should be to produce   a certain output length OUT but with the following three constraints:   1. IN <= max_insize, where max_insize is the maximum possible input      block length   2. OUT <= max_outsize, where max_outsize is the maximum possible      output block length   3. If possible OUT >= len.    Return -1 in case of error */ int af_calc_insize_constrained(af_stream_t* s, int len,			       int max_outsize,int max_insize){  int t   = s->input.bps*s->input.nch;  int in  = 0;  int out = 0;  af_instance_t* af=s->first;   frac_t mul = {1,1};  // Iterate through all filters and calculate total multiplication factor  do{    af_frac_mul(&mul, &af->mul);    af=af->next;  }while(af);  // Sanity check   if(!mul.n || !mul.d)     return -1;  in = t * (((len/t) * mul.d - 1)/mul.n);    if(in>max_insize) in=t*(max_insize/t);  // Try to meet constraint nr 3.   while((out=t * (((in/t+1)*mul.n - 1)/mul.d)) <= max_outsize && in<=max_insize){    if( (t * (((in/t)*mul.n))/mul.d) >= len) return in;    in+=t;  }    // Could no meet constraint nr 3.  while(out > max_outsize || in > max_insize){    in-=t;    if(in<t) return -1; // Input parameters are probably incorrect    out = t * (((in/t)*mul.n + 1)/mul.d);  }  return in;}/* Calculate the total delay [ms] caused by the filters */double af_calc_delay(af_stream_t* s){  af_instance_t* af=s->first;   register double delay = 0.0;  // Iterate through all filters   while(af){    delay += af->delay;    af=af->next;  }  return delay;}/* Helper function called by the macro with the same name this   function should not be called directly */inline int af_resize_local_buffer(af_instance_t* af, af_data_t* data){  // Calculate new length  register int len = af_lencalc(af->mul,data);  af_msg(AF_MSG_VERBOSE,"[libaf] Reallocating memory in module %s, " 	 "old len = %i, new len = %i\n",af->info->name,af->data->len,len);  // If there is a buffer free it  if(af->data->audio)     free(af->data->audio);  // Create new buffer and check that it is OK  af->data->audio = malloc(len);  if(!af->data->audio){    af_msg(AF_MSG_FATAL,"[libaf] Could not allocate memory \n");    return AF_ERROR;  }  af->data->len=len;  return AF_OK;}/** * \brief send control to all filters, starting with the last, until *        one responds with AF_OK * \return The instance that accepted the command or NULL if none did. */af_instance_t *af_control_any_rev (af_stream_t* s, int cmd, void* arg) {  int res = AF_UNKNOWN;  af_instance_t* filt = s->last;  while (filt) {    res = filt->control(filt, cmd, arg);    if (res == AF_OK)      return filt;    filt = filt->prev;  }  return NULL;}/** * \brief calculate greatest common divisior of a and b. *   Extended for negative and 0 values. If both are 0 the result is 1. *   The sign of the result will be so that it has the same sign as b. */int af_gcd(register int a, register int b) {  int b_org = b;  while (b != 0) {    a %= b;    if (a == 0)      break;    b %= a;  }  // the result is either in a or b. As the other one is 0 just add them.  a += b;  if (!a)    return 1;  if (a * b_org < 0)    return -a;  return a;}/** * \brief cancel down a fraction f */void af_frac_cancel(frac_t *f) {  int gcd = af_gcd(f->n, f->d);  f->n /= gcd;  f->d /= gcd;}/** * \brief multiply out by in and store result in out. *        the resulting fraction wil be cancelled down *        if in and out were. */void af_frac_mul(frac_t *out, const frac_t *in) {  int gcd1 = af_gcd(out->n, in->d);  int gcd2 = af_gcd(in->n, out->d);  out->n = (out->n / gcd1) * (in->n / gcd2);  out->d = (out->d / gcd2) * (in->d / gcd1);}void af_help (void) {  int i = 0;  af_msg(AF_MSG_INFO, "Available audio filters:\n");  while (filter_list[i]) {    if (filter_list[i]->comment && filter_list[i]->comment[0])      af_msg(AF_MSG_INFO, "  %-15s: %s (%s)\n", filter_list[i]->name, filter_list[i]->info, filter_list[i]->comment);    else      af_msg(AF_MSG_INFO, "  %-15s: %s\n", filter_list[i]->name, filter_list[i]->info);    i++;  }}void af_fix_parameters(af_data_t *data){    data->bps = af_fmt2bits(data->format)/8;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -