#include "libavutil/intfloat_readwrite.h"#include "avformat.h"#include "raw.h"#include "riff.h"Go to the source code of this file.
Defines | |
| #define | AIFF 0 |
| #define | AIFF_C_VERSION1 0xA2805140 |
| #define | MAX_SIZE 4096 |
Functions | |
| static int | aiff_codec_get_id (int bps) |
| static int | get_tag (ByteIOContext *pb, uint32_t *tag) |
| static void | get_meta (ByteIOContext *pb, char *str, int strsize, int size) |
| static unsigned int | get_aiff_header (ByteIOContext *pb, AVCodecContext *codec, int size, unsigned version) |
| static int | aiff_probe (AVProbeData *p) |
| static int | aiff_read_header (AVFormatContext *s, AVFormatParameters *ap) |
| static int | aiff_read_packet (AVFormatContext *s, AVPacket *pkt) |
Variables | |
| static const AVCodecTag | codec_aiff_tags [] |
| #define AIFF 0 |
| #define AIFF_C_VERSION1 0xA2805140 |
| #define MAX_SIZE 4096 |
Definition at line 414 of file aiff.c.
Referenced by aiff_read_packet(), au_read_packet(), mmf_read_packet(), sol_read_packet(), and wav_read_packet().
| static int aiff_codec_get_id | ( | int | bps | ) | [static] |
Definition at line 47 of file aiff.c.
References CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S24BE, CODEC_ID_PCM_S32BE, and CODEC_ID_PCM_S8.
Referenced by get_aiff_header().
00048 { 00049 if (bps <= 8) 00050 return CODEC_ID_PCM_S8; 00051 if (bps <= 16) 00052 return CODEC_ID_PCM_S16BE; 00053 if (bps <= 24) 00054 return CODEC_ID_PCM_S24BE; 00055 if (bps <= 32) 00056 return CODEC_ID_PCM_S32BE; 00057 00058 /* bigger than 32 isn't allowed */ 00059 return 0; 00060 }
| static int aiff_probe | ( | AVProbeData * | p | ) | [static] |
Definition at line 292 of file aiff.c.
References AVPROBE_SCORE_MAX, and AVProbeData::buf.
00293 { 00294 /* check file header */ 00295 if (p->buf[0] == 'F' && p->buf[1] == 'O' && 00296 p->buf[2] == 'R' && p->buf[3] == 'M' && 00297 p->buf[8] == 'A' && p->buf[9] == 'I' && 00298 p->buf[10] == 'F' && (p->buf[11] == 'F' || p->buf[11] == 'C')) 00299 return AVPROBE_SCORE_MAX; 00300 else 00301 return 0; 00302 }
| static int aiff_read_header | ( | AVFormatContext * | s, | |
| AVFormatParameters * | ap | |||
| ) | [static] |
Definition at line 305 of file aiff.c.
References AIFF, AIFF_C_VERSION1, AVFormatContext::author, av_log(), AV_LOG_ERROR, av_mallocz(), av_new_stream(), av_set_pts_info(), AVERROR, AVERROR_INVALIDDATA, AVCodecContext::block_align, AVStream::codec, AVFormatContext::comment, AVFormatContext::copyright, AVStream::duration, AVCodecContext::extradata, AVCodecContext::extradata_size, FF_INPUT_BUFFER_PADDING_SIZE, AVFormatContext::file_size, AVCodecContext::frame_size, get_aiff_header(), get_be32(), get_buffer(), get_le32(), get_meta(), get_tag(), MKTAG, AVStream::nb_frames, offset, AVFormatContext::pb, AVCodecContext::sample_rate, size, AVStream::start_time, AVFormatContext::streams, AVFormatContext::title, url_fseek(), url_fskip(), url_ftell(), and url_is_streamed().
00307 { 00308 int size, filesize; 00309 offset_t offset = 0; 00310 uint32_t tag; 00311 unsigned version = AIFF_C_VERSION1; 00312 ByteIOContext *pb = s->pb; 00313 AVStream * st = s->streams[0]; 00314 00315 /* check FORM header */ 00316 filesize = get_tag(pb, &tag); 00317 if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M')) 00318 return AVERROR_INVALIDDATA; 00319 00320 /* AIFF data type */ 00321 tag = get_le32(pb); 00322 if (tag == MKTAG('A', 'I', 'F', 'F')) /* Got an AIFF file */ 00323 version = AIFF; 00324 else if (tag != MKTAG('A', 'I', 'F', 'C')) /* An AIFF-C file then */ 00325 return AVERROR_INVALIDDATA; 00326 00327 filesize -= 4; 00328 00329 st = av_new_stream(s, 0); 00330 if (!st) 00331 return AVERROR(ENOMEM); 00332 00333 while (filesize > 0) { 00334 /* parse different chunks */ 00335 size = get_tag(pb, &tag); 00336 if (size < 0) 00337 return size; 00338 00339 filesize -= size + 8; 00340 00341 switch (tag) { 00342 case MKTAG('C', 'O', 'M', 'M'): /* Common chunk */ 00343 /* Then for the complete header info */ 00344 st->nb_frames = get_aiff_header(pb, st->codec, size, version); 00345 if (st->nb_frames < 0) 00346 return st->nb_frames; 00347 if (offset > 0) // COMM is after SSND 00348 goto got_sound; 00349 break; 00350 case MKTAG('F', 'V', 'E', 'R'): /* Version chunk */ 00351 version = get_be32(pb); 00352 break; 00353 case MKTAG('N', 'A', 'M', 'E'): /* Sample name chunk */ 00354 get_meta(pb, s->title, sizeof(s->title), size); 00355 break; 00356 case MKTAG('A', 'U', 'T', 'H'): /* Author chunk */ 00357 get_meta(pb, s->author, sizeof(s->author), size); 00358 break; 00359 case MKTAG('(', 'c', ')', ' '): /* Copyright chunk */ 00360 get_meta(pb, s->copyright, sizeof(s->copyright), size); 00361 break; 00362 case MKTAG('A', 'N', 'N', 'O'): /* Annotation chunk */ 00363 get_meta(pb, s->comment, sizeof(s->comment), size); 00364 break; 00365 case MKTAG('S', 'S', 'N', 'D'): /* Sampled sound chunk */ 00366 offset = get_be32(pb); /* Offset of sound data */ 00367 get_be32(pb); /* BlockSize... don't care */ 00368 offset += url_ftell(pb); /* Compute absolute data offset */ 00369 if (st->codec->block_align) /* Assume COMM already parsed */ 00370 goto got_sound; 00371 if (url_is_streamed(pb)) { 00372 av_log(s, AV_LOG_ERROR, "file is not seekable\n"); 00373 return -1; 00374 } 00375 url_fskip(pb, size - 8); 00376 break; 00377 case MKTAG('w', 'a', 'v', 'e'): 00378 if ((uint64_t)size > (1<<30)) 00379 return -1; 00380 st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); 00381 if (!st->codec->extradata) 00382 return AVERROR(ENOMEM); 00383 st->codec->extradata_size = size; 00384 get_buffer(pb, st->codec->extradata, size); 00385 break; 00386 default: /* Jump */ 00387 if (size & 1) /* Always even aligned */ 00388 size++; 00389 url_fskip (pb, size); 00390 } 00391 } 00392 00393 if (!st->codec->block_align) { 00394 av_log(s, AV_LOG_ERROR, "could not find COMM tag\n"); 00395 return -1; 00396 } 00397 00398 got_sound: 00399 /* Now positioned, get the sound data start and end */ 00400 if (st->nb_frames) 00401 s->file_size = st->nb_frames * st->codec->block_align; 00402 00403 av_set_pts_info(st, 64, 1, st->codec->sample_rate); 00404 st->start_time = 0; 00405 st->duration = st->codec->frame_size ? 00406 st->nb_frames * st->codec->frame_size : st->nb_frames; 00407 00408 /* Position the stream at the first block */ 00409 url_fseek(pb, offset, SEEK_SET); 00410 00411 return 0; 00412 }
| static int aiff_read_packet | ( | AVFormatContext * | s, | |
| AVPacket * | pkt | |||
| ) | [static] |
Definition at line 416 of file aiff.c.
References av_get_packet(), AVERROR, AVCodecContext::block_align, AVStream::codec, MAX_SIZE, AVFormatContext::pb, AVPacket::stream_index, AVFormatContext::streams, and url_feof().
00418 { 00419 AVStream *st = s->streams[0]; 00420 int res; 00421 00422 /* End of stream may be reached */ 00423 if (url_feof(s->pb)) 00424 return AVERROR(EIO); 00425 00426 /* Now for that packet */ 00427 res = av_get_packet(s->pb, pkt, (MAX_SIZE / st->codec->block_align) * st->codec->block_align); 00428 if (res < 0) 00429 return res; 00430 00431 /* Only one stream in an AIFF file */ 00432 pkt->stream_index = 0; 00433 return 0; 00434 }
| static unsigned int get_aiff_header | ( | ByteIOContext * | pb, | |
| AVCodecContext * | codec, | |||
| int | size, | |||
| unsigned | version | |||
| ) | [static] |
Definition at line 101 of file aiff.c.
References AIFF_C_VERSION1, aiff_codec_get_id(), av_ext2dbl(), av_get_bits_per_sample(), AVCodecContext::bit_rate, AVCodecContext::bits_per_sample, AVCodecContext::block_align, AVCodecContext::channels, codec_aiff_tags, codec_get_id(), AVCodecContext::codec_id, CODEC_ID_ADPCM_IMA_QT, CODEC_ID_MACE3, CODEC_ID_MACE6, CODEC_ID_PCM_S16BE, AVCodecContext::codec_tag, AVCodecContext::codec_type, CODEC_TYPE_AUDIO, AVCodecContext::frame_size, get_be16(), get_be32(), get_buffer(), get_le32(), AVCodecContext::sample_rate, and url_fseek().
Referenced by aiff_read_header().
00103 { 00104 AVExtFloat ext; 00105 double sample_rate; 00106 unsigned int num_frames; 00107 00108 if (size & 1) 00109 size++; 00110 codec->codec_type = CODEC_TYPE_AUDIO; 00111 codec->channels = get_be16(pb); 00112 num_frames = get_be32(pb); 00113 codec->bits_per_sample = get_be16(pb); 00114 00115 get_buffer(pb, (uint8_t*)&ext, sizeof(ext));/* Sample rate is in */ 00116 sample_rate = av_ext2dbl(ext); /* 80 bits BE IEEE extended float */ 00117 codec->sample_rate = sample_rate; 00118 size -= 18; 00119 00120 /* Got an AIFF-C? */ 00121 if (version == AIFF_C_VERSION1) { 00122 codec->codec_tag = get_le32(pb); 00123 codec->codec_id = codec_get_id(codec_aiff_tags, codec->codec_tag); 00124 00125 switch (codec->codec_id) { 00126 case 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 break; 00130 case CODEC_ID_ADPCM_IMA_QT: 00131 codec->block_align = 34*codec->channels; 00132 codec->frame_size = 64; 00133 break; 00134 case CODEC_ID_MACE3: 00135 codec->block_align = 2*codec->channels; 00136 codec->frame_size = 6; 00137 break; 00138 case CODEC_ID_MACE6: 00139 codec->block_align = 1*codec->channels; 00140 codec->frame_size = 6; 00141 break; 00142 default: 00143 break; 00144 } 00145 size -= 4; 00146 } else { 00147 /* Need the codec type */ 00148 codec->codec_id = aiff_codec_get_id(codec->bits_per_sample); 00149 codec->bits_per_sample = av_get_bits_per_sample(codec->codec_id); 00150 } 00151 00152 /* Block align needs to be computed in all cases, as the definition 00153 * is specific to applications -> here we use the WAVE format definition */ 00154 if (!codec->block_align) 00155 codec->block_align = (codec->bits_per_sample * codec->channels) >> 3; 00156 00157 codec->bit_rate = (codec->frame_size ? codec->sample_rate/codec->frame_size : 00158 codec->sample_rate) * (codec->block_align << 3); 00159 00160 /* Chunk is over */ 00161 if (size) 00162 url_fseek(pb, size, SEEK_CUR); 00163 00164 return num_frames; 00165 }
| static void get_meta | ( | ByteIOContext * | pb, | |
| char * | str, | |||
| int | strsize, | |||
| int | size | |||
| ) | [static] |
Definition at line 80 of file aiff.c.
References get_buffer(), and url_fskip().
Referenced by aiff_read_header().
00081 { 00082 int res; 00083 00084 if (size > strsize-1) 00085 res = get_buffer(pb, (uint8_t*)str, strsize-1); 00086 else 00087 res = get_buffer(pb, (uint8_t*)str, size); 00088 00089 if (res < 0) 00090 return; 00091 00092 str[res] = 0; 00093 if (size & 1) 00094 size++; 00095 size -= res; 00096 if (size) 00097 url_fskip(pb, size); 00098 }
| static int get_tag | ( | ByteIOContext * | pb, | |
| uint32_t * | tag | |||
| ) | [static] |
Definition at line 63 of file aiff.c.
References AVERROR, get_be32(), get_le32(), size, and url_feof().
Referenced by aiff_read_header().
00064 { 00065 int size; 00066 00067 if (url_feof(pb)) 00068 return AVERROR(EIO); 00069 00070 *tag = get_le32(pb); 00071 size = get_be32(pb); 00072 00073 if (size < 0) 00074 size = 0x7fffffff; 00075 00076 return size; 00077 }
const AVCodecTag codec_aiff_tags[] [static] |
Initial value:
{
{ CODEC_ID_PCM_S16BE, MKTAG('N','O','N','E') },
{ CODEC_ID_PCM_S8, MKTAG('N','O','N','E') },
{ CODEC_ID_PCM_S24BE, MKTAG('N','O','N','E') },
{ CODEC_ID_PCM_S32BE, MKTAG('N','O','N','E') },
{ CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') },
{ CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') },
{ CODEC_ID_MACE3, MKTAG('M','A','C','3') },
{ CODEC_ID_MACE6, MKTAG('M','A','C','6') },
{ CODEC_ID_GSM, MKTAG('G','S','M',' ') },
{ CODEC_ID_ADPCM_G726, MKTAG('G','7','2','6') },
{ CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') },
{ CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') },
{ CODEC_ID_QDM2, MKTAG('Q','D','M','2') },
{ 0, 0 },
}
Definition at line 27 of file aiff.c.
Referenced by get_aiff_header().
1.5.1