diff options
author | wm4 <wm4@nowhere> | 2015-06-19 21:42:55 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-06-19 21:42:55 +0200 |
commit | fd557a0178ec64f03ec543eaf334209d7c2d08c5 (patch) | |
tree | ed2e6c723c3cf1c445ed5cd3422ac26a6c8a6d6b | |
parent | f544cd05010fe1e5d6da7f8674fa0cc357c6d035 (diff) |
demux_mkv: separate generic and non-VfW audio codec handling parts
Native Matroska codec support has to map the Matroska codec IDs to
libavcodec ones, and also has to undo codec-specific Matroska
strangeness, such as restoring AAC extradata and realaudio handling. The
VfW codec support doesn't need it, because AVI maps well enough to
libavcodec conventions (possibly because AVI was a dominant codec when
libavcodec was created). But there's still some need for generic codec
handling, such as enabling parsers and messing with various codec
parameters.
Separate these two, and move the parts which are guaranteed not to be
needed by VfW to the if-else tree that handles the VfW case
("A_MS/ACM"), making the cases exclusive.
(This should probably be done more radically, since it's very unlikely
that we should or have to mess with the VfW parameters at all - they
should just be passed through to the decoder.)
-rw-r--r-- | demux/demux_mkv.c | 173 |
1 files changed, 84 insertions, 89 deletions
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c index 0ffa1b8d52..773a8a288a 100644 --- a/demux/demux_mkv.c +++ b/demux/demux_mkv.c @@ -1334,18 +1334,13 @@ static int demux_mkv_open_video(demuxer_t *demuxer, mkv_track_t *track) static const struct mkv_audio_tag { const char *id; const char *codec; - bool prefix; } mkv_audio_tags[] = { { "A_MPEG/L2", "mp3" }, { "A_MPEG/L3", "mp3" }, - { "A_AC3", "ac3", .prefix = true }, - { "A_EAC3", "eac3", .prefix = true }, + { "A_AC3", "ac3" }, + { "A_EAC3", "eac3" }, { "A_DTS", "dts" }, - { "A_PCM/INT/LIT", "pcm" }, // not a real lavc codec name - { "A_PCM/INT/BIG", "pcm" }, - { "A_PCM/FLOAT/IEEE", "pcm-flt" }, // also not a real lavc codec name { "A_AAC", "aac" }, - { "A_AAC/", "aac", .prefix = true }, { "A_VORBIS", "vorbis" }, { "A_OPUS", "opus" }, { "A_OPUS/EXPERIMENTAL", "opus" }, @@ -1355,11 +1350,6 @@ static const struct mkv_audio_tag { { "A_TRUEHD", "truehd" }, { "A_FLAC", "flac" }, { "A_ALAC", "alac" }, - { "A_REAL/28_8", "ra_288" }, - { "A_REAL/ATRC", "atrac3" }, - { "A_REAL/COOK", "cook" }, - { "A_REAL/DNET", "ac3" }, - { "A_REAL/SIPR", "sipr" }, { "A_TTA1", "tta" }, { NULL }, }; @@ -1386,6 +1376,14 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track) if (!track->a_osfreq) track->a_osfreq = track->a_sfreq; sh_a->bits_per_coded_sample = track->a_bps ? track->a_bps : 16; + sh_a->samplerate = (uint32_t) track->a_osfreq; + + for (int i = 0; mkv_audio_tags[i].id; i++) { + if (!strcmp(track->codec_id, mkv_audio_tags[i].id)) { + sh->codec = mkv_audio_tags[i].codec; + break; + } + } if (!strcmp(track->codec_id, "A_MS/ACM")) { /* AVI compatibility mode */ // The private_data contains a WAVEFORMATEX struct @@ -1396,8 +1394,8 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track) 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) - track->a_osfreq = AV_RL32(h + 4); // nSamplesPerSec + if (sh_a->samplerate == 0) + sh_a->samplerate = AV_RL32(h + 4); // nSamplesPerSec sh_a->bitrate = AV_RL32(h + 8) * 8; // nAvgBytesPerSec sh_a->block_align = AV_RL16(h + 12); // nBlockAlign if (track->a_bps == 0) @@ -1406,79 +1404,14 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track) 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; - if (t->id == NULL) - goto error; - if (t->prefix) { - if (!bstr_startswith0(bstr0(track->codec_id), t->id)) - continue; - } else { - if (strcmp(track->codec_id, t->id)) - continue; - } - sh->codec = t->codec; - break; - } - } - - if (!sh->codec) - goto error; - - mp_chmap_set_unknown(&sh_a->channels, track->a_channels); - sh_a->samplerate = (uint32_t) track->a_osfreq; - - const char *codec = sh->codec; - if (!strcmp(codec, "mp3")) { - sh_a->bitrate = 16000 * 8; - sh_a->block_align = 1152; - track->parse = true; - } else if (!strcmp(codec, "pcm")) { - bool is_be = !strcmp(track->codec_id, "A_PCM/INT/BIG"); + } else if (!strcmp(track->codec_id, "A_PCM/INT/LIT")) { 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")) { + mp_set_pcm_codec(sh, sign, false, sh_a->bits_per_coded_sample, false); + } else if (!strcmp(track->codec_id, "A_PCM/INT/BIG")) { + bool sign = sh_a->bits_per_coded_sample > 8; + mp_set_pcm_codec(sh, sign, false, sh_a->bits_per_coded_sample, true); + } else if (!strcmp(track->codec_id, "A_PCM/FLOAT/IEEE")) { 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 (!strcmp(codec, "aac")) { - sh_a->bitrate = 16000 * 8; - sh_a->block_align = 1024; - - 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 = ""; - if (strlen(track->codec_id) >= 12) - tail = &track->codec_id[12]; - int profile = 3; - if (!strncmp(tail, "MAIN", 4)) - profile = 0; - else if (!strncmp(tail, "LC", 2)) - profile = 1; - else if (!strncmp(tail, "SSR", 3)) - profile = 2; - sh_a->codecdata = talloc_size(sh_a, 5); - sh_a->codecdata[0] = ((profile + 1) << 3) | ((srate_idx & 0xE) >> 1); - sh_a->codecdata[1] = - ((srate_idx & 0x1) << 7) | (track->a_channels << 3); - - if (strstr(track->codec_id, "SBR") != NULL) { - /* HE-AAC (aka SBR AAC) */ - sh_a->codecdata_len = 5; - - srate_idx = aac_get_sample_rate_index(sh_a->samplerate); - sh_a->codecdata[2] = AAC_SYNC_EXTENSION_TYPE >> 3; - sh_a->codecdata[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5; - sh_a->codecdata[4] = (1 << 7) | (srate_idx << 3); - track->default_duration = 1024.0 / (sh_a->samplerate / 2); - } else { - sh_a->codecdata_len = 2; - track->default_duration = 1024.0 / sh_a->samplerate; - } - } } else if (!strncmp(track->codec_id, "A_REAL/", 7)) { if (track->private_size < RAPROPERTIES4_SIZE) goto error; @@ -1517,31 +1450,93 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track) extradata_len = codecdata_length; extradata = src; - if (!strcmp(codec, "atrac3")) { + if (!strcmp(track->codec_id, "A_REAL/ATRC")) { + sh->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; - } else if (!strcmp(codec, "cook")) { + } else if (!strcmp(track->codec_id, "A_REAL/COOK")) { + sh->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; - } else if (!strcmp(codec, "sipr")) { + } else if (!strcmp(track->codec_id, "A_REAL/SIPR")) { + sh->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; - } else if (!strcmp(codec, "ra_288")) { + } else if (!strcmp(track->codec_id, "A_REAL/28_8")) { + sh->codec = "ra_288"; sh_a->bitrate = 3600 * 8; sh_a->block_align = track->coded_framesize; + } else if (!strcmp(track->codec_id, "A_REAL/DNET")) { + sh->codec = "ac3"; + } else { + goto error; } track->audio_buf = talloc_array_size(track, track->sub_packet_h, track->audiopk_size); track->audio_timestamp = talloc_array(track, double, track->sub_packet_h); + } else if (!strncmp(track->codec_id, "A_AAC/", 6)) { + sh->codec = "aac"; + + /* Recreate the 'private data' (not needed for plain A_AAC) */ + int srate_idx = aac_get_sample_rate_index(track->a_sfreq); + const char *tail = ""; + if (strlen(track->codec_id) >= 12) + tail = &track->codec_id[12]; + int profile = 3; + if (!strncmp(tail, "MAIN", 4)) + profile = 0; + else if (!strncmp(tail, "LC", 2)) + profile = 1; + else if (!strncmp(tail, "SSR", 3)) + profile = 2; + sh_a->codecdata = talloc_size(sh_a, 5); + sh_a->codecdata[0] = ((profile + 1) << 3) | ((srate_idx & 0xE) >> 1); + sh_a->codecdata[1] = + ((srate_idx & 0x1) << 7) | (track->a_channels << 3); + + if (strstr(track->codec_id, "SBR") != NULL) { + /* HE-AAC (aka SBR AAC) */ + sh_a->codecdata_len = 5; + + srate_idx = aac_get_sample_rate_index(sh_a->samplerate); + sh_a->codecdata[2] = AAC_SYNC_EXTENSION_TYPE >> 3; + sh_a->codecdata[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5; + sh_a->codecdata[4] = (1 << 7) | (srate_idx << 3); + track->default_duration = 1024.0 / (sh_a->samplerate / 2); + } else { + sh_a->codecdata_len = 2; + track->default_duration = 1024.0 / sh_a->samplerate; + } + } else if (!strncmp(track->codec_id, "A_AC3/", 6)) { + sh->codec = "ac3"; + } else if (!strncmp(track->codec_id, "A_EAC3/", 7)) { + sh->codec = "eac3"; + } + if (!sh->codec) + goto error; + + mp_chmap_set_unknown(&sh_a->channels, track->a_channels); + + const char *codec = sh->codec; + if (!strcmp(codec, "mp3")) { + sh_a->bitrate = 16000 * 8; + sh_a->block_align = 1152; + track->parse = true; + } else if (!strcmp(codec, "qdmc") || !strcmp(codec, "qdm2")) { + sh_a->bitrate = 16000 * 8; + sh_a->block_align = 1486; + } else if (!strcmp(codec, "aac")) { + sh_a->bitrate = 16000 * 8; + sh_a->block_align = 1024; } else if (!strcmp(codec, "flac")) { sh_a->bits_per_coded_sample = 0; sh_a->bitrate = 0; |