3 * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
5 * This file is part of FFmpeg.
7 * FFmpeg 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.
12 * FFmpeg 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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "libavutil/channel_layout.h"
33 #include "gsmdec_template.c"
35 static av_cold
int gsm_init(AVCodecContext
*avctx
)
38 avctx
->channel_layout
= AV_CH_LAYOUT_MONO
;
39 if (!avctx
->sample_rate
)
40 avctx
->sample_rate
= 8000;
41 avctx
->sample_fmt
= AV_SAMPLE_FMT_S16
;
43 switch (avctx
->codec_id
) {
45 avctx
->frame_size
= GSM_FRAME_SIZE
;
46 avctx
->block_align
= GSM_BLOCK_SIZE
;
48 case AV_CODEC_ID_GSM_MS
:
49 avctx
->frame_size
= 2 * GSM_FRAME_SIZE
;
50 if (!avctx
->block_align
)
51 avctx
->block_align
= GSM_MS_BLOCK_SIZE
;
53 if (avctx
->block_align
< MSN_MIN_BLOCK_SIZE
||
54 avctx
->block_align
> GSM_MS_BLOCK_SIZE
||
55 (avctx
->block_align
- MSN_MIN_BLOCK_SIZE
) % 3) {
56 av_log(avctx
, AV_LOG_ERROR
, "Invalid block alignment %d\n",
58 return AVERROR_INVALIDDATA
;
65 static int gsm_decode_frame(AVCodecContext
*avctx
, void *data
,
66 int *got_frame_ptr
, AVPacket
*avpkt
)
68 AVFrame
*frame
= data
;
71 const uint8_t *buf
= avpkt
->data
;
72 int buf_size
= avpkt
->size
;
75 if (buf_size
< avctx
->block_align
) {
76 av_log(avctx
, AV_LOG_ERROR
, "Packet is too small\n");
77 return AVERROR_INVALIDDATA
;
80 /* get output buffer */
81 frame
->nb_samples
= avctx
->frame_size
;
82 if ((res
= ff_get_buffer(avctx
, frame
, 0)) < 0)
84 samples
= (int16_t *)frame
->data
[0];
86 switch (avctx
->codec_id
) {
88 init_get_bits(&gb
, buf
, buf_size
* 8);
89 if (get_bits(&gb
, 4) != 0xd)
90 av_log(avctx
, AV_LOG_WARNING
, "Missing GSM magic!\n");
91 res
= gsm_decode_block(avctx
, samples
, &gb
, GSM_13000
);
95 case AV_CODEC_ID_GSM_MS
:
96 res
= ff_msgsm_decode_block(avctx
, samples
, buf
,
97 (GSM_MS_BLOCK_SIZE
- avctx
->block_align
) / 3);
104 return avctx
->block_align
;
107 static void gsm_flush(AVCodecContext
*avctx
)
109 GSMContext
*s
= avctx
->priv_data
;
110 memset(s
, 0, sizeof(*s
));
113 #if CONFIG_GSM_DECODER
114 AVCodec ff_gsm_decoder
= {
116 .long_name
= NULL_IF_CONFIG_SMALL("GSM"),
117 .type
= AVMEDIA_TYPE_AUDIO
,
118 .id
= AV_CODEC_ID_GSM
,
119 .priv_data_size
= sizeof(GSMContext
),
121 .decode
= gsm_decode_frame
,
123 .capabilities
= CODEC_CAP_DR1
,
126 #if CONFIG_GSM_MS_DECODER
127 AVCodec ff_gsm_ms_decoder
= {
129 .long_name
= NULL_IF_CONFIG_SMALL("GSM Microsoft variant"),
130 .type
= AVMEDIA_TYPE_AUDIO
,
131 .id
= AV_CODEC_ID_GSM_MS
,
132 .priv_data_size
= sizeof(GSMContext
),
134 .decode
= gsm_decode_frame
,
136 .capabilities
= CODEC_CAP_DR1
,