summaryrefslogtreecommitdiffstats
path: root/libmpdemux/demux_mkv.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@mplayer2.org>2011-08-20 05:54:27 +0300
committerUoti Urpala <uau@mplayer2.org>2011-08-20 05:54:27 +0300
commit46d90010ba1f78b68cdd6b2ee84a51fe46ee37a8 (patch)
tree2e9f4d591212d39f9913e5d7619eec7d742a5f0e /libmpdemux/demux_mkv.c
parent01fa34d53790ab9efd214bcc12f46b01c9d8057e (diff)
downloadmpv-46d90010ba1f78b68cdd6b2ee84a51fe46ee37a8.tar.bz2
mpv-46d90010ba1f78b68cdd6b2ee84a51fe46ee37a8.tar.xz
demux_mkv: clean up audio codec handling somewhat
Diffstat (limited to 'libmpdemux/demux_mkv.c')
-rw-r--r--libmpdemux/demux_mkv.c169
1 files changed, 78 insertions, 91 deletions
diff --git a/libmpdemux/demux_mkv.c b/libmpdemux/demux_mkv.c
index 9bb98f9f6f..8cccf24889 100644
--- a/libmpdemux/demux_mkv.c
+++ b/libmpdemux/demux_mkv.c
@@ -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,