mirror of
https://github.com/mpv-player/mpv
synced 2025-01-09 01:36:25 +01:00
Added buffering of output data
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4314 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
d00d8ff8bf
commit
9fa55b07a5
@ -25,16 +25,19 @@ LIBAO_EXTERN(plugin)
|
|||||||
// local data
|
// local data
|
||||||
typedef struct ao_plugin_local_data_s
|
typedef struct ao_plugin_local_data_s
|
||||||
{
|
{
|
||||||
ao_functions_t* driver; // Output driver set in mplayer.c
|
void* buf; // Output data buffer
|
||||||
|
int len; // Amount of data in buffer
|
||||||
|
float bps; // Bytes per second out
|
||||||
|
ao_functions_t* driver; // Output driver
|
||||||
ao_plugin_functions_t** plugins; // List of used plugins
|
ao_plugin_functions_t** plugins; // List of used plugins
|
||||||
ao_plugin_functions_t* available_plugins[NPL]; // List of available plugins
|
ao_plugin_functions_t* available_plugins[NPL]; // List of available plugins
|
||||||
} ao_plugin_local_data_t;
|
} ao_plugin_local_data_t;
|
||||||
|
|
||||||
static ao_plugin_local_data_t ao_plugin_local_data={NULL,NULL,AO_PLUGINS};
|
static ao_plugin_local_data_t ao_plugin_local_data={NULL,0,0.0,NULL,NULL,AO_PLUGINS};
|
||||||
|
|
||||||
// gloabal data
|
// global data
|
||||||
volatile ao_plugin_data_t ao_plugin_data; // data used by the plugins
|
volatile ao_plugin_data_t ao_plugin_data; // Data used by the plugins
|
||||||
volatile ao_plugin_cfg_t ao_plugin_cfg=CFG_DEFAULTS; // cfg data set in cfg-mplayer.h
|
volatile ao_plugin_cfg_t ao_plugin_cfg=CFG_DEFAULTS; // Set in cfg-mplayer.h
|
||||||
|
|
||||||
// to set/get/query special features/parameters
|
// to set/get/query special features/parameters
|
||||||
static int control(int cmd,int arg){
|
static int control(int cmd,int arg){
|
||||||
@ -102,7 +105,7 @@ int add_plugin(int i,char* cfg){
|
|||||||
static int init(int rate,int channels,int format,int flags){
|
static int init(int rate,int channels,int format,int flags){
|
||||||
int ok=1;
|
int ok=1;
|
||||||
|
|
||||||
/* Create list of plugins from cfg option */
|
// Create list of plugins from cfg option
|
||||||
int i=0;
|
int i=0;
|
||||||
if(ao_plugin_cfg.plugin_list){
|
if(ao_plugin_cfg.plugin_list){
|
||||||
if(!add_plugin(i,ao_plugin_cfg.plugin_list))
|
if(!add_plugin(i,ao_plugin_cfg.plugin_list))
|
||||||
@ -124,6 +127,20 @@ static int init(int rate,int channels,int format,int flags){
|
|||||||
|
|
||||||
if(!ok) return 0;
|
if(!ok) return 0;
|
||||||
|
|
||||||
|
// Calculate bps
|
||||||
|
ao_plugin_local_data.bps=(float)(ao_plugin_data.rate *
|
||||||
|
ao_plugin_data.channels);
|
||||||
|
|
||||||
|
if(ao_plugin_data.format == AFMT_S16_LE ||
|
||||||
|
ao_plugin_data.format == AFMT_S16_BE ||
|
||||||
|
ao_plugin_data.format == AFMT_U16_LE ||
|
||||||
|
ao_plugin_data.format == AFMT_U16_BE)
|
||||||
|
ao_plugin_local_data.bps *= 2;
|
||||||
|
|
||||||
|
if(ao_plugin_data.format == AFMT_S32_LE ||
|
||||||
|
ao_plugin_data.format == AFMT_S32_BE)
|
||||||
|
ao_plugin_local_data.bps *= 4;
|
||||||
|
|
||||||
// This should never happen but check anyway
|
// This should never happen but check anyway
|
||||||
if(NULL==ao_plugin_local_data.driver)
|
if(NULL==ao_plugin_local_data.driver)
|
||||||
return 0;
|
return 0;
|
||||||
@ -142,6 +159,13 @@ static int init(int rate,int channels,int format,int flags){
|
|||||||
|
|
||||||
if(!ok) return 0;
|
if(!ok) return 0;
|
||||||
|
|
||||||
|
// Allocate output buffer */
|
||||||
|
if(ao_plugin_local_data.buf)
|
||||||
|
free(ao_plugin_local_data.buf);
|
||||||
|
ao_plugin_local_data.buf=malloc(MAX_OUTBURST);
|
||||||
|
|
||||||
|
if(!ao_plugin_local_data.buf) return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +177,8 @@ static void uninit(){
|
|||||||
plugin(i++)->uninit();
|
plugin(i++)->uninit();
|
||||||
if(ao_plugin_local_data.plugins)
|
if(ao_plugin_local_data.plugins)
|
||||||
free(ao_plugin_local_data.plugins);
|
free(ao_plugin_local_data.plugins);
|
||||||
|
if(ao_plugin_local_data.buf)
|
||||||
|
free(ao_plugin_local_data.buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop playing and empty buffers (for seeking/pause)
|
// stop playing and empty buffers (for seeking/pause)
|
||||||
@ -161,6 +187,7 @@ static void reset(){
|
|||||||
driver()->reset();
|
driver()->reset();
|
||||||
while(plugin(i))
|
while(plugin(i))
|
||||||
plugin(i++)->reset();
|
plugin(i++)->reset();
|
||||||
|
ao_plugin_local_data.len=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop playing, keep buffers (for pause)
|
// stop playing, keep buffers (for pause)
|
||||||
@ -176,6 +203,8 @@ static void audio_resume(){
|
|||||||
// return: how many bytes can be played without blocking
|
// return: how many bytes can be played without blocking
|
||||||
static int get_space(){
|
static int get_space(){
|
||||||
double sz=(double)(driver()->get_space());
|
double sz=(double)(driver()->get_space());
|
||||||
|
if(sz+(double)ao_plugin_local_data.len > (double)MAX_OUTBURST)
|
||||||
|
sz=(double)MAX_OUTBURST-(double)ao_plugin_local_data.len;
|
||||||
sz*=ao_plugin_data.sz_mult;
|
sz*=ao_plugin_data.sz_mult;
|
||||||
sz+=ao_plugin_data.sz_fix;
|
sz+=ao_plugin_data.sz_fix;
|
||||||
return (int)(sz);
|
return (int)(sz);
|
||||||
@ -184,22 +213,25 @@ static int get_space(){
|
|||||||
// plays 'len' bytes of 'data'
|
// plays 'len' bytes of 'data'
|
||||||
// return: number of bytes played
|
// return: number of bytes played
|
||||||
static int play(void* data,int len,int flags){
|
static int play(void* data,int len,int flags){
|
||||||
int i=0;
|
int l,i=0;
|
||||||
/* Due to constant buffer sizes in plugins limit length */
|
// Limit length to avoid over flow in plugins
|
||||||
int tmp = get_space();
|
int tmp = driver()->get_space();
|
||||||
int ret_len =(tmp<len)?tmp:len;
|
int ret_len =(tmp<len)?tmp:len;
|
||||||
/* Filter data */
|
// Filter data
|
||||||
ao_plugin_data.len=ret_len;
|
ao_plugin_data.len=ret_len;
|
||||||
ao_plugin_data.data=data;
|
ao_plugin_data.data=data;
|
||||||
while(plugin(i))
|
while(plugin(i))
|
||||||
plugin(i++)->play();
|
plugin(i++)->play();
|
||||||
/* Send data to output */
|
// Copy data to output buffer
|
||||||
//fprintf(stderr, "ao_plugin: ret_len=%d, len=%d\n", ret_len, len);
|
memcpy(ao_plugin_local_data.buf+ao_plugin_local_data.len,
|
||||||
len=driver()->play(ao_plugin_data.data,ao_plugin_data.len,flags);
|
ao_plugin_data.data,ao_plugin_data.len);
|
||||||
//fprintf(stderr, "ao_plugin: returned len=%d\n", len);
|
// Send data to output
|
||||||
|
l=driver()->play(ao_plugin_local_data.buf,
|
||||||
if(len!=ao_plugin_data.len)
|
ao_plugin_data.len+ao_plugin_local_data.len,flags);
|
||||||
fprintf(stderr,"[ao_plugin] Warning under or over flow in sound plugin\n");
|
// Save away unsent data
|
||||||
|
ao_plugin_local_data.len=ao_plugin_data.len+ao_plugin_local_data.len-l;
|
||||||
|
memcpy(ao_plugin_local_data.buf,ao_plugin_local_data.buf+l,
|
||||||
|
ao_plugin_local_data.len);
|
||||||
|
|
||||||
return ret_len;
|
return ret_len;
|
||||||
}
|
}
|
||||||
@ -207,6 +239,7 @@ static int play(void* data,int len,int flags){
|
|||||||
// return: delay in seconds between first and last sample in buffer
|
// return: delay in seconds between first and last sample in buffer
|
||||||
static float get_delay(){
|
static float get_delay(){
|
||||||
float delay=driver()->get_delay();
|
float delay=driver()->get_delay();
|
||||||
|
delay+=(float)ao_plugin_local_data.len/ao_plugin_local_data.bps;
|
||||||
delay*=ao_plugin_data.delay_mult;
|
delay*=ao_plugin_data.delay_mult;
|
||||||
delay+=ao_plugin_data.delay_fix;
|
delay+=ao_plugin_data.delay_fix;
|
||||||
return delay;
|
return delay;
|
||||||
|
Loading…
Reference in New Issue
Block a user