~ubuntu-branches/ubuntu/vivid/linphone/vivid

« back to all changes in this revision

Viewing changes to ffmpeg/libav/wav.c

  • Committer: Bazaar Package Importer
  • Author(s): Samuel Mimram
  • Date: 2006-11-15 10:34:50 UTC
  • mfrom: (1.2.1 upstream) (2.1.8 feisty)
  • Revision ID: james.westby@ubuntu.com-20061115103450-qgafwcks2lkhctlj
* New upstream release.
* Enable video support.
* Fix mismatched #endif in mscommon.h, closes: #398307.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
 * WAV encoder and decoder
3
 
 * Copyright (c) 2001 Gerard Lantau.
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
 
 */
19
 
#include "avformat.h"
20
 
#include "avi.h"
21
 
 
22
 
typedef struct {
23
 
    offset_t data;
24
 
} WAVContext;
25
 
 
26
 
static int wav_write_header(AVFormatContext *s)
27
 
{
28
 
    WAVContext *wav;
29
 
    ByteIOContext *pb = &s->pb;
30
 
    offset_t fmt;
31
 
 
32
 
    wav = malloc(sizeof(WAVContext));
33
 
    if (!wav)
34
 
        return -1;
35
 
    memset(wav, 0, sizeof(WAVContext));
36
 
    s->priv_data = wav;
37
 
 
38
 
    put_tag(pb, "RIFF");
39
 
    put_le32(pb, 0); /* file length */
40
 
    put_tag(pb, "WAVE");
41
 
 
42
 
    /* format header */
43
 
    fmt = start_tag(pb, "fmt ");
44
 
    put_wav_header(pb, &s->streams[0]->codec);
45
 
    end_tag(pb, fmt);
46
 
 
47
 
    /* data header */
48
 
    wav->data = start_tag(pb, "data");
49
 
    
50
 
    put_flush_packet(pb);
51
 
 
52
 
    return 0;
53
 
}
54
 
 
55
 
static int wav_write_packet(AVFormatContext *s, int stream_index_ptr,
56
 
                           UINT8 *buf, int size)
57
 
{
58
 
    ByteIOContext *pb = &s->pb;
59
 
    put_buffer(pb, buf, size);
60
 
    return 0;
61
 
}
62
 
 
63
 
static int wav_write_trailer(AVFormatContext *s)
64
 
{
65
 
    ByteIOContext *pb = &s->pb;
66
 
    WAVContext *wav = s->priv_data;
67
 
    offset_t file_size;
68
 
 
69
 
    if (!url_is_streamed(&s->pb)) {
70
 
        end_tag(pb, wav->data);
71
 
 
72
 
        /* update file size */
73
 
        file_size = url_ftell(pb);
74
 
        url_fseek(pb, 4, SEEK_SET);
75
 
        put_le32(pb, (UINT32)(file_size - 8));
76
 
        url_fseek(pb, file_size, SEEK_SET);
77
 
 
78
 
        put_flush_packet(pb);
79
 
    }
80
 
 
81
 
    free(wav);
82
 
    return 0;
83
 
}
84
 
 
85
 
/* return the size of the found tag */
86
 
/* XXX: > 2GB ? */
87
 
static int find_tag(ByteIOContext *pb, UINT32 tag1)
88
 
{
89
 
    unsigned int tag;
90
 
    int size;
91
 
 
92
 
    for(;;) {
93
 
        if (url_feof(pb))
94
 
            return -1;
95
 
        tag = get_le32(pb);
96
 
        size = get_le32(pb);
97
 
        if (tag == tag1)
98
 
            break;
99
 
        url_fseek(pb, size, SEEK_CUR);
100
 
    }
101
 
    if (size < 0)
102
 
        size = 0x7fffffff;
103
 
    return size;
104
 
}
105
 
 
106
 
/* wav input */
107
 
static int wav_read_header(AVFormatContext *s,
108
 
                           AVFormatParameters *ap)
109
 
{
110
 
    int size;
111
 
    unsigned int tag;
112
 
    ByteIOContext *pb = &s->pb;
113
 
    unsigned int id, channels, rate, bit_rate, extra_size;
114
 
    AVStream *st;
115
 
 
116
 
    /* check RIFF header */
117
 
    tag = get_le32(pb);
118
 
 
119
 
    if (tag != MKTAG('R', 'I', 'F', 'F'))
120
 
        return -1;
121
 
    get_le32(pb); /* file size */
122
 
    tag = get_le32(pb);
123
 
    if (tag != MKTAG('W', 'A', 'V', 'E'))
124
 
        return -1;
125
 
    
126
 
    /* parse fmt header */
127
 
    size = find_tag(pb, MKTAG('f', 'm', 't', ' '));
128
 
    if (size < 0)
129
 
        return -1;
130
 
    id = get_le16(pb); 
131
 
    channels = get_le16(pb);
132
 
    rate = get_le32(pb);
133
 
    bit_rate = get_le32(pb) * 8;
134
 
    get_le16(pb); /* block align */
135
 
    get_le16(pb); /* bits per sample */
136
 
    if (size >= 18) {
137
 
        /* wav_extra_size */
138
 
        extra_size = get_le16(pb); 
139
 
        /* skip unused data */
140
 
        url_fseek(pb, size - 18, SEEK_CUR);
141
 
    }
142
 
 
143
 
    size = find_tag(pb, MKTAG('d', 'a', 't', 'a'));
144
 
    if (size < 0)
145
 
        return -1;
146
 
    
147
 
    /* now we are ready: build format streams */
148
 
    st = malloc(sizeof(AVStream));
149
 
    if (!st)
150
 
        return -1;
151
 
    s->nb_streams = 1;
152
 
    s->streams[0] = st;
153
 
 
154
 
    st->id = 0;
155
 
    
156
 
    st->codec.codec_type = CODEC_TYPE_AUDIO;
157
 
    st->codec.codec_tag = id;
158
 
    st->codec.codec_id = codec_get_id(codec_wav_tags, id);
159
 
    st->codec.channels = channels;
160
 
    st->codec.sample_rate = rate;
161
 
    return 0;
162
 
}
163
 
 
164
 
#define MAX_SIZE 4096
165
 
 
166
 
static int wav_read_packet(AVFormatContext *s,
167
 
                           AVPacket *pkt)
168
 
{
169
 
    int packet_size, n, ret;
170
 
 
171
 
    if (url_feof(&s->pb))
172
 
        return -EIO;
173
 
    packet_size = url_get_packet_size(&s->pb);
174
 
    n = MAX_SIZE / packet_size;
175
 
    if (n <= 0)
176
 
        return n = 1;
177
 
    if (av_new_packet(pkt, n * packet_size))
178
 
        return -EIO;
179
 
    pkt->stream_index = 0;
180
 
 
181
 
    ret = get_buffer(&s->pb, pkt->data, pkt->size);
182
 
    if (ret < 0)
183
 
        av_free_packet(pkt);
184
 
    return ret;
185
 
}
186
 
 
187
 
static int wav_read_close(AVFormatContext *s)
188
 
{
189
 
    return 0;
190
 
}
191
 
 
192
 
AVFormat wav_format = {
193
 
    "wav",
194
 
    "wav format",
195
 
    "audio/x-wav",
196
 
    "wav",
197
 
    CODEC_ID_PCM,
198
 
    CODEC_ID_NONE,
199
 
    wav_write_header,
200
 
    wav_write_packet,
201
 
    wav_write_trailer,
202
 
 
203
 
    wav_read_header,
204
 
    wav_read_packet,
205
 
    wav_read_close,
206
 
};