00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavutil/intreadwrite.h"
00023 #include "libavutil/mathematics.h"
00024 #include "libavutil/dict.h"
00025 #include "avformat.h"
00026 #include "internal.h"
00027 #include "pcm.h"
00028 #include "aiff.h"
00029 #include "isom.h"
00030 #include "id3v2.h"
00031 #include "mov_chan.h"
00032
00033 #define AIFF 0
00034 #define AIFF_C_VERSION1 0xA2805140
00035
00036 typedef struct {
00037 int64_t data_end;
00038 int block_duration;
00039 } AIFFInputContext;
00040
00041 static enum AVCodecID aiff_codec_get_id(int bps)
00042 {
00043 if (bps <= 8)
00044 return AV_CODEC_ID_PCM_S8;
00045 if (bps <= 16)
00046 return AV_CODEC_ID_PCM_S16BE;
00047 if (bps <= 24)
00048 return AV_CODEC_ID_PCM_S24BE;
00049 if (bps <= 32)
00050 return AV_CODEC_ID_PCM_S32BE;
00051
00052
00053 return AV_CODEC_ID_NONE;
00054 }
00055
00056
00057 static int get_tag(AVIOContext *pb, uint32_t * tag)
00058 {
00059 int size;
00060
00061 if (url_feof(pb))
00062 return AVERROR(EIO);
00063
00064 *tag = avio_rl32(pb);
00065 size = avio_rb32(pb);
00066
00067 if (size < 0)
00068 size = 0x7fffffff;
00069
00070 return size;
00071 }
00072
00073
00074 static void get_meta(AVFormatContext *s, const char *key, int size)
00075 {
00076 uint8_t *str = av_malloc(size+1);
00077
00078 if (str) {
00079 int res = avio_read(s->pb, str, size);
00080 if (res < 0){
00081 av_free(str);
00082 return;
00083 }
00084 size += (size&1)-res;
00085 str[res] = 0;
00086 av_dict_set(&s->metadata, key, str, AV_DICT_DONT_STRDUP_VAL);
00087 }else
00088 size+= size&1;
00089
00090 avio_skip(s->pb, size);
00091 }
00092
00093
00094 static unsigned int get_aiff_header(AVFormatContext *s, int size,
00095 unsigned version)
00096 {
00097 AVIOContext *pb = s->pb;
00098 AVCodecContext *codec = s->streams[0]->codec;
00099 AIFFInputContext *aiff = s->priv_data;
00100 int exp;
00101 uint64_t val;
00102 double sample_rate;
00103 unsigned int num_frames;
00104
00105 if (size & 1)
00106 size++;
00107 codec->codec_type = AVMEDIA_TYPE_AUDIO;
00108 codec->channels = avio_rb16(pb);
00109 num_frames = avio_rb32(pb);
00110 codec->bits_per_coded_sample = avio_rb16(pb);
00111
00112 exp = avio_rb16(pb);
00113 val = avio_rb64(pb);
00114 sample_rate = ldexp(val, exp - 16383 - 63);
00115 codec->sample_rate = sample_rate;
00116 size -= 18;
00117
00118
00119 if (version == AIFF_C_VERSION1) {
00120 codec->codec_tag = avio_rl32(pb);
00121 codec->codec_id = ff_codec_get_id(ff_codec_aiff_tags, codec->codec_tag);
00122 size -= 4;
00123 }
00124
00125 if (version != AIFF_C_VERSION1 || codec->codec_id == AV_CODEC_ID_PCM_S16BE) {
00126 codec->codec_id = aiff_codec_get_id(codec->bits_per_coded_sample);
00127 codec->bits_per_coded_sample = av_get_bits_per_sample(codec->codec_id);
00128 aiff->block_duration = 1;
00129 } else {
00130 switch (codec->codec_id) {
00131 case AV_CODEC_ID_PCM_F32BE:
00132 case AV_CODEC_ID_PCM_F64BE:
00133 case AV_CODEC_ID_PCM_S16LE:
00134 case AV_CODEC_ID_PCM_ALAW:
00135 case AV_CODEC_ID_PCM_MULAW:
00136 aiff->block_duration = 1;
00137 break;
00138 case AV_CODEC_ID_ADPCM_IMA_QT:
00139 codec->block_align = 34*codec->channels;
00140 break;
00141 case AV_CODEC_ID_MACE3:
00142 codec->block_align = 2*codec->channels;
00143 break;
00144 case AV_CODEC_ID_MACE6:
00145 codec->block_align = 1*codec->channels;
00146 break;
00147 case AV_CODEC_ID_GSM:
00148 codec->block_align = 33;
00149 break;
00150 case AV_CODEC_ID_QCELP:
00151 codec->block_align = 35;
00152 break;
00153 default:
00154 aiff->block_duration = 1;
00155 break;
00156 }
00157 if (codec->block_align > 0)
00158 aiff->block_duration = av_get_audio_frame_duration(codec,
00159 codec->block_align);
00160 }
00161
00162
00163
00164 if (!codec->block_align)
00165 codec->block_align = (av_get_bits_per_sample(codec->codec_id) * codec->channels) >> 3;
00166
00167 if (aiff->block_duration) {
00168 codec->bit_rate = codec->sample_rate * (codec->block_align << 3) /
00169 aiff->block_duration;
00170 }
00171
00172
00173 if (size)
00174 avio_skip(pb, size);
00175
00176 return num_frames;
00177 }
00178
00179 static int aiff_probe(AVProbeData *p)
00180 {
00181
00182 if (p->buf[0] == 'F' && p->buf[1] == 'O' &&
00183 p->buf[2] == 'R' && p->buf[3] == 'M' &&
00184 p->buf[8] == 'A' && p->buf[9] == 'I' &&
00185 p->buf[10] == 'F' && (p->buf[11] == 'F' || p->buf[11] == 'C'))
00186 return AVPROBE_SCORE_MAX;
00187 else
00188 return 0;
00189 }
00190
00191
00192 static int aiff_read_header(AVFormatContext *s)
00193 {
00194 int ret, size, filesize;
00195 int64_t offset = 0;
00196 uint32_t tag;
00197 unsigned version = AIFF_C_VERSION1;
00198 AVIOContext *pb = s->pb;
00199 AVStream * st;
00200 AIFFInputContext *aiff = s->priv_data;
00201 ID3v2ExtraMeta *id3v2_extra_meta = NULL;
00202
00203
00204 filesize = get_tag(pb, &tag);
00205 if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M'))
00206 return AVERROR_INVALIDDATA;
00207
00208
00209 tag = avio_rl32(pb);
00210 if (tag == MKTAG('A', 'I', 'F', 'F'))
00211 version = AIFF;
00212 else if (tag != MKTAG('A', 'I', 'F', 'C'))
00213 return AVERROR_INVALIDDATA;
00214
00215 filesize -= 4;
00216
00217 st = avformat_new_stream(s, NULL);
00218 if (!st)
00219 return AVERROR(ENOMEM);
00220
00221 while (filesize > 0) {
00222
00223 size = get_tag(pb, &tag);
00224 if (size < 0)
00225 return size;
00226
00227 filesize -= size + 8;
00228
00229 switch (tag) {
00230 case MKTAG('C', 'O', 'M', 'M'):
00231
00232 st->nb_frames = get_aiff_header(s, size, version);
00233 if (st->nb_frames < 0)
00234 return st->nb_frames;
00235 if (offset > 0)
00236 goto got_sound;
00237 break;
00238 case MKTAG('I', 'D', '3', ' '):
00239 ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);
00240 if (id3v2_extra_meta)
00241 if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) {
00242 ff_id3v2_free_extra_meta(&id3v2_extra_meta);
00243 return ret;
00244 }
00245 ff_id3v2_free_extra_meta(&id3v2_extra_meta);
00246 break;
00247 case MKTAG('F', 'V', 'E', 'R'):
00248 version = avio_rb32(pb);
00249 break;
00250 case MKTAG('N', 'A', 'M', 'E'):
00251 get_meta(s, "title" , size);
00252 break;
00253 case MKTAG('A', 'U', 'T', 'H'):
00254 get_meta(s, "author" , size);
00255 break;
00256 case MKTAG('(', 'c', ')', ' '):
00257 get_meta(s, "copyright", size);
00258 break;
00259 case MKTAG('A', 'N', 'N', 'O'):
00260 get_meta(s, "comment" , size);
00261 break;
00262 case MKTAG('S', 'S', 'N', 'D'):
00263 aiff->data_end = avio_tell(pb) + size;
00264 offset = avio_rb32(pb);
00265 avio_rb32(pb);
00266 offset += avio_tell(pb);
00267 if (st->codec->block_align && !pb->seekable)
00268 goto got_sound;
00269 if (!pb->seekable) {
00270 av_log(s, AV_LOG_ERROR, "file is not seekable\n");
00271 return -1;
00272 }
00273 avio_skip(pb, size - 8);
00274 break;
00275 case MKTAG('w', 'a', 'v', 'e'):
00276 if ((uint64_t)size > (1<<30))
00277 return -1;
00278 st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
00279 if (!st->codec->extradata)
00280 return AVERROR(ENOMEM);
00281 st->codec->extradata_size = size;
00282 avio_read(pb, st->codec->extradata, size);
00283 if (st->codec->codec_id == AV_CODEC_ID_QDM2 && size>=12*4 && !st->codec->block_align)
00284 st->codec->block_align = AV_RB32(st->codec->extradata+11*4);
00285 break;
00286 case MKTAG('C','H','A','N'):
00287 if(ff_mov_read_chan(s, pb, st, size) < 0)
00288 return AVERROR_INVALIDDATA;
00289 break;
00290 default:
00291 if (size & 1)
00292 size++;
00293 avio_skip(pb, size);
00294 }
00295 }
00296
00297 got_sound:
00298 if (!st->codec->block_align) {
00299 av_log(s, AV_LOG_ERROR, "could not find COMM tag or invalid block_align value\n");
00300 return -1;
00301 }
00302
00303
00304 avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
00305 st->start_time = 0;
00306 st->duration = st->nb_frames * aiff->block_duration;
00307
00308
00309 avio_seek(pb, offset, SEEK_SET);
00310
00311 return 0;
00312 }
00313
00314 #define MAX_SIZE 4096
00315
00316 static int aiff_read_packet(AVFormatContext *s,
00317 AVPacket *pkt)
00318 {
00319 AVStream *st = s->streams[0];
00320 AIFFInputContext *aiff = s->priv_data;
00321 int64_t max_size;
00322 int res, size;
00323
00324
00325 max_size = aiff->data_end - avio_tell(s->pb);
00326 if (max_size <= 0)
00327 return AVERROR_EOF;
00328
00329
00330 if (st->codec->block_align >= 33)
00331 size = st->codec->block_align;
00332 else
00333 size = (MAX_SIZE / st->codec->block_align) * st->codec->block_align;
00334 size = FFMIN(max_size, size);
00335 res = av_get_packet(s->pb, pkt, size);
00336 if (res < 0)
00337 return res;
00338
00339 if (size >= st->codec->block_align)
00340 pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
00341
00342 pkt->stream_index = 0;
00343 pkt->duration = (res / st->codec->block_align) * aiff->block_duration;
00344 return 0;
00345 }
00346
00347 AVInputFormat ff_aiff_demuxer = {
00348 .name = "aiff",
00349 .long_name = NULL_IF_CONFIG_SMALL("Audio IFF"),
00350 .priv_data_size = sizeof(AIFFInputContext),
00351 .read_probe = aiff_probe,
00352 .read_header = aiff_read_header,
00353 .read_packet = aiff_read_packet,
00354 .read_seek = ff_pcm_read_seek,
00355 .codec_tag = (const AVCodecTag* const []){ ff_codec_aiff_tags, 0 },
00356 };