From 23e303859aa93572f00b17e3b2bc0a552ad7c348 Mon Sep 17 00:00:00 2001 From: wm4 Date: Thu, 11 Jul 2013 19:15:09 +0200 Subject: mplayer: fix incorrect audio sync after format changes This is not directly related to the handling of format changes itself, but playing audio normally after the change. This was broken: the output byte rate was not recalculated, so audio-video sync was simply broken. Fix this by calculating the byte rate on the fly, instead of storing it in sh_audio. Format changes are relatively common (switches between stereo and 5.1 in TV recordings), so this fixes a somewhat critical bug. --- audio/decode/dec_audio.c | 10 ++-------- core/mplayer.c | 8 ++++++-- demux/stheader.h | 1 - stream/tv.c | 2 +- 4 files changed, 9 insertions(+), 12 deletions(-) diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c index 8c80a0b119..d6b57dd2b5 100644 --- a/audio/decode/dec_audio.c +++ b/audio/decode/dec_audio.c @@ -84,9 +84,6 @@ static int init_audio_codec(sh_audio_t *sh_audio, const char *decoder) return 0; } - if (!sh_audio->o_bps) - sh_audio->o_bps = sh_audio->channels.num * sh_audio->samplerate - * sh_audio->samplesize; return 1; } @@ -150,12 +147,9 @@ int init_best_audio_codec(sh_audio_t *sh_audio, char *audio_decoders) mp_msg(MSGT_DECAUDIO, MSGL_INFO, "Selected audio codec: %s\n", sh_audio->gsh->decoder_desc); mp_msg(MSGT_DECAUDIO, MSGL_V, - "AUDIO: %d Hz, %d ch, %s, %3.1f kbit/%3.2f%% (ratio: %d->%d)\n", + "AUDIO: %d Hz, %d ch, %s\n", sh_audio->samplerate, sh_audio->channels.num, - af_fmt2str_short(sh_audio->sample_format), - sh_audio->i_bps * 8 * 0.001, - ((float) sh_audio->i_bps / sh_audio->o_bps) * 100.0, - sh_audio->i_bps, sh_audio->o_bps); + af_fmt2str_short(sh_audio->sample_format)); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_BITRATE=%d\nID_AUDIO_RATE=%d\n" "ID_AUDIO_NCH=%d\n", sh_audio->i_bps * 8, sh_audio->samplerate, sh_audio->channels.num); diff --git a/core/mplayer.c b/core/mplayer.c index 87bef0e3c5..7b3cf65026 100644 --- a/core/mplayer.c +++ b/core/mplayer.c @@ -1668,6 +1668,10 @@ static double written_audio_pts(struct MPContext *mpctx) sh_audio_t *sh_audio = mpctx->sh_audio; if (!sh_audio) return MP_NOPTS_VALUE; + + double bps = sh_audio->channels.num * sh_audio->samplerate * + sh_audio->samplesize; + // first calculate the end pts of audio that has been output by decoder double a_pts = sh_audio->pts; if (a_pts == MP_NOPTS_VALUE) @@ -1676,13 +1680,13 @@ static double written_audio_pts(struct MPContext *mpctx) // sh_audio->pts is the timestamp of the latest input packet with // known pts that the decoder has decoded. sh_audio->pts_bytes is // the amount of bytes the decoder has written after that timestamp. - a_pts += sh_audio->pts_bytes / (double) sh_audio->o_bps; + a_pts += sh_audio->pts_bytes / bps; // Now a_pts hopefully holds the pts for end of audio from decoder. // Subtract data in buffers between decoder and audio out. // Decoded but not filtered - a_pts -= sh_audio->a_buffer_len / (double)sh_audio->o_bps; + a_pts -= sh_audio->a_buffer_len / bps; // Data buffered in audio filters, measured in bytes of "missing" output double buffered_output = af_calc_delay(sh_audio->afilter); diff --git a/demux/stheader.h b/demux/stheader.h index 8b584396ca..447cacfc02 100644 --- a/demux/stheader.h +++ b/demux/stheader.h @@ -92,7 +92,6 @@ typedef struct sh_audio { int container_out_samplerate; int samplesize; struct mp_chmap channels; - int o_bps; // == samplerate*samplesize*channels.num (uncompr. bytes/sec) int i_bps; // == bitrate (compressed bytes/sec) // decoder buffers: int audio_out_minsize; // minimal output from decoder may be this much diff --git a/stream/tv.c b/stream/tv.c index e5768a350a..72b67b7f9e 100644 --- a/stream/tv.c +++ b/stream/tv.c @@ -794,7 +794,7 @@ static demuxer_t* demux_open_tv(demuxer_t *demuxer) sh_audio->gsh->codec = "mp-pcm"; sh_audio->format = audio_format; - sh_audio->i_bps = sh_audio->o_bps = + sh_audio->i_bps = sh_audio->samplerate * sh_audio->samplesize * sh_audio->channels.num; -- cgit v1.2.3