00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "avcodec.h"
00028 #include "get_bits.h"
00029 #include "msgsmdec.h"
00030
00031 #include "gsmdec_template.c"
00032
00033 static av_cold int gsm_init(AVCodecContext *avctx)
00034 {
00035 avctx->channels = 1;
00036 if (!avctx->sample_rate)
00037 avctx->sample_rate = 8000;
00038 avctx->sample_fmt = AV_SAMPLE_FMT_S16;
00039
00040 switch (avctx->codec_id) {
00041 case CODEC_ID_GSM:
00042 avctx->frame_size = GSM_FRAME_SIZE;
00043 avctx->block_align = GSM_BLOCK_SIZE;
00044 break;
00045 case CODEC_ID_GSM_MS:
00046 avctx->frame_size = 2 * GSM_FRAME_SIZE;
00047 avctx->block_align = GSM_MS_BLOCK_SIZE;
00048 }
00049
00050 return 0;
00051 }
00052
00053 static int gsm_decode_frame(AVCodecContext *avctx, void *data,
00054 int *data_size, AVPacket *avpkt)
00055 {
00056 int res;
00057 GetBitContext gb;
00058 const uint8_t *buf = avpkt->data;
00059 int buf_size = avpkt->size;
00060 int16_t *samples = data;
00061 int frame_bytes = 2 * avctx->frame_size;
00062
00063 if (*data_size < frame_bytes)
00064 return -1;
00065 *data_size = 0;
00066 if(buf_size < avctx->block_align)
00067 return AVERROR_INVALIDDATA;
00068
00069 switch (avctx->codec_id) {
00070 case CODEC_ID_GSM:
00071 init_get_bits(&gb, buf, buf_size * 8);
00072 if (get_bits(&gb, 4) != 0xd)
00073 av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n");
00074 res = gsm_decode_block(avctx, samples, &gb);
00075 if (res < 0)
00076 return res;
00077 break;
00078 case CODEC_ID_GSM_MS:
00079 res = ff_msgsm_decode_block(avctx, samples, buf);
00080 if (res < 0)
00081 return res;
00082 }
00083 *data_size = frame_bytes;
00084 return avctx->block_align;
00085 }
00086
00087 AVCodec ff_gsm_decoder = {
00088 "gsm",
00089 AVMEDIA_TYPE_AUDIO,
00090 CODEC_ID_GSM,
00091 sizeof(GSMContext),
00092 gsm_init,
00093 NULL,
00094 NULL,
00095 gsm_decode_frame,
00096 .long_name = NULL_IF_CONFIG_SMALL("GSM"),
00097 };
00098
00099 AVCodec ff_gsm_ms_decoder = {
00100 "gsm_ms",
00101 AVMEDIA_TYPE_AUDIO,
00102 CODEC_ID_GSM_MS,
00103 sizeof(GSMContext),
00104 gsm_init,
00105 NULL,
00106 NULL,
00107 gsm_decode_frame,
00108 .long_name = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"),
00109 };