dec_audio.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 496 行 · 第 1/2 页

C
496
字号
    }    return 0;}int init_best_audio_codec(sh_audio_t *sh_audio,char** audio_codec_list,char** audio_fm_list){char* ac_l_default[2]={"",(char*)NULL};// hack:if(!audio_codec_list) audio_codec_list=ac_l_default;// Go through the codec.conf and find the best codec...sh_audio->inited=0;codecs_reset_selection(1);while(!sh_audio->inited && *audio_codec_list){  char* audio_codec=*(audio_codec_list++);  if(audio_codec[0]){    if(audio_codec[0]=='-'){      // disable this codec:      select_codec(audio_codec+1,1);    } else {      // forced codec by name:      mp_msg(MSGT_DECAUDIO,MSGL_INFO,MSGTR_ForcedAudioCodec,audio_codec);      init_audio(sh_audio,audio_codec,NULL,-1);    }  } else {    int status;    // try in stability order: UNTESTED, WORKING, BUGGY. never try CRASHING.    if(audio_fm_list){      char** fmlist=audio_fm_list;      // try first the preferred codec families:      while(!sh_audio->inited && *fmlist){        char* audio_fm=*(fmlist++);	mp_msg(MSGT_DECAUDIO,MSGL_INFO,MSGTR_TryForceAudioFmtStr,audio_fm);	for(status=CODECS_STATUS__MAX;status>=CODECS_STATUS__MIN;--status)	    if(init_audio(sh_audio,NULL,audio_fm,status)) break;      }    }    if(!sh_audio->inited)	for(status=CODECS_STATUS__MAX;status>=CODECS_STATUS__MIN;--status)	    if(init_audio(sh_audio,NULL,NULL,status)) break;  }}if(!sh_audio->inited){    mp_msg(MSGT_DECAUDIO,MSGL_ERR,MSGTR_CantFindAudioCodec,sh_audio->format);    mp_msg(MSGT_DECAUDIO,MSGL_HINT, MSGTR_RTFMCodecs);    return 0; // failed}mp_msg(MSGT_DECAUDIO,MSGL_INFO,MSGTR_SelectedAudioCodec,    sh_audio->codec->name,sh_audio->codec->drv,sh_audio->codec->info);return 1; // success}void uninit_audio(sh_audio_t *sh_audio){    if(sh_audio->afilter){	mp_msg(MSGT_DECAUDIO,MSGL_V,"Uninit audio filters...\n");	af_uninit(sh_audio->afilter);	free(sh_audio->afilter);	sh_audio->afilter=NULL;    }    if(sh_audio->inited){	mp_msg(MSGT_DECAUDIO,MSGL_V,MSGTR_UninitAudioStr,sh_audio->codec->drv);	sh_audio->ad_driver->uninit(sh_audio);#ifdef DYNAMIC_PLUGINS	if (sh_audio->dec_handle)	    dlclose(sh_audio->dec_handle);#endif	sh_audio->inited=0;    }    if(sh_audio->a_out_buffer!=sh_audio->a_buffer) free(sh_audio->a_out_buffer);    sh_audio->a_out_buffer=NULL;    sh_audio->a_out_buffer_size=0;    if(sh_audio->a_buffer) free(sh_audio->a_buffer);    sh_audio->a_buffer=NULL;    if(sh_audio->a_in_buffer) free(sh_audio->a_in_buffer);    sh_audio->a_in_buffer=NULL;} /* Init audio filters */int preinit_audio_filters(sh_audio_t *sh_audio, 	int in_samplerate, int in_channels, int in_format,	int* out_samplerate, int* out_channels, int* out_format){  return init_audio_filters(sh_audio, in_samplerate, in_channels, in_format,      out_samplerate, out_channels, out_format, 0, 0);} /* Init audio filters */int init_audio_filters(sh_audio_t *sh_audio, 	int in_samplerate, int in_channels, int in_format,	int *out_samplerate, int *out_channels, int *out_format,	int out_minsize, int out_maxsize){  af_stream_t* afs=sh_audio->afilter;  if(!afs){    afs = malloc(sizeof(af_stream_t));    memset(afs,0,sizeof(af_stream_t));  }  // input format: same as codec's output format:  afs->input.rate   = in_samplerate;  afs->input.nch    = in_channels;  afs->input.format = in_format;  af_fix_parameters(&(afs->input));  // output format: same as ao driver's input format (if missing, fallback to input)  afs->output.rate   = *out_samplerate;  afs->output.nch    = *out_channels;  afs->output.format = *out_format;  af_fix_parameters(&(afs->output));  // filter config:    memcpy(&afs->cfg,&af_cfg,sizeof(af_cfg_t));    mp_msg(MSGT_DECAUDIO, MSGL_V, MSGTR_BuildingAudioFilterChain,      afs->input.rate,afs->input.nch,af_fmt2str_short(afs->input.format),      afs->output.rate,afs->output.nch,af_fmt2str_short(afs->output.format));    // let's autoprobe it!  if(0 != af_init(afs)){    sh_audio->afilter=NULL;    free(afs);    return 0; // failed :(  }  *out_samplerate=afs->output.rate;  *out_channels=afs->output.nch;  *out_format=afs->output.format;    if (out_maxsize || out_minsize) {  // allocate the a_out_* buffers:  if(out_maxsize<out_minsize) out_maxsize=out_minsize;  if(out_maxsize<8192) out_maxsize=MAX_OUTBURST; // not sure this is ok  sh_audio->a_out_buffer_size=out_maxsize;  if (sh_audio->a_out_buffer != sh_audio->a_buffer)      free(sh_audio->a_out_buffer);  sh_audio->a_out_buffer=memalign(16,sh_audio->a_out_buffer_size);  memset(sh_audio->a_out_buffer,0,sh_audio->a_out_buffer_size);  sh_audio->a_out_buffer_len=0;  }    // ok!  sh_audio->afilter=(void*)afs;  return 1;}int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen){  int declen;  af_data_t  afd;  // filter input  af_data_t* pafd; // filter output  ad_functions_t* mpadec = sh_audio->ad_driver;  if(!sh_audio->inited) return -1; // no codec  if(!sh_audio->afilter){      // no filter, just decode:      // FIXME: don't drop initial decoded data in a_buffer!      return mpadec->decode_audio(sh_audio,buf,minlen,maxlen);  }  //  declen=af_inputlen(sh_audio->afilter,minlen);  declen=af_calc_insize_constrained(sh_audio->afilter,minlen,maxlen,      sh_audio->a_buffer_size-sh_audio->audio_out_minsize);  mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"\ndecaudio: minlen=%d maxlen=%d declen=%d (max=%d)\n",      minlen, maxlen, declen, sh_audio->a_buffer_size);  if(declen<=0) return -1; // error!  // limit declen to buffer size: - DONE by af_calc_insize_constrained//  if(declen>sh_audio->a_buffer_size) declen=sh_audio->a_buffer_size;  // decode if needed:  while(declen>sh_audio->a_buffer_len){      int len=declen-sh_audio->a_buffer_len;      int maxlen=sh_audio->a_buffer_size-sh_audio->a_buffer_len;      mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"decaudio: decoding %d bytes, max: %d (%d)\n",        len, maxlen, sh_audio->audio_out_minsize);      // When a decoder sets audio_out_minsize that should guarantee it can      // write up to audio_out_minsize bytes at a time until total >= minlen      // without checking maxlen. Thus maxlen must be at least minlen +      // audio_out_minsize. Check that to guard against buffer overflows.      if (maxlen < len + sh_audio->audio_out_minsize)	  break;      // not enough decoded data waiting, decode 'len' bytes more:      len=mpadec->decode_audio(sh_audio,          sh_audio->a_buffer+sh_audio->a_buffer_len, len, maxlen);      if(len<=0) break; // EOF?      sh_audio->a_buffer_len+=len;  }  if(declen>sh_audio->a_buffer_len)    declen=sh_audio->a_buffer_len; // still no enough data (EOF) :(  // round to whole samples://  declen/=sh_audio->samplesize*sh_audio->channels;//  declen*=sh_audio->samplesize*sh_audio->channels;  // run the filters:  afd.audio=sh_audio->a_buffer;  afd.len=declen;  afd.rate=sh_audio->samplerate;  afd.nch=sh_audio->channels;  afd.format=sh_audio->sample_format;  af_fix_parameters(&afd);  //pafd=&afd;//  printf("\nAF: %d --> ",declen);  pafd=af_play(sh_audio->afilter,&afd);//  printf("%d  \n",pafd->len);  if(!pafd) return -1; // error  mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"decaudio: declen=%d out=%d (max %d)\n",      declen, pafd->len, maxlen);    // copy filter==>out:  if(maxlen < pafd->len) {    af_stream_t *afs = sh_audio->afilter;    maxlen -= maxlen % (afs->output.nch * afs->output.bps);    mp_msg(MSGT_DECAUDIO,MSGL_WARN,"%i bytes of audio data lost due to buffer overflow, len = %i\n", pafd->len - maxlen,pafd->len);  }  else    maxlen=pafd->len;  memmove(buf, pafd->audio, maxlen);    // remove processed data from decoder buffer:  sh_audio->a_buffer_len-=declen;  if(sh_audio->a_buffer_len>0)    memmove(sh_audio->a_buffer, sh_audio->a_buffer+declen, sh_audio->a_buffer_len);    return maxlen;}void resync_audio_stream(sh_audio_t *sh_audio){  sh_audio->a_in_buffer_len=0;        // clear audio input buffer  if(!sh_audio->inited) return;  sh_audio->ad_driver->control(sh_audio,ADCTRL_RESYNC_STREAM,NULL);}void skip_audio_frame(sh_audio_t *sh_audio){  if(!sh_audio->inited) return;  if(sh_audio->ad_driver->control(sh_audio,ADCTRL_SKIP_FRAME,NULL)==CONTROL_TRUE) return;  // default skip code:  ds_fill_buffer(sh_audio->ds);  // skip block}

⌨️ 快捷键说明

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