mirror of
https://github.com/mpv-player/mpv
synced 2025-03-30 07:18:17 +00:00
demux_mkv: clean up audio codec handling somewhat
This commit is contained in:
parent
01fa34d537
commit
46d90010ba
@ -1301,6 +1301,39 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mkv_audio_tag {
|
||||
char *id; bool prefix; uint32_t formattag;
|
||||
} mkv_audio_tags[] = {
|
||||
{ MKV_A_MP2, 0, 0x0055 },
|
||||
{ MKV_A_MP3, 0, 0x0055 },
|
||||
{ MKV_A_AC3, 1, 0x2000 },
|
||||
{ MKV_A_EAC3, 1, mmioFOURCC('E', 'A', 'C', '3') },
|
||||
{ MKV_A_DTS, 0, 0x2001 },
|
||||
{ MKV_A_PCM, 0, 0x0001 },
|
||||
{ MKV_A_PCM_BE, 0, 0x0001 },
|
||||
{ MKV_A_AAC_2MAIN, 0, mmioFOURCC('M', 'P', '4', 'A') },
|
||||
{ MKV_A_AAC_2LC, 1, mmioFOURCC('M', 'P', '4', 'A') },
|
||||
{ MKV_A_AAC_2SSR, 0, mmioFOURCC('M', 'P', '4', 'A') },
|
||||
{ MKV_A_AAC_4MAIN, 0, mmioFOURCC('M', 'P', '4', 'A') },
|
||||
{ MKV_A_AAC_4LC, 1, mmioFOURCC('M', 'P', '4', 'A') },
|
||||
{ MKV_A_AAC_4SSR, 0, mmioFOURCC('M', 'P', '4', 'A') },
|
||||
{ MKV_A_AAC_4LTP, 0, mmioFOURCC('M', 'P', '4', 'A') },
|
||||
{ MKV_A_AAC, 0, mmioFOURCC('M', 'P', '4', 'A') },
|
||||
{ MKV_A_VORBIS, 0, mmioFOURCC('v', 'r', 'b', 's') },
|
||||
{ MKV_A_QDMC, 0, mmioFOURCC('Q', 'D', 'M', 'C') },
|
||||
{ MKV_A_QDMC2, 0, mmioFOURCC('Q', 'D', 'M', '2') },
|
||||
{ MKV_A_WAVPACK, 0, mmioFOURCC('W', 'V', 'P', 'K') },
|
||||
{ MKV_A_TRUEHD, 0, mmioFOURCC('T', 'R', 'H', 'D') },
|
||||
{ MKV_A_FLAC, 0, mmioFOURCC('f', 'L', 'a', 'C') },
|
||||
{ MKV_A_REAL28, 0, mmioFOURCC('2', '8', '_', '8') },
|
||||
{ MKV_A_REALATRC, 0, mmioFOURCC('a', 't', 'r', 'c') },
|
||||
{ MKV_A_REALCOOK, 0, mmioFOURCC('c', 'o', 'o', 'k') },
|
||||
{ MKV_A_REALDNET, 0, mmioFOURCC('d', 'n', 'e', 't') },
|
||||
{ MKV_A_REALSIPR, 0, mmioFOURCC('s', 'i', 'p', 'r') },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
||||
static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
||||
int aid)
|
||||
{
|
||||
@ -1313,10 +1346,11 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
||||
sh_a->title = talloc_strdup(sh_a, track->name);
|
||||
sh_a->default_track = track->default_track;
|
||||
sh_a->ds = demuxer->audio;
|
||||
sh_a->wf = malloc(sizeof(*sh_a->wf));
|
||||
if (track->ms_compat && (track->private_size >= sizeof(*sh_a->wf))) {
|
||||
if (track->ms_compat) {
|
||||
if (track->private_size < sizeof(*sh_a->wf))
|
||||
goto error;
|
||||
WAVEFORMATEX *wf = (WAVEFORMATEX *) track->private_data;
|
||||
sh_a->wf = realloc(sh_a->wf, track->private_size);
|
||||
sh_a->wf = calloc(1, track->private_size);
|
||||
sh_a->wf->wFormatTag = le2me_16(wf->wFormatTag);
|
||||
sh_a->wf->nChannels = le2me_16(wf->nChannels);
|
||||
sh_a->wf->nSamplesPerSec = le2me_32(wf->nSamplesPerSec);
|
||||
@ -1334,66 +1368,20 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
||||
track->a_bps = sh_a->wf->wBitsPerSample;
|
||||
track->a_formattag = sh_a->wf->wFormatTag;
|
||||
} else {
|
||||
memset(sh_a->wf, 0, sizeof(*sh_a->wf));
|
||||
if (!strcmp(track->codec_id, MKV_A_MP3)
|
||||
|| !strcmp(track->codec_id, MKV_A_MP2))
|
||||
track->a_formattag = 0x0055;
|
||||
else if (!strncmp(track->codec_id, MKV_A_AC3, strlen(MKV_A_AC3)))
|
||||
track->a_formattag = 0x2000;
|
||||
else if (!strncmp(track->codec_id, MKV_A_EAC3, strlen(MKV_A_EAC3)))
|
||||
track->a_formattag = mmioFOURCC('E', 'A', 'C', '3');
|
||||
else if (!strcmp(track->codec_id, MKV_A_DTS))
|
||||
track->a_formattag = 0x2001;
|
||||
else if (!strcmp(track->codec_id, MKV_A_PCM)
|
||||
|| !strcmp(track->codec_id, MKV_A_PCM_BE))
|
||||
track->a_formattag = 0x0001;
|
||||
else if (!strcmp(track->codec_id, MKV_A_AAC_2MAIN)
|
||||
|| !strncmp(track->codec_id, MKV_A_AAC_2LC,
|
||||
strlen(MKV_A_AAC_2LC))
|
||||
|| !strcmp(track->codec_id, MKV_A_AAC_2SSR)
|
||||
|| !strcmp(track->codec_id, MKV_A_AAC_4MAIN)
|
||||
|| !strncmp(track->codec_id, MKV_A_AAC_4LC,
|
||||
strlen(MKV_A_AAC_4LC))
|
||||
|| !strcmp(track->codec_id, MKV_A_AAC_4SSR)
|
||||
|| !strcmp(track->codec_id, MKV_A_AAC_4LTP)
|
||||
|| !strcmp(track->codec_id, MKV_A_AAC))
|
||||
track->a_formattag = mmioFOURCC('M', 'P', '4', 'A');
|
||||
else if (!strcmp(track->codec_id, MKV_A_VORBIS)) {
|
||||
if (track->private_data == NULL)
|
||||
return 1;
|
||||
track->a_formattag = mmioFOURCC('v', 'r', 'b', 's');
|
||||
} else if (!strcmp(track->codec_id, MKV_A_QDMC))
|
||||
track->a_formattag = mmioFOURCC('Q', 'D', 'M', 'C');
|
||||
else if (!strcmp(track->codec_id, MKV_A_QDMC2))
|
||||
track->a_formattag = mmioFOURCC('Q', 'D', 'M', '2');
|
||||
else if (!strcmp(track->codec_id, MKV_A_WAVPACK))
|
||||
track->a_formattag = mmioFOURCC('W', 'V', 'P', 'K');
|
||||
else if (!strcmp(track->codec_id, MKV_A_TRUEHD))
|
||||
track->a_formattag = mmioFOURCC('T', 'R', 'H', 'D');
|
||||
else if (!strcmp(track->codec_id, MKV_A_FLAC)) {
|
||||
if (track->private_data == NULL || track->private_size == 0) {
|
||||
mp_tmsg(MSGT_DEMUX, MSGL_WARN,
|
||||
"[mkv] FLAC track does not contain valid headers.\n");
|
||||
return 1;
|
||||
sh_a->wf = calloc(1, sizeof(*sh_a->wf));
|
||||
for (int i = 0; ; i++) {
|
||||
struct mkv_audio_tag *t = mkv_audio_tags + i;
|
||||
if (t->id == NULL)
|
||||
goto error;
|
||||
if (t->prefix) {
|
||||
if (!bstr_startswith0(bstr(track->codec_id), t->id))
|
||||
continue;
|
||||
} else {
|
||||
if (strcmp(track->codec_id, t->id))
|
||||
continue;
|
||||
}
|
||||
track->a_formattag = mmioFOURCC('f', 'L', 'a', 'C');
|
||||
} else if (track->private_size >= RAPROPERTIES4_SIZE) {
|
||||
if (!strcmp(track->codec_id, MKV_A_REAL28))
|
||||
track->a_formattag = mmioFOURCC('2', '8', '_', '8');
|
||||
else if (!strcmp(track->codec_id, MKV_A_REALATRC))
|
||||
track->a_formattag = mmioFOURCC('a', 't', 'r', 'c');
|
||||
else if (!strcmp(track->codec_id, MKV_A_REALCOOK))
|
||||
track->a_formattag = mmioFOURCC('c', 'o', 'o', 'k');
|
||||
else if (!strcmp(track->codec_id, MKV_A_REALDNET))
|
||||
track->a_formattag = mmioFOURCC('d', 'n', 'e', 't');
|
||||
else if (!strcmp(track->codec_id, MKV_A_REALSIPR))
|
||||
track->a_formattag = mmioFOURCC('s', 'i', 'p', 'r');
|
||||
} else {
|
||||
mp_tmsg(MSGT_DEMUX, MSGL_WARN, "[mkv] Unknown/unsupported audio "
|
||||
"codec ID '%s' for track %u or missing/faulty\n[mkv] "
|
||||
"private codec data.\n", track->codec_id, track->tnum);
|
||||
free_sh_audio(demuxer, track->id);
|
||||
return 1;
|
||||
track->a_formattag = t->formattag;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1441,8 +1429,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
||||
sh_a->wf->nAvgBytesPerSec = 16000;
|
||||
sh_a->wf->nBlockAlign = 1024;
|
||||
|
||||
if (!strcmp(track->codec_id, MKV_A_AAC)
|
||||
&& (NULL != track->private_data)) {
|
||||
if (!strcmp(track->codec_id, MKV_A_AAC) && track->private_data) {
|
||||
sh_a->codecdata = malloc(track->private_size);
|
||||
memcpy(sh_a->codecdata, track->private_data, track->private_size);
|
||||
sh_a->codecdata_len = track->private_size;
|
||||
@ -1480,13 +1467,19 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
||||
sh_a->codecdata_len = 2;
|
||||
track->default_duration = 1024.0 / sh_a->samplerate;
|
||||
}
|
||||
} else if (track->a_formattag == mmioFOURCC('v', 'r', 'b', 's')) { /* VORBIS */
|
||||
sh_a->wf->cbSize = track->private_size;
|
||||
sh_a->wf = realloc(sh_a->wf, sizeof(*sh_a->wf) + sh_a->wf->cbSize);
|
||||
memcpy((unsigned char *) (sh_a->wf + 1), track->private_data,
|
||||
sh_a->wf->cbSize);
|
||||
} else if (track->private_size >= RAPROPERTIES4_SIZE
|
||||
&& !strncmp(track->codec_id, MKV_A_REALATRC, 7)) {
|
||||
} else if (track->a_formattag == mmioFOURCC('v', 'r', 'b', 's')) {
|
||||
/* VORBIS */
|
||||
if (track->private_size == 0 || track->ms_compat && !sh_a->wf->cbSize)
|
||||
goto error;
|
||||
if (!track->ms_compat) {
|
||||
sh_a->wf->cbSize = track->private_size;
|
||||
sh_a->wf = realloc(sh_a->wf, sizeof(*sh_a->wf) + sh_a->wf->cbSize);
|
||||
memcpy((unsigned char *) (sh_a->wf + 1), track->private_data,
|
||||
sh_a->wf->cbSize);
|
||||
}
|
||||
} else if (!strncmp(track->codec_id, MKV_A_REALATRC, 7)) {
|
||||
if (track->private_size < RAPROPERTIES4_SIZE)
|
||||
goto error;
|
||||
/* Common initialization for all RealAudio codecs */
|
||||
unsigned char *src = track->private_data;
|
||||
int codecdata_length, version;
|
||||
@ -1520,30 +1513,19 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
||||
case mmioFOURCC('a', 't', 'r', 'c'):
|
||||
sh_a->wf->nAvgBytesPerSec = atrc_fl2bps[flavor];
|
||||
sh_a->wf->nBlockAlign = track->sub_packet_size;
|
||||
track->audio_buf =
|
||||
malloc(track->sub_packet_h * track->audiopk_size);
|
||||
track->audio_timestamp =
|
||||
malloc(track->sub_packet_h * sizeof(double));
|
||||
break;
|
||||
goto audiobuf;
|
||||
case mmioFOURCC('c', 'o', 'o', 'k'):
|
||||
sh_a->wf->nAvgBytesPerSec = cook_fl2bps[flavor];
|
||||
sh_a->wf->nBlockAlign = track->sub_packet_size;
|
||||
track->audio_buf =
|
||||
malloc(track->sub_packet_h * track->audiopk_size);
|
||||
track->audio_timestamp =
|
||||
malloc(track->sub_packet_h * sizeof(double));
|
||||
break;
|
||||
goto audiobuf;
|
||||
case mmioFOURCC('s', 'i', 'p', 'r'):
|
||||
sh_a->wf->nAvgBytesPerSec = sipr_fl2bps[flavor];
|
||||
sh_a->wf->nBlockAlign = track->coded_framesize;
|
||||
track->audio_buf =
|
||||
malloc(track->sub_packet_h * track->audiopk_size);
|
||||
track->audio_timestamp =
|
||||
malloc(track->sub_packet_h * sizeof(double));
|
||||
break;
|
||||
goto audiobuf;
|
||||
case mmioFOURCC('2', '8', '_', '8'):
|
||||
sh_a->wf->nAvgBytesPerSec = 3600;
|
||||
sh_a->wf->nBlockAlign = track->coded_framesize;
|
||||
audiobuf:
|
||||
track->audio_buf =
|
||||
malloc(track->sub_packet_h * track->audiopk_size);
|
||||
track->audio_timestamp =
|
||||
@ -1559,7 +1541,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
||||
free(sh_a->wf);
|
||||
sh_a->wf = NULL;
|
||||
|
||||
if (track->a_formattag == mmioFOURCC('f', 'L', 'a', 'C')) {
|
||||
if (!track->ms_compat) {
|
||||
ptr = track->private_data;
|
||||
size = track->private_size;
|
||||
} else {
|
||||
@ -1578,13 +1560,18 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
|
||||
memcpy(sh_a->codecdata, ptr, size);
|
||||
}
|
||||
} else if (track->a_formattag == mmioFOURCC('W', 'V', 'P', 'K') || track->a_formattag == mmioFOURCC('T', 'R', 'H', 'D')) { /* do nothing, still works */
|
||||
} else if (!track->ms_compat
|
||||
|| (track->private_size < sizeof(*sh_a->wf))) {
|
||||
free_sh_audio(demuxer, track->id);
|
||||
return 1;
|
||||
} else if (!track->ms_compat) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
mp_tmsg(MSGT_DEMUX, MSGL_WARN, "[mkv] Unknown/unsupported audio "
|
||||
"codec ID '%s' for track %u or missing/faulty\n[mkv] "
|
||||
"private codec data.\n", track->codec_id, track->tnum);
|
||||
free_sh_audio(demuxer, track->id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track,
|
||||
|
Loading…
Reference in New Issue
Block a user