2
* iLBC storage file format
3
* Copyright (c) 2012 Martin Storsjo
5
* This file is part of Libav.
7
* Libav is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
12
* Libav is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25
static const char mode20_header[] = "#!iLBC20\n";
26
static const char mode30_header[] = "#!iLBC30\n";
28
static int ilbc_write_header(AVFormatContext *s)
30
AVIOContext *pb = s->pb;
33
if (s->nb_streams != 1) {
34
av_log(s, AV_LOG_ERROR, "Unsupported number of streams\n");
35
return AVERROR(EINVAL);
37
enc = s->streams[0]->codec;
39
if (enc->codec_id != AV_CODEC_ID_ILBC) {
40
av_log(s, AV_LOG_ERROR, "Unsupported codec\n");
41
return AVERROR(EINVAL);
44
if (enc->block_align == 50) {
45
avio_write(pb, mode30_header, sizeof(mode30_header) - 1);
46
} else if (enc->block_align == 38) {
47
avio_write(pb, mode20_header, sizeof(mode20_header) - 1);
49
av_log(s, AV_LOG_ERROR, "Unsupported mode\n");
50
return AVERROR(EINVAL);
56
static int ilbc_write_packet(AVFormatContext *s, AVPacket *pkt)
58
avio_write(s->pb, pkt->data, pkt->size);
63
static int ilbc_probe(AVProbeData *p)
65
// Only check for "#!iLBC" which matches both formats
66
if (!memcmp(p->buf, mode20_header, 6))
67
return AVPROBE_SCORE_MAX;
72
static int ilbc_read_header(AVFormatContext *s)
74
AVIOContext *pb = s->pb;
78
avio_read(pb, header, 9);
80
st = avformat_new_stream(s, NULL);
82
return AVERROR(ENOMEM);
83
st->codec->codec_id = AV_CODEC_ID_ILBC;
84
st->codec->sample_rate = 8000;
85
st->codec->channels = 1;
86
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
88
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
89
if (!memcmp(header, mode20_header, sizeof(mode20_header) - 1)) {
90
st->codec->block_align = 38;
91
st->codec->bit_rate = 15200;
92
} else if (!memcmp(header, mode30_header, sizeof(mode30_header) - 1)) {
93
st->codec->block_align = 50;
94
st->codec->bit_rate = 13333;
96
av_log(s, AV_LOG_ERROR, "Unrecognized iLBC file header\n");
97
return AVERROR_INVALIDDATA;
103
static int ilbc_read_packet(AVFormatContext *s,
106
AVCodecContext *enc = s->streams[0]->codec;
109
if ((ret = av_new_packet(pkt, enc->block_align)) < 0)
112
pkt->stream_index = 0;
113
pkt->pos = avio_tell(s->pb);
114
pkt->duration = enc->block_align == 38 ? 160 : 240;
115
if ((ret = avio_read(s->pb, pkt->data, enc->block_align)) != enc->block_align) {
117
return ret < 0 ? ret : AVERROR(EIO);
123
AVInputFormat ff_ilbc_demuxer = {
125
.long_name = NULL_IF_CONFIG_SMALL("iLBC storage"),
126
.read_probe = ilbc_probe,
127
.read_header = ilbc_read_header,
128
.read_packet = ilbc_read_packet,
129
.flags = AVFMT_GENERIC_INDEX,
132
AVOutputFormat ff_ilbc_muxer = {
134
.long_name = NULL_IF_CONFIG_SMALL("iLBC storage"),
135
.mime_type = "audio/iLBC",
137
.audio_codec = AV_CODEC_ID_ILBC,
138
.write_header = ilbc_write_header,
139
.write_packet = ilbc_write_packet,
140
.flags = AVFMT_NOTIMESTAMPS,