Mercurial > libavcodec.hg
annotate libgsm.c @ 8204:507854688c43 libavcodec
Some BMP files have file size declared in the header equal to headers size
without image data, so try to correct that value before conducting checks on
declared file size.
author | kostya |
---|---|
date | Mon, 24 Nov 2008 11:24:02 +0000 |
parents | 4070139042c7 |
children | e9d9d946f213 |
rev | line source |
---|---|
2729 | 1 /* |
2 * Interface to libgsm for gsm encoding/decoding | |
3 * Copyright (c) 2005 Alban Bedel <albeu@free.fr> | |
4551 | 4 * Copyright (c) 2006, 2007 Michel Bardiaux <mbardiaux@mediaxim.be> |
2729 | 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 | 9 * modify it under the terms of the GNU Lesser General Public |
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 | 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 | 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 | |
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 | 21 */ |
2967 | 22 |
2729 | 23 /** |
24 * @file libgsm.c | |
25 * Interface to libgsm for gsm encoding/decoding | |
26 */ | |
27 | |
4551 | 28 // The idiosyncrasies of GSM-in-WAV are explained at http://kbs.cs.tu-berlin.de/~jutta/toast.html |
29 | |
2729 | 30 #include "avcodec.h" |
31 #include <gsm.h> | |
32 | |
5408 | 33 // gsm.h misses some essential constants |
2729 | 34 #define GSM_BLOCK_SIZE 33 |
4551 | 35 #define GSM_MS_BLOCK_SIZE 65 |
2729 | 36 #define GSM_FRAME_SIZE 160 |
37 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
5408
diff
changeset
|
38 static av_cold int libgsm_init(AVCodecContext *avctx) { |
6672
79984fdb1203
Allow bitrates zero and 13200 (needed for decoding mov and aiff)
mbardiaux
parents:
6517
diff
changeset
|
39 if (avctx->channels > 1) { |
79984fdb1203
Allow bitrates zero and 13200 (needed for decoding mov and aiff)
mbardiaux
parents:
6517
diff
changeset
|
40 av_log(avctx, AV_LOG_ERROR, "Mono required for GSM, got %d channels\n", |
79984fdb1203
Allow bitrates zero and 13200 (needed for decoding mov and aiff)
mbardiaux
parents:
6517
diff
changeset
|
41 avctx->channels); |
79984fdb1203
Allow bitrates zero and 13200 (needed for decoding mov and aiff)
mbardiaux
parents:
6517
diff
changeset
|
42 return -1; |
79984fdb1203
Allow bitrates zero and 13200 (needed for decoding mov and aiff)
mbardiaux
parents:
6517
diff
changeset
|
43 } |
6720 | 44 |
45 if(avctx->codec->decode){ | |
46 if(!avctx->channels) | |
47 avctx->channels= 1; | |
48 | |
49 if(!avctx->sample_rate) | |
50 avctx->sample_rate= 8000; | |
7451
85ab7655ad4d
Modify all codecs to report their supported input and output sample format(s).
pross
parents:
7040
diff
changeset
|
51 |
85ab7655ad4d
Modify all codecs to report their supported input and output sample format(s).
pross
parents:
7040
diff
changeset
|
52 avctx->sample_fmt = SAMPLE_FMT_S16; |
6720 | 53 }else{ |
6721 | 54 if (avctx->sample_rate != 8000) { |
55 av_log(avctx, AV_LOG_ERROR, "Sample rate 8000Hz required for GSM, got %dHz\n", | |
56 avctx->sample_rate); | |
57 if(avctx->strict_std_compliance > FF_COMPLIANCE_INOFFICIAL) | |
58 return -1; | |
59 } | |
60 if (avctx->bit_rate != 13000 /* Official */ && | |
61 avctx->bit_rate != 13200 /* Very common */ && | |
62 avctx->bit_rate != 0 /* Unknown; a.o. mov does not set bitrate when decoding */ ) { | |
63 av_log(avctx, AV_LOG_ERROR, "Bitrate 13000bps required for GSM, got %dbps\n", | |
64 avctx->bit_rate); | |
65 if(avctx->strict_std_compliance > FF_COMPLIANCE_INOFFICIAL) | |
66 return -1; | |
67 } | |
6720 | 68 } |
2729 | 69 |
4551 | 70 avctx->priv_data = gsm_create(); |
2729 | 71 |
4551 | 72 switch(avctx->codec_id) { |
73 case CODEC_ID_GSM: | |
74 avctx->frame_size = GSM_FRAME_SIZE; | |
75 avctx->block_align = GSM_BLOCK_SIZE; | |
76 break; | |
77 case CODEC_ID_GSM_MS: { | |
78 int one = 1; | |
79 gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one); | |
80 avctx->frame_size = 2*GSM_FRAME_SIZE; | |
81 avctx->block_align = GSM_MS_BLOCK_SIZE; | |
82 } | |
83 } | |
2967 | 84 |
2729 | 85 avctx->coded_frame= avcodec_alloc_frame(); |
86 avctx->coded_frame->key_frame= 1; | |
2967 | 87 |
2729 | 88 return 0; |
89 } | |
90 | |
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
5408
diff
changeset
|
91 static av_cold int libgsm_close(AVCodecContext *avctx) { |
8124 | 92 av_freep(&avctx->coded_frame); |
2729 | 93 gsm_destroy(avctx->priv_data); |
94 avctx->priv_data = NULL; | |
95 return 0; | |
96 } | |
97 | |
98 static int libgsm_encode_frame(AVCodecContext *avctx, | |
99 unsigned char *frame, int buf_size, void *data) { | |
100 // we need a full block | |
4551 | 101 if(buf_size < avctx->block_align) return 0; |
2729 | 102 |
4551 | 103 switch(avctx->codec_id) { |
104 case CODEC_ID_GSM: | |
105 gsm_encode(avctx->priv_data,data,frame); | |
106 break; | |
107 case CODEC_ID_GSM_MS: | |
108 gsm_encode(avctx->priv_data,data,frame); | |
109 gsm_encode(avctx->priv_data,((short*)data)+GSM_FRAME_SIZE,frame+32); | |
110 } | |
111 return avctx->block_align; | |
2729 | 112 } |
113 | |
114 | |
115 AVCodec libgsm_encoder = { | |
5102
4323e587708d
Give names of external library decoders/encoders a lib prefix
diego
parents:
4551
diff
changeset
|
116 "libgsm", |
2729 | 117 CODEC_TYPE_AUDIO, |
118 CODEC_ID_GSM, | |
119 0, | |
120 libgsm_init, | |
121 libgsm_encode_frame, | |
122 libgsm_close, | |
7451
85ab7655ad4d
Modify all codecs to report their supported input and output sample format(s).
pross
parents:
7040
diff
changeset
|
123 .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6721
diff
changeset
|
124 .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"), |
2729 | 125 }; |
126 | |
4551 | 127 AVCodec libgsm_ms_encoder = { |
5102
4323e587708d
Give names of external library decoders/encoders a lib prefix
diego
parents:
4551
diff
changeset
|
128 "libgsm_ms", |
4551 | 129 CODEC_TYPE_AUDIO, |
130 CODEC_ID_GSM_MS, | |
131 0, | |
132 libgsm_init, | |
133 libgsm_encode_frame, | |
134 libgsm_close, | |
7451
85ab7655ad4d
Modify all codecs to report their supported input and output sample format(s).
pross
parents:
7040
diff
changeset
|
135 .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6721
diff
changeset
|
136 .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"), |
4551 | 137 }; |
138 | |
2729 | 139 static int libgsm_decode_frame(AVCodecContext *avctx, |
140 void *data, int *data_size, | |
141 uint8_t *buf, int buf_size) { | |
6673
679b9ef6f5f3
Make sure some value is always returned via data_size
mbardiaux
parents:
6672
diff
changeset
|
142 *data_size = 0; /* In case of error */ |
679b9ef6f5f3
Make sure some value is always returned via data_size
mbardiaux
parents:
6672
diff
changeset
|
143 if(buf_size < avctx->block_align) return -1; |
4551 | 144 switch(avctx->codec_id) { |
145 case CODEC_ID_GSM: | |
146 if(gsm_decode(avctx->priv_data,buf,data)) return -1; | |
147 *data_size = GSM_FRAME_SIZE*sizeof(int16_t); | |
148 break; | |
149 case CODEC_ID_GSM_MS: | |
150 if(gsm_decode(avctx->priv_data,buf,data) || | |
151 gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1; | |
152 *data_size = GSM_FRAME_SIZE*sizeof(int16_t)*2; | |
153 } | |
154 return avctx->block_align; | |
2729 | 155 } |
156 | |
157 AVCodec libgsm_decoder = { | |
5102
4323e587708d
Give names of external library decoders/encoders a lib prefix
diego
parents:
4551
diff
changeset
|
158 "libgsm", |
2729 | 159 CODEC_TYPE_AUDIO, |
160 CODEC_ID_GSM, | |
161 0, | |
162 libgsm_init, | |
163 NULL, | |
164 libgsm_close, | |
165 libgsm_decode_frame, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6721
diff
changeset
|
166 .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"), |
2729 | 167 }; |
4551 | 168 |
169 AVCodec libgsm_ms_decoder = { | |
5102
4323e587708d
Give names of external library decoders/encoders a lib prefix
diego
parents:
4551
diff
changeset
|
170 "libgsm_ms", |
4551 | 171 CODEC_TYPE_AUDIO, |
172 CODEC_ID_GSM_MS, | |
173 0, | |
174 libgsm_init, | |
175 NULL, | |
176 libgsm_close, | |
177 libgsm_decode_frame, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6721
diff
changeset
|
178 .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"), |
4551 | 179 }; |