00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "avformat.h"
00022 #include "raw.h"
00023 #include "riff.h"
00024 #include "intfloat_readwrite.h"
00025
00026 static const AVCodecTag codec_aiff_tags[] = {
00027 { CODEC_ID_PCM_S16BE, MKTAG('N','O','N','E') },
00028 { CODEC_ID_PCM_S8, MKTAG('N','O','N','E') },
00029 { CODEC_ID_PCM_S24BE, MKTAG('N','O','N','E') },
00030 { CODEC_ID_PCM_S32BE, MKTAG('N','O','N','E') },
00031 { CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') },
00032 { CODEC_ID_PCM_ALAW, MKTAG('A','L','A','W') },
00033 { CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') },
00034 { CODEC_ID_PCM_MULAW, MKTAG('U','L','A','W') },
00035 { CODEC_ID_MACE3, MKTAG('M','A','C','3') },
00036 { CODEC_ID_MACE6, MKTAG('M','A','C','6') },
00037 { CODEC_ID_GSM, MKTAG('G','S','M',' ') },
00038 { CODEC_ID_ADPCM_G726, MKTAG('G','7','2','6') },
00039 { CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') },
00040 { 0, 0 },
00041 };
00042
00043 #define AIFF 0
00044 #define AIFF_C_VERSION1 0xA2805140
00045
00046 static int aiff_codec_get_id (int bps)
00047 {
00048 if (bps <= 8)
00049 return CODEC_ID_PCM_S8;
00050 if (bps <= 16)
00051 return CODEC_ID_PCM_S16BE;
00052 if (bps <= 24)
00053 return CODEC_ID_PCM_S24BE;
00054 if (bps <= 32)
00055 return CODEC_ID_PCM_S32BE;
00056
00057
00058 return 0;
00059 }
00060
00061
00062 static int get_tag(ByteIOContext *pb, uint32_t * tag)
00063 {
00064 int size;
00065
00066 if (url_feof(pb))
00067 return AVERROR(EIO);
00068
00069 *tag = get_le32(pb);
00070 size = get_be32(pb);
00071
00072 if (size < 0)
00073 size = 0x7fffffff;
00074
00075 return size;
00076 }
00077
00078
00079 static void get_meta(ByteIOContext *pb, char * str, int strsize, int size)
00080 {
00081 int res;
00082
00083 if (size > strsize-1)
00084 res = get_buffer(pb, (uint8_t*)str, strsize-1);
00085 else
00086 res = get_buffer(pb, (uint8_t*)str, size);
00087
00088 if (res < 0)
00089 return;
00090
00091 str[res] = 0;
00092 if (size & 1)
00093 size++;
00094 size -= res;
00095 if (size)
00096 url_fskip(pb, size);
00097 }
00098
00099
00100 static unsigned int get_aiff_header(ByteIOContext *pb, AVCodecContext *codec,
00101 int size, unsigned version)
00102 {
00103 AVExtFloat ext;
00104 double sample_rate;
00105 unsigned int num_frames;
00106
00107
00108 if (size & 1)
00109 size++;
00110
00111 codec->codec_type = CODEC_TYPE_AUDIO;
00112 codec->channels = get_be16(pb);
00113 num_frames = get_be32(pb);
00114 codec->bits_per_sample = get_be16(pb);
00115
00116 get_buffer(pb, (uint8_t*)&ext, sizeof(ext));
00117 sample_rate = av_ext2dbl(ext);
00118 codec->sample_rate = sample_rate;
00119 size -= 18;
00120
00121
00122 if (version == AIFF_C_VERSION1) {
00123 codec->codec_tag = get_le32(pb);
00124 codec->codec_id = codec_get_id (codec_aiff_tags, codec->codec_tag);
00125
00126 if (codec->codec_id == CODEC_ID_PCM_S16BE) {
00127 codec->codec_id = aiff_codec_get_id (codec->bits_per_sample);
00128 codec->bits_per_sample = av_get_bits_per_sample(codec->codec_id);
00129 }
00130
00131 size -= 4;
00132 } else {
00133
00134 codec->codec_id = aiff_codec_get_id (codec->bits_per_sample);
00135 codec->bits_per_sample = av_get_bits_per_sample(codec->codec_id);
00136 }
00137
00138 if (!codec->codec_id)
00139 return AVERROR_INVALIDDATA;
00140
00141
00142
00143 codec->block_align = (codec->bits_per_sample * codec->channels) >> 3;
00144
00145 codec->bit_rate = codec->sample_rate * (codec->block_align << 3);
00146
00147
00148 if (size)
00149 url_fseek(pb, size, SEEK_CUR);
00150
00151 return num_frames;
00152 }
00153
00154 #ifdef CONFIG_MUXERS
00155 typedef struct {
00156 offset_t form;
00157 offset_t frames;
00158 offset_t ssnd;
00159 } AIFFOutputContext;
00160
00161 static int aiff_write_header(AVFormatContext *s)
00162 {
00163 AIFFOutputContext *aiff = s->priv_data;
00164 ByteIOContext *pb = s->pb;
00165 AVCodecContext *enc = s->streams[0]->codec;
00166 AVExtFloat sample_rate;
00167 int aifc = 0;
00168
00169
00170 if (!enc->codec_tag) {
00171 return -1;
00172 }
00173
00174 if (enc->codec_tag != MKTAG('N','O','N','E'))
00175 aifc = 1;
00176
00177
00178 put_tag(pb, "FORM");
00179 aiff->form = url_ftell(pb);
00180 put_be32(pb, 0);
00181 put_tag(pb, aifc ? "AIFC" : "AIFF");
00182
00183 if (aifc) {
00184
00185 put_tag(pb, "FVER");
00186 put_be32(pb, 4);
00187 put_be32(pb, 0xA2805140);
00188 }
00189
00190
00191 put_tag(pb, "COMM");
00192 put_be32(pb, aifc ? 24 : 18);
00193 put_be16(pb, enc->channels);
00194
00195 aiff->frames = url_ftell(pb);
00196 put_be32(pb, 0);
00197
00198 if (!enc->bits_per_sample)
00199 enc->bits_per_sample = av_get_bits_per_sample(enc->codec_id);
00200 if (!enc->bits_per_sample) {
00201 av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n");
00202 return -1;
00203 }
00204 if (!enc->block_align)
00205 enc->block_align = (enc->bits_per_sample * enc->channels) >> 3;
00206
00207 put_be16(pb, enc->bits_per_sample);
00208
00209 sample_rate = av_dbl2ext((double)enc->sample_rate);
00210 put_buffer(pb, (uint8_t*)&sample_rate, sizeof(sample_rate));
00211
00212 if (aifc) {
00213 put_le32(pb, enc->codec_tag);
00214 put_be16(pb, 0);
00215 }
00216
00217
00218 put_tag(pb, "SSND");
00219 aiff->ssnd = url_ftell(pb);
00220 put_be32(pb, 0);
00221 put_be32(pb, 0);
00222 put_be32(pb, 0);
00223
00224 av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
00225
00226
00227 put_flush_packet(pb);
00228
00229 return 0;
00230 }
00231
00232 static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt)
00233 {
00234 ByteIOContext *pb = s->pb;
00235 put_buffer(pb, pkt->data, pkt->size);
00236 return 0;
00237 }
00238
00239 static int aiff_write_trailer(AVFormatContext *s)
00240 {
00241 ByteIOContext *pb = s->pb;
00242 AIFFOutputContext *aiff = s->priv_data;
00243 AVCodecContext *enc = s->streams[0]->codec;
00244
00245
00246 offset_t file_size, end_size;
00247 end_size = file_size = url_ftell(pb);
00248 if (file_size & 1) {
00249 put_byte(pb, 0);
00250 end_size++;
00251 }
00252
00253 if (!url_is_streamed(s->pb)) {
00254
00255 url_fseek(pb, aiff->form, SEEK_SET);
00256 put_be32(pb, (uint32_t)(file_size - aiff->form - 4));
00257
00258
00259 url_fseek(pb, aiff->frames, SEEK_SET);
00260 put_be32(pb, ((uint32_t)(file_size-aiff->ssnd-12))/enc->block_align);
00261
00262
00263 url_fseek(pb, aiff->ssnd, SEEK_SET);
00264 put_be32(pb, (uint32_t)(file_size - aiff->ssnd - 4));
00265
00266
00267 url_fseek(pb, end_size, SEEK_SET);
00268
00269 put_flush_packet(pb);
00270 }
00271
00272 return 0;
00273 }
00274 #endif //CONFIG_MUXERS
00275
00276 static int aiff_probe(AVProbeData *p)
00277 {
00278
00279 if (p->buf[0] == 'F' && p->buf[1] == 'O' &&
00280 p->buf[2] == 'R' && p->buf[3] == 'M' &&
00281 p->buf[8] == 'A' && p->buf[9] == 'I' &&
00282 p->buf[10] == 'F' && (p->buf[11] == 'F' || p->buf[11] == 'C'))
00283 return AVPROBE_SCORE_MAX;
00284 else
00285 return 0;
00286 }
00287
00288
00289 static int aiff_read_header(AVFormatContext *s,
00290 AVFormatParameters *ap)
00291 {
00292 int size, filesize;
00293 offset_t offset = 0;
00294 uint32_t tag;
00295 unsigned version = AIFF_C_VERSION1;
00296 ByteIOContext *pb = s->pb;
00297 AVStream * st = s->streams[0];
00298
00299
00300 filesize = get_tag(pb, &tag);
00301 if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M'))
00302 return AVERROR_INVALIDDATA;
00303
00304
00305 tag = get_le32(pb);
00306 if (tag == MKTAG('A', 'I', 'F', 'F'))
00307 version = AIFF;
00308 else if (tag != MKTAG('A', 'I', 'F', 'C'))
00309 return AVERROR_INVALIDDATA;
00310
00311 filesize -= 4;
00312
00313 st = av_new_stream(s, 0);
00314 if (!st)
00315 return AVERROR(ENOMEM);
00316
00317 while (filesize > 0) {
00318
00319 size = get_tag(pb, &tag);
00320 if (size < 0)
00321 return size;
00322
00323 filesize -= size + 8;
00324
00325 switch (tag) {
00326 case MKTAG('C', 'O', 'M', 'M'):
00327
00328 st->nb_frames = get_aiff_header (pb, st->codec, size, version);
00329 if (st->nb_frames < 0)
00330 return st->nb_frames;
00331 if (offset > 0)
00332 goto got_sound;
00333 break;
00334
00335 case MKTAG('F', 'V', 'E', 'R'):
00336 version = get_be32(pb);
00337 break;
00338
00339 case MKTAG('N', 'A', 'M', 'E'):
00340 get_meta (pb, s->title, sizeof(s->title), size);
00341 break;
00342
00343 case MKTAG('A', 'U', 'T', 'H'):
00344 get_meta (pb, s->author, sizeof(s->author), size);
00345 break;
00346
00347 case MKTAG('(', 'c', ')', ' '):
00348 get_meta (pb, s->copyright, sizeof(s->copyright), size);
00349 break;
00350
00351 case MKTAG('A', 'N', 'N', 'O'):
00352 get_meta (pb, s->comment, sizeof(s->comment), size);
00353 break;
00354
00355 case MKTAG('S', 'S', 'N', 'D'):
00356 offset = get_be32(pb);
00357 get_be32(pb);
00358 offset += url_ftell(pb);
00359 if (st->codec->codec_id)
00360 goto got_sound;
00361 if (url_is_streamed(pb)) {
00362 av_log(s, AV_LOG_ERROR, "file is not seekable\n");
00363 return -1;
00364 }
00365 url_fskip(pb, size - 8);
00366 break;
00367
00368 default:
00369 if (size & 1)
00370 size++;
00371 url_fskip (pb, size);
00372 }
00373 }
00374
00375
00376 return AVERROR_INVALIDDATA;
00377
00378 got_sound:
00379
00380 if (st->nb_frames)
00381 s->file_size = st->nb_frames * st->codec->block_align;
00382
00383 av_set_pts_info(st, 64, 1, st->codec->sample_rate);
00384 st->start_time = 0;
00385 st->duration = st->nb_frames;
00386
00387
00388 url_fseek(pb, offset, SEEK_SET);
00389
00390 return 0;
00391 }
00392
00393 #define MAX_SIZE 4096
00394
00395 static int aiff_read_packet(AVFormatContext *s,
00396 AVPacket *pkt)
00397 {
00398 AVStream *st = s->streams[0];
00399 int res;
00400
00401
00402 if (url_feof(s->pb))
00403 return AVERROR(EIO);
00404
00405
00406 res = av_get_packet(s->pb, pkt, (MAX_SIZE / st->codec->block_align) * st->codec->block_align);
00407 if (res < 0)
00408 return res;
00409
00410
00411 pkt->stream_index = 0;
00412 return 0;
00413 }
00414
00415 static int aiff_read_close(AVFormatContext *s)
00416 {
00417 return 0;
00418 }
00419
00420 static int aiff_read_seek(AVFormatContext *s,
00421 int stream_index, int64_t timestamp, int flags)
00422 {
00423 return pcm_read_seek(s, stream_index, timestamp, flags);
00424 }
00425
00426 #ifdef CONFIG_AIFF_DEMUXER
00427 AVInputFormat aiff_demuxer = {
00428 "aiff",
00429 "Audio IFF",
00430 0,
00431 aiff_probe,
00432 aiff_read_header,
00433 aiff_read_packet,
00434 aiff_read_close,
00435 aiff_read_seek,
00436 .codec_tag= (const AVCodecTag*[]){codec_aiff_tags, 0},
00437 };
00438 #endif
00439
00440 #ifdef CONFIG_AIFF_MUXER
00441 AVOutputFormat aiff_muxer = {
00442 "aiff",
00443 "Audio IFF",
00444 "audio/aiff",
00445 "aif,aiff,afc,aifc",
00446 sizeof(AIFFOutputContext),
00447 CODEC_ID_PCM_S16BE,
00448 CODEC_ID_NONE,
00449 aiff_write_header,
00450 aiff_write_packet,
00451 aiff_write_trailer,
00452 .codec_tag= (const AVCodecTag*[]){codec_aiff_tags, 0},
00453 };
00454 #endif