Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavcodec
gsmdec.c
Go to the documentation of this file.
1
/*
2
* gsm 06.10 decoder
3
* Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
4
*
5
* This file is part of Libav.
6
*
7
* Libav is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* Libav is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with Libav; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
27
#include "
avcodec.h
"
28
#include "
internal.h
"
29
#include "
get_bits.h
"
30
#include "
msgsmdec.h
"
31
32
#include "
gsmdec_template.c
"
33
34
static
av_cold
int
gsm_init
(
AVCodecContext
*avctx)
35
{
36
GSMContext
*s = avctx->
priv_data
;
37
38
avctx->
channels
= 1;
39
if
(!avctx->
sample_rate
)
40
avctx->
sample_rate
= 8000;
41
avctx->
sample_fmt
=
AV_SAMPLE_FMT_S16
;
42
43
switch
(avctx->
codec_id
) {
44
case
CODEC_ID_GSM
:
45
avctx->
frame_size
=
GSM_FRAME_SIZE
;
46
avctx->
block_align
=
GSM_BLOCK_SIZE
;
47
break
;
48
case
CODEC_ID_GSM_MS
:
49
avctx->
frame_size
= 2 *
GSM_FRAME_SIZE
;
50
avctx->
block_align
=
GSM_MS_BLOCK_SIZE
;
51
}
52
53
avcodec_get_frame_defaults
(&s->
frame
);
54
avctx->
coded_frame
= &s->
frame
;
55
56
return
0;
57
}
58
59
static
int
gsm_decode_frame
(
AVCodecContext
*avctx,
void
*
data
,
60
int
*got_frame_ptr,
AVPacket
*avpkt)
61
{
62
GSMContext
*s = avctx->
priv_data
;
63
int
res;
64
GetBitContext
gb;
65
const
uint8_t *buf = avpkt->
data
;
66
int
buf_size = avpkt->
size
;
67
int16_t *
samples
;
68
69
if
(buf_size < avctx->block_align) {
70
av_log
(avctx,
AV_LOG_ERROR
,
"Packet is too small\n"
);
71
return
AVERROR_INVALIDDATA
;
72
}
73
74
/* get output buffer */
75
s->
frame
.
nb_samples
= avctx->
frame_size
;
76
if
((res =
ff_get_buffer
(avctx, &s->
frame
)) < 0) {
77
av_log
(avctx,
AV_LOG_ERROR
,
"get_buffer() failed\n"
);
78
return
res;
79
}
80
samples = (int16_t *)s->
frame
.
data
[0];
81
82
switch (avctx->
codec_id
) {
83
case
CODEC_ID_GSM
:
84
init_get_bits
(&gb, buf, buf_size * 8);
85
if
(
get_bits
(&gb, 4) != 0xd)
86
av_log
(avctx,
AV_LOG_WARNING
,
"Missing GSM magic!\n"
);
87
res =
gsm_decode_block
(avctx, samples, &gb);
88
if
(res < 0)
89
return
res;
90
break
;
91
case
CODEC_ID_GSM_MS
:
92
res =
ff_msgsm_decode_block
(avctx, samples, buf);
93
if
(res < 0)
94
return
res;
95
}
96
97
*got_frame_ptr = 1;
98
*(
AVFrame
*)data = s->
frame
;
99
100
return
avctx->
block_align
;
101
}
102
103
static
void
gsm_flush
(
AVCodecContext
*avctx)
104
{
105
GSMContext
*s = avctx->
priv_data
;
106
memset(s, 0,
sizeof
(*s));
107
}
108
109
AVCodec
ff_gsm_decoder
= {
110
.
name
=
"gsm"
,
111
.type =
AVMEDIA_TYPE_AUDIO
,
112
.id =
CODEC_ID_GSM
,
113
.priv_data_size =
sizeof
(
GSMContext
),
114
.
init
=
gsm_init
,
115
.
decode
=
gsm_decode_frame
,
116
.
flush
=
gsm_flush
,
117
.capabilities =
CODEC_CAP_DR1
,
118
.long_name =
NULL_IF_CONFIG_SMALL
(
"GSM"
),
119
};
120
121
AVCodec
ff_gsm_ms_decoder
= {
122
.
name
=
"gsm_ms"
,
123
.type =
AVMEDIA_TYPE_AUDIO
,
124
.id =
CODEC_ID_GSM_MS
,
125
.priv_data_size =
sizeof
(
GSMContext
),
126
.
init
=
gsm_init
,
127
.
decode
=
gsm_decode_frame
,
128
.
flush
=
gsm_flush
,
129
.capabilities =
CODEC_CAP_DR1
,
130
.long_name =
NULL_IF_CONFIG_SMALL
(
"GSM Microsoft variant"
),
131
};