diff --git a/libavformat/Makefile b/libavformat/Makefile index 83f92e1799..428c641d67 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -23,7 +23,7 @@ OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o OBJS-$(CONFIG_AC3_MUXER) += rawenc.o OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o -OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o caf.o +OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o isom.o OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o riff.o OBJS-$(CONFIG_AMR_DEMUXER) += amr.o OBJS-$(CONFIG_AMR_MUXER) += amr.o diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index a3aecee0a8..cc2631448b 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -23,7 +23,7 @@ #include "avformat.h" #include "pcm.h" #include "aiff.h" -#include "caf.h" +#include "isom.h" #define AIFF 0 #define AIFF_C_VERSION1 0xA2805140 @@ -257,7 +257,7 @@ static int aiff_read_header(AVFormatContext *s, case MKTAG('C','H','A','N'): if (size < 12) return AVERROR_INVALIDDATA; - ff_read_chan_chunk(s, size, st->codec); + ff_mov_read_chan(s, size, st->codec); break; default: /* Jump */ if (size & 1) /* Always even aligned */ diff --git a/libavformat/caf.c b/libavformat/caf.c index 3aec1d7203..fd916746d8 100644 --- a/libavformat/caf.c +++ b/libavformat/caf.c @@ -57,62 +57,3 @@ const AVCodecTag ff_codec_caf_tags[] = { { CODEC_ID_NONE, 0 }, }; -typedef struct CafChannelLayout { - int64_t channel_layout; - uint32_t layout_tag; -} CafChannelLayout; - -static const CafChannelLayout caf_channel_layout[] = { - { AV_CH_LAYOUT_MONO, (100<<16) | 1}, //< kCAFChannelLayoutTag_Mono - { AV_CH_LAYOUT_STEREO, (101<<16) | 2}, //< kCAFChannelLayoutTag_Stereo - { AV_CH_LAYOUT_STEREO, (102<<16) | 2}, //< kCAFChannelLayoutTag_StereoHeadphones - { AV_CH_LAYOUT_2_1, (131<<16) | 3}, //< kCAFChannelLayoutTag_ITU_2_1 - { AV_CH_LAYOUT_QUAD, (132<<16) | 4}, //< kCAFChannelLayoutTag_ITU_2_2 - { AV_CH_LAYOUT_2_2, (132<<16) | 4}, //< kCAFChannelLayoutTag_ITU_2_2 - { AV_CH_LAYOUT_QUAD, (108<<16) | 4}, //< kCAFChannelLayoutTag_Quadraphonic - { AV_CH_LAYOUT_SURROUND, (113<<16) | 3}, //< kCAFChannelLayoutTag_MPEG_3_0_A - { AV_CH_LAYOUT_4POINT0, (115<<16) | 4}, //< kCAFChannelLayoutTag_MPEG_4_0_A - { AV_CH_LAYOUT_5POINT0_BACK, (117<<16) | 5}, //< kCAFChannelLayoutTag_MPEG_5_0_A - { AV_CH_LAYOUT_5POINT0, (117<<16) | 5}, //< kCAFChannelLayoutTag_MPEG_5_0_A - { AV_CH_LAYOUT_5POINT1_BACK, (121<<16) | 6}, //< kCAFChannelLayoutTag_MPEG_5_1_A - { AV_CH_LAYOUT_5POINT1, (121<<16) | 6}, //< kCAFChannelLayoutTag_MPEG_5_1_A - { AV_CH_LAYOUT_7POINT1, (128<<16) | 8}, //< kCAFChannelLayoutTag_MPEG_7_1_C - { AV_CH_LAYOUT_7POINT1_WIDE, (126<<16) | 8}, //< kCAFChannelLayoutTag_MPEG_7_1_A - { AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY, (133<<16) | 3}, //< kCAFChannelLayoutTag_DVD_4 - { AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY, (134<<16) | 4}, //< kCAFChannelLayoutTag_DVD_5 - { AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, //< kCAFChannelLayoutTag_DVD_6 - { AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, //< kCAFChannelLayoutTag_DVD_6 - { AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY, (136<<16) | 4}, //< kCAFChannelLayoutTag_DVD_10 - { AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY, (137<<16) | 5}, //< kCAFChannelLayoutTag_DVD_11 - { 0, 0}, -}; - -void ff_read_chan_chunk(AVFormatContext *s, int64_t size, AVCodecContext *codec) -{ - uint32_t layout_tag; - AVIOContext *pb = s->pb; - const CafChannelLayout *caf_layout = caf_channel_layout; - if (size != 12) { - // Channel descriptions not implemented - av_log_ask_for_sample(s, "Unimplemented channel layout.\n"); - avio_skip(pb, size); - return; - } - layout_tag = avio_rb32(pb); - if (layout_tag == 0x10000) { //< kCAFChannelLayoutTag_UseChannelBitmap - codec->channel_layout = avio_rb32(pb); - avio_skip(pb, 4); - return; - } - while (caf_layout->channel_layout) { - if (layout_tag == caf_layout->layout_tag) { - codec->channel_layout = caf_layout->channel_layout; - break; - } - caf_layout++; - } - if (!codec->channel_layout) - av_log(s, AV_LOG_WARNING, "Unknown channel layout.\n"); - avio_skip(pb, 8); -} - diff --git a/libavformat/caf.h b/libavformat/caf.h index 181cfaf92a..9c25f2c683 100644 --- a/libavformat/caf.h +++ b/libavformat/caf.h @@ -27,11 +27,8 @@ #ifndef AVFORMAT_CAF_H #define AVFORMAT_CAF_H -#include "avformat.h" #include "internal.h" extern const AVCodecTag ff_codec_caf_tags[]; -void ff_read_chan_chunk(AVFormatContext *s, int64_t size, AVCodecContext *codec); - #endif /* AVFORMAT_CAF_H */ diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index 3cf4b6ca0c..ea9a3c17ae 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -260,7 +260,7 @@ static int read_header(AVFormatContext *s, case MKBETAG('c','h','a','n'): if (size < 12) return AVERROR_INVALIDDATA; - ff_read_chan_chunk(s, size, st->codec); + ff_mov_read_chan(s, size, st->codec); break; default: diff --git a/libavformat/isom.c b/libavformat/isom.c index 3246df889f..6ab996c45b 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -420,3 +420,63 @@ int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext } return 0; } + +typedef struct MovChannelLayout { + int64_t channel_layout; + uint32_t layout_tag; +} MovChannelLayout; + +static const MovChannelLayout mov_channel_layout[] = { + { AV_CH_LAYOUT_MONO, (100<<16) | 1}, //< kCAFChannelLayoutTag_Mono + { AV_CH_LAYOUT_STEREO, (101<<16) | 2}, //< kCAFChannelLayoutTag_Stereo + { AV_CH_LAYOUT_STEREO, (102<<16) | 2}, //< kCAFChannelLayoutTag_StereoHeadphones + { AV_CH_LAYOUT_2_1, (131<<16) | 3}, //< kCAFChannelLayoutTag_ITU_2_1 + { AV_CH_LAYOUT_QUAD, (132<<16) | 4}, //< kCAFChannelLayoutTag_ITU_2_2 + { AV_CH_LAYOUT_2_2, (132<<16) | 4}, //< kCAFChannelLayoutTag_ITU_2_2 + { AV_CH_LAYOUT_QUAD, (108<<16) | 4}, //< kCAFChannelLayoutTag_Quadraphonic + { AV_CH_LAYOUT_SURROUND, (113<<16) | 3}, //< kCAFChannelLayoutTag_MPEG_3_0_A + { AV_CH_LAYOUT_4POINT0, (115<<16) | 4}, //< kCAFChannelLayoutTag_MPEG_4_0_A + { AV_CH_LAYOUT_5POINT0_BACK, (117<<16) | 5}, //< kCAFChannelLayoutTag_MPEG_5_0_A + { AV_CH_LAYOUT_5POINT0, (117<<16) | 5}, //< kCAFChannelLayoutTag_MPEG_5_0_A + { AV_CH_LAYOUT_5POINT1_BACK, (121<<16) | 6}, //< kCAFChannelLayoutTag_MPEG_5_1_A + { AV_CH_LAYOUT_5POINT1, (121<<16) | 6}, //< kCAFChannelLayoutTag_MPEG_5_1_A + { AV_CH_LAYOUT_7POINT1, (128<<16) | 8}, //< kCAFChannelLayoutTag_MPEG_7_1_C + { AV_CH_LAYOUT_7POINT1_WIDE, (126<<16) | 8}, //< kCAFChannelLayoutTag_MPEG_7_1_A + { AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY, (133<<16) | 3}, //< kCAFChannelLayoutTag_DVD_4 + { AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY, (134<<16) | 4}, //< kCAFChannelLayoutTag_DVD_5 + { AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, //< kCAFChannelLayoutTag_DVD_6 + { AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, //< kCAFChannelLayoutTag_DVD_6 + { AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY, (136<<16) | 4}, //< kCAFChannelLayoutTag_DVD_10 + { AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY, (137<<16) | 5}, //< kCAFChannelLayoutTag_DVD_11 + { 0, 0}, +}; + +void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec) +{ + uint32_t layout_tag; + AVIOContext *pb = s->pb; + const MovChannelLayout *layouts = mov_channel_layout; + if (size != 12) { + // Channel descriptions not implemented + av_log_ask_for_sample(s, "Unimplemented channel layout.\n"); + avio_skip(pb, size); + return; + } + layout_tag = avio_rb32(pb); + if (layout_tag == 0x10000) { //< kCAFChannelLayoutTag_UseChannelBitmap + codec->channel_layout = avio_rb32(pb); + avio_skip(pb, 4); + return; + } + while (layouts->channel_layout) { + if (layout_tag == layouts->layout_tag) { + codec->channel_layout = layouts->channel_layout; + break; + } + layouts++; + } + if (!codec->channel_layout) + av_log(s, AV_LOG_WARNING, "Unknown channel layout.\n"); + avio_skip(pb, 8); +} + diff --git a/libavformat/isom.h b/libavformat/isom.h index 4227aa0770..081d2279ba 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -156,5 +156,6 @@ int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom); enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags); int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries); +void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec); #endif /* AVFORMAT_ISOM_H */