00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028
00029
00030 #include "avcodec.h"
00031 #include <gsm.h>
00032
00033
00034 #define GSM_BLOCK_SIZE 33
00035 #define GSM_MS_BLOCK_SIZE 65
00036 #define GSM_FRAME_SIZE 160
00037
00038 static int libgsm_init(AVCodecContext *avctx) {
00039 if (avctx->channels > 1 || avctx->sample_rate != 8000 || avctx->bit_rate != 13000)
00040 return -1;
00041
00042 avctx->priv_data = gsm_create();
00043
00044 switch(avctx->codec_id) {
00045 case CODEC_ID_GSM:
00046 avctx->frame_size = GSM_FRAME_SIZE;
00047 avctx->block_align = GSM_BLOCK_SIZE;
00048 break;
00049 case CODEC_ID_GSM_MS: {
00050 int one = 1;
00051 gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one);
00052 avctx->frame_size = 2*GSM_FRAME_SIZE;
00053 avctx->block_align = GSM_MS_BLOCK_SIZE;
00054 }
00055 }
00056
00057 avctx->coded_frame= avcodec_alloc_frame();
00058 avctx->coded_frame->key_frame= 1;
00059
00060 return 0;
00061 }
00062
00063 static int libgsm_close(AVCodecContext *avctx) {
00064 gsm_destroy(avctx->priv_data);
00065 avctx->priv_data = NULL;
00066 return 0;
00067 }
00068
00069 static int libgsm_encode_frame(AVCodecContext *avctx,
00070 unsigned char *frame, int buf_size, void *data) {
00071
00072 if(buf_size < avctx->block_align) return 0;
00073
00074 switch(avctx->codec_id) {
00075 case CODEC_ID_GSM:
00076 gsm_encode(avctx->priv_data,data,frame);
00077 break;
00078 case CODEC_ID_GSM_MS:
00079 gsm_encode(avctx->priv_data,data,frame);
00080 gsm_encode(avctx->priv_data,((short*)data)+GSM_FRAME_SIZE,frame+32);
00081 }
00082 return avctx->block_align;
00083 }
00084
00085
00086 AVCodec libgsm_encoder = {
00087 "libgsm",
00088 CODEC_TYPE_AUDIO,
00089 CODEC_ID_GSM,
00090 0,
00091 libgsm_init,
00092 libgsm_encode_frame,
00093 libgsm_close,
00094 };
00095
00096 AVCodec libgsm_ms_encoder = {
00097 "libgsm_ms",
00098 CODEC_TYPE_AUDIO,
00099 CODEC_ID_GSM_MS,
00100 0,
00101 libgsm_init,
00102 libgsm_encode_frame,
00103 libgsm_close,
00104 };
00105
00106 static int libgsm_decode_frame(AVCodecContext *avctx,
00107 void *data, int *data_size,
00108 uint8_t *buf, int buf_size) {
00109
00110 if(buf_size < avctx->block_align) return 0;
00111
00112 switch(avctx->codec_id) {
00113 case CODEC_ID_GSM:
00114 if(gsm_decode(avctx->priv_data,buf,data)) return -1;
00115 *data_size = GSM_FRAME_SIZE*sizeof(int16_t);
00116 break;
00117 case CODEC_ID_GSM_MS:
00118 if(gsm_decode(avctx->priv_data,buf,data) ||
00119 gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1;
00120 *data_size = GSM_FRAME_SIZE*sizeof(int16_t)*2;
00121 }
00122 return avctx->block_align;
00123 }
00124
00125 AVCodec libgsm_decoder = {
00126 "libgsm",
00127 CODEC_TYPE_AUDIO,
00128 CODEC_ID_GSM,
00129 0,
00130 libgsm_init,
00131 NULL,
00132 libgsm_close,
00133 libgsm_decode_frame,
00134 };
00135
00136 AVCodec libgsm_ms_decoder = {
00137 "libgsm_ms",
00138 CODEC_TYPE_AUDIO,
00139 CODEC_ID_GSM_MS,
00140 0,
00141 libgsm_init,
00142 NULL,
00143 libgsm_close,
00144 libgsm_decode_frame,
00145 };