1
0
mirror of https://github.com/mpv-player/mpv synced 2025-04-01 00:07:33 +00:00

demux_mkv: clean up audio codec handling somewhat

This commit is contained in:
Uoti Urpala 2011-08-20 05:54:27 +03:00
parent 01fa34d537
commit 46d90010ba

View File

@ -1301,6 +1301,39 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track,
return 0; 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, static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
int aid) 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->title = talloc_strdup(sh_a, track->name);
sh_a->default_track = track->default_track; sh_a->default_track = track->default_track;
sh_a->ds = demuxer->audio; sh_a->ds = demuxer->audio;
sh_a->wf = malloc(sizeof(*sh_a->wf)); if (track->ms_compat) {
if (track->ms_compat && (track->private_size >= sizeof(*sh_a->wf))) { if (track->private_size < sizeof(*sh_a->wf))
goto error;
WAVEFORMATEX *wf = (WAVEFORMATEX *) track->private_data; 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->wFormatTag = le2me_16(wf->wFormatTag);
sh_a->wf->nChannels = le2me_16(wf->nChannels); sh_a->wf->nChannels = le2me_16(wf->nChannels);
sh_a->wf->nSamplesPerSec = le2me_32(wf->nSamplesPerSec); 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_bps = sh_a->wf->wBitsPerSample;
track->a_formattag = sh_a->wf->wFormatTag; track->a_formattag = sh_a->wf->wFormatTag;
} else { } else {
memset(sh_a->wf, 0, sizeof(*sh_a->wf)); sh_a->wf = calloc(1, sizeof(*sh_a->wf));
if (!strcmp(track->codec_id, MKV_A_MP3) for (int i = 0; ; i++) {
|| !strcmp(track->codec_id, MKV_A_MP2)) struct mkv_audio_tag *t = mkv_audio_tags + i;
track->a_formattag = 0x0055; if (t->id == NULL)
else if (!strncmp(track->codec_id, MKV_A_AC3, strlen(MKV_A_AC3))) goto error;
track->a_formattag = 0x2000; if (t->prefix) {
else if (!strncmp(track->codec_id, MKV_A_EAC3, strlen(MKV_A_EAC3))) if (!bstr_startswith0(bstr(track->codec_id), t->id))
track->a_formattag = mmioFOURCC('E', 'A', 'C', '3'); continue;
else if (!strcmp(track->codec_id, MKV_A_DTS)) } else {
track->a_formattag = 0x2001; if (strcmp(track->codec_id, t->id))
else if (!strcmp(track->codec_id, MKV_A_PCM) continue;
|| !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;
} }
track->a_formattag = mmioFOURCC('f', 'L', 'a', 'C'); track->a_formattag = t->formattag;
} else if (track->private_size >= RAPROPERTIES4_SIZE) { break;
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;
} }
} }
@ -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->nAvgBytesPerSec = 16000;
sh_a->wf->nBlockAlign = 1024; sh_a->wf->nBlockAlign = 1024;
if (!strcmp(track->codec_id, MKV_A_AAC) if (!strcmp(track->codec_id, MKV_A_AAC) && track->private_data) {
&& (NULL != track->private_data)) {
sh_a->codecdata = malloc(track->private_size); sh_a->codecdata = malloc(track->private_size);
memcpy(sh_a->codecdata, track->private_data, track->private_size); memcpy(sh_a->codecdata, track->private_data, track->private_size);
sh_a->codecdata_len = 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; sh_a->codecdata_len = 2;
track->default_duration = 1024.0 / sh_a->samplerate; track->default_duration = 1024.0 / sh_a->samplerate;
} }
} else if (track->a_formattag == mmioFOURCC('v', 'r', 'b', 's')) { /* VORBIS */ } else if (track->a_formattag == mmioFOURCC('v', 'r', 'b', 's')) {
sh_a->wf->cbSize = track->private_size; /* VORBIS */
sh_a->wf = realloc(sh_a->wf, sizeof(*sh_a->wf) + sh_a->wf->cbSize); if (track->private_size == 0 || track->ms_compat && !sh_a->wf->cbSize)
memcpy((unsigned char *) (sh_a->wf + 1), track->private_data, goto error;
sh_a->wf->cbSize); if (!track->ms_compat) {
} else if (track->private_size >= RAPROPERTIES4_SIZE sh_a->wf->cbSize = track->private_size;
&& !strncmp(track->codec_id, MKV_A_REALATRC, 7)) { 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 */ /* Common initialization for all RealAudio codecs */
unsigned char *src = track->private_data; unsigned char *src = track->private_data;
int codecdata_length, version; 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'): case mmioFOURCC('a', 't', 'r', 'c'):
sh_a->wf->nAvgBytesPerSec = atrc_fl2bps[flavor]; sh_a->wf->nAvgBytesPerSec = atrc_fl2bps[flavor];
sh_a->wf->nBlockAlign = track->sub_packet_size; sh_a->wf->nBlockAlign = track->sub_packet_size;
track->audio_buf = goto audiobuf;
malloc(track->sub_packet_h * track->audiopk_size);
track->audio_timestamp =
malloc(track->sub_packet_h * sizeof(double));
break;
case mmioFOURCC('c', 'o', 'o', 'k'): case mmioFOURCC('c', 'o', 'o', 'k'):
sh_a->wf->nAvgBytesPerSec = cook_fl2bps[flavor]; sh_a->wf->nAvgBytesPerSec = cook_fl2bps[flavor];
sh_a->wf->nBlockAlign = track->sub_packet_size; sh_a->wf->nBlockAlign = track->sub_packet_size;
track->audio_buf = goto audiobuf;
malloc(track->sub_packet_h * track->audiopk_size);
track->audio_timestamp =
malloc(track->sub_packet_h * sizeof(double));
break;
case mmioFOURCC('s', 'i', 'p', 'r'): case mmioFOURCC('s', 'i', 'p', 'r'):
sh_a->wf->nAvgBytesPerSec = sipr_fl2bps[flavor]; sh_a->wf->nAvgBytesPerSec = sipr_fl2bps[flavor];
sh_a->wf->nBlockAlign = track->coded_framesize; sh_a->wf->nBlockAlign = track->coded_framesize;
track->audio_buf = goto audiobuf;
malloc(track->sub_packet_h * track->audiopk_size);
track->audio_timestamp =
malloc(track->sub_packet_h * sizeof(double));
break;
case mmioFOURCC('2', '8', '_', '8'): case mmioFOURCC('2', '8', '_', '8'):
sh_a->wf->nAvgBytesPerSec = 3600; sh_a->wf->nAvgBytesPerSec = 3600;
sh_a->wf->nBlockAlign = track->coded_framesize; sh_a->wf->nBlockAlign = track->coded_framesize;
audiobuf:
track->audio_buf = track->audio_buf =
malloc(track->sub_packet_h * track->audiopk_size); malloc(track->sub_packet_h * track->audiopk_size);
track->audio_timestamp = track->audio_timestamp =
@ -1559,7 +1541,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
free(sh_a->wf); free(sh_a->wf);
sh_a->wf = NULL; sh_a->wf = NULL;
if (track->a_formattag == mmioFOURCC('f', 'L', 'a', 'C')) { if (!track->ms_compat) {
ptr = track->private_data; ptr = track->private_data;
size = track->private_size; size = track->private_size;
} else { } else {
@ -1578,13 +1560,18 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track,
memcpy(sh_a->codecdata, ptr, size); 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->a_formattag == mmioFOURCC('W', 'V', 'P', 'K') || track->a_formattag == mmioFOURCC('T', 'R', 'H', 'D')) { /* do nothing, still works */
} else if (!track->ms_compat } else if (!track->ms_compat) {
|| (track->private_size < sizeof(*sh_a->wf))) { goto error;
free_sh_audio(demuxer, track->id);
return 1;
} }
return 0; 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, static int demux_mkv_open_sub(demuxer_t *demuxer, mkv_track_t *track,