summaryrefslogtreecommitdiffstats
path: root/demux/demux_mkv.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2015-06-19 21:39:59 +0200
committerwm4 <wm4@nowhere>2015-06-19 21:39:59 +0200
commit0641ec0525b75d0dc7aeddcccbfe4d9fab7af786 (patch)
treeae422dcf88fd6211480190d674db2ed793a5d0c9 /demux/demux_mkv.c
parentaed7c848407a472ccc63337b3bd7cef97defe8e4 (diff)
downloadmpv-0641ec0525b75d0dc7aeddcccbfe4d9fab7af786.tar.bz2
mpv-0641ec0525b75d0dc7aeddcccbfe4d9fab7af786.tar.xz
demux_mkv: remove FourCCs from audio codec handling
This removes the last traces of the old MPlayer FourCC-based codec mapping code. Forcing all codec IDs through a FourCC table and then back to codec names was confusing at best, so this is a nice cleanup. Handling of PCM (non-VfW case) is redone to some degree. Handling of AC3 is moved below realaudio handling, since "A_REAL/DNET" is apparently AC3, and we must not skip realaudio-specific handling. (It seems unlikely that anything would actually break, but on the other hand I don't have any A_REAL/DNET samples for testing.) Instead of explicitly matching all the specific AAC codec names, just match them all as prefix. Some codecs don't need special handling other than their mapping entries, so they fall away (like Vorbis and Opus). The prores check in mkv_parse_and_add_packet() is not strictly related to this, but is done for consistency with the wavpack check above.
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) {