Originally committed as revision 8039 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -71,6 +71,7 @@ version <next> | |||
| - Theora encoding via libtheora | |||
| - BMP encoder | |||
| - WMA encoder | |||
| - GSM-MS encoder and decoder | |||
| version 0.4.9-pre1: | |||
| @@ -133,6 +133,7 @@ Codecs: | |||
| jpeg_ls.c Kostya Shishkov | |||
| kmvc.c Kostya Shishkov | |||
| lcl.c Roberto Togni | |||
| libgsm.c Michel Bardiaux | |||
| loco.c Kostya Shishkov | |||
| lzo.h, lzo.c Reimar Doeffinger | |||
| mdec.c Michael Niedermayer | |||
| @@ -168,6 +168,7 @@ void avcodec_register_all(void) | |||
| REGISTER_DECODER(IMC, imc); | |||
| REGISTER_DECODER(LIBA52, liba52); | |||
| REGISTER_ENCDEC (LIBGSM, libgsm); | |||
| REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms); | |||
| REGISTER_ENCODER(LIBTHEORA, libtheora); | |||
| REGISTER_DECODER(MACE3, mace3); | |||
| REGISTER_DECODER(MACE6, mace6); | |||
| @@ -37,8 +37,8 @@ extern "C" { | |||
| #define AV_STRINGIFY(s) AV_TOSTRING(s) | |||
| #define AV_TOSTRING(s) #s | |||
| #define LIBAVCODEC_VERSION_INT ((51<<16)+(33<<8)+0) | |||
| #define LIBAVCODEC_VERSION 51.33.0 | |||
| #define LIBAVCODEC_VERSION_INT ((51<<16)+(34<<8)+0) | |||
| #define LIBAVCODEC_VERSION 51.34.0 | |||
| #define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT | |||
| #define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) | |||
| @@ -227,7 +227,7 @@ enum CodecID { | |||
| CODEC_ID_SHORTEN, | |||
| CODEC_ID_ALAC, | |||
| CODEC_ID_WESTWOOD_SND1, | |||
| CODEC_ID_GSM, | |||
| CODEC_ID_GSM, /* As in Berlin toast format */ | |||
| CODEC_ID_QDM2, | |||
| CODEC_ID_COOK, | |||
| CODEC_ID_TRUESPEECH, | |||
| @@ -239,6 +239,7 @@ enum CodecID { | |||
| CODEC_ID_IMC, | |||
| CODEC_ID_MUSEPACK7, | |||
| CODEC_ID_MLP, | |||
| CODEC_ID_GSM_MS, /* As found in WAV */ | |||
| /* subtitle codecs */ | |||
| CODEC_ID_DVD_SUBTITLE= 0x17000, | |||
| @@ -2165,6 +2166,7 @@ extern AVCodec h264_encoder; | |||
| extern AVCodec huffyuv_encoder; | |||
| extern AVCodec jpegls_encoder; | |||
| extern AVCodec libgsm_encoder; | |||
| extern AVCodec libgsm_ms_encoder; | |||
| extern AVCodec libtheora_encoder; | |||
| extern AVCodec ljpeg_encoder; | |||
| extern AVCodec mdec_encoder; | |||
| @@ -2242,6 +2244,7 @@ extern AVCodec interplay_dpcm_decoder; | |||
| extern AVCodec interplay_video_decoder; | |||
| extern AVCodec kmvc_decoder; | |||
| extern AVCodec libgsm_decoder; | |||
| extern AVCodec libgsm_ms_decoder; | |||
| extern AVCodec loco_decoder; | |||
| extern AVCodec mace3_decoder; | |||
| extern AVCodec mace6_decoder; | |||
| @@ -1,6 +1,7 @@ | |||
| /* | |||
| * Interface to libgsm for gsm encoding/decoding | |||
| * Copyright (c) 2005 Alban Bedel <albeu@free.fr> | |||
| * Copyright (c) 2006, 2007 Michel Bardiaux <mbardiaux@mediaxim.be> | |||
| * | |||
| * This file is part of FFmpeg. | |||
| * | |||
| @@ -24,22 +25,35 @@ | |||
| * Interface to libgsm for gsm encoding/decoding | |||
| */ | |||
| // The idiosyncrasies of GSM-in-WAV are explained at http://kbs.cs.tu-berlin.de/~jutta/toast.html | |||
| #include "avcodec.h" | |||
| #include <gsm.h> | |||
| // gsm.h miss some essential constants | |||
| #define GSM_BLOCK_SIZE 33 | |||
| #define GSM_MS_BLOCK_SIZE 65 | |||
| #define GSM_FRAME_SIZE 160 | |||
| static int libgsm_init(AVCodecContext *avctx) { | |||
| if (avctx->channels > 1 || avctx->sample_rate != 8000) | |||
| if (avctx->channels > 1 || avctx->sample_rate != 8000 || avctx->bit_rate != 13000) | |||
| return -1; | |||
| avctx->frame_size = GSM_FRAME_SIZE; | |||
| avctx->block_align = GSM_BLOCK_SIZE; | |||
| avctx->priv_data = gsm_create(); | |||
| switch(avctx->codec_id) { | |||
| case CODEC_ID_GSM: | |||
| avctx->frame_size = GSM_FRAME_SIZE; | |||
| avctx->block_align = GSM_BLOCK_SIZE; | |||
| break; | |||
| case CODEC_ID_GSM_MS: { | |||
| int one = 1; | |||
| gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one); | |||
| avctx->frame_size = 2*GSM_FRAME_SIZE; | |||
| avctx->block_align = GSM_MS_BLOCK_SIZE; | |||
| } | |||
| } | |||
| avctx->coded_frame= avcodec_alloc_frame(); | |||
| avctx->coded_frame->key_frame= 1; | |||
| @@ -55,11 +69,17 @@ static int libgsm_close(AVCodecContext *avctx) { | |||
| static int libgsm_encode_frame(AVCodecContext *avctx, | |||
| unsigned char *frame, int buf_size, void *data) { | |||
| // we need a full block | |||
| if(buf_size < GSM_BLOCK_SIZE) return 0; | |||
| gsm_encode(avctx->priv_data,data,frame); | |||
| return GSM_BLOCK_SIZE; | |||
| if(buf_size < avctx->block_align) return 0; | |||
| switch(avctx->codec_id) { | |||
| case CODEC_ID_GSM: | |||
| gsm_encode(avctx->priv_data,data,frame); | |||
| break; | |||
| case CODEC_ID_GSM_MS: | |||
| gsm_encode(avctx->priv_data,data,frame); | |||
| gsm_encode(avctx->priv_data,((short*)data)+GSM_FRAME_SIZE,frame+32); | |||
| } | |||
| return avctx->block_align; | |||
| } | |||
| @@ -73,16 +93,33 @@ AVCodec libgsm_encoder = { | |||
| libgsm_close, | |||
| }; | |||
| AVCodec libgsm_ms_encoder = { | |||
| "gsm", | |||
| CODEC_TYPE_AUDIO, | |||
| CODEC_ID_GSM_MS, | |||
| 0, | |||
| libgsm_init, | |||
| libgsm_encode_frame, | |||
| libgsm_close, | |||
| }; | |||
| static int libgsm_decode_frame(AVCodecContext *avctx, | |||
| void *data, int *data_size, | |||
| uint8_t *buf, int buf_size) { | |||
| if(buf_size < GSM_BLOCK_SIZE) return 0; | |||
| if(gsm_decode(avctx->priv_data,buf,data)) return -1; | |||
| *data_size = GSM_FRAME_SIZE*2; | |||
| return GSM_BLOCK_SIZE; | |||
| if(buf_size < avctx->block_align) return 0; | |||
| switch(avctx->codec_id) { | |||
| case CODEC_ID_GSM: | |||
| if(gsm_decode(avctx->priv_data,buf,data)) return -1; | |||
| *data_size = GSM_FRAME_SIZE*sizeof(int16_t); | |||
| break; | |||
| case CODEC_ID_GSM_MS: | |||
| if(gsm_decode(avctx->priv_data,buf,data) || | |||
| gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1; | |||
| *data_size = GSM_FRAME_SIZE*sizeof(int16_t)*2; | |||
| } | |||
| return avctx->block_align; | |||
| } | |||
| AVCodec libgsm_decoder = { | |||
| @@ -95,3 +132,14 @@ AVCodec libgsm_decoder = { | |||
| libgsm_close, | |||
| libgsm_decode_frame, | |||
| }; | |||
| AVCodec libgsm_ms_decoder = { | |||
| "gsm_ms", | |||
| CODEC_TYPE_AUDIO, | |||
| CODEC_ID_GSM_MS, | |||
| 0, | |||
| libgsm_init, | |||
| NULL, | |||
| libgsm_close, | |||
| libgsm_decode_frame, | |||
| }; | |||
| @@ -198,6 +198,7 @@ const AVCodecTag codec_wav_tags[] = { | |||
| { CODEC_ID_TRUESPEECH, 0x22 }, | |||
| { CODEC_ID_FLAC, 0xF1AC }, | |||
| { CODEC_ID_IMC, 0x401 }, | |||
| { CODEC_ID_GSM_MS, 0x31 }, | |||
| /* FIXME: All of the IDs below are not 16 bit and thus illegal. */ | |||
| // for NuppelVideo (nuv.c) | |||
| @@ -305,7 +306,7 @@ int put_wav_header(ByteIOContext *pb, AVCodecContext *enc) | |||
| enc->codec_id == CODEC_ID_PCM_ALAW || | |||
| enc->codec_id == CODEC_ID_PCM_MULAW) { | |||
| bps = 8; | |||
| } else if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3) { | |||
| } else if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_GSM_MS) { | |||
| bps = 0; | |||
| } 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) { // | |||
| bps = 4; | |||
| @@ -317,7 +318,7 @@ int put_wav_header(ByteIOContext *pb, AVCodecContext *enc) | |||
| bps = 16; | |||
| } | |||
| if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3) { | |||
| if (enc->codec_id == CODEC_ID_MP2 || enc->codec_id == CODEC_ID_MP3 || enc->codec_id == CODEC_ID_GSM_MS) { | |||
| blkalign = enc->frame_size; //this is wrong, but seems many demuxers dont work if this is set correctly | |||
| //blkalign = 144 * enc->bit_rate/enc->sample_rate; | |||
| } else if (enc->codec_id == CODEC_ID_ADPCM_G726) { // | |||
| @@ -356,6 +357,10 @@ int put_wav_header(ByteIOContext *pb, AVCodecContext *enc) | |||
| put_le16(pb, 16); /* fwHeadFlags */ | |||
| put_le32(pb, 0); /* dwPTSLow */ | |||
| put_le32(pb, 0); /* dwPTSHigh */ | |||
| } else if (enc->codec_id == CODEC_ID_GSM_MS) { | |||
| put_le16(pb, 2); /* wav_extra_size */ | |||
| hdrsize += 2; | |||
| put_le16(pb, enc->frame_size); /* wSamplesPerBlock */ | |||
| } else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) { | |||
| put_le16(pb, 2); /* wav_extra_size */ | |||
| hdrsize += 2; | |||