Originally committed as revision 8039 to svn://svn.ffmpeg.org/ffmpeg/trunk
Michel Bardiaux authored on 2007/02/20 20:09:47... | ... |
@@ -168,6 +168,7 @@ void avcodec_register_all(void) |
168 | 168 |
REGISTER_DECODER(IMC, imc); |
169 | 169 |
REGISTER_DECODER(LIBA52, liba52); |
170 | 170 |
REGISTER_ENCDEC (LIBGSM, libgsm); |
171 |
+ REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms); |
|
171 | 172 |
REGISTER_ENCODER(LIBTHEORA, libtheora); |
172 | 173 |
REGISTER_DECODER(MACE3, mace3); |
173 | 174 |
REGISTER_DECODER(MACE6, mace6); |
... | ... |
@@ -37,8 +37,8 @@ extern "C" { |
37 | 37 |
#define AV_STRINGIFY(s) AV_TOSTRING(s) |
38 | 38 |
#define AV_TOSTRING(s) #s |
39 | 39 |
|
40 |
-#define LIBAVCODEC_VERSION_INT ((51<<16)+(33<<8)+0) |
|
41 |
-#define LIBAVCODEC_VERSION 51.33.0 |
|
40 |
+#define LIBAVCODEC_VERSION_INT ((51<<16)+(34<<8)+0) |
|
41 |
+#define LIBAVCODEC_VERSION 51.34.0 |
|
42 | 42 |
#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT |
43 | 43 |
|
44 | 44 |
#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) |
... | ... |
@@ -227,7 +227,7 @@ enum CodecID { |
227 | 227 |
CODEC_ID_SHORTEN, |
228 | 228 |
CODEC_ID_ALAC, |
229 | 229 |
CODEC_ID_WESTWOOD_SND1, |
230 |
- CODEC_ID_GSM, |
|
230 |
+ CODEC_ID_GSM, /* As in Berlin toast format */ |
|
231 | 231 |
CODEC_ID_QDM2, |
232 | 232 |
CODEC_ID_COOK, |
233 | 233 |
CODEC_ID_TRUESPEECH, |
... | ... |
@@ -239,6 +239,7 @@ enum CodecID { |
239 | 239 |
CODEC_ID_IMC, |
240 | 240 |
CODEC_ID_MUSEPACK7, |
241 | 241 |
CODEC_ID_MLP, |
242 |
+ CODEC_ID_GSM_MS, /* As found in WAV */ |
|
242 | 243 |
|
243 | 244 |
/* subtitle codecs */ |
244 | 245 |
CODEC_ID_DVD_SUBTITLE= 0x17000, |
... | ... |
@@ -2165,6 +2166,7 @@ extern AVCodec h264_encoder; |
2165 | 2165 |
extern AVCodec huffyuv_encoder; |
2166 | 2166 |
extern AVCodec jpegls_encoder; |
2167 | 2167 |
extern AVCodec libgsm_encoder; |
2168 |
+extern AVCodec libgsm_ms_encoder; |
|
2168 | 2169 |
extern AVCodec libtheora_encoder; |
2169 | 2170 |
extern AVCodec ljpeg_encoder; |
2170 | 2171 |
extern AVCodec mdec_encoder; |
... | ... |
@@ -2242,6 +2244,7 @@ extern AVCodec interplay_dpcm_decoder; |
2242 | 2242 |
extern AVCodec interplay_video_decoder; |
2243 | 2243 |
extern AVCodec kmvc_decoder; |
2244 | 2244 |
extern AVCodec libgsm_decoder; |
2245 |
+extern AVCodec libgsm_ms_decoder; |
|
2245 | 2246 |
extern AVCodec loco_decoder; |
2246 | 2247 |
extern AVCodec mace3_decoder; |
2247 | 2248 |
extern AVCodec mace6_decoder; |
... | ... |
@@ -1,6 +1,7 @@ |
1 | 1 |
/* |
2 | 2 |
* Interface to libgsm for gsm encoding/decoding |
3 | 3 |
* Copyright (c) 2005 Alban Bedel <albeu@free.fr> |
4 |
+ * Copyright (c) 2006, 2007 Michel Bardiaux <mbardiaux@mediaxim.be> |
|
4 | 5 |
* |
5 | 6 |
* This file is part of FFmpeg. |
6 | 7 |
* |
... | ... |
@@ -24,22 +25,35 @@ |
24 | 24 |
* Interface to libgsm for gsm encoding/decoding |
25 | 25 |
*/ |
26 | 26 |
|
27 |
+// The idiosyncrasies of GSM-in-WAV are explained at http://kbs.cs.tu-berlin.de/~jutta/toast.html |
|
28 |
+ |
|
27 | 29 |
#include "avcodec.h" |
28 | 30 |
#include <gsm.h> |
29 | 31 |
|
30 | 32 |
// gsm.h miss some essential constants |
31 | 33 |
#define GSM_BLOCK_SIZE 33 |
34 |
+#define GSM_MS_BLOCK_SIZE 65 |
|
32 | 35 |
#define GSM_FRAME_SIZE 160 |
33 | 36 |
|
34 | 37 |
static int libgsm_init(AVCodecContext *avctx) { |
35 |
- if (avctx->channels > 1 || avctx->sample_rate != 8000) |
|
38 |
+ if (avctx->channels > 1 || avctx->sample_rate != 8000 || avctx->bit_rate != 13000) |
|
36 | 39 |
return -1; |
37 | 40 |
|
38 |
- avctx->frame_size = GSM_FRAME_SIZE; |
|
39 |
- avctx->block_align = GSM_BLOCK_SIZE; |
|
40 |
- |
|
41 | 41 |
avctx->priv_data = gsm_create(); |
42 | 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 |
+ int one = 1; |
|
50 |
+ gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one); |
|
51 |
+ avctx->frame_size = 2*GSM_FRAME_SIZE; |
|
52 |
+ avctx->block_align = GSM_MS_BLOCK_SIZE; |
|
53 |
+ } |
|
54 |
+ } |
|
55 |
+ |
|
43 | 56 |
avctx->coded_frame= avcodec_alloc_frame(); |
44 | 57 |
avctx->coded_frame->key_frame= 1; |
45 | 58 |
|
... | ... |
@@ -55,11 +69,17 @@ static int libgsm_close(AVCodecContext *avctx) { |
55 | 55 |
static int libgsm_encode_frame(AVCodecContext *avctx, |
56 | 56 |
unsigned char *frame, int buf_size, void *data) { |
57 | 57 |
// we need a full block |
58 |
- if(buf_size < GSM_BLOCK_SIZE) return 0; |
|
59 |
- |
|
60 |
- gsm_encode(avctx->priv_data,data,frame); |
|
61 |
- |
|
62 |
- return GSM_BLOCK_SIZE; |
|
58 |
+ if(buf_size < avctx->block_align) return 0; |
|
59 |
+ |
|
60 |
+ switch(avctx->codec_id) { |
|
61 |
+ case CODEC_ID_GSM: |
|
62 |
+ gsm_encode(avctx->priv_data,data,frame); |
|
63 |
+ break; |
|
64 |
+ case CODEC_ID_GSM_MS: |
|
65 |
+ gsm_encode(avctx->priv_data,data,frame); |
|
66 |
+ gsm_encode(avctx->priv_data,((short*)data)+GSM_FRAME_SIZE,frame+32); |
|
67 |
+ } |
|
68 |
+ return avctx->block_align; |
|
63 | 69 |
} |
64 | 70 |
|
65 | 71 |
|
... | ... |
@@ -73,16 +93,33 @@ AVCodec libgsm_encoder = { |
73 | 73 |
libgsm_close, |
74 | 74 |
}; |
75 | 75 |
|
76 |
+AVCodec libgsm_ms_encoder = { |
|
77 |
+ "gsm", |
|
78 |
+ CODEC_TYPE_AUDIO, |
|
79 |
+ CODEC_ID_GSM_MS, |
|
80 |
+ 0, |
|
81 |
+ libgsm_init, |
|
82 |
+ libgsm_encode_frame, |
|
83 |
+ libgsm_close, |
|
84 |
+}; |
|
85 |
+ |
|
76 | 86 |
static int libgsm_decode_frame(AVCodecContext *avctx, |
77 | 87 |
void *data, int *data_size, |
78 | 88 |
uint8_t *buf, int buf_size) { |
79 | 89 |
|
80 |
- if(buf_size < GSM_BLOCK_SIZE) return 0; |
|
81 |
- |
|
82 |
- if(gsm_decode(avctx->priv_data,buf,data)) return -1; |
|
83 |
- |
|
84 |
- *data_size = GSM_FRAME_SIZE*2; |
|
85 |
- return GSM_BLOCK_SIZE; |
|
90 |
+ if(buf_size < avctx->block_align) return 0; |
|
91 |
+ |
|
92 |
+ switch(avctx->codec_id) { |
|
93 |
+ case CODEC_ID_GSM: |
|
94 |
+ if(gsm_decode(avctx->priv_data,buf,data)) return -1; |
|
95 |
+ *data_size = GSM_FRAME_SIZE*sizeof(int16_t); |
|
96 |
+ break; |
|
97 |
+ case CODEC_ID_GSM_MS: |
|
98 |
+ if(gsm_decode(avctx->priv_data,buf,data) || |
|
99 |
+ gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1; |
|
100 |
+ *data_size = GSM_FRAME_SIZE*sizeof(int16_t)*2; |
|
101 |
+ } |
|
102 |
+ return avctx->block_align; |
|
86 | 103 |
} |
87 | 104 |
|
88 | 105 |
AVCodec libgsm_decoder = { |
... | ... |
@@ -95,3 +132,14 @@ AVCodec libgsm_decoder = { |
95 | 95 |
libgsm_close, |
96 | 96 |
libgsm_decode_frame, |
97 | 97 |
}; |
98 |
+ |
|
99 |
+AVCodec libgsm_ms_decoder = { |
|
100 |
+ "gsm_ms", |
|
101 |
+ CODEC_TYPE_AUDIO, |
|
102 |
+ CODEC_ID_GSM_MS, |
|
103 |
+ 0, |
|
104 |
+ libgsm_init, |
|
105 |
+ NULL, |
|
106 |
+ libgsm_close, |
|
107 |
+ libgsm_decode_frame, |
|
108 |
+}; |
... | ... |
@@ -198,6 +198,7 @@ const AVCodecTag codec_wav_tags[] = { |
198 | 198 |
{ CODEC_ID_TRUESPEECH, 0x22 }, |
199 | 199 |
{ CODEC_ID_FLAC, 0xF1AC }, |
200 | 200 |
{ CODEC_ID_IMC, 0x401 }, |
201 |
+ { CODEC_ID_GSM_MS, 0x31 }, |
|
201 | 202 |
|
202 | 203 |
/* FIXME: All of the IDs below are not 16 bit and thus illegal. */ |
203 | 204 |
// for NuppelVideo (nuv.c) |
... | ... |
@@ -305,7 +306,7 @@ int put_wav_header(ByteIOContext *pb, AVCodecContext *enc) |
305 | 305 |
enc->codec_id == CODEC_ID_PCM_ALAW || |
306 | 306 |
enc->codec_id == CODEC_ID_PCM_MULAW) { |
307 | 307 |
bps = 8; |
308 |
- } else if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3) { |
|
308 |
+ } else if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_GSM_MS) { |
|
309 | 309 |
bps = 0; |
310 | 310 |
} else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV || enc->codec_id == CODEC_ID_ADPCM_MS || enc->codec_id == CODEC_ID_ADPCM_G726 || enc->codec_id == CODEC_ID_ADPCM_YAMAHA) { // |
311 | 311 |
bps = 4; |
... | ... |
@@ -317,7 +318,7 @@ int put_wav_header(ByteIOContext *pb, AVCodecContext *enc) |
317 | 317 |
bps = 16; |
318 | 318 |
} |
319 | 319 |
|
320 |
- if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3) { |
|
320 |
+ if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_GSM_MS) { |
|
321 | 321 |
blkalign = enc->frame_size; //this is wrong, but seems many demuxers dont work if this is set correctly |
322 | 322 |
//blkalign = 144 * enc->bit_rate/enc->sample_rate; |
323 | 323 |
} else if (enc->codec_id == CODEC_ID_ADPCM_G726) { // |
... | ... |
@@ -356,6 +357,10 @@ int put_wav_header(ByteIOContext *pb, AVCodecContext *enc) |
356 | 356 |
put_le16(pb, 16); /* fwHeadFlags */ |
357 | 357 |
put_le32(pb, 0); /* dwPTSLow */ |
358 | 358 |
put_le32(pb, 0); /* dwPTSHigh */ |
359 |
+ } else if (enc->codec_id == CODEC_ID_GSM_MS) { |
|
360 |
+ put_le16(pb, 2); /* wav_extra_size */ |
|
361 |
+ hdrsize += 2; |
|
362 |
+ put_le16(pb, enc->frame_size); /* wSamplesPerBlock */ |
|
359 | 363 |
} else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) { |
360 | 364 |
put_le16(pb, 2); /* wav_extra_size */ |
361 | 365 |
hdrsize += 2; |