mirror of https://github.com/mpv-player/mpv
demux_mkv: never force output sample rate
Matroska has an output sample rate (OutputSamplingFrequency), which in theory should be forced instead of whatever the decoder outputs. But it appears no software (other than mplayer2 and mpv until now) actually respects this. Even worse, there were broken files around, which played correctly with (in theory) broken software, but not mplayer2/mpv. Hacks were added to our code to play these files correctly, but they didn't catch all cases. Simplify this by doing what everyone else does, and always use the decoder's sample rate instead. In particular, we try to handle all sample rate issues like libavformat's Matroska demuxer does.
This commit is contained in:
parent
6230e0b896
commit
66a9eb570d
|
@ -160,16 +160,12 @@ static int setup_format(sh_audio_t *sh_audio,
|
||||||
struct priv *priv = sh_audio->context;
|
struct priv *priv = sh_audio->context;
|
||||||
int sample_format =
|
int sample_format =
|
||||||
af_from_avformat(av_get_packed_sample_fmt(lavc_context->sample_fmt));
|
af_from_avformat(av_get_packed_sample_fmt(lavc_context->sample_fmt));
|
||||||
bool broken_srate = false;
|
|
||||||
int samplerate = lavc_context->sample_rate;
|
int samplerate = lavc_context->sample_rate;
|
||||||
int container_samplerate = sh_audio->container_out_samplerate;
|
// If not set, try container samplerate
|
||||||
if (!container_samplerate && sh_audio->wf)
|
if (!samplerate && sh_audio->wf) {
|
||||||
container_samplerate = sh_audio->wf->nSamplesPerSec;
|
samplerate = sh_audio->wf->nSamplesPerSec;
|
||||||
if (lavc_context->codec_id == AV_CODEC_ID_AAC
|
mp_tmsg(MSGT_DECAUDIO, MSGL_V, "ad_lavc: using container rate.\n");
|
||||||
&& samplerate == 2 * container_samplerate)
|
}
|
||||||
broken_srate = true;
|
|
||||||
else if (container_samplerate)
|
|
||||||
samplerate = container_samplerate;
|
|
||||||
|
|
||||||
struct mp_chmap lavc_chmap;
|
struct mp_chmap lavc_chmap;
|
||||||
mp_chmap_from_lavc(&lavc_chmap, lavc_context->channel_layout);
|
mp_chmap_from_lavc(&lavc_chmap, lavc_context->channel_layout);
|
||||||
|
@ -188,9 +184,6 @@ static int setup_format(sh_audio_t *sh_audio,
|
||||||
sh_audio->samplerate = samplerate;
|
sh_audio->samplerate = samplerate;
|
||||||
sh_audio->sample_format = sample_format;
|
sh_audio->sample_format = sample_format;
|
||||||
sh_audio->samplesize = af_fmt2bits(sh_audio->sample_format) / 8;
|
sh_audio->samplesize = af_fmt2bits(sh_audio->sample_format) / 8;
|
||||||
if (broken_srate)
|
|
||||||
mp_msg(MSGT_DECAUDIO, MSGL_WARN,
|
|
||||||
"Ignoring broken container sample rate for AAC with SBR\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -488,14 +488,6 @@ static void parse_trackaudio(struct demuxer *demuxer, struct mkv_track *track,
|
||||||
"[mkv] | + Output sampling frequency: %f\n", track->a_osfreq);
|
"[mkv] | + Output sampling frequency: %f\n", track->a_osfreq);
|
||||||
} else
|
} else
|
||||||
track->a_osfreq = track->a_sfreq;
|
track->a_osfreq = track->a_sfreq;
|
||||||
// Something creates files with osfreq incorrectly set
|
|
||||||
if (track->a_sfreq == 44100 && track->a_osfreq == 96000) {
|
|
||||||
mp_msg(MSGT_DEMUX, MSGL_WARN, "[mkv] Audio track has codec frequency "
|
|
||||||
"%.1f and playback frequency %.1f.\n[mkv] This looks wrong. "
|
|
||||||
"Assuming this file is corrupt and ignoring the latter.\n",
|
|
||||||
track->a_sfreq, track->a_osfreq);
|
|
||||||
track->a_osfreq = track->a_sfreq;
|
|
||||||
}
|
|
||||||
if (audio->n_bit_depth) {
|
if (audio->n_bit_depth) {
|
||||||
track->a_bps = audio->bit_depth;
|
track->a_bps = audio->bit_depth;
|
||||||
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Bit depth: %u\n",
|
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] | + Bit depth: %u\n",
|
||||||
|
@ -1359,9 +1351,12 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
|
||||||
sh_a->gsh->demuxer_id = track->tnum;
|
sh_a->gsh->demuxer_id = track->tnum;
|
||||||
sh_a->gsh->title = talloc_strdup(sh_a, track->name);
|
sh_a->gsh->title = talloc_strdup(sh_a, track->name);
|
||||||
sh_a->gsh->default_track = track->default_track;
|
sh_a->gsh->default_track = track->default_track;
|
||||||
|
if (!track->a_osfreq)
|
||||||
|
track->a_osfreq = track->a_sfreq;
|
||||||
if (track->ms_compat) {
|
if (track->ms_compat) {
|
||||||
if (track->private_size < sizeof(*sh_a->wf))
|
if (track->private_size < sizeof(*sh_a->wf))
|
||||||
goto error;
|
goto error;
|
||||||
|
mp_msg(MSGT_DEMUX, MSGL_V, "[mkv] track with MS compat audio.\n");
|
||||||
WAVEFORMATEX *wf = (WAVEFORMATEX *) track->private_data;
|
WAVEFORMATEX *wf = (WAVEFORMATEX *) track->private_data;
|
||||||
sh_a->wf = calloc(1, track->private_size);
|
sh_a->wf = calloc(1, track->private_size);
|
||||||
sh_a->wf->wFormatTag = le2me_16(wf->wFormatTag);
|
sh_a->wf->wFormatTag = le2me_16(wf->wFormatTag);
|
||||||
|
@ -1373,8 +1368,8 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
|
||||||
sh_a->wf->cbSize = track->private_size - sizeof(*sh_a->wf);
|
sh_a->wf->cbSize = track->private_size - sizeof(*sh_a->wf);
|
||||||
memcpy(sh_a->wf + 1, wf + 1,
|
memcpy(sh_a->wf + 1, wf + 1,
|
||||||
track->private_size - sizeof(*sh_a->wf));
|
track->private_size - sizeof(*sh_a->wf));
|
||||||
if (track->a_sfreq == 0.0)
|
if (track->a_osfreq == 0.0)
|
||||||
track->a_sfreq = sh_a->wf->nSamplesPerSec;
|
track->a_osfreq = sh_a->wf->nSamplesPerSec;
|
||||||
if (track->a_channels == 0)
|
if (track->a_channels == 0)
|
||||||
track->a_channels = sh_a->wf->nChannels;
|
track->a_channels = sh_a->wf->nChannels;
|
||||||
if (track->a_bps == 0)
|
if (track->a_bps == 0)
|
||||||
|
@ -1402,9 +1397,8 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
|
||||||
sh_a->wf->wFormatTag = track->a_formattag;
|
sh_a->wf->wFormatTag = track->a_formattag;
|
||||||
mp_chmap_from_channels(&sh_a->channels, track->a_channels);
|
mp_chmap_from_channels(&sh_a->channels, track->a_channels);
|
||||||
sh_a->wf->nChannels = track->a_channels;
|
sh_a->wf->nChannels = track->a_channels;
|
||||||
sh_a->samplerate = (uint32_t) track->a_sfreq;
|
sh_a->samplerate = (uint32_t) track->a_osfreq;
|
||||||
sh_a->container_out_samplerate = track->a_osfreq;
|
sh_a->wf->nSamplesPerSec = (uint32_t) track->a_osfreq;
|
||||||
sh_a->wf->nSamplesPerSec = (uint32_t) track->a_sfreq;
|
|
||||||
if (track->a_bps == 0)
|
if (track->a_bps == 0)
|
||||||
sh_a->wf->wBitsPerSample = 16;
|
sh_a->wf->wBitsPerSample = 16;
|
||||||
else
|
else
|
||||||
|
@ -1438,7 +1432,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
|
||||||
} else {
|
} else {
|
||||||
/* Recreate the 'private data' */
|
/* Recreate the 'private data' */
|
||||||
/* which faad2 uses in its initialization */
|
/* which faad2 uses in its initialization */
|
||||||
srate_idx = aac_get_sample_rate_index(sh_a->samplerate);
|
srate_idx = aac_get_sample_rate_index(track->a_sfreq);
|
||||||
if (!strncmp(&track->codec_id[12], "MAIN", 4))
|
if (!strncmp(&track->codec_id[12], "MAIN", 4))
|
||||||
profile = 0;
|
profile = 0;
|
||||||
else if (!strncmp(&track->codec_id[12], "LC", 2))
|
else if (!strncmp(&track->codec_id[12], "LC", 2))
|
||||||
|
@ -1456,8 +1450,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
|
||||||
/* HE-AAC (aka SBR AAC) */
|
/* HE-AAC (aka SBR AAC) */
|
||||||
sh_a->codecdata_len = 5;
|
sh_a->codecdata_len = 5;
|
||||||
|
|
||||||
sh_a->samplerate *= 2;
|
sh_a->samplerate = sh_a->wf->nSamplesPerSec = track->a_osfreq;
|
||||||
sh_a->wf->nSamplesPerSec *= 2;
|
|
||||||
srate_idx = aac_get_sample_rate_index(sh_a->samplerate);
|
srate_idx = aac_get_sample_rate_index(sh_a->samplerate);
|
||||||
sh_a->codecdata[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
|
sh_a->codecdata[2] = AAC_SYNC_EXTENSION_TYPE >> 3;
|
||||||
sh_a->codecdata[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
|
sh_a->codecdata[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5;
|
||||||
|
@ -1587,7 +1580,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
|
||||||
AV_WL16(data + 4, 1);
|
AV_WL16(data + 4, 1);
|
||||||
AV_WL16(data + 6, sh_a->channels.num);
|
AV_WL16(data + 6, sh_a->channels.num);
|
||||||
AV_WL16(data + 8, sh_a->wf->wBitsPerSample);
|
AV_WL16(data + 8, sh_a->wf->wBitsPerSample);
|
||||||
AV_WL32(data + 10, sh_a->samplerate);
|
AV_WL32(data + 10, track->a_osfreq);
|
||||||
// Bogus: last frame won't be played.
|
// Bogus: last frame won't be played.
|
||||||
AV_WL32(data + 14, 0);
|
AV_WL32(data + 14, 0);
|
||||||
} else if (!track->ms_compat) {
|
} else if (!track->ms_compat) {
|
||||||
|
|
|
@ -90,7 +90,6 @@ typedef struct sh_audio {
|
||||||
// output format:
|
// output format:
|
||||||
int sample_format;
|
int sample_format;
|
||||||
int samplerate;
|
int samplerate;
|
||||||
int container_out_samplerate;
|
|
||||||
int samplesize;
|
int samplesize;
|
||||||
struct mp_chmap channels;
|
struct mp_chmap channels;
|
||||||
int i_bps; // == bitrate (compressed bytes/sec)
|
int i_bps; // == bitrate (compressed bytes/sec)
|
||||||
|
|
Loading…
Reference in New Issue