1/* 2 * gsm 06.10 decoder 3 * Copyright (c) 2010 Reimar D��ffinger <Reimar.Doeffinger@gmx.de> 4 * 5 * This file is part of Libav. 6 * 7 * Libav is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * Libav is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with Libav; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * GSM decoder 25 */ 26 27#include "avcodec.h" 28#include "get_bits.h" 29#include "msgsmdec.h" 30 31#include "gsmdec_template.c" 32 33static av_cold int gsm_init(AVCodecContext *avctx) 34{ 35 GSMContext *s = avctx->priv_data; 36 37 avctx->channels = 1; 38 if (!avctx->sample_rate) 39 avctx->sample_rate = 8000; 40 avctx->sample_fmt = AV_SAMPLE_FMT_S16; 41 42 switch (avctx->codec_id) { 43 case CODEC_ID_GSM: 44 avctx->frame_size = GSM_FRAME_SIZE; 45 avctx->block_align = GSM_BLOCK_SIZE; 46 break; 47 case CODEC_ID_GSM_MS: 48 avctx->frame_size = 2 * GSM_FRAME_SIZE; 49 avctx->block_align = GSM_MS_BLOCK_SIZE; 50 } 51 52 avcodec_get_frame_defaults(&s->frame); 53 avctx->coded_frame = &s->frame; 54 55 return 0; 56} 57 58static int gsm_decode_frame(AVCodecContext *avctx, void *data, 59 int *got_frame_ptr, AVPacket *avpkt) 60{ 61 GSMContext *s = avctx->priv_data; 62 int res; 63 GetBitContext gb; 64 const uint8_t *buf = avpkt->data; 65 int buf_size = avpkt->size; 66 int16_t *samples; 67 68 if (buf_size < avctx->block_align) { 69 av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); 70 return AVERROR_INVALIDDATA; 71 } 72 73 /* get output buffer */ 74 s->frame.nb_samples = avctx->frame_size; 75 if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) { 76 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 77 return res; 78 } 79 samples = (int16_t *)s->frame.data[0]; 80 81 switch (avctx->codec_id) { 82 case CODEC_ID_GSM: 83 init_get_bits(&gb, buf, buf_size * 8); 84 if (get_bits(&gb, 4) != 0xd) 85 av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n"); 86 res = gsm_decode_block(avctx, samples, &gb); 87 if (res < 0) 88 return res; 89 break; 90 case CODEC_ID_GSM_MS: 91 res = ff_msgsm_decode_block(avctx, samples, buf); 92 if (res < 0) 93 return res; 94 } 95 96 *got_frame_ptr = 1; 97 *(AVFrame *)data = s->frame; 98 99 return avctx->block_align; 100} 101 102static void gsm_flush(AVCodecContext *avctx) 103{ 104 GSMContext *s = avctx->priv_data; 105 memset(s, 0, sizeof(*s)); 106} 107 108AVCodec ff_gsm_decoder = { 109 .name = "gsm", 110 .type = AVMEDIA_TYPE_AUDIO, 111 .id = CODEC_ID_GSM, 112 .priv_data_size = sizeof(GSMContext), 113 .init = gsm_init, 114 .decode = gsm_decode_frame, 115 .flush = gsm_flush, 116 .capabilities = CODEC_CAP_DR1, 117 .long_name = NULL_IF_CONFIG_SMALL("GSM"), 118}; 119 120AVCodec ff_gsm_ms_decoder = { 121 .name = "gsm_ms", 122 .type = AVMEDIA_TYPE_AUDIO, 123 .id = CODEC_ID_GSM_MS, 124 .priv_data_size = sizeof(GSMContext), 125 .init = gsm_init, 126 .decode = gsm_decode_frame, 127 .flush = gsm_flush, 128 .capabilities = CODEC_CAP_DR1, 129 .long_name = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"), 130}; 131