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