diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2012-11-27 14:52:38 -0500 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2012-11-28 11:18:50 -0500 |
commit | 261e9348ef377efc8672c6f8ade974cee7db8e49 (patch) | |
tree | ff98f739e44a47e958e029c54026725b0f610cb5 | |
parent | bfe5454cd238b16e7977085f880205229103eccb (diff) | |
download | ffmpeg-261e9348ef377efc8672c6f8ade974cee7db8e49.tar.gz |
lavf: add a common function for selecting a pcm codec from parameters
-rw-r--r-- | libavformat/internal.h | 15 | ||||
-rw-r--r-- | libavformat/mov.c | 33 | ||||
-rw-r--r-- | libavformat/riff.c | 15 | ||||
-rw-r--r-- | libavformat/utils.c | 30 |
4 files changed, 57 insertions, 36 deletions
diff --git a/libavformat/internal.h b/libavformat/internal.h index aafbed94a0..ac4a5d0794 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -358,4 +358,19 @@ unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id); enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag); +/** + * Select a PCM codec based on the given parameters. + * + * @param bps bits-per-sample + * @param flt floating-point + * @param be big-endian + * @param sflags signed flags. each bit corresponds to one byte of bit depth. + * e.g. the 1st bit indicates if 8-bit should be signed or + * unsigned, the 2nd bit indicates if 16-bit should be signed or + * unsigned, etc... This is useful for formats such as WAVE where + * only 8-bit is unsigned and all other bit depths are signed. + * @return a PCM codec id or AV_CODEC_ID_NONE + */ +enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags); + #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/mov.c b/libavformat/mov.c index 35c07bd0a2..c6ff84bbcd 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1057,33 +1057,12 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom) */ enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags) { - if (flags & 1) { // floating point - if (flags & 2) { // big endian - if (bps == 32) return AV_CODEC_ID_PCM_F32BE; - else if (bps == 64) return AV_CODEC_ID_PCM_F64BE; - } else { - if (bps == 32) return AV_CODEC_ID_PCM_F32LE; - else if (bps == 64) return AV_CODEC_ID_PCM_F64LE; - } - } else { - if (flags & 2) { - if (bps == 8) - // signed integer - if (flags & 4) return AV_CODEC_ID_PCM_S8; - else return AV_CODEC_ID_PCM_U8; - else if (bps == 16) return AV_CODEC_ID_PCM_S16BE; - else if (bps == 24) return AV_CODEC_ID_PCM_S24BE; - else if (bps == 32) return AV_CODEC_ID_PCM_S32BE; - } else { - if (bps == 8) - if (flags & 4) return AV_CODEC_ID_PCM_S8; - else return AV_CODEC_ID_PCM_U8; - else if (bps == 16) return AV_CODEC_ID_PCM_S16LE; - else if (bps == 24) return AV_CODEC_ID_PCM_S24LE; - else if (bps == 32) return AV_CODEC_ID_PCM_S32LE; - } - } - return AV_CODEC_ID_NONE; + /* lpcm flags: + * 0x1 = float + * 0x2 = big-endian + * 0x4 = signed + */ + return ff_get_pcm_codec_id(bps, flags & 1, flags & 2, flags & 4 ? -1 : 0); } int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) diff --git a/libavformat/riff.c b/libavformat/riff.c index fde11317fe..475486da82 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -678,15 +678,12 @@ enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps) id = ff_codec_get_id(ff_codec_wav_tags, tag); if (id <= 0) return id; - /* handle specific u8 codec */ - if (id == AV_CODEC_ID_PCM_S16LE && bps == 8) - id = AV_CODEC_ID_PCM_U8; - if (id == AV_CODEC_ID_PCM_S16LE && bps == 24) - id = AV_CODEC_ID_PCM_S24LE; - if (id == AV_CODEC_ID_PCM_S16LE && bps == 32) - id = AV_CODEC_ID_PCM_S32LE; - if (id == AV_CODEC_ID_PCM_F32LE && bps == 64) - id = AV_CODEC_ID_PCM_F64LE; + + if (id == AV_CODEC_ID_PCM_S16LE) + id = ff_get_pcm_codec_id(bps, 0, 0, ~1); + else if (id == AV_CODEC_ID_PCM_F32LE) + id = ff_get_pcm_codec_id(bps, 1, 0, 0); + if (id == AV_CODEC_ID_ADPCM_IMA_WAV && bps == 8) id = AV_CODEC_ID_PCM_ZORK; return id; diff --git a/libavformat/utils.c b/libavformat/utils.c index fc8b770a85..481760b5ad 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2135,6 +2135,36 @@ enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag) return AV_CODEC_ID_NONE; } +enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags) +{ + if (flt) { + switch (bps) { + case 32: return be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE; + case 64: return be ? AV_CODEC_ID_PCM_F64BE : AV_CODEC_ID_PCM_F64LE; + default: return AV_CODEC_ID_NONE; + } + } else { + bps >>= 3; + if (sflags & (1 << (bps - 1))) { + switch (bps) { + case 1: return AV_CODEC_ID_PCM_S8; + case 2: return be ? AV_CODEC_ID_PCM_S16BE : AV_CODEC_ID_PCM_S16LE; + case 3: return be ? AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE; + case 4: return be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE; + default: return AV_CODEC_ID_NONE; + } + } else { + switch (bps) { + case 1: return AV_CODEC_ID_PCM_U8; + case 2: return be ? AV_CODEC_ID_PCM_U16BE : AV_CODEC_ID_PCM_U16LE; + case 3: return be ? AV_CODEC_ID_PCM_U24BE : AV_CODEC_ID_PCM_U24LE; + case 4: return be ? AV_CODEC_ID_PCM_U32BE : AV_CODEC_ID_PCM_U32LE; + default: return AV_CODEC_ID_NONE; + } + } + } +} + unsigned int av_codec_get_tag(const AVCodecTag * const *tags, enum AVCodecID id) { int i; |