Mercurial > libavcodec.hg
annotate libgsm.c @ 12266:48d6738904a9 libavcodec
Fix SPLATB_REG mess. Used to be a if/elseif/elseif/elseif spaghetti, so this
splits it into small optimization-specific macros which are selected for each
DSP function. The advantage of this approach is that the sse4 functions now
use the ssse3 codepath also without needing an explicit sse4 codepath.
author | rbultje |
---|---|
date | Sat, 24 Jul 2010 19:33:05 +0000 |
parents | b6cf19580e47 |
children |
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 /** |
11644
7dd2a45249a9
Remove explicit filename from Doxygen @file commands.
diego
parents:
11560
diff
changeset
|
24 * @file |
2729 | 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" |
11138
76b57b8e2a9a
Fix compilation with --enable-libgsm on Gentoo and OpenSUSE.
cehoyos
parents:
10145
diff
changeset
|
31 #include <gsm/gsm.h> |
2729 | 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); | |
12084
b6cf19580e47
Change all occurences of "inofficial" to "unofficial" in code, comments
cehoyos
parents:
11644
diff
changeset
|
57 if(avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) |
6721 | 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); | |
12084
b6cf19580e47
Change all occurences of "inofficial" to "unofficial" in code, comments
cehoyos
parents:
11644
diff
changeset
|
65 if(avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) |
6721 | 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", |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
11138
diff
changeset
|
117 AVMEDIA_TYPE_AUDIO, |
2729 | 118 CODEC_ID_GSM, |
119 0, | |
120 libgsm_init, | |
121 libgsm_encode_frame, | |
122 libgsm_close, | |
10145
7955db355703
Make sample_fmts and channel_layouts compound literals const to reduce size of
reimar
parents:
9355
diff
changeset
|
123 .sample_fmts = (const 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", |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
11138
diff
changeset
|
129 AVMEDIA_TYPE_AUDIO, |
4551 | 130 CODEC_ID_GSM_MS, |
131 0, | |
132 libgsm_init, | |
133 libgsm_encode_frame, | |
134 libgsm_close, | |
10145
7955db355703
Make sample_fmts and channel_layouts compound literals const to reduce size of
reimar
parents:
9355
diff
changeset
|
135 .sample_fmts = (const 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, | |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
141 AVPacket *avpkt) { |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
142 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
143 int buf_size = avpkt->size; |
6673
679b9ef6f5f3
Make sure some value is always returned via data_size
mbardiaux
parents:
6672
diff
changeset
|
144 *data_size = 0; /* In case of error */ |
679b9ef6f5f3
Make sure some value is always returned via data_size
mbardiaux
parents:
6672
diff
changeset
|
145 if(buf_size < avctx->block_align) return -1; |
4551 | 146 switch(avctx->codec_id) { |
147 case CODEC_ID_GSM: | |
148 if(gsm_decode(avctx->priv_data,buf,data)) return -1; | |
149 *data_size = GSM_FRAME_SIZE*sizeof(int16_t); | |
150 break; | |
151 case CODEC_ID_GSM_MS: | |
152 if(gsm_decode(avctx->priv_data,buf,data) || | |
153 gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1; | |
154 *data_size = GSM_FRAME_SIZE*sizeof(int16_t)*2; | |
155 } | |
156 return avctx->block_align; | |
2729 | 157 } |
158 | |
159 AVCodec libgsm_decoder = { | |
5102
4323e587708d
Give names of external library decoders/encoders a lib prefix
diego
parents:
4551
diff
changeset
|
160 "libgsm", |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
11138
diff
changeset
|
161 AVMEDIA_TYPE_AUDIO, |
2729 | 162 CODEC_ID_GSM, |
163 0, | |
164 libgsm_init, | |
165 NULL, | |
166 libgsm_close, | |
167 libgsm_decode_frame, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6721
diff
changeset
|
168 .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"), |
2729 | 169 }; |
4551 | 170 |
171 AVCodec libgsm_ms_decoder = { | |
5102
4323e587708d
Give names of external library decoders/encoders a lib prefix
diego
parents:
4551
diff
changeset
|
172 "libgsm_ms", |
11560
8a4984c5cacc
Define AVMediaType enum, and use it instead of enum CodecType, which
stefano
parents:
11138
diff
changeset
|
173 AVMEDIA_TYPE_AUDIO, |
4551 | 174 CODEC_ID_GSM_MS, |
175 0, | |
176 libgsm_init, | |
177 NULL, | |
178 libgsm_close, | |
179 libgsm_decode_frame, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6721
diff
changeset
|
180 .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"), |
4551 | 181 }; |