mirror of https://github.com/mpv-player/mpv
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.
This commit is contained in:
parent
7a4f9cc4d2
commit
23e303859a
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue