diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index 56d68bbd90..a590de92fd 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -71,50 +71,6 @@ const struct m_sub_options ad_lavc_conf = { }, }; -struct pcm_map -{ - int tag; - const char *codecs[6]; // {any, 1byte, 2bytes, 3bytes, 4bytes, 8bytes} -}; - -// NOTE: these are needed to make rawaudio with demux_mkv work. -static const struct pcm_map tag_map[] = { - // Microsoft PCM - {0x0, {NULL, "pcm_u8", "pcm_s16le", "pcm_s24le", "pcm_s32le"}}, - {0x1, {NULL, "pcm_u8", "pcm_s16le", "pcm_s24le", "pcm_s32le"}}, - // MS PCM, Extended - {0xfffe, {NULL, "pcm_u8", "pcm_s16le", "pcm_s24le", "pcm_s32le"}}, - // IEEE float - {0x3, {"pcm_f32le", [5] = "pcm_f64le"}}, - // 'raw ' - {0x20776172, {"pcm_s16be", [1] = "pcm_u8"}}, - // 'twos', used by demux_mkv.c internally - {MKTAG('t', 'w', 'o', 's'), - {NULL, "pcm_s8", "pcm_s16be", "pcm_s24be", "pcm_s32be"}}, - {-1}, -}; - -static const char *find_pcm_decoder(const struct pcm_map *map, int format, - int bits_per_sample) -{ - int bytes = (bits_per_sample + 7) / 8; - if (bytes == 8) - bytes = 5; // 64 bit entry - for (int n = 0; map[n].tag != -1; n++) { - const struct pcm_map *entry = &map[n]; - if (entry->tag == format) { - const char *dec = NULL; - if (bytes >= 1 && bytes <= 5) - dec = entry->codecs[bytes]; - if (!dec) - dec = entry->codecs[0]; - if (dec) - return dec; - } - } - return NULL; -} - static void set_data_from_avframe(struct dec_audio *da) { struct priv *priv = da->priv; @@ -170,11 +126,6 @@ static int init(struct dec_audio *da, const char *decoder) struct priv *ctx = talloc_zero(NULL, struct priv); da->priv = ctx; - if (sh_audio->wf && strcmp(decoder, "pcm") == 0) { - decoder = find_pcm_decoder(tag_map, sh->format, - sh_audio->wf->wBitsPerSample); - } - ctx->force_channel_map = sh_audio->force_channels; lavc_codec = avcodec_find_decoder_by_name(decoder); @@ -336,7 +287,6 @@ static int decode_packet(struct dec_audio *da) static void add_decoders(struct mp_decoder_list *list) { mp_add_lavc_decoders(list, AVMEDIA_TYPE_AUDIO); - mp_add_decoder(list, "lavc", "pcm", "pcm", "Raw PCM"); } const struct ad_functions ad_lavc = { 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: ; }