Statistics
| Branch: | Revision:

ffmpeg / libavformat / amr.c @ 2f4db4d5

History | View | Annotate | Download (3.78 KB)

1
/* 
2
 * amr file format
3
 * Copyright (c) 2001 ffmpeg project
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library 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 GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19

    
20
/*
21
Write and read amr data according to RFC3267, http://www.ietf.org/rfc/rfc3267.txt?number=3267
22

23
Only amr narrowband (not amr-wb) is supported for now.
24

25
*/
26
#include "avformat.h"
27
#include "avi.h"
28

    
29
static const unsigned char AMR_header [] = "#!AMR\n";
30

    
31
/* AMR_FILE header */
32
static int put_amr_header(ByteIOContext *pb, AVCodecContext *enc)
33
{
34
    put_tag(pb, AMR_header);       /* magic number */
35
    return 0;
36
}
37

    
38
static int amr_write_header(AVFormatContext *s)
39
{
40
    ByteIOContext *pb = &s->pb;
41

    
42
    s->priv_data = NULL;
43

    
44
    /* format header */
45
    if (put_amr_header(pb, &s->streams[0]->codec) < 0) {
46
        return -1;
47
    }
48

    
49
    put_flush_packet(pb);
50

    
51
    return 0;
52
}
53

    
54
static int amr_write_packet(AVFormatContext *s, int stream_index_ptr,
55
                           uint8_t *buf, int size, int force_pts)
56
{
57
    put_buffer(&s->pb, buf, size);
58
    put_flush_packet(&s->pb);
59
    return 0;
60
}
61

    
62
static int amr_write_trailer(AVFormatContext *s)
63
{
64
    return 0;
65
}
66

    
67
static int amr_probe(AVProbeData *p)
68
{
69
    /* check file header */
70
    if (p->buf_size < 6)
71
        return 0;
72
    if(memcmp(p->buf,AMR_header,6)==0)
73
        return AVPROBE_SCORE_MAX;
74
    else
75
        return 0;
76
}
77

    
78
/* amr input */
79
static int amr_read_header(AVFormatContext *s,
80
                           AVFormatParameters *ap)
81
{
82
    ByteIOContext *pb = &s->pb;
83
    AVStream *st;
84
    uint8_t header[6];
85

    
86
    get_buffer(pb, header, 6);
87

    
88
    if(memcmp(header,AMR_header,6)!=0)
89
    {
90
        return -1;
91
    }
92

    
93
    st = av_new_stream(s, 0);
94
    if (!st)
95
        return AVERROR_NOMEM;
96

    
97
    st->codec.codec_type = CODEC_TYPE_AUDIO;
98
    st->codec.codec_tag = CODEC_ID_AMR_NB;
99
    st->codec.codec_id = CODEC_ID_AMR_NB;
100
    st->codec.channels = 1;
101
    st->codec.sample_rate = 8000;
102
    return 0;
103
}
104

    
105
#define MAX_SIZE 32
106

    
107
static int amr_read_packet(AVFormatContext *s,
108
                          AVPacket *pkt)
109
{
110
    static uint16_t packed_size[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0};
111
    uint8_t toc, q, ft;
112
    int read;
113
    int size;
114

    
115
    if (url_feof(&s->pb))
116
        return -EIO;
117

    
118
    toc=0;
119

    
120
    toc=get_byte(&s->pb);
121

    
122
    q  = (toc >> 2) & 0x01;
123
    ft = (toc >> 3) & 0x0F;
124

    
125
    size=packed_size[ft];
126
    //printf("amr_read_packet size=%d\n",size);
127

    
128
    if (av_new_packet(pkt, size+1))
129
        return -EIO;
130
    pkt->stream_index = 0;
131
    
132
    pkt->data[0]=toc;
133

    
134
    read = get_buffer(&s->pb, pkt->data+1, size);
135

    
136
    if (read != size)
137
    {
138
        av_free_packet(pkt);
139
        return -EIO;
140
    }
141

    
142
    return 0;
143
}
144

    
145
static int amr_read_close(AVFormatContext *s)
146
{
147
    return 0;
148
}
149

    
150
static AVInputFormat amr_iformat = {
151
    "amr",
152
    "3gpp amr file format",
153
    0,
154
    amr_probe,
155
    amr_read_header,
156
    amr_read_packet,
157
    amr_read_close,
158
};
159

    
160
static AVOutputFormat amr_oformat = {
161
    "amr",
162
    "3gpp amr file format",
163
    "audio/amr",
164
    "amr",
165
    0,
166
    CODEC_ID_AMR_NB,
167
    CODEC_ID_NONE,
168
    amr_write_header,
169
    amr_write_packet,
170
    amr_write_trailer,
171
};
172

    
173
int amr_init(void)
174
{
175
    av_register_input_format(&amr_iformat);
176
    av_register_output_format(&amr_oformat);
177
    return 0;
178
}