X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fshorten.c;h=328aaccd29828b1c5a470c0687abc992092ebb73;hb=5f000d5f386601e2316a243c3e41536dfbbccf4d;hp=4d80d40a561a35bca1939a5b57bac23a7b0df75c;hpb=f038fe8b4a023351c82afcc901891097fa9b0d29;p=ffmpeg diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index 4d80d40a561..328aaccd298 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -2,23 +2,25 @@ * Shorten decoder * Copyright (c) 2005 Jeff Muizelaar * - * This library is free software; you can redistribute it and/or + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * 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 - * License along with this library; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file shorten.c + * @file libavcodec/shorten.c * Shorten decoder * @author Jeff Muizelaar * @@ -27,7 +29,7 @@ #define DEBUG #include #include "avcodec.h" -#include "bitstream.h" +#include "get_bits.h" #include "golomb.h" #define MAX_CHANNELS 8 @@ -98,26 +100,36 @@ typedef struct ShortenContext { int32_t lpcqoffset; } ShortenContext; -static int shorten_decode_init(AVCodecContext * avctx) +static av_cold int shorten_decode_init(AVCodecContext * avctx) { ShortenContext *s = avctx->priv_data; s->avctx = avctx; + avctx->sample_fmt = SAMPLE_FMT_S16; return 0; } -static void allocate_buffers(ShortenContext *s) +static int allocate_buffers(ShortenContext *s) { int i, chan; for (chan=0; chanchannels; chan++) { + if(FFMAX(1, s->nmean) >= UINT_MAX/sizeof(int32_t)){ + av_log(s->avctx, AV_LOG_ERROR, "nmean too large\n"); + return -1; + } + if(s->blocksize + s->nwrap >= UINT_MAX/sizeof(int32_t) || s->blocksize + s->nwrap <= (unsigned)s->nwrap){ + av_log(s->avctx, AV_LOG_ERROR, "s->blocksize + s->nwrap too large\n"); + return -1; + } + s->offset[chan] = av_realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean)); s->decoded[chan] = av_realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap)); for (i=0; inwrap; i++) s->decoded[chan][i] = 0; s->decoded[chan] += s->nwrap; - } + return 0; } @@ -161,12 +173,12 @@ static void init_offset(ShortenContext *s) s->offset[chan][i] = mean; } -static int inline get_le32(GetBitContext *gb) +static inline int get_le32(GetBitContext *gb) { return bswap_32(get_bits_long(gb, 32)); } -static short inline get_le16(GetBitContext *gb) +static inline short get_le16(GetBitContext *gb) { return bswap_16(get_bits_long(gb, 16)); } @@ -216,9 +228,9 @@ static int decode_wave_header(AVCodecContext *avctx, uint8_t *header, int header avctx->sample_rate = get_le32(&hb); avctx->bit_rate = get_le32(&hb) * 8; avctx->block_align = get_le16(&hb); - avctx->bits_per_sample = get_le16(&hb); + avctx->bits_per_coded_sample = get_le16(&hb); - if (avctx->bits_per_sample != 16) { + if (avctx->bits_per_coded_sample != 16) { av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n"); return -1; } @@ -257,8 +269,10 @@ static void decode_subframe_lpc(ShortenContext *s, int channel, int residual_siz static int shorten_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - uint8_t *buf, int buf_size) + AVPacket *avpkt) { + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; ShortenContext *s = avctx->priv_data; int i, input_buf_size = 0; int16_t *samples = data; @@ -282,17 +296,18 @@ static int shorten_decode_frame(AVCodecContext *avctx, s->bitstream_size= buf_size; if(buf_size < s->max_framesize){ - //dprintf("wanna more data ... %d\n", buf_size); + //dprintf(avctx, "wanna more data ... %d\n", buf_size); + *data_size = 0; return input_buf_size; } } init_get_bits(&s->gb, buf, buf_size*8); - get_bits(&s->gb, s->bitindex); + skip_bits(&s->gb, s->bitindex); if (!s->blocksize) { int maxnlpc = 0; /* shorten signature */ - if (get_bits_long(&s->gb, 32) != bswap_32(ff_get_fourcc("ajkg"))) { + if (get_bits_long(&s->gb, 32) != AV_RB32("ajkg")) { av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n"); return -1; } @@ -324,7 +339,8 @@ static int shorten_decode_frame(AVCodecContext *avctx, } s->nwrap = FFMAX(NWRAP, maxnlpc); - allocate_buffers(s); + if (allocate_buffers(s)) + return -1; init_offset(s); @@ -332,7 +348,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, s->lpcqoffset = V2LPCQOFFSET; if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) { - av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at begining of stream\n"); + av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at beginning of stream\n"); return -1; } @@ -459,6 +475,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, s->blocksize = get_uint(s, av_log2(s->blocksize)); break; case FN_QUIT: + *data_size = 0; return buf_size; break; default: @@ -487,7 +504,7 @@ frame_done: return i; } -static int shorten_decode_close(AVCodecContext *avctx) +static av_cold int shorten_decode_close(AVCodecContext *avctx) { ShortenContext *s = avctx->priv_data; int i; @@ -518,4 +535,5 @@ AVCodec shorten_decoder = { shorten_decode_close, shorten_decode_frame, .flush= shorten_flush, + .long_name= NULL_IF_CONFIG_SMALL("Shorten"), };