FFmpeg
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
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 FFmpeg.
7
*
8
* FFmpeg 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
* FFmpeg 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 FFmpeg; if not, write to the Free Software
20
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
*/
22
23
/**
24
* @file
25
* Interface to libgsm for gsm encoding/decoding
26
*/
27
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_close
(
AVCodecContext
*avctx) {
39
#if FF_API_OLD_ENCODE_AUDIO
40
av_freep
(&avctx->
coded_frame
);
41
#endif
42
gsm_destroy(avctx->
priv_data
);
43
avctx->
priv_data
=
NULL
;
44
return
0;
45
}
46
47
static
av_cold
int
libgsm_encode_init
(
AVCodecContext
*avctx) {
48
if
(avctx->
channels
> 1) {
49
av_log
(avctx,
AV_LOG_ERROR
,
"Mono required for GSM, got %d channels\n"
,
50
avctx->
channels
);
51
return
-1;
52
}
53
54
if
(avctx->
sample_rate
!= 8000) {
55
av_log
(avctx,
AV_LOG_ERROR
,
"Sample rate 8000Hz required for GSM, got %dHz\n"
,
56
avctx->
sample_rate
);
57
if
(avctx->
strict_std_compliance
>
FF_COMPLIANCE_UNOFFICIAL
)
58
return
-1;
59
}
60
if
(avctx->
bit_rate
!= 13000
/* Official */
&&
61
avctx->
bit_rate
!= 13200
/* Very common */
&&
62
avctx->
bit_rate
!= 0
/* Unknown; a.o. mov does not set bitrate when decoding */
) {
63
av_log
(avctx,
AV_LOG_ERROR
,
"Bitrate 13000bps required for GSM, got %dbps\n"
,
64
avctx->
bit_rate
);
65
if
(avctx->
strict_std_compliance
>
FF_COMPLIANCE_UNOFFICIAL
)
66
return
-1;
67
}
68
69
avctx->
priv_data
= gsm_create();
70
if
(!avctx->
priv_data
)
71
goto
error;
72
73
switch
(avctx->
codec_id
) {
74
case
AV_CODEC_ID_GSM
:
75
avctx->
frame_size
=
GSM_FRAME_SIZE
;
76
avctx->
block_align
=
GSM_BLOCK_SIZE
;
77
break
;
78
case
AV_CODEC_ID_GSM_MS
: {
79
int
one = 1;
80
gsm_option(avctx->
priv_data
, GSM_OPT_WAV49, &one);
81
avctx->
frame_size
= 2*
GSM_FRAME_SIZE
;
82
avctx->
block_align
=
GSM_MS_BLOCK_SIZE
;
83
}
84
}
85
86
#if FF_API_OLD_ENCODE_AUDIO
87
avctx->
coded_frame
=
avcodec_alloc_frame
();
88
if
(!avctx->
coded_frame
)
89
goto
error;
90
#endif
91
92
return
0;
93
error:
94
libgsm_encode_close
(avctx);
95
return
-1;
96
}
97
98
static
int
libgsm_encode_frame
(
AVCodecContext
*avctx,
AVPacket
*avpkt,
99
const
AVFrame
*
frame
,
int
*got_packet_ptr)
100
{
101
int
ret;
102
gsm_signal *
samples
= (gsm_signal *)frame->
data
[0];
103
struct
gsm_state *
state
= avctx->
priv_data
;
104
105
if
((ret =
ff_alloc_packet2
(avctx, avpkt, avctx->
block_align
)))
106
return
ret;
107
108
switch
(avctx->
codec_id
) {
109
case
AV_CODEC_ID_GSM
:
110
gsm_encode(
state
, samples, avpkt->
data
);
111
break
;
112
case
AV_CODEC_ID_GSM_MS
:
113
gsm_encode(
state
, samples, avpkt->
data
);
114
gsm_encode(
state
, samples +
GSM_FRAME_SIZE
, avpkt->
data
+ 32);
115
}
116
117
*got_packet_ptr = 1;
118
return
0;
119
}
120
121
122
#if CONFIG_LIBGSM_ENCODER
123
AVCodec
ff_libgsm_encoder = {
124
.
name
=
"libgsm"
,
125
.type =
AVMEDIA_TYPE_AUDIO
,
126
.id =
AV_CODEC_ID_GSM
,
127
.init =
libgsm_encode_init
,
128
.encode2 =
libgsm_encode_frame
,
129
.close =
libgsm_encode_close
,
130
.sample_fmts = (
const
enum
AVSampleFormat
[]){
AV_SAMPLE_FMT_S16
,
131
AV_SAMPLE_FMT_NONE
},
132
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM"
),
133
};
134
#endif
135
#if CONFIG_LIBGSM_MS_ENCODER
136
AVCodec
ff_libgsm_ms_encoder = {
137
.
name
=
"libgsm_ms"
,
138
.type =
AVMEDIA_TYPE_AUDIO
,
139
.id =
AV_CODEC_ID_GSM_MS
,
140
.init =
libgsm_encode_init
,
141
.encode2 =
libgsm_encode_frame
,
142
.close =
libgsm_encode_close
,
143
.sample_fmts = (
const
enum
AVSampleFormat
[]){
AV_SAMPLE_FMT_S16
,
144
AV_SAMPLE_FMT_NONE
},
145
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM Microsoft variant"
),
146
};
147
#endif
148
149
typedef
struct
LibGSMDecodeContext
{
150
AVFrame
frame
;
151
struct
gsm_state *
state
;
152
}
LibGSMDecodeContext
;
153
154
static
av_cold
int
libgsm_decode_init
(
AVCodecContext
*avctx) {
155
LibGSMDecodeContext
*s = avctx->
priv_data
;
156
157
avctx->
channels
= 1;
158
avctx->
channel_layout
=
AV_CH_LAYOUT_MONO
;
159
if
(!avctx->
sample_rate
)
160
avctx->
sample_rate
= 8000;
161
avctx->
sample_fmt
=
AV_SAMPLE_FMT_S16
;
162
163
s->
state
= gsm_create();
164
165
switch
(avctx->
codec_id
) {
166
case
AV_CODEC_ID_GSM
:
167
avctx->
frame_size
=
GSM_FRAME_SIZE
;
168
avctx->
block_align
=
GSM_BLOCK_SIZE
;
169
break
;
170
case
AV_CODEC_ID_GSM_MS
: {
171
int
one = 1;
172
gsm_option(s->
state
, GSM_OPT_WAV49, &one);
173
avctx->
frame_size
= 2 *
GSM_FRAME_SIZE
;
174
avctx->
block_align
=
GSM_MS_BLOCK_SIZE
;
175
}
176
}
177
178
avcodec_get_frame_defaults
(&s->
frame
);
179
avctx->
coded_frame
= &s->
frame
;
180
181
return
0;
182
}
183
184
static
av_cold
int
libgsm_decode_close
(
AVCodecContext
*avctx) {
185
LibGSMDecodeContext
*s = avctx->
priv_data
;
186
187
gsm_destroy(s->
state
);
188
s->
state
=
NULL
;
189
return
0;
190
}
191
192
static
int
libgsm_decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
193
int
*got_frame_ptr,
AVPacket
*avpkt)
194
{
195
int
i, ret;
196
LibGSMDecodeContext
*s = avctx->
priv_data
;
197
uint8_t
*buf = avpkt->
data
;
198
int
buf_size = avpkt->
size
;
199
int16_t *
samples
;
200
201
if
(buf_size < avctx->block_align) {
202
av_log
(avctx,
AV_LOG_ERROR
,
"Packet is too small\n"
);
203
return
AVERROR_INVALIDDATA
;
204
}
205
206
/* get output buffer */
207
s->
frame
.
nb_samples
= avctx->
frame_size
;
208
if
((ret =
ff_get_buffer
(avctx, &s->
frame
)) < 0) {
209
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
210
return
ret;
211
}
212
samples = (int16_t *)s->
frame
.
data
[0];
213
214
for
(i = 0; i < avctx->
frame_size
/
GSM_FRAME_SIZE
; i++) {
215
if
((ret = gsm_decode(s->
state
, buf, samples)) < 0)
216
return
-1;
217
buf +=
GSM_BLOCK_SIZE
;
218
samples +=
GSM_FRAME_SIZE
;
219
}
220
221
*got_frame_ptr = 1;
222
*(
AVFrame
*)data = s->
frame
;
223
224
return
avctx->
block_align
;
225
}
226
227
static
void
libgsm_flush
(
AVCodecContext
*avctx) {
228
LibGSMDecodeContext
*s = avctx->
priv_data
;
229
int
one = 1;
230
231
gsm_destroy(s->
state
);
232
s->
state
= gsm_create();
233
if
(avctx->
codec_id
==
AV_CODEC_ID_GSM_MS
)
234
gsm_option(s->
state
, GSM_OPT_WAV49, &one);
235
}
236
237
#if CONFIG_LIBGSM_DECODER
238
AVCodec
ff_libgsm_decoder = {
239
.
name
=
"libgsm"
,
240
.type =
AVMEDIA_TYPE_AUDIO
,
241
.id =
AV_CODEC_ID_GSM
,
242
.priv_data_size =
sizeof
(
LibGSMDecodeContext
),
243
.
init
=
libgsm_decode_init
,
244
.
close
=
libgsm_decode_close
,
245
.
decode
=
libgsm_decode_frame
,
246
.
flush
=
libgsm_flush
,
247
.capabilities =
CODEC_CAP_DR1
,
248
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM"
),
249
};
250
#endif
251
#if CONFIG_LIBGSM_MS_DECODER
252
AVCodec
ff_libgsm_ms_decoder = {
253
.
name
=
"libgsm_ms"
,
254
.type =
AVMEDIA_TYPE_AUDIO
,
255
.id =
AV_CODEC_ID_GSM_MS
,
256
.priv_data_size =
sizeof
(
LibGSMDecodeContext
),
257
.
init
=
libgsm_decode_init
,
258
.
close
=
libgsm_decode_close
,
259
.
decode
=
libgsm_decode_frame
,
260
.
flush
=
libgsm_flush
,
261
.capabilities =
CODEC_CAP_DR1
,
262
.long_name =
NULL_IF_CONFIG_SMALL
(
"libgsm GSM Microsoft variant"
),
263
};
264
#endif
Generated on Sat May 25 2013 03:58:35 for FFmpeg by
1.8.2