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