Originally committed as revision 8039 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -71,6 +71,7 @@ version <next> | |||||
| - Theora encoding via libtheora | - Theora encoding via libtheora | ||||
| - BMP encoder | - BMP encoder | ||||
| - WMA encoder | - WMA encoder | ||||
| - GSM-MS encoder and decoder | |||||
| version 0.4.9-pre1: | version 0.4.9-pre1: | ||||
| @@ -133,6 +133,7 @@ Codecs: | |||||
| jpeg_ls.c Kostya Shishkov | jpeg_ls.c Kostya Shishkov | ||||
| kmvc.c Kostya Shishkov | kmvc.c Kostya Shishkov | ||||
| lcl.c Roberto Togni | lcl.c Roberto Togni | ||||
| libgsm.c Michel Bardiaux | |||||
| loco.c Kostya Shishkov | loco.c Kostya Shishkov | ||||
| lzo.h, lzo.c Reimar Doeffinger | lzo.h, lzo.c Reimar Doeffinger | ||||
| mdec.c Michael Niedermayer | mdec.c Michael Niedermayer | ||||
| @@ -168,6 +168,7 @@ void avcodec_register_all(void) | |||||
| REGISTER_DECODER(IMC, imc); | REGISTER_DECODER(IMC, imc); | ||||
| REGISTER_DECODER(LIBA52, liba52); | REGISTER_DECODER(LIBA52, liba52); | ||||
| REGISTER_ENCDEC (LIBGSM, libgsm); | REGISTER_ENCDEC (LIBGSM, libgsm); | ||||
| REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms); | |||||
| REGISTER_ENCODER(LIBTHEORA, libtheora); | REGISTER_ENCODER(LIBTHEORA, libtheora); | ||||
| REGISTER_DECODER(MACE3, mace3); | REGISTER_DECODER(MACE3, mace3); | ||||
| REGISTER_DECODER(MACE6, mace6); | REGISTER_DECODER(MACE6, mace6); | ||||
| @@ -37,8 +37,8 @@ extern "C" { | |||||
| #define AV_STRINGIFY(s) AV_TOSTRING(s) | #define AV_STRINGIFY(s) AV_TOSTRING(s) | ||||
| #define AV_TOSTRING(s) #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_BUILD LIBAVCODEC_VERSION_INT | ||||
| #define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) | #define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) | ||||
| @@ -227,7 +227,7 @@ enum CodecID { | |||||
| CODEC_ID_SHORTEN, | CODEC_ID_SHORTEN, | ||||
| CODEC_ID_ALAC, | CODEC_ID_ALAC, | ||||
| CODEC_ID_WESTWOOD_SND1, | CODEC_ID_WESTWOOD_SND1, | ||||
| CODEC_ID_GSM, | |||||
| CODEC_ID_GSM, /* As in Berlin toast format */ | |||||
| CODEC_ID_QDM2, | CODEC_ID_QDM2, | ||||
| CODEC_ID_COOK, | CODEC_ID_COOK, | ||||
| CODEC_ID_TRUESPEECH, | CODEC_ID_TRUESPEECH, | ||||
| @@ -239,6 +239,7 @@ enum CodecID { | |||||
| CODEC_ID_IMC, | CODEC_ID_IMC, | ||||
| CODEC_ID_MUSEPACK7, | CODEC_ID_MUSEPACK7, | ||||
| CODEC_ID_MLP, | CODEC_ID_MLP, | ||||
| CODEC_ID_GSM_MS, /* As found in WAV */ | |||||
| /* subtitle codecs */ | /* subtitle codecs */ | ||||
| CODEC_ID_DVD_SUBTITLE= 0x17000, | CODEC_ID_DVD_SUBTITLE= 0x17000, | ||||
| @@ -2165,6 +2166,7 @@ extern AVCodec h264_encoder; | |||||
| extern AVCodec huffyuv_encoder; | extern AVCodec huffyuv_encoder; | ||||
| extern AVCodec jpegls_encoder; | extern AVCodec jpegls_encoder; | ||||
| extern AVCodec libgsm_encoder; | extern AVCodec libgsm_encoder; | ||||
| extern AVCodec libgsm_ms_encoder; | |||||
| extern AVCodec libtheora_encoder; | extern AVCodec libtheora_encoder; | ||||
| extern AVCodec ljpeg_encoder; | extern AVCodec ljpeg_encoder; | ||||
| extern AVCodec mdec_encoder; | extern AVCodec mdec_encoder; | ||||
| @@ -2242,6 +2244,7 @@ extern AVCodec interplay_dpcm_decoder; | |||||
| extern AVCodec interplay_video_decoder; | extern AVCodec interplay_video_decoder; | ||||
| extern AVCodec kmvc_decoder; | extern AVCodec kmvc_decoder; | ||||
| extern AVCodec libgsm_decoder; | extern AVCodec libgsm_decoder; | ||||
| extern AVCodec libgsm_ms_decoder; | |||||
| extern AVCodec loco_decoder; | extern AVCodec loco_decoder; | ||||
| extern AVCodec mace3_decoder; | extern AVCodec mace3_decoder; | ||||
| extern AVCodec mace6_decoder; | extern AVCodec mace6_decoder; | ||||
| @@ -1,6 +1,7 @@ | |||||
| /* | /* | ||||
| * Interface to libgsm for gsm encoding/decoding | * Interface to libgsm for gsm encoding/decoding | ||||
| * Copyright (c) 2005 Alban Bedel <albeu@free.fr> | * Copyright (c) 2005 Alban Bedel <albeu@free.fr> | ||||
| * Copyright (c) 2006, 2007 Michel Bardiaux <mbardiaux@mediaxim.be> | |||||
| * | * | ||||
| * This file is part of FFmpeg. | * This file is part of FFmpeg. | ||||
| * | * | ||||
| @@ -24,22 +25,35 @@ | |||||
| * Interface to libgsm for gsm encoding/decoding | * 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 "avcodec.h" | ||||
| #include <gsm.h> | #include <gsm.h> | ||||
| // gsm.h miss some essential constants | // gsm.h miss some essential constants | ||||
| #define GSM_BLOCK_SIZE 33 | #define GSM_BLOCK_SIZE 33 | ||||
| #define GSM_MS_BLOCK_SIZE 65 | |||||
| #define GSM_FRAME_SIZE 160 | #define GSM_FRAME_SIZE 160 | ||||
| static int libgsm_init(AVCodecContext *avctx) { | 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; | return -1; | ||||
| avctx->frame_size = GSM_FRAME_SIZE; | |||||
| avctx->block_align = GSM_BLOCK_SIZE; | |||||
| avctx->priv_data = gsm_create(); | 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= avcodec_alloc_frame(); | ||||
| avctx->coded_frame->key_frame= 1; | avctx->coded_frame->key_frame= 1; | ||||
| @@ -55,11 +69,17 @@ static int libgsm_close(AVCodecContext *avctx) { | |||||
| static int libgsm_encode_frame(AVCodecContext *avctx, | static int libgsm_encode_frame(AVCodecContext *avctx, | ||||
| unsigned char *frame, int buf_size, void *data) { | unsigned char *frame, int buf_size, void *data) { | ||||
| // we need a full block | // 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, | 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, | static int libgsm_decode_frame(AVCodecContext *avctx, | ||||
| void *data, int *data_size, | void *data, int *data_size, | ||||
| uint8_t *buf, int buf_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 = { | AVCodec libgsm_decoder = { | ||||
| @@ -95,3 +132,14 @@ AVCodec libgsm_decoder = { | |||||
| libgsm_close, | libgsm_close, | ||||
| libgsm_decode_frame, | 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_TRUESPEECH, 0x22 }, | ||||
| { CODEC_ID_FLAC, 0xF1AC }, | { CODEC_ID_FLAC, 0xF1AC }, | ||||
| { CODEC_ID_IMC, 0x401 }, | { CODEC_ID_IMC, 0x401 }, | ||||
| { CODEC_ID_GSM_MS, 0x31 }, | |||||
| /* FIXME: All of the IDs below are not 16 bit and thus illegal. */ | /* FIXME: All of the IDs below are not 16 bit and thus illegal. */ | ||||
| // for NuppelVideo (nuv.c) | // 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_ALAW || | ||||
| enc->codec_id == CODEC_ID_PCM_MULAW) { | enc->codec_id == CODEC_ID_PCM_MULAW) { | ||||
| bps = 8; | 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; | 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) { // | } 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; | bps = 4; | ||||
| @@ -317,7 +318,7 @@ int put_wav_header(ByteIOContext *pb, AVCodecContext *enc) | |||||
| bps = 16; | 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 = 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; | //blkalign = 144 * enc->bit_rate/enc->sample_rate; | ||||
| } else if (enc->codec_id == CODEC_ID_ADPCM_G726) { // | } 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_le16(pb, 16); /* fwHeadFlags */ | ||||
| put_le32(pb, 0); /* dwPTSLow */ | put_le32(pb, 0); /* dwPTSLow */ | ||||
| put_le32(pb, 0); /* dwPTSHigh */ | 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) { | } else if (enc->codec_id == CODEC_ID_ADPCM_IMA_WAV) { | ||||
| put_le16(pb, 2); /* wav_extra_size */ | put_le16(pb, 2); /* wav_extra_size */ | ||||
| hdrsize += 2; | hdrsize += 2; | ||||