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