diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-11-29 13:58:57 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-11-29 14:00:44 +0100 |
commit | d7b20bfbb582c369518c73720fb4b0266714cde6 (patch) | |
tree | 27dfaa2c3e2f273e661555336b6ed6d6b9eb9e5e /libavformat | |
parent | 076300bf8b43d5d56a91cd2ad845d596969c87cf (diff) | |
parent | 5c7bf2dddee5bdfa247ff0d57cb8a37d19077f66 (diff) | |
download | ffmpeg-d7b20bfbb582c369518c73720fb4b0266714cde6.tar.gz |
Merge commit '5c7bf2dddee5bdfa247ff0d57cb8a37d19077f66'
* commit '5c7bf2dddee5bdfa247ff0d57cb8a37d19077f66':
lavf: move nuv fourcc audio tags from riff to nuv
lavf: add a common function for selecting a pcm codec from parameters
Conflicts:
libavformat/internal.h
libavformat/mov.c
libavformat/riff.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/internal.h | 15 | ||||
-rw-r--r-- | libavformat/mov.c | 33 | ||||
-rw-r--r-- | libavformat/nuv.c | 23 | ||||
-rw-r--r-- | libavformat/riff.c | 21 | ||||
-rw-r--r-- | libavformat/utils.c | 31 |
5 files changed, 78 insertions, 45 deletions
diff --git a/libavformat/internal.h b/libavformat/internal.h index 4f740c99d1..14f4cdbdf1 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -360,6 +360,21 @@ 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); + +/** * Chooses a timebase for muxing the specified stream. * * The choosen timebase allows sample accurate timestamps based diff --git a/libavformat/mov.c b/libavformat/mov.c index 1a8a5a7182..149bd20954 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1170,33 +1170,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/nuv.c b/libavformat/nuv.c index c67c1fa695..37d92e284f 100644 --- a/libavformat/nuv.c +++ b/libavformat/nuv.c @@ -26,6 +26,12 @@ #include "internal.h" #include "riff.h" +static const AVCodecTag nuv_audio_tags[] = { + { AV_CODEC_ID_PCM_S16LE, MKTAG('R', 'A', 'W', 'A') }, + { AV_CODEC_ID_MP3, MKTAG('L', 'A', 'M', 'E') }, + { AV_CODEC_ID_NONE, 0 }, +}; + typedef struct { int v_id; int a_id; @@ -96,14 +102,25 @@ static int get_codec_data(AVIOContext *pb, AVStream *vst, avio_skip(pb, 4); if (ast) { + int id; + ast->codec->codec_tag = avio_rl32(pb); ast->codec->sample_rate = avio_rl32(pb); ast->codec->bits_per_coded_sample = avio_rl32(pb); ast->codec->channels = avio_rl32(pb); ast->codec->channel_layout = 0; - ast->codec->codec_id = - ff_wav_codec_get_id(ast->codec->codec_tag, - ast->codec->bits_per_coded_sample); + + id = ff_wav_codec_get_id(ast->codec->codec_tag, + ast->codec->bits_per_coded_sample); + if (id == AV_CODEC_ID_NONE) { + id = ff_codec_get_id(nuv_audio_tags, + ast->codec->codec_tag); + if (id == AV_CODEC_ID_PCM_S16LE) + id = ff_get_pcm_codec_id(ast->codec->bits_per_coded_sample, + 0, 0, ~1); + } + ast->codec->codec_id = id; + ast->need_parsing = AVSTREAM_PARSE_FULL; } else avio_skip(pb, 4 * 4); diff --git a/libavformat/riff.c b/libavformat/riff.c index cddbec477c..57d6ca68df 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -384,11 +384,6 @@ const AVCodecTag ff_codec_wav_tags[] = { { AV_CODEC_ID_FLAC, 0xF1AC }, { AV_CODEC_ID_ADPCM_SWF, ('S'<<8)+'F' }, { AV_CODEC_ID_VORBIS, ('V'<<8)+'o' }, //HACK/FIXME, does vorbis in WAV/AVI have an (in)official id? - - /* FIXME: All of the IDs below are not 16 bit and thus illegal. */ - // for NuppelVideo (nuv.c) - { AV_CODEC_ID_PCM_S16LE, MKTAG('R', 'A', 'W', 'A') }, - { AV_CODEC_ID_MP3, MKTAG('L', 'A', 'M', 'E') }, { AV_CODEC_ID_NONE, 0 }, }; @@ -757,16 +752,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 == 20 || - 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 3e87dbc76e..b7506dea98 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2440,6 +2440,37 @@ 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 += 7; + 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; |