00001 /* 00002 * Copyright (c) 2012 Justin Ruggles 00003 * 00004 * This file is part of Libav. 00005 * 00006 * Libav is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * Libav is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with Libav; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00028 #include "parser.h" 00029 #include "gsm.h" 00030 00031 typedef struct GSMParseContext { 00032 ParseContext pc; 00033 int block_size; 00034 int remaining; 00035 } GSMParseContext; 00036 00037 static int gsm_parse(AVCodecParserContext *s1, AVCodecContext *avctx, 00038 const uint8_t **poutbuf, int *poutbuf_size, 00039 const uint8_t *buf, int buf_size) 00040 { 00041 GSMParseContext *s = s1->priv_data; 00042 ParseContext *pc = &s->pc; 00043 int next; 00044 00045 if (!s->block_size) { 00046 switch (avctx->codec_id) { 00047 case CODEC_ID_GSM: s->block_size = GSM_BLOCK_SIZE; break; 00048 case CODEC_ID_GSM_MS: s->block_size = GSM_MS_BLOCK_SIZE; break; 00049 default: 00050 return AVERROR(EINVAL); 00051 } 00052 } 00053 00054 if (!s->remaining) 00055 s->remaining = s->block_size; 00056 if (s->remaining <= buf_size) { 00057 next = s->remaining; 00058 s->remaining = 0; 00059 } else { 00060 next = END_NOT_FOUND; 00061 s->remaining -= buf_size; 00062 } 00063 00064 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) { 00065 *poutbuf = NULL; 00066 *poutbuf_size = 0; 00067 return buf_size; 00068 } 00069 *poutbuf = buf; 00070 *poutbuf_size = buf_size; 00071 return next; 00072 } 00073 00074 AVCodecParser ff_gsm_parser = { 00075 .codec_ids = { CODEC_ID_GSM, CODEC_ID_GSM_MS }, 00076 .priv_data_size = sizeof(GSMParseContext), 00077 .parser_parse = gsm_parse, 00078 .parser_close = ff_parse_close, 00079 };