LCOV - code coverage report
Current view: top level - libavcodec - gsmdec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 38 52 73.1 %
Date: 2017-12-11 04:34:20 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /*
       2             :  * gsm 06.10 decoder
       3             :  * Copyright (c) 2010 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg 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             :  * FFmpeg 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 FFmpeg; 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 "libavutil/channel_layout.h"
      28             : #include "avcodec.h"
      29             : #include "get_bits.h"
      30             : #include "internal.h"
      31             : #include "msgsmdec.h"
      32             : 
      33             : #include "gsmdec_template.c"
      34             : 
      35           4 : static av_cold int gsm_init(AVCodecContext *avctx)
      36             : {
      37           4 :     avctx->channels       = 1;
      38           4 :     avctx->channel_layout = AV_CH_LAYOUT_MONO;
      39           4 :     if (!avctx->sample_rate)
      40           0 :         avctx->sample_rate = 8000;
      41           4 :     avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
      42             : 
      43           4 :     switch (avctx->codec_id) {
      44           2 :     case AV_CODEC_ID_GSM:
      45           2 :         avctx->frame_size  = GSM_FRAME_SIZE;
      46           2 :         avctx->block_align = GSM_BLOCK_SIZE;
      47           2 :         break;
      48           2 :     case AV_CODEC_ID_GSM_MS:
      49           2 :         avctx->frame_size  = 2 * GSM_FRAME_SIZE;
      50           2 :         if (!avctx->block_align)
      51           0 :             avctx->block_align = GSM_MS_BLOCK_SIZE;
      52             :         else
      53           4 :             if (avctx->block_align < MSN_MIN_BLOCK_SIZE ||
      54           4 :                 avctx->block_align > GSM_MS_BLOCK_SIZE  ||
      55           2 :                 (avctx->block_align - MSN_MIN_BLOCK_SIZE) % 3) {
      56           0 :                 av_log(avctx, AV_LOG_ERROR, "Invalid block alignment %d\n",
      57             :                        avctx->block_align);
      58           0 :                 return AVERROR_INVALIDDATA;
      59             :             }
      60             :     }
      61             : 
      62           4 :     return 0;
      63             : }
      64             : 
      65         591 : static int gsm_decode_frame(AVCodecContext *avctx, void *data,
      66             :                             int *got_frame_ptr, AVPacket *avpkt)
      67             : {
      68         591 :     AVFrame *frame = data;
      69             :     int res;
      70             :     GetBitContext gb;
      71         591 :     const uint8_t *buf = avpkt->data;
      72         591 :     int buf_size = avpkt->size;
      73             :     int16_t *samples;
      74             : 
      75         591 :     if (buf_size < avctx->block_align) {
      76           0 :         av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
      77           0 :         return AVERROR_INVALIDDATA;
      78             :     }
      79             : 
      80             :     /* get output buffer */
      81         591 :     frame->nb_samples = avctx->frame_size;
      82         591 :     if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
      83           0 :         return res;
      84         591 :     samples = (int16_t *)frame->data[0];
      85             : 
      86         591 :     switch (avctx->codec_id) {
      87         502 :     case AV_CODEC_ID_GSM:
      88         502 :         init_get_bits(&gb, buf, buf_size * 8);
      89         502 :         if (get_bits(&gb, 4) != 0xd)
      90           0 :             av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n");
      91         502 :         res = gsm_decode_block(avctx, samples, &gb, GSM_13000);
      92         502 :         if (res < 0)
      93           0 :             return res;
      94         502 :         break;
      95          89 :     case AV_CODEC_ID_GSM_MS:
      96          89 :         res = ff_msgsm_decode_block(avctx, samples, buf,
      97          89 :                                     (GSM_MS_BLOCK_SIZE - avctx->block_align) / 3);
      98          89 :         if (res < 0)
      99           0 :             return res;
     100             :     }
     101             : 
     102         591 :     *got_frame_ptr = 1;
     103             : 
     104         591 :     return avctx->block_align;
     105             : }
     106             : 
     107           0 : static void gsm_flush(AVCodecContext *avctx)
     108             : {
     109           0 :     GSMContext *s = avctx->priv_data;
     110           0 :     memset(s, 0, sizeof(*s));
     111           0 : }
     112             : 
     113             : #if CONFIG_GSM_DECODER
     114             : AVCodec ff_gsm_decoder = {
     115             :     .name           = "gsm",
     116             :     .long_name      = NULL_IF_CONFIG_SMALL("GSM"),
     117             :     .type           = AVMEDIA_TYPE_AUDIO,
     118             :     .id             = AV_CODEC_ID_GSM,
     119             :     .priv_data_size = sizeof(GSMContext),
     120             :     .init           = gsm_init,
     121             :     .decode         = gsm_decode_frame,
     122             :     .flush          = gsm_flush,
     123             :     .capabilities   = AV_CODEC_CAP_DR1,
     124             : };
     125             : #endif
     126             : #if CONFIG_GSM_MS_DECODER
     127             : AVCodec ff_gsm_ms_decoder = {
     128             :     .name           = "gsm_ms",
     129             :     .long_name      = NULL_IF_CONFIG_SMALL("GSM Microsoft variant"),
     130             :     .type           = AVMEDIA_TYPE_AUDIO,
     131             :     .id             = AV_CODEC_ID_GSM_MS,
     132             :     .priv_data_size = sizeof(GSMContext),
     133             :     .init           = gsm_init,
     134             :     .decode         = gsm_decode_frame,
     135             :     .flush          = gsm_flush,
     136             :     .capabilities   = AV_CODEC_CAP_DR1,
     137             : };
     138             : #endif

Generated by: LCOV version 1.13