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