Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
libgsm.c
Go to the documentation of this file.
1
/*
2
* Interface to libgsm for gsm encoding/decoding
3
* Copyright (c) 2005 Alban Bedel <albeu@free.fr>
4
* Copyright (c) 2006, 2007 Michel Bardiaux <mbardiaux@mediaxim.be>
5
*
6
* This file is part of Libav.
7
*
8
* Libav is free software; you can redistribute it and/or
9
* modify it under the terms of the GNU Lesser General Public
10
* License as published by the Free Software Foundation; either
11
* version 2.1 of the License, or (at your option) any later version.
12
*
13
* Libav is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
* Lesser General Public License for more details.
17
*
18
* You should have received a copy of the GNU Lesser General Public
19
* License along with Libav; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
*/
22
28
// The idiosyncrasies of GSM-in-WAV are explained at http://kbs.cs.tu-berlin.de/~jutta/toast.html
29
30
#include <gsm/gsm.h>
31
32
#include "
libavutil/channel_layout.h
"
33
#include "
libavutil/common.h
"
34
#include "
avcodec.h
"
35
#include "
internal.h
"
36
#include "
gsm.h
"
37
38
static
av_cold
int
libgsm_encode_init
(
AVCodecContext
*avctx) {
39
if
(avctx->
channels
> 1) {
40
av_log
(avctx,
AV_LOG_ERROR
,
"Mono required for GSM, got %d channels\n"
,
41
avctx->
channels
);
42
return
-1;
43
}
44
45
if
(avctx->
sample_rate
!= 8000) {
46
av_log
(avctx,
AV_LOG_ERROR
,
"Sample rate 8000Hz required for GSM, got %dHz\n"
,
47
avctx->
sample_rate
);
48
if
(avctx->
strict_std_compliance
>
FF_COMPLIANCE_UNOFFICIAL
)
49
return
-1;
50
}
51
if
(avctx->
bit_rate
!= 13000
/* Official */
&&
52
avctx->
bit_rate
!= 13200
/* Very common */
&&
53
avctx->
bit_rate
!= 0
/* Unknown; a.o. mov does not set bitrate when decoding */
) {
54
av_log
(avctx,
AV_LOG_ERROR
,
"Bitrate 13000bps required for GSM, got %dbps\n"
,
55
avctx->
bit_rate
);
56
if
(avctx->
strict_std_compliance
>
FF_COMPLIANCE_UNOFFICIAL
)
57
return
-1;
58
}
59
60
avctx->
priv_data
= gsm_create();
61
62
switch
(avctx->
codec_id
) {
63
case
AV_CODEC_ID_GSM
:
64
avctx->
frame_size
=
GSM_FRAME_SIZE
;
65
avctx->
block_align
=
GSM_BLOCK_SIZE
;
66
break
;
67
case
AV_CODEC_ID_GSM_MS
: {
68
int
one = 1;
69
gsm_option(avctx->
priv_data
, GSM_OPT_WAV49, &one);
70
avctx->
frame_size
= 2*
GSM_FRAME_SIZE
;
71
avctx->
block_align
=
GSM_MS_BLOCK_SIZE
;
72
}
73
}
74
75
#if FF_API_OLD_ENCODE_AUDIO
76
avctx->
coded_frame
=
avcodec_alloc_frame
();
77
if
(!avctx->
coded_frame
) {
78
gsm_destroy(avctx->
priv_data
);
79
return
AVERROR
(ENOMEM);
80
}
81
#endif
82
83
return
0;
84
}
85
86
static
av_cold
int
libgsm_encode_close
(
AVCodecContext
*avctx) {
87
#if FF_API_OLD_ENCODE_AUDIO
88
av_freep
(&avctx->
coded_frame
);
89
#endif
90
gsm_destroy(avctx->
priv_data
);
91
avctx->
priv_data
=
NULL
;
92
return
0;
93
}
94
95
static
int
libgsm_encode_frame
(
AVCodecContext
*avctx,
AVPacket
*avpkt,
96
const
AVFrame
*frame,
int
*got_packet_ptr)
97
{
98
int
ret;
99
gsm_signal *
samples
= (gsm_signal *)frame->
data
[0];
100
struct
gsm_state *
state
= avctx->
priv_data
;
101
102
if ((ret =
ff_alloc_packet
(avpkt, avctx->
block_align
))) {
103
av_log
(avctx,
AV_LOG_ERROR
,
"Error getting output packet\n"
);
104
return
ret;
105
}
106
107
switch
(avctx->
codec_id
) {
108
case
AV_CODEC_ID_GSM
:
109
gsm_encode(
state
, samples, avpkt->
data
);
110
break
;
111
case
AV_CODEC_ID_GSM_MS
:
112
gsm_encode(
state
, samples, avpkt->
data
);
113
gsm_encode(
state
, samples +
GSM_FRAME_SIZE
, avpkt->
data
+ 32);
114
}
115
116
*got_packet_ptr = 1;
117
return
0;
118
}
119
120
121
AVCodec
ff_libgsm_encoder
= {
122
.
name
=
"libgsm"
,
123
.type =
AVMEDIA_TYPE_AUDIO
,
124
.id =
AV_CODEC_ID_GSM
,
125
.init =
libgsm_encode_init
,
126
.encode2 =
libgsm_encode_frame
,
127
.close =
libgsm_encode_close
,
128
.sample_fmts = (
const
enum
AVSampleFormat
[]){
AV_SAMPLE_FMT_S16
,
129
AV_SAMPLE_FMT_NONE
},
130
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM"
),
131
};
132
133
AVCodec
ff_libgsm_ms_encoder
= {
134
.
name
=
"libgsm_ms"
,
135
.type =
AVMEDIA_TYPE_AUDIO
,
136
.id =
AV_CODEC_ID_GSM_MS
,
137
.init =
libgsm_encode_init
,
138
.encode2 =
libgsm_encode_frame
,
139
.close =
libgsm_encode_close
,
140
.sample_fmts = (
const
enum
AVSampleFormat
[]){
AV_SAMPLE_FMT_S16
,
141
AV_SAMPLE_FMT_NONE
},
142
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM Microsoft variant"
),
143
};
144
145
typedef
struct
LibGSMDecodeContext
{
146
AVFrame
frame
;
147
struct
gsm_state *
state
;
148
}
LibGSMDecodeContext
;
149
150
static
av_cold
int
libgsm_decode_init
(
AVCodecContext
*avctx) {
151
LibGSMDecodeContext
*s = avctx->
priv_data
;
152
153
avctx->
channels
= 1;
154
avctx->
channel_layout
=
AV_CH_LAYOUT_MONO
;
155
avctx->
sample_rate
= 8000;
156
avctx->
sample_fmt
=
AV_SAMPLE_FMT_S16
;
157
158
s->
state
= gsm_create();
159
160
switch
(avctx->
codec_id
) {
161
case
AV_CODEC_ID_GSM
:
162
avctx->
frame_size
=
GSM_FRAME_SIZE
;
163
avctx->
block_align
=
GSM_BLOCK_SIZE
;
164
break
;
165
case
AV_CODEC_ID_GSM_MS
: {
166
int
one = 1;
167
gsm_option(s->
state
, GSM_OPT_WAV49, &one);
168
avctx->
frame_size
= 2 *
GSM_FRAME_SIZE
;
169
avctx->
block_align
=
GSM_MS_BLOCK_SIZE
;
170
}
171
}
172
173
avcodec_get_frame_defaults
(&s->
frame
);
174
avctx->
coded_frame
= &s->
frame
;
175
176
return
0;
177
}
178
179
static
av_cold
int
libgsm_decode_close
(
AVCodecContext
*avctx) {
180
LibGSMDecodeContext
*s = avctx->
priv_data
;
181
182
gsm_destroy(s->
state
);
183
s->
state
=
NULL
;
184
return
0;
185
}
186
187
static
int
libgsm_decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
188
int
*got_frame_ptr,
AVPacket
*avpkt)
189
{
190
int
i, ret;
191
LibGSMDecodeContext
*s = avctx->
priv_data
;
192
uint8_t
*buf = avpkt->
data
;
193
int
buf_size = avpkt->
size
;
194
int16_t *
samples
;
195
196
if
(buf_size < avctx->block_align) {
197
av_log
(avctx,
AV_LOG_ERROR
,
"Packet is too small\n"
);
198
return
AVERROR_INVALIDDATA
;
199
}
200
201
/* get output buffer */
202
s->
frame
.
nb_samples
= avctx->
frame_size
;
203
if
((ret =
ff_get_buffer
(avctx, &s->
frame
)) < 0) {
204
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
205
return
ret;
206
}
207
samples = (int16_t *)s->
frame
.
data
[0];
208
209
for
(i = 0; i < avctx->
frame_size
/
GSM_FRAME_SIZE
; i++) {
210
if
((ret = gsm_decode(s->
state
, buf, samples)) < 0)
211
return
-1;
212
buf +=
GSM_BLOCK_SIZE
;
213
samples +=
GSM_FRAME_SIZE
;
214
}
215
216
*got_frame_ptr = 1;
217
*(
AVFrame
*)data = s->
frame
;
218
219
return
avctx->
block_align
;
220
}
221
222
static
void
libgsm_flush
(
AVCodecContext
*avctx) {
223
LibGSMDecodeContext
*s = avctx->
priv_data
;
224
int
one = 1;
225
226
gsm_destroy(s->
state
);
227
s->
state
= gsm_create();
228
if
(avctx->
codec_id
==
AV_CODEC_ID_GSM_MS
)
229
gsm_option(s->
state
, GSM_OPT_WAV49, &one);
230
}
231
232
AVCodec
ff_libgsm_decoder
= {
233
.
name
=
"libgsm"
,
234
.type =
AVMEDIA_TYPE_AUDIO
,
235
.id =
AV_CODEC_ID_GSM
,
236
.priv_data_size =
sizeof
(
LibGSMDecodeContext
),
237
.
init
=
libgsm_decode_init
,
238
.
close
=
libgsm_decode_close
,
239
.
decode
=
libgsm_decode_frame
,
240
.
flush
=
libgsm_flush
,
241
.capabilities =
CODEC_CAP_DR1
,
242
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM"
),
243
};
244
245
AVCodec
ff_libgsm_ms_decoder
= {
246
.
name
=
"libgsm_ms"
,
247
.type =
AVMEDIA_TYPE_AUDIO
,
248
.id =
AV_CODEC_ID_GSM_MS
,
249
.priv_data_size =
sizeof
(
LibGSMDecodeContext
),
250
.
init
=
libgsm_decode_init
,
251
.
close
=
libgsm_decode_close
,
252
.
decode
=
libgsm_decode_frame
,
253
.
flush
=
libgsm_flush
,
254
.capabilities =
CODEC_CAP_DR1
,
255
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM Microsoft variant"
),
256
};