summaryrefslogtreecommitdiffstats
path: root/demux/codec_tags.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-09-24 23:20:19 +0200
committerwm4 <wm4@nowhere>2014-09-24 23:33:21 +0200
commite977624d8723ab8c129e8cefc5bdac31aa8a9475 (patch)
treee6982c5348387f879fece01ba153f89e846382eb /demux/codec_tags.c
parent9ac86d9e994aeb764207f4d0279b3d37266f79e6 (diff)
downloadmpv-e977624d8723ab8c129e8cefc5bdac31aa8a9475.tar.bz2
mpv-e977624d8723ab8c129e8cefc5bdac31aa8a9475.tar.xz
audio: confine demux_mkv audio PCM hack
Let codec_tags.c do the messy mapping. In theory we could simplify further by makign demux_mkv.c directly use codec names instead of the MPlayer-inherited "internal FourCC" business, but I'd rather not touch this - it would just break things.
Diffstat (limited to 'demux/codec_tags.c')
-rw-r--r--demux/codec_tags.c34
1 files changed, 28 insertions, 6 deletions
diff --git a/demux/codec_tags.c b/demux/codec_tags.c
index 23e1935dba..0833757b31 100644
--- a/demux/codec_tags.c
+++ b/demux/codec_tags.c
@@ -97,12 +97,6 @@ static const struct mp_codec_tag mp_audio_codec_tags[] = {
{MKTAG('s', 'a', 'm', 'r'), "amr_nb"},
{MKTAG('s', 'a', 'w', 'b'), "amr_wb"},
{MKTAG('v', 'r', 'b', 's'), "vorbis"},
- // Special cased in ad_lavc:
- {0 , "pcm"},
- {0x1 , "pcm"}, // lavf: pcm_s16le
- {0x3 , "pcm"}, // lavf: pcm_f32le
- {0xfffe , "pcm"},
- {MKTAG('t', 'w', 'o', 's'), "pcm"},
// ------- internal mplayer FourCCs ------
{MKTAG('O', 'p', 'u', 's'), "opus"}, // demux_mkv.c
{MKTAG('a', 'L', 'a', 'C'), "alac"}, // demux_mkv.c
@@ -358,6 +352,28 @@ static const char *lookup_tag(const struct mp_codec_tag *mp_table,
return id == AV_CODEC_ID_NONE ? NULL : mp_codec_from_av_codec_id(id);
}
+static const char *pcm_le[] = {"pcm_u8", "pcm_s16le", "pcm_s24le", "pcm_s32le"};
+static const char *pcm_be[] = {"pcm_s8", "pcm_s16be", "pcm_s24be", "pcm_s32be"};
+
+static const char *map_audio_pcm_tag(uint32_t tag, int bits)
+{
+ int bytes = (bits + 7) / 8;
+ switch (tag) {
+ case 0x0: // Microsoft PCM
+ case 0x1:
+ case 0xfffe: // MS PCM, Extended
+ return bytes >= 1 && bytes <= 4 ? pcm_le[bytes - 1] : NULL;
+ case 0x3: // IEEE float
+ return bits == 64 ? "pcm_f64le" : "pcm_f32le";
+ case 0x20776172:// 'raw '
+ return bits == 8 ? "pcm_u8" : "pcm_s16be";
+ case MKTAG('t', 'w', 'o', 's'): // demux_mkv.c internal
+ return bytes >= 1 && bytes <= 4 ? pcm_be[bytes - 1] : NULL;
+ default:
+ return NULL;
+ }
+}
+
void mp_set_codec_from_tag(struct sh_stream *sh)
{
switch (sh->type) {
@@ -370,6 +386,12 @@ void mp_set_codec_from_tag(struct sh_stream *sh)
sh->codec = lookup_tag(mp_audio_codec_tags,
avformat_get_riff_audio_tags(),
sh->format);
+ if (sh->audio && sh->audio->wf) {
+ const char *codec =
+ map_audio_pcm_tag(sh->format, sh->audio->wf->wBitsPerSample);
+ if (codec)
+ sh->codec = codec;
+ }
break;
default: ;
}