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 + -
显示快捷键?