annotate libgsm.c @ 5594:384629ebcb93 libavcodec

avoid overflow in the 3rd lifting step, this now needs mmx2 at minimum (patch for plain mmx support is welcome ...)
author michael
date Sun, 26 Aug 2007 01:11:02 +0000
parents 20bea6a9950c
children 48759bfbd073
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
1 /*
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
2 * Interface to libgsm for gsm encoding/decoding
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
3 * Copyright (c) 2005 Alban Bedel <albeu@free.fr>
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
4 * Copyright (c) 2006, 2007 Michel Bardiaux <mbardiaux@mediaxim.be>
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
5 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
6 * This file is part of FFmpeg.
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
7 *
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
12 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
16 * Lesser General Public License for more details.
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
17 *
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
3036
0b546eab515d Update licensing information: The FSF changed postal address.
diego
parents: 2967
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
21 */
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2729
diff changeset
22
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
23 /**
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
24 * @file libgsm.c
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
25 * Interface to libgsm for gsm encoding/decoding
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
26 */
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
27
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
28 // The idiosyncrasies of GSM-in-WAV are explained at http://kbs.cs.tu-berlin.de/~jutta/toast.html
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
29
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
30 #include "avcodec.h"
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
31 #include <gsm.h>
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
32
5408
20bea6a9950c cosmetics: misc typo fixes
diego
parents: 5102
diff changeset
33 // gsm.h misses some essential constants
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
34 #define GSM_BLOCK_SIZE 33
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
35 #define GSM_MS_BLOCK_SIZE 65
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
36 #define GSM_FRAME_SIZE 160
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
37
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
38 static int libgsm_init(AVCodecContext *avctx) {
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
39 if (avctx->channels > 1 || avctx->sample_rate != 8000 || avctx->bit_rate != 13000)
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
40 return -1;
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
41
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
42 avctx->priv_data = gsm_create();
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
43
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
44 switch(avctx->codec_id) {
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
45 case CODEC_ID_GSM:
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
46 avctx->frame_size = GSM_FRAME_SIZE;
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
47 avctx->block_align = GSM_BLOCK_SIZE;
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
48 break;
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
49 case CODEC_ID_GSM_MS: {
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
50 int one = 1;
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
51 gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one);
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
52 avctx->frame_size = 2*GSM_FRAME_SIZE;
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
53 avctx->block_align = GSM_MS_BLOCK_SIZE;
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
54 }
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
55 }
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2729
diff changeset
56
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
57 avctx->coded_frame= avcodec_alloc_frame();
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
58 avctx->coded_frame->key_frame= 1;
2967
ef2149182f1c COSMETICS: Remove all trailing whitespace.
diego
parents: 2729
diff changeset
59
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
60 return 0;
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
61 }
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
62
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
63 static int libgsm_close(AVCodecContext *avctx) {
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
64 gsm_destroy(avctx->priv_data);
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
65 avctx->priv_data = NULL;
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
66 return 0;
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
67 }
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
68
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
69 static int libgsm_encode_frame(AVCodecContext *avctx,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
70 unsigned char *frame, int buf_size, void *data) {
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
71 // we need a full block
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
72 if(buf_size < avctx->block_align) return 0;
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
73
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
74 switch(avctx->codec_id) {
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
75 case CODEC_ID_GSM:
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
76 gsm_encode(avctx->priv_data,data,frame);
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
77 break;
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
78 case CODEC_ID_GSM_MS:
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
79 gsm_encode(avctx->priv_data,data,frame);
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
80 gsm_encode(avctx->priv_data,((short*)data)+GSM_FRAME_SIZE,frame+32);
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
81 }
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
82 return avctx->block_align;
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
83 }
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
84
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
85
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
86 AVCodec libgsm_encoder = {
5102
4323e587708d Give names of external library decoders/encoders a lib prefix
diego
parents: 4551
diff changeset
87 "libgsm",
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
88 CODEC_TYPE_AUDIO,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
89 CODEC_ID_GSM,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
90 0,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
91 libgsm_init,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
92 libgsm_encode_frame,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
93 libgsm_close,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
94 };
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
95
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
96 AVCodec libgsm_ms_encoder = {
5102
4323e587708d Give names of external library decoders/encoders a lib prefix
diego
parents: 4551
diff changeset
97 "libgsm_ms",
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
98 CODEC_TYPE_AUDIO,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
99 CODEC_ID_GSM_MS,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
100 0,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
101 libgsm_init,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
102 libgsm_encode_frame,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
103 libgsm_close,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
104 };
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
105
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
106 static int libgsm_decode_frame(AVCodecContext *avctx,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
107 void *data, int *data_size,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
108 uint8_t *buf, int buf_size) {
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
109
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
110 if(buf_size < avctx->block_align) return 0;
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
111
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
112 switch(avctx->codec_id) {
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
113 case CODEC_ID_GSM:
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
114 if(gsm_decode(avctx->priv_data,buf,data)) return -1;
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
115 *data_size = GSM_FRAME_SIZE*sizeof(int16_t);
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
116 break;
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
117 case CODEC_ID_GSM_MS:
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
118 if(gsm_decode(avctx->priv_data,buf,data) ||
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
119 gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1;
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
120 *data_size = GSM_FRAME_SIZE*sizeof(int16_t)*2;
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
121 }
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
122 return avctx->block_align;
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
123 }
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
124
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
125 AVCodec libgsm_decoder = {
5102
4323e587708d Give names of external library decoders/encoders a lib prefix
diego
parents: 4551
diff changeset
126 "libgsm",
2729
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
127 CODEC_TYPE_AUDIO,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
128 CODEC_ID_GSM,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
129 0,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
130 libgsm_init,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
131 NULL,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
132 libgsm_close,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
133 libgsm_decode_frame,
26bf6f4e9945 libgsm warper by (Alban Bedel: albeu, free fr)
michael
parents:
diff changeset
134 };
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
135
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
136 AVCodec libgsm_ms_decoder = {
5102
4323e587708d Give names of external library decoders/encoders a lib prefix
diego
parents: 4551
diff changeset
137 "libgsm_ms",
4551
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
138 CODEC_TYPE_AUDIO,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
139 CODEC_ID_GSM_MS,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
140 0,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
141 libgsm_init,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
142 NULL,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
143 libgsm_close,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
144 libgsm_decode_frame,
c0bf618fbe7e Add support for MS-GSM codec
mbardiaux
parents: 3947
diff changeset
145 };