Revision 47b47bbd libavformat/aiff.c

View differences:

libavformat/aiff.c
1 1
/*
2
 * AIFF/AIFF-C muxer and demuxer
2
 * AIFF/AIFF-C demuxer
3 3
 * Copyright (c) 2006  Patrick Guimond
4 4
 *
5 5
 * This file is part of FFmpeg.
......
22 22
#include "libavutil/intfloat_readwrite.h"
23 23
#include "avformat.h"
24 24
#include "raw.h"
25
#include "riff.h"
26

  
27
static const AVCodecTag codec_aiff_tags[] = {
28
    { CODEC_ID_PCM_S16BE,    MKTAG('N','O','N','E') },
29
    { CODEC_ID_PCM_S8,       MKTAG('N','O','N','E') },
30
    { CODEC_ID_PCM_S24BE,    MKTAG('N','O','N','E') },
31
    { CODEC_ID_PCM_S32BE,    MKTAG('N','O','N','E') },
32
    { CODEC_ID_PCM_F32BE,    MKTAG('f','l','3','2') },
33
    { CODEC_ID_PCM_F64BE,    MKTAG('f','l','6','4') },
34
    { CODEC_ID_PCM_ALAW,     MKTAG('a','l','a','w') },
35
    { CODEC_ID_PCM_MULAW,    MKTAG('u','l','a','w') },
36
    { CODEC_ID_MACE3,        MKTAG('M','A','C','3') },
37
    { CODEC_ID_MACE6,        MKTAG('M','A','C','6') },
38
    { CODEC_ID_GSM,          MKTAG('G','S','M',' ') },
39
    { CODEC_ID_ADPCM_G726,   MKTAG('G','7','2','6') },
40
    { CODEC_ID_PCM_S16LE,    MKTAG('s','o','w','t') },
41
    { CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') },
42
    { CODEC_ID_QDM2,         MKTAG('Q','D','M','2') },
43
    { 0, 0 },
44
};
25
#include "aiff.h"
45 26

  
46 27
#define AIFF                    0
47 28
#define AIFF_C_VERSION1         0xA2805140
......
123 104
    /* Got an AIFF-C? */
124 105
    if (version == AIFF_C_VERSION1) {
125 106
        codec->codec_tag = get_le32(pb);
126
        codec->codec_id  = ff_codec_get_id(codec_aiff_tags, codec->codec_tag);
107
        codec->codec_id  = ff_codec_get_id(ff_codec_aiff_tags, codec->codec_tag);
127 108

  
128 109
        switch (codec->codec_id) {
129 110
        case CODEC_ID_PCM_S16BE:
......
171 152
    return num_frames;
172 153
}
173 154

  
174
#if CONFIG_AIFF_MUXER
175
typedef struct {
176
    int64_t form;
177
    int64_t frames;
178
    int64_t ssnd;
179
} AIFFOutputContext;
180

  
181
static int aiff_write_header(AVFormatContext *s)
182
{
183
    AIFFOutputContext *aiff = s->priv_data;
184
    ByteIOContext *pb = s->pb;
185
    AVCodecContext *enc = s->streams[0]->codec;
186
    AVExtFloat sample_rate;
187
    int aifc = 0;
188

  
189
    /* First verify if format is ok */
190
    if (!enc->codec_tag)
191
        return -1;
192
    if (enc->codec_tag != MKTAG('N','O','N','E'))
193
        aifc = 1;
194

  
195
    /* FORM AIFF header */
196
    put_tag(pb, "FORM");
197
    aiff->form = url_ftell(pb);
198
    put_be32(pb, 0);                    /* file length */
199
    put_tag(pb, aifc ? "AIFC" : "AIFF");
200

  
201
    if (aifc) { // compressed audio
202
        enc->bits_per_coded_sample = 16;
203
        if (!enc->block_align) {
204
            av_log(s, AV_LOG_ERROR, "block align not set\n");
205
            return -1;
206
        }
207
        /* Version chunk */
208
        put_tag(pb, "FVER");
209
        put_be32(pb, 4);
210
        put_be32(pb, 0xA2805140);
211
    }
212

  
213
    /* Common chunk */
214
    put_tag(pb, "COMM");
215
    put_be32(pb, aifc ? 24 : 18); /* size */
216
    put_be16(pb, enc->channels);  /* Number of channels */
217

  
218
    aiff->frames = url_ftell(pb);
219
    put_be32(pb, 0);              /* Number of frames */
220

  
221
    if (!enc->bits_per_coded_sample)
222
        enc->bits_per_coded_sample = av_get_bits_per_sample(enc->codec_id);
223
    if (!enc->bits_per_coded_sample) {
224
        av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n");
225
        return -1;
226
    }
227
    if (!enc->block_align)
228
        enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3;
229

  
230
    put_be16(pb, enc->bits_per_coded_sample); /* Sample size */
231

  
232
    sample_rate = av_dbl2ext((double)enc->sample_rate);
233
    put_buffer(pb, (uint8_t*)&sample_rate, sizeof(sample_rate));
234

  
235
    if (aifc) {
236
        put_le32(pb, enc->codec_tag);
237
        put_be16(pb, 0);
238
    }
239

  
240
    /* Sound data chunk */
241
    put_tag(pb, "SSND");
242
    aiff->ssnd = url_ftell(pb);         /* Sound chunk size */
243
    put_be32(pb, 0);                    /* Sound samples data size */
244
    put_be32(pb, 0);                    /* Data offset */
245
    put_be32(pb, 0);                    /* Block-size (block align) */
246

  
247
    av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate);
248

  
249
    /* Data is starting here */
250
    put_flush_packet(pb);
251

  
252
    return 0;
253
}
254

  
255
static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt)
256
{
257
    ByteIOContext *pb = s->pb;
258
    put_buffer(pb, pkt->data, pkt->size);
259
    return 0;
260
}
261

  
262
static int aiff_write_trailer(AVFormatContext *s)
263
{
264
    ByteIOContext *pb = s->pb;
265
    AIFFOutputContext *aiff = s->priv_data;
266
    AVCodecContext *enc = s->streams[0]->codec;
267

  
268
    /* Chunks sizes must be even */
269
    int64_t file_size, end_size;
270
    end_size = file_size = url_ftell(pb);
271
    if (file_size & 1) {
272
        put_byte(pb, 0);
273
        end_size++;
274
    }
275

  
276
    if (!url_is_streamed(s->pb)) {
277
        /* File length */
278
        url_fseek(pb, aiff->form, SEEK_SET);
279
        put_be32(pb, file_size - aiff->form - 4);
280

  
281
        /* Number of sample frames */
282
        url_fseek(pb, aiff->frames, SEEK_SET);
283
        put_be32(pb, (file_size-aiff->ssnd-12)/enc->block_align);
284

  
285
        /* Sound Data chunk size */
286
        url_fseek(pb, aiff->ssnd, SEEK_SET);
287
        put_be32(pb, file_size - aiff->ssnd - 4);
288

  
289
        /* return to the end */
290
        url_fseek(pb, end_size, SEEK_SET);
291

  
292
        put_flush_packet(pb);
293
    }
294

  
295
    return 0;
296
}
297
#endif /* CONFIG_AIFF_MUXER */
298

  
299 155
static int aiff_probe(AVProbeData *p)
300 156
{
301 157
    /* check file header */
......
446 302
    return 0;
447 303
}
448 304

  
449
#if CONFIG_AIFF_DEMUXER
450 305
AVInputFormat aiff_demuxer = {
451 306
    "aiff",
452 307
    NULL_IF_CONFIG_SMALL("Audio IFF"),
......
456 311
    aiff_read_packet,
457 312
    NULL,
458 313
    pcm_read_seek,
459
    .codec_tag= (const AVCodecTag* const []){codec_aiff_tags, 0},
460
};
461
#endif
462

  
463
#if CONFIG_AIFF_MUXER
464
AVOutputFormat aiff_muxer = {
465
    "aiff",
466
    NULL_IF_CONFIG_SMALL("Audio IFF"),
467
    "audio/aiff",
468
    "aif,aiff,afc,aifc",
469
    sizeof(AIFFOutputContext),
470
    CODEC_ID_PCM_S16BE,
471
    CODEC_ID_NONE,
472
    aiff_write_header,
473
    aiff_write_packet,
474
    aiff_write_trailer,
475
    .codec_tag= (const AVCodecTag* const []){codec_aiff_tags, 0},
314
    .codec_tag= (const AVCodecTag* const []){ff_codec_aiff_tags, 0},
476 315
};
477
#endif

Also available in: Unified diff