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