libavcodec/gsm_parser.c
82390f57
 /*
  * Copyright (c) 2012  Justin Ruggles
  *
d814a839
  * This file is part of FFmpeg.
82390f57
  *
d814a839
  * FFmpeg is free software; you can redistribute it and/or
82390f57
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
d814a839
  * FFmpeg is distributed in the hope that it will be useful,
82390f57
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
d814a839
  * License along with FFmpeg; if not, write to the Free Software
82390f57
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 /**
  * @file
  * GSM audio parser
  *
  * Splits packets into individual blocks.
  */
 
 #include "parser.h"
 #include "gsm.h"
 
 typedef struct GSMParseContext {
     ParseContext pc;
     int block_size;
2460b168
     int duration;
82390f57
     int remaining;
 } GSMParseContext;
 
 static int gsm_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
                      const uint8_t **poutbuf, int *poutbuf_size,
                      const uint8_t *buf, int buf_size)
 {
     GSMParseContext *s = s1->priv_data;
     ParseContext *pc = &s->pc;
     int next;
 
     if (!s->block_size) {
         switch (avctx->codec_id) {
36ef5369
         case AV_CODEC_ID_GSM:
2460b168
             s->block_size = GSM_BLOCK_SIZE;
             s->duration   = GSM_FRAME_SIZE;
             break;
36ef5369
         case AV_CODEC_ID_GSM_MS:
a16577d9
             s->block_size = avctx->block_align ? avctx->block_align
                                                : GSM_MS_BLOCK_SIZE;
2460b168
             s->duration   = GSM_FRAME_SIZE * 2;
             break;
82390f57
         default:
4d2f83f8
             *poutbuf      = buf;
             *poutbuf_size = buf_size;
             av_log(avctx, AV_LOG_ERROR, "Invalid codec_id\n");
             return buf_size;
82390f57
         }
     }
 
     if (!s->remaining)
         s->remaining = s->block_size;
     if (s->remaining <= buf_size) {
         next = s->remaining;
         s->remaining = 0;
     } else {
         next = END_NOT_FOUND;
         s->remaining -= buf_size;
     }
 
     if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) {
         *poutbuf      = NULL;
         *poutbuf_size = 0;
         return buf_size;
     }
2460b168
 
     s1->duration = s->duration;
 
82390f57
     *poutbuf      = buf;
     *poutbuf_size = buf_size;
     return next;
 }
 
 AVCodecParser ff_gsm_parser = {
36ef5369
     .codec_ids      = { AV_CODEC_ID_GSM, AV_CODEC_ID_GSM_MS },
82390f57
     .priv_data_size = sizeof(GSMParseContext),
     .parser_parse   = gsm_parse,
     .parser_close   = ff_parse_close,
 };