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 "
avcodec.h
"
33
#include "
internal.h
"
34
#include "
gsm.h
"
35
36
static
av_cold
int
libgsm_encode_init
(
AVCodecContext
*avctx) {
37
if
(avctx->
channels
> 1) {
38
av_log
(avctx,
AV_LOG_ERROR
,
"Mono required for GSM, got %d channels\n"
,
39
avctx->
channels
);
40
return
-1;
41
}
42
43
if
(avctx->
sample_rate
!= 8000) {
44
av_log
(avctx,
AV_LOG_ERROR
,
"Sample rate 8000Hz required for GSM, got %dHz\n"
,
45
avctx->
sample_rate
);
46
if
(avctx->
strict_std_compliance
>
FF_COMPLIANCE_UNOFFICIAL
)
47
return
-1;
48
}
49
if
(avctx->
bit_rate
!= 13000
/* Official */
&&
50
avctx->
bit_rate
!= 13200
/* Very common */
&&
51
avctx->
bit_rate
!= 0
/* Unknown; a.o. mov does not set bitrate when decoding */
) {
52
av_log
(avctx,
AV_LOG_ERROR
,
"Bitrate 13000bps required for GSM, got %dbps\n"
,
53
avctx->
bit_rate
);
54
if
(avctx->
strict_std_compliance
>
FF_COMPLIANCE_UNOFFICIAL
)
55
return
-1;
56
}
57
58
avctx->
priv_data
= gsm_create();
59
60
switch
(avctx->
codec_id
) {
61
case
CODEC_ID_GSM
:
62
avctx->
frame_size
=
GSM_FRAME_SIZE
;
63
avctx->
block_align
=
GSM_BLOCK_SIZE
;
64
break
;
65
case
CODEC_ID_GSM_MS
: {
66
int
one = 1;
67
gsm_option(avctx->
priv_data
, GSM_OPT_WAV49, &one);
68
avctx->
frame_size
= 2*
GSM_FRAME_SIZE
;
69
avctx->
block_align
=
GSM_MS_BLOCK_SIZE
;
70
}
71
}
72
73
avctx->
coded_frame
=
avcodec_alloc_frame
();
74
avctx->
coded_frame
->
key_frame
= 1;
75
76
return
0;
77
}
78
79
static
av_cold
int
libgsm_encode_close
(
AVCodecContext
*avctx) {
80
av_freep
(&avctx->
coded_frame
);
81
gsm_destroy(avctx->
priv_data
);
82
avctx->
priv_data
=
NULL
;
83
return
0;
84
}
85
86
static
int
libgsm_encode_frame
(
AVCodecContext
*avctx,
87
unsigned
char
*frame,
int
buf_size,
void
*
data
) {
88
// we need a full block
89
if
(buf_size < avctx->block_align)
return
0;
90
91
switch
(avctx->
codec_id
) {
92
case
CODEC_ID_GSM
:
93
gsm_encode(avctx->
priv_data
,data,frame);
94
break
;
95
case
CODEC_ID_GSM_MS
:
96
gsm_encode(avctx->
priv_data
,data,frame);
97
gsm_encode(avctx->
priv_data
,((
short
*)data)+
GSM_FRAME_SIZE
,frame+32);
98
}
99
return
avctx->
block_align
;
100
}
101
102
103
AVCodec
ff_libgsm_encoder
= {
104
.
name
=
"libgsm"
,
105
.type =
AVMEDIA_TYPE_AUDIO
,
106
.id =
CODEC_ID_GSM
,
107
.init =
libgsm_encode_init
,
108
.encode =
libgsm_encode_frame
,
109
.close =
libgsm_encode_close
,
110
.sample_fmts = (
const
enum
AVSampleFormat
[]){
AV_SAMPLE_FMT_S16
,
AV_SAMPLE_FMT_NONE
},
111
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM"
),
112
};
113
114
AVCodec
ff_libgsm_ms_encoder
= {
115
.
name
=
"libgsm_ms"
,
116
.type =
AVMEDIA_TYPE_AUDIO
,
117
.id =
CODEC_ID_GSM_MS
,
118
.init =
libgsm_encode_init
,
119
.encode =
libgsm_encode_frame
,
120
.close =
libgsm_encode_close
,
121
.sample_fmts = (
const
enum
AVSampleFormat
[]){
AV_SAMPLE_FMT_S16
,
AV_SAMPLE_FMT_NONE
},
122
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM Microsoft variant"
),
123
};
124
125
typedef
struct
LibGSMDecodeContext
{
126
AVFrame
frame
;
127
struct
gsm_state *
state
;
128
}
LibGSMDecodeContext
;
129
130
static
av_cold
int
libgsm_decode_init
(
AVCodecContext
*avctx) {
131
LibGSMDecodeContext
*s = avctx->
priv_data
;
132
133
if
(avctx->
channels
> 1) {
134
av_log
(avctx,
AV_LOG_ERROR
,
"Mono required for GSM, got %d channels\n"
,
135
avctx->
channels
);
136
return
-1;
137
}
138
139
if
(!avctx->
channels
)
140
avctx->
channels
= 1;
141
142
if
(!avctx->
sample_rate
)
143
avctx->
sample_rate
= 8000;
144
145
avctx->
sample_fmt
=
AV_SAMPLE_FMT_S16
;
146
147
s->
state
= gsm_create();
148
149
switch
(avctx->
codec_id
) {
150
case
CODEC_ID_GSM
:
151
avctx->
frame_size
=
GSM_FRAME_SIZE
;
152
avctx->
block_align
=
GSM_BLOCK_SIZE
;
153
break
;
154
case
CODEC_ID_GSM_MS
: {
155
int
one = 1;
156
gsm_option(s->
state
, GSM_OPT_WAV49, &one);
157
avctx->
frame_size
= 2 *
GSM_FRAME_SIZE
;
158
avctx->
block_align
=
GSM_MS_BLOCK_SIZE
;
159
}
160
}
161
162
avcodec_get_frame_defaults
(&s->
frame
);
163
avctx->
coded_frame
= &s->
frame
;
164
165
return
0;
166
}
167
168
static
av_cold
int
libgsm_decode_close
(
AVCodecContext
*avctx) {
169
LibGSMDecodeContext
*s = avctx->
priv_data
;
170
171
gsm_destroy(s->
state
);
172
s->
state
=
NULL
;
173
return
0;
174
}
175
176
static
int
libgsm_decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
177
int
*got_frame_ptr,
AVPacket
*avpkt)
178
{
179
int
i, ret;
180
LibGSMDecodeContext
*s = avctx->
priv_data
;
181
uint8_t *buf = avpkt->
data
;
182
int
buf_size = avpkt->
size
;
183
int16_t *
samples
;
184
185
if
(buf_size < avctx->block_align) {
186
av_log
(avctx,
AV_LOG_ERROR
,
"Packet is too small\n"
);
187
return
AVERROR_INVALIDDATA
;
188
}
189
190
/* get output buffer */
191
s->
frame
.
nb_samples
= avctx->
frame_size
;
192
if
((ret =
ff_get_buffer
(avctx, &s->
frame
)) < 0) {
193
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
194
return
ret;
195
}
196
samples = (int16_t *)s->
frame
.
data
[0];
197
198
for
(i = 0; i < avctx->
frame_size
/
GSM_FRAME_SIZE
; i++) {
199
if
((ret = gsm_decode(s->
state
, buf, samples)) < 0)
200
return
-1;
201
buf +=
GSM_BLOCK_SIZE
;
202
samples +=
GSM_FRAME_SIZE
;
203
}
204
205
*got_frame_ptr = 1;
206
*(
AVFrame
*)data = s->
frame
;
207
208
return
avctx->
block_align
;
209
}
210
211
static
void
libgsm_flush
(
AVCodecContext
*avctx) {
212
LibGSMDecodeContext
*s = avctx->
priv_data
;
213
int
one = 1;
214
215
gsm_destroy(s->
state
);
216
s->
state
= gsm_create();
217
if
(avctx->
codec_id
==
CODEC_ID_GSM_MS
)
218
gsm_option(s->
state
, GSM_OPT_WAV49, &one);
219
}
220
221
AVCodec
ff_libgsm_decoder
= {
222
.
name
=
"libgsm"
,
223
.type =
AVMEDIA_TYPE_AUDIO
,
224
.id =
CODEC_ID_GSM
,
225
.priv_data_size =
sizeof
(
LibGSMDecodeContext
),
226
.
init
=
libgsm_decode_init
,
227
.
close
=
libgsm_decode_close
,
228
.
decode
=
libgsm_decode_frame
,
229
.
flush
=
libgsm_flush
,
230
.capabilities =
CODEC_CAP_DR1
,
231
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM"
),
232
};
233
234
AVCodec
ff_libgsm_ms_decoder
= {
235
.
name
=
"libgsm_ms"
,
236
.type =
AVMEDIA_TYPE_AUDIO
,
237
.id =
CODEC_ID_GSM_MS
,
238
.priv_data_size =
sizeof
(
LibGSMDecodeContext
),
239
.
init
=
libgsm_decode_init
,
240
.
close
=
libgsm_decode_close
,
241
.
decode
=
libgsm_decode_frame
,
242
.
flush
=
libgsm_flush
,
243
.capabilities =
CODEC_CAP_DR1
,
244
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM Microsoft variant"
),
245
};