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