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/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 av_cold int libgsm_init(AVCodecContext *avctx) {
00039 if (avctx->channels > 1) {
00040 av_log(avctx, AV_LOG_ERROR, "Mono required for GSM, got %d channels\n",
00041 avctx->channels);
00042 return -1;
00043 }
00044
00045 if(avctx->codec->decode){
00046 if(!avctx->channels)
00047 avctx->channels= 1;
00048
00049 if(!avctx->sample_rate)
00050 avctx->sample_rate= 8000;
00051
00052 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00053 }else{
00054 if (avctx->sample_rate != 8000) {
00055 av_log(avctx, AV_LOG_ERROR, "Sample rate 8000Hz required for GSM, got %dHz\n",
00056 avctx->sample_rate);
00057 if(avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)
00058 return -1;
00059 }
00060 if (avctx->bit_rate != 13000 &&
00061 avctx->bit_rate != 13200 &&
00062 avctx->bit_rate != 0 ) {
00063 av_log(avctx, AV_LOG_ERROR, "Bitrate 13000bps required for GSM, got %dbps\n",
00064 avctx->bit_rate);
00065 if(avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL)
00066 return -1;
00067 }
00068 }
00069
00070 avctx->priv_data = gsm_create();
00071
00072 switch(avctx->codec_id) {
00073 case CODEC_ID_GSM:
00074 avctx->frame_size = GSM_FRAME_SIZE;
00075 avctx->block_align = GSM_BLOCK_SIZE;
00076 break;
00077 case CODEC_ID_GSM_MS: {
00078 int one = 1;
00079 gsm_option(avctx->priv_data, GSM_OPT_WAV49, &one);
00080 avctx->frame_size = 2*GSM_FRAME_SIZE;
00081 avctx->block_align = GSM_MS_BLOCK_SIZE;
00082 }
00083 }
00084
00085 avctx->coded_frame= avcodec_alloc_frame();
00086 avctx->coded_frame->key_frame= 1;
00087
00088 return 0;
00089 }
00090
00091 static av_cold int libgsm_close(AVCodecContext *avctx) {
00092 av_freep(&avctx->coded_frame);
00093 gsm_destroy(avctx->priv_data);
00094 avctx->priv_data = NULL;
00095 return 0;
00096 }
00097
00098 static int libgsm_encode_frame(AVCodecContext *avctx,
00099 unsigned char *frame, int buf_size, void *data) {
00100
00101 if(buf_size < avctx->block_align) return 0;
00102
00103 switch(avctx->codec_id) {
00104 case CODEC_ID_GSM:
00105 gsm_encode(avctx->priv_data,data,frame);
00106 break;
00107 case CODEC_ID_GSM_MS:
00108 gsm_encode(avctx->priv_data,data,frame);
00109 gsm_encode(avctx->priv_data,((short*)data)+GSM_FRAME_SIZE,frame+32);
00110 }
00111 return avctx->block_align;
00112 }
00113
00114
00115 AVCodec ff_libgsm_encoder = {
00116 "libgsm",
00117 AVMEDIA_TYPE_AUDIO,
00118 CODEC_ID_GSM,
00119 0,
00120 libgsm_init,
00121 libgsm_encode_frame,
00122 libgsm_close,
00123 .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
00124 .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"),
00125 };
00126
00127 AVCodec ff_libgsm_ms_encoder = {
00128 "libgsm_ms",
00129 AVMEDIA_TYPE_AUDIO,
00130 CODEC_ID_GSM_MS,
00131 0,
00132 libgsm_init,
00133 libgsm_encode_frame,
00134 libgsm_close,
00135 .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
00136 .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
00137 };
00138
00139 static int libgsm_decode_frame(AVCodecContext *avctx,
00140 void *data, int *data_size,
00141 AVPacket *avpkt) {
00142 const uint8_t *buf = avpkt->data;
00143 int buf_size = avpkt->size;
00144 int out_size = avctx->frame_size * av_get_bytes_per_sample(avctx->sample_fmt);
00145
00146 if (*data_size < out_size) {
00147 av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
00148 return AVERROR(EINVAL);
00149 }
00150
00151 *data_size = 0;
00152 if(buf_size < avctx->block_align) return -1;
00153 switch(avctx->codec_id) {
00154 case CODEC_ID_GSM:
00155 if(gsm_decode(avctx->priv_data,buf,data)) return -1;
00156 break;
00157 case CODEC_ID_GSM_MS:
00158 if(gsm_decode(avctx->priv_data,buf,data) ||
00159 gsm_decode(avctx->priv_data,buf+33,((int16_t*)data)+GSM_FRAME_SIZE)) return -1;
00160 }
00161
00162 *data_size = out_size;
00163 return avctx->block_align;
00164 }
00165
00166 AVCodec ff_libgsm_decoder = {
00167 "libgsm",
00168 AVMEDIA_TYPE_AUDIO,
00169 CODEC_ID_GSM,
00170 0,
00171 libgsm_init,
00172 NULL,
00173 libgsm_close,
00174 libgsm_decode_frame,
00175 .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM"),
00176 };
00177
00178 AVCodec ff_libgsm_ms_decoder = {
00179 "libgsm_ms",
00180 AVMEDIA_TYPE_AUDIO,
00181 CODEC_ID_GSM_MS,
00182 0,
00183 libgsm_init,
00184 NULL,
00185 libgsm_close,
00186 libgsm_decode_frame,
00187 .long_name = NULL_IF_CONFIG_SMALL("libgsm GSM Microsoft variant"),
00188 };