aiff.c File Reference

#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 Documentation

#define AIFF   0

Definition at line 44 of file aiff.c.

Referenced by aiff_read_header(), and av_register_all().

#define AIFF_C_VERSION1   0xA2805140

Definition at line 45 of file aiff.c.

Referenced by aiff_read_header(), and get_aiff_header().

#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().


Function Documentation

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 }


Variable Documentation

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().


Generated on Thu Aug 28 16:44:30 2008 for libextractor by  doxygen 1.5.1