summaryrefslogtreecommitdiffstats
path: root/mplayer.c
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2010-07-15 17:59:46 +0000
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-11-02 04:14:44 +0200
commit5ed772b9cddc4c0de6762e223428b3e36eceefff (patch)
tree338d1623dd003d777b17c3c64c90049b4c9ebd2c /mplayer.c
parent6be6ba40946d333e9d2cf741ba401366e9081c79 (diff)
downloadmpv-5ed772b9cddc4c0de6762e223428b3e36eceefff.tar.bz2
mpv-5ed772b9cddc4c0de6762e223428b3e36eceefff.tar.xz
audio: support parameter changes (e.g. channel count) during playback
Add support for parameter changes (e.g. channel count) during playback. This makes decoding AC3 files that switch between 2 and 6 channels work reasonably well even with -channels 6 and ffac3 decoder. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31737 b3059339-0415-0410-9bf9-f77b7e298cf2 Fix typo in error message: ACC -> AAC git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32473 b3059339-0415-0410-9bf9-f77b7e298cf2 Avoid printing AAC with SBR warning on every decode call, instead print it only after every decoder reconfiguration. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@32476 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'mplayer.c')
-rw-r--r--mplayer.c105
1 files changed, 62 insertions, 43 deletions
diff --git a/mplayer.c b/mplayer.c
index 6e664e164c..87c6d7b0a2 100644
--- a/mplayer.c
+++ b/mplayer.c
@@ -1764,49 +1764,54 @@ void reinit_audio_chain(struct MPContext *mpctx)
struct MPOpts *opts = &mpctx->opts;
if (!mpctx->sh_audio)
return;
- current_module="init_audio_codec";
- mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
- if(!init_best_audio_codec(mpctx->sh_audio,audio_codec_list,audio_fm_list)){
- goto init_error;
- }
- mpctx->initialized_flags|=INITIALIZED_ACODEC;
- mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
-
-
- current_module="af_preinit";
- ao_data.samplerate=force_srate;
- ao_data.channels=0;
- ao_data.format=audio_output_format;
- // first init to detect best values
- if(!init_audio_filters(mpctx->sh_audio, // preliminary init
- // input:
- mpctx->sh_audio->samplerate,
- // output:
- &ao_data.samplerate, &ao_data.channels, &ao_data.format)){
- mp_tmsg(MSGT_CPLAYER,MSGL_ERR, "Error at audio filter chain "
- "pre-init!\n");
- exit_player(mpctx, EXIT_ERROR);
+ if (!(mpctx->initialized_flags & INITIALIZED_ACODEC)) {
+ current_module="init_audio_codec";
+ mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
+ if(!init_best_audio_codec(mpctx->sh_audio,audio_codec_list,audio_fm_list)){
+ goto init_error;
+ }
+ mpctx->initialized_flags|=INITIALIZED_ACODEC;
+ mp_msg(MSGT_CPLAYER,MSGL_INFO,"==========================================================================\n");
}
- current_module="ao2_init";
- mpctx->audio_out = init_best_audio_out(opts->audio_driver_list,
- 0, // plugin flag
- ao_data.samplerate,
- ao_data.channels,
- ao_data.format, 0);
- if(!mpctx->audio_out){
- mp_tmsg(MSGT_CPLAYER,MSGL_ERR,"Could not open/initialize audio device -> no sound.\n");
- goto init_error;
+
+
+ if (!(mpctx->initialized_flags & INITIALIZED_AO)) {
+ current_module="af_preinit";
+ ao_data.samplerate=force_srate;
+ ao_data.channels=0;
+ ao_data.format=audio_output_format;
+ // first init to detect best values
+ if(!init_audio_filters(mpctx->sh_audio, // preliminary init
+ // input:
+ mpctx->sh_audio->samplerate,
+ // output:
+ &ao_data.samplerate, &ao_data.channels, &ao_data.format)){
+ mp_tmsg(MSGT_CPLAYER,MSGL_ERR, "Error at audio filter chain "
+ "pre-init!\n");
+ exit_player(mpctx, EXIT_ERROR);
+ }
+ current_module="ao2_init";
+ mpctx->audio_out = init_best_audio_out(opts->audio_driver_list,
+ 0, // plugin flag
+ ao_data.samplerate,
+ ao_data.channels,
+ ao_data.format, 0);
+ if(!mpctx->audio_out){
+ mp_tmsg(MSGT_CPLAYER,MSGL_ERR,"Could not open/initialize audio device -> no sound.\n");
+ goto init_error;
+ }
+ mpctx->initialized_flags|=INITIALIZED_AO;
+ mp_msg(MSGT_CPLAYER,MSGL_INFO,"AO: [%s] %dHz %dch %s (%d bytes per sample)\n",
+ mpctx->audio_out->info->short_name,
+ ao_data.samplerate, ao_data.channels,
+ af_fmt2str_short(ao_data.format),
+ af_fmt2bits(ao_data.format)/8 );
+ mp_msg(MSGT_CPLAYER,MSGL_V,"AO: Description: %s\nAO: Author: %s\n",
+ mpctx->audio_out->info->name, mpctx->audio_out->info->author);
+ if(strlen(mpctx->audio_out->info->comment) > 0)
+ mp_msg(MSGT_CPLAYER,MSGL_V,"AO: Comment: %s\n", mpctx->audio_out->info->comment);
}
- mpctx->initialized_flags|=INITIALIZED_AO;
- mp_msg(MSGT_CPLAYER,MSGL_INFO,"AO: [%s] %dHz %dch %s (%d bytes per sample)\n",
- mpctx->audio_out->info->short_name,
- ao_data.samplerate, ao_data.channels,
- af_fmt2str_short(ao_data.format),
- af_fmt2bits(ao_data.format)/8 );
- mp_msg(MSGT_CPLAYER,MSGL_V,"AO: Description: %s\nAO: Author: %s\n",
- mpctx->audio_out->info->name, mpctx->audio_out->info->author);
- if(strlen(mpctx->audio_out->info->comment) > 0)
- mp_msg(MSGT_CPLAYER,MSGL_V,"AO: Comment: %s\n", mpctx->audio_out->info->comment);
+
// init audio filters:
current_module="af_init";
if(!build_afilter_chain(mpctx, mpctx->sh_audio, &ao_data)) {
@@ -2167,6 +2172,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
int playsize;
int playflags=0;
int audio_eof=0;
+ bool format_change = false;
sh_audio_t * const sh_audio = mpctx->sh_audio;
current_module="play_audio";
@@ -2192,12 +2198,16 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
// Fill buffer if needed:
current_module="decode_audio";
t = GetTimer();
- if (decode_audio(sh_audio, playsize) < 0) // EOF or error
- if (mpctx->d_audio->eof) {
+ int res = decode_audio(sh_audio, playsize);
+ if (res < 0) { // EOF, error or format change
+ if (res == -2)
+ format_change = true;
+ else if (mpctx->d_audio->eof) {
audio_eof = 1;
if (sh_audio->a_out_buffer_len == 0)
return 0;
}
+ }
t = GetTimer() - t;
tt = t*0.000001f; audio_time_usage+=tt;
if (playsize > sh_audio->a_out_buffer_len) {
@@ -2230,6 +2240,15 @@ static int fill_audio_out_buffers(struct MPContext *mpctx)
sh_audio->a_out_buffer_len = 0;
}
+ /* The format change isn't handled too gracefully. A more precise
+ * implementation would require draining buffered old-format audio
+ * while displaying video, then doing the output format switch.
+ */
+ if (format_change) {
+ uninit_player(mpctx, INITIALIZED_AO);
+ reinit_audio_chain(mpctx);
+ }
+
return 1;
}