summaryrefslogtreecommitdiffstats
path: root/demux/demux_mkv.c
diff options
context:
space:
mode:
Diffstat (limited to 'demux/demux_mkv.c')
-rw-r--r--demux/demux_mkv.c165
1 files changed, 73 insertions, 92 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 9432be8567..e4c1e94023 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -106,7 +106,6 @@ typedef struct mkv_track {
uint32_t colorspace;
int stereo_mode;
- uint32_t a_formattag;
uint32_t a_channels, a_bps;
float a_sfreq;
float a_osfreq;
@@ -1333,39 +1332,35 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track)
}
static const struct mkv_audio_tag {
- char *id; bool prefix; uint32_t formattag;
+ const char *id;
+ const char *codec;
+ bool prefix;
} mkv_audio_tags[] = {
- { MKV_A_MP2, 0, 0x0055 },
- { MKV_A_MP3, 0, 0x0055 },
- { MKV_A_AC3, 1, 0x2000 },
- { MKV_A_EAC3, 1, MP_FOURCC('E', 'A', 'C', '3') },
- { MKV_A_DTS, 0, 0x2001 },
- { MKV_A_PCM, 0, 0x0001 },
- { MKV_A_PCM_BE, 0, 0x0001 },
- { MKV_A_PCM_FLT, 0, 0x0003 },
- { MKV_A_AAC_2MAIN, 0, MP_FOURCC('M', 'P', '4', 'A') },
- { MKV_A_AAC_2LC, 1, MP_FOURCC('M', 'P', '4', 'A') },
- { MKV_A_AAC_2SSR, 0, MP_FOURCC('M', 'P', '4', 'A') },
- { MKV_A_AAC_4MAIN, 0, MP_FOURCC('M', 'P', '4', 'A') },
- { MKV_A_AAC_4LC, 1, MP_FOURCC('M', 'P', '4', 'A') },
- { MKV_A_AAC_4SSR, 0, MP_FOURCC('M', 'P', '4', 'A') },
- { MKV_A_AAC_4LTP, 0, MP_FOURCC('M', 'P', '4', 'A') },
- { MKV_A_AAC, 0, MP_FOURCC('M', 'P', '4', 'A') },
- { MKV_A_VORBIS, 0, MP_FOURCC('v', 'r', 'b', 's') },
- { MKV_A_OPUS, 0, MP_FOURCC('O', 'p', 'u', 's') },
- { MKV_A_OPUS_EXP, 0, MP_FOURCC('O', 'p', 'u', 's') },
- { MKV_A_QDMC, 0, MP_FOURCC('Q', 'D', 'M', 'C') },
- { MKV_A_QDMC2, 0, MP_FOURCC('Q', 'D', 'M', '2') },
- { MKV_A_WAVPACK, 0, MP_FOURCC('W', 'V', 'P', 'K') },
- { MKV_A_TRUEHD, 0, MP_FOURCC('T', 'R', 'H', 'D') },
- { MKV_A_FLAC, 0, MP_FOURCC('f', 'L', 'a', 'C') },
- { MKV_A_ALAC, 0, MP_FOURCC('a', 'L', 'a', 'C') },
- { MKV_A_REAL28, 0, MP_FOURCC('2', '8', '_', '8') },
- { MKV_A_REALATRC, 0, MP_FOURCC('a', 't', 'r', 'c') },
- { MKV_A_REALCOOK, 0, MP_FOURCC('c', 'o', 'o', 'k') },
- { MKV_A_REALDNET, 0, MP_FOURCC('d', 'n', 'e', 't') },
- { MKV_A_REALSIPR, 0, MP_FOURCC('s', 'i', 'p', 'r') },
- { MKV_A_TTA1, 0, MP_FOURCC('T', 'T', 'A', '1') },
+ { MKV_A_MP2, "mp3" },
+ { MKV_A_MP3, "mp3" },
+ { MKV_A_AC3, "ac3", .prefix = true },
+ { MKV_A_EAC3, "eac3", .prefix = true },
+ { MKV_A_DTS, "dts" },
+ { MKV_A_PCM, "pcm" }, // not a real lavc codec name
+ { MKV_A_PCM_BE, "pcm" },
+ { MKV_A_PCM_FLT, "pcm-flt" }, // also not a real lavc codec name
+ { MKV_A_AAC, "aac" },
+ { "A_AAC/", "aac", .prefix = true },
+ { MKV_A_VORBIS, "vorbis" },
+ { MKV_A_OPUS, "opus" },
+ { MKV_A_OPUS_EXP, "opus" },
+ { MKV_A_QDMC, "qdmc" },
+ { MKV_A_QDMC2, "qdm2" },
+ { MKV_A_WAVPACK, "wavpack" },
+ { MKV_A_TRUEHD, "truehd" },
+ { MKV_A_FLAC, "flac" },
+ { MKV_A_ALAC, "alac" },
+ { MKV_A_REAL28, "ra_288" },
+ { MKV_A_REALATRC, "atrac3" },
+ { MKV_A_REALCOOK, "cook" },
+ { MKV_A_REALDNET, "ac3" },
+ { MKV_A_REALSIPR, "sipr" },
+ { MKV_A_TTA1, "tta" },
{ NULL },
};
@@ -1390,6 +1385,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
sh->default_track = track->default_track;
if (!track->a_osfreq)
track->a_osfreq = track->a_sfreq;
+ sh_a->bits_per_coded_sample = track->a_bps ? track->a_bps : 16;
if (!strcmp(track->codec_id, MKV_A_ACM)) { /* AVI compatibility mode */
// The private_data contains a WAVEFORMATEX struct
@@ -1397,7 +1393,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
goto error;
MP_VERBOSE(demuxer, "track with MS compat audio.\n");
unsigned char *h = track->private_data;
- track->a_formattag = AV_RL16(h + 0); // wFormatTag
+ sh->format = AV_RL16(h + 0); // wFormatTag
if (track->a_channels == 0)
track->a_channels = AV_RL16(h + 2); // nChannels
if (track->a_osfreq == 0.0)
@@ -1408,6 +1404,8 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
track->a_bps = AV_RL16(h + 14); // wBitsPerSample
extradata = track->private_data + 18;
extradata_len = track->private_size - 18;
+ sh_a->bits_per_coded_sample = track->a_bps;
+ mp_set_codec_from_tag(sh);
} else {
for (int i = 0; ; i++) {
const struct mkv_audio_tag *t = mkv_audio_tags + i;
@@ -1420,39 +1418,36 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
if (strcmp(track->codec_id, t->id))
continue;
}
- track->a_formattag = t->formattag;
+ sh->codec = t->codec;
break;
}
}
- sh->format = track->a_formattag;
+ if (!sh->codec)
+ goto error;
+
mp_chmap_set_unknown(&sh_a->channels, track->a_channels);
sh_a->samplerate = (uint32_t) track->a_osfreq;
- sh_a->bits_per_coded_sample = track->a_bps ? track->a_bps : 16;
- if (track->a_formattag == 0x0055) { /* MP3 || MP2 */
+
+ const char *codec = sh->codec;
+ if (!strcmp(codec, "mp3")) {
sh_a->bitrate = 16000 * 8;
sh_a->block_align = 1152;
track->parse = true;
- } else if ((track->a_formattag == 0x2000) /* AC3 */
- || track->a_formattag == MP_FOURCC('E', 'A', 'C', '3')
- || (track->a_formattag == 0x2001)) { /* DTS */
- sh_a->bits_per_coded_sample = 0;
- sh_a->bitrate = 0;
- sh_a->block_align = 0;
- } else if (track->a_formattag == 0x0001) { /* PCM || PCM_BE */
- if (!strcmp(track->codec_id, MKV_A_PCM_BE))
- sh->format = MP_FOURCC('t', 'w', 'o', 's');
- } else if (track->a_formattag == 0x0003) { /* PCM_FLT */
- /* ok */
- } else if (!strcmp(track->codec_id, MKV_A_QDMC)
- || !strcmp(track->codec_id, MKV_A_QDMC2)) {
+ } else if (!strcmp(codec, "pcm")) {
+ bool is_be = !strcmp(track->codec_id, MKV_A_PCM_BE);
+ bool sign = sh_a->bits_per_coded_sample > 8;
+ mp_set_pcm_codec(sh, sign, false, sh_a->bits_per_coded_sample, is_be);
+ } else if (!strcmp(codec, "pcm-flt")) {
+ sh->codec = sh_a->bits_per_coded_sample == 64 ? "pcm_f64le" : "pcm_f32le";
+ } else if (!strcmp(codec, "qdmc") || !strcmp(codec, "qdm2")) {
sh_a->bitrate = 16000 * 8;
sh_a->block_align = 1486;
- } else if (track->a_formattag == MP_FOURCC('M', 'P', '4', 'A')) {
+ } else if (!strcmp(codec, "aac")) {
sh_a->bitrate = 16000 * 8;
sh_a->block_align = 1024;
- if (strcmp(track->codec_id, MKV_A_AAC)) {
+ if (!strncmp(track->codec_id, "A_AAC/", 6)) {
/* Recreate the 'private data' */
int srate_idx = aac_get_sample_rate_index(track->a_sfreq);
const char *tail = "";
@@ -1484,12 +1479,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
track->default_duration = 1024.0 / sh_a->samplerate;
}
}
- } else if (track->a_formattag == MP_FOURCC('v', 'r', 'b', 's')) {
- /* VORBIS */
- } else if (!strcmp(track->codec_id, MKV_A_OPUS)
- || !strcmp(track->codec_id, MKV_A_OPUS_EXP)) {
- sh->format = MP_FOURCC('O', 'p', 'u', 's');
- } else if (!strncmp(track->codec_id, MKV_A_REALATRC, 7)) {
+ } else if (!strncmp(track->codec_id, "A_REAL/", 7)) {
if (track->private_size < RAPROPERTIES4_SIZE)
goto error;
/* Common initialization for all RealAudio codecs */
@@ -1527,29 +1517,24 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
extradata_len = codecdata_length;
extradata = src;
- switch (track->a_formattag) {
- case MP_FOURCC('a', 't', 'r', 'c'):
+ if (!strcmp(codec, "atrac3")) {
if (flavor >= MP_ARRAY_SIZE(atrc_fl2bps))
goto error;
sh_a->bitrate = atrc_fl2bps[flavor] * 8;
sh_a->block_align = track->sub_packet_size;
- break;
- case MP_FOURCC('c', 'o', 'o', 'k'):
+ } else if (!strcmp(codec, "cook")) {
if (flavor >= MP_ARRAY_SIZE(cook_fl2bps))
goto error;
sh_a->bitrate = cook_fl2bps[flavor] * 8;
sh_a->block_align = track->sub_packet_size;
- break;
- case MP_FOURCC('s', 'i', 'p', 'r'):
+ } else if (!strcmp(codec, "sipr")) {
if (flavor >= MP_ARRAY_SIZE(sipr_fl2bps))
goto error;
sh_a->bitrate = sipr_fl2bps[flavor] * 8;
sh_a->block_align = track->coded_framesize;
- break;
- case MP_FOURCC('2', '8', '_', '8'):
+ } else if (!strcmp(codec, "ra_288")) {
sh_a->bitrate = 3600 * 8;
sh_a->block_align = track->coded_framesize;
- break;
}
track->audio_buf =
@@ -1557,8 +1542,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
track->audio_timestamp =
talloc_array(track, double, track->sub_packet_h);
- } else if (!strcmp(track->codec_id, MKV_A_FLAC)
- || (track->a_formattag == 0xf1ac)) {
+ } else if (!strcmp(codec, "flac")) {
sh_a->bits_per_coded_sample = 0;
sh_a->bitrate = 0;
sh_a->block_align = 0;
@@ -1575,7 +1559,7 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
sh_a->codecdata_len = size;
memcpy(sh_a->codecdata, ptr, size);
}
- } else if (!strcmp(track->codec_id, MKV_A_ALAC)) {
+ } else if (!strcmp(codec, "alac")) {
if (track->private_size) {
sh_a->codecdata_len = track->private_size + 12;
sh_a->codecdata = talloc_size(sh_a, sh_a->codecdata_len);
@@ -1585,11 +1569,9 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
AV_WB32(data + 8, 0);
memcpy(data + 12, track->private_data, track->private_size);
}
- } else if (track->a_formattag == MP_FOURCC('W', 'V', 'P', 'K')) {
- /* ok */
- } else if (track->a_formattag == MP_FOURCC('T', 'R', 'H', 'D')) {
+ } else if (!strcmp(codec, "truehd")) {
track->parse = true;
- } else if (track->a_formattag == MP_FOURCC('T', 'T', 'A', '1')) {
+ } else if (!strcmp(codec, "tta")) {
sh_a->codecdata_len = 30;
sh_a->codecdata = talloc_zero_size(sh_a, sh_a->codecdata_len);
if (!sh_a->codecdata)
@@ -1602,18 +1584,21 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
AV_WL32(data + 10, track->a_osfreq);
// Bogus: last frame won't be played.
AV_WL32(data + 14, 0);
- } else if (!track->a_formattag) {
- goto error;
+ } else if (!strcmp(codec, "ac3") ||
+ !strcmp(codec, "eac3") ||
+ !strcmp(codec, "dts"))
+ {
+ sh_a->bits_per_coded_sample = 0;
+ sh_a->bitrate = 0;
+ sh_a->block_align = 0;
}
// Some files have broken default DefaultDuration set, which will lead to
// audio packets with incorrect timestamps. This follows FFmpeg commit
// 6158a3b, sample see FFmpeg ticket 2508.
- if (sh_a->samplerate == 8000 && strcmp(track->codec_id, MKV_A_AC3) == 0)
+ if (sh_a->samplerate == 8000 && strcmp(codec, "ac3") == 0)
track->default_duration = 0;
- mp_set_codec_from_tag(sh);
-
if (!sh_a->codecdata && extradata_len) {
sh_a->codecdata = talloc_memdup(sh_a, extradata, extradata_len);
sh_a->codecdata_len = extradata_len;
@@ -1964,11 +1949,11 @@ static bool handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
// track->audio_buf allocation size
size_t audiobuf_size = sph * w;
- if (!track->audio_buf || !track->audio_timestamp)
+ if (!track->audio_buf || !track->audio_timestamp || !track->stream)
return false;
- switch (track->a_formattag) {
- case MP_FOURCC('2', '8', '_', '8'):
+ const char *codec = track->stream->codec ? track->stream->codec : "";
+ if (!strcmp(codec, "ra_288")) {
for (int x = 0; x < sph / 2; x++) {
uint64_t dst_offset = x * 2 * w + spc * (uint64_t)cfs;
if (dst_offset + cfs > audiobuf_size)
@@ -1978,9 +1963,7 @@ static bool handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
goto error;
memcpy(track->audio_buf + dst_offset, buffer + src_offset, cfs);
}
- break;
- case MP_FOURCC('c', 'o', 'o', 'k'):
- case MP_FOURCC('a', 't', 'r', 'c'):
+ } else if (!strcmp(codec, "cook") || !strcmp(codec, "atrac3")) {
for (int x = 0; x < w / sps; x++) {
uint32_t dst_offset =
sps * (sph * x + ((sph + 1) / 2) * (spc & 1) + (spc >> 1));
@@ -1991,8 +1974,7 @@ static bool handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
goto error;
memcpy(track->audio_buf + dst_offset, buffer + src_offset, sps);
}
- break;
- case MP_FOURCC('s', 'i', 'p', 'r'):
+ } else if (!strcmp(codec, "sipr")) {
if (spc * w + w > audiobuf_size || w > size)
goto error;
memcpy(track->audio_buf + spc * w, buffer, w);
@@ -2018,8 +2000,7 @@ static bool handle_realaudio(demuxer_t *demuxer, mkv_track_t *track,
}
}
}
- break;
- default:
+ } else {
// Not a codec that requires reordering
return false;
}
@@ -2164,7 +2145,7 @@ static void mkv_parse_and_add_packet(demuxer_t *demuxer, mkv_track_t *track,
if (stream->type == STREAM_AUDIO && handle_realaudio(demuxer, track, dp))
return;
- if (track->a_formattag == MP_FOURCC('W', 'V', 'P', 'K')) {
+ if (stream->codec && strcmp(stream->codec, "wavpack") == 0) {
int size = dp->len;
uint8_t *parsed;
if (libav_parse_wavpack(track, dp->buffer, &parsed, &size) >= 0) {
@@ -2178,7 +2159,7 @@ static void mkv_parse_and_add_packet(demuxer_t *demuxer, mkv_track_t *track,
}
}
- if (track->codec_id && strcmp(track->codec_id, MKV_V_PRORES) == 0) {
+ if (stream->codec && strcmp(stream->codec, "prores") == 0) {
size_t newlen = dp->len + 8;
struct demux_packet *new = new_demux_packet(newlen);
if (new) {