X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fshorten.c;h=31251ac95b17fad2ad322082355e8ef2280a5441;hb=728c4658563dc82115ade0f1679679eddb7be5ff;hp=d99877bb02c3ae690bda955246b1de9e58838f5c;hpb=c10da30d8426a1f681d99a780b6e311f7fb4e5c5;p=ffmpeg diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index d99877bb02c..31251ac95b1 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -83,7 +83,7 @@ typedef struct ShortenContext { GetBitContext gb; int min_framesize, max_framesize; - int channels; + unsigned channels; int32_t *decoded[MAX_CHANNELS]; int32_t *decoded_base[MAX_CHANNELS]; @@ -108,10 +108,10 @@ typedef struct ShortenContext { int got_quit_command; } ShortenContext; -static av_cold int shorten_decode_init(AVCodecContext * avctx) +static av_cold int shorten_decode_init(AVCodecContext *avctx) { ShortenContext *s = avctx->priv_data; - s->avctx = avctx; + s->avctx = avctx; avctx->sample_fmt = AV_SAMPLE_FMT_S16P; return 0; @@ -123,17 +123,20 @@ static int allocate_buffers(ShortenContext *s) int *coeffs; void *tmp_ptr; - for (chan=0; chanchannels; chan++) { - if(FFMAX(1, s->nmean) >= UINT_MAX/sizeof(int32_t)){ + for (chan = 0; chan < s->channels; chan++) { + if (FFMAX(1, s->nmean) >= UINT_MAX / sizeof(int32_t)) { av_log(s->avctx, AV_LOG_ERROR, "nmean too large\n"); - return -1; + return AVERROR_INVALIDDATA; } - 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; + 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 AVERROR_INVALIDDATA; } - tmp_ptr = av_realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean)); + tmp_ptr = + av_realloc(s->offset[chan], sizeof(int32_t) * FFMAX(1, s->nmean)); if (!tmp_ptr) return AVERROR(ENOMEM); s->offset[chan] = tmp_ptr; @@ -143,7 +146,7 @@ static int allocate_buffers(ShortenContext *s) if (!tmp_ptr) return AVERROR(ENOMEM); s->decoded_base[chan] = tmp_ptr; - for (i=0; inwrap; i++) + for (i = 0; i < s->nwrap; i++) s->decoded_base[chan][i] = 0; s->decoded[chan] = s->decoded_base[chan] + s->nwrap; } @@ -156,7 +159,6 @@ static int allocate_buffers(ShortenContext *s) return 0; } - static inline unsigned int get_uint(ShortenContext *s, int k) { if (s->version != 0) @@ -164,7 +166,6 @@ static inline unsigned int get_uint(ShortenContext *s, int k) return get_ur_golomb_shorten(&s->gb, k); } - static void fix_bitshift(ShortenContext *s, int32_t *buffer) { int i; @@ -174,22 +175,20 @@ static void fix_bitshift(ShortenContext *s, int32_t *buffer) buffer[i] <<= s->bitshift; } - static int init_offset(ShortenContext *s) { int32_t mean = 0; - int chan, i; + int chan, i; int nblock = FFMAX(1, s->nmean); /* initialise offset */ - switch (s->internal_ftype) - { - case TYPE_S16HL: - case TYPE_S16LH: - mean = 0; - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "unknown audio type"); - return AVERROR_INVALIDDATA; + switch (s->internal_ftype) { + case TYPE_S16HL: + case TYPE_S16LH: + mean = 0; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "unknown audio type"); + return AVERROR_INVALIDDATA; } for (chan = 0; chan < s->channels; chan++) @@ -203,50 +202,56 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, { int len; short wave_format; + GetByteContext gb; + bytestream2_init(&gb, header, header_size); - if (bytestream_get_le32(&header) != MKTAG('R','I','F','F')) { + if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) { av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n"); - return -1; + return AVERROR_INVALIDDATA; } - header += 4; /* chunk size */; + bytestream2_skip(&gb, 4); /* chunk size */ - if (bytestream_get_le32(&header) != MKTAG('W','A','V','E')) { + if (bytestream2_get_le32(&gb) != MKTAG('W', 'A', 'V', 'E')) { av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n"); - return -1; + return AVERROR_INVALIDDATA; } - while (bytestream_get_le32(&header) != MKTAG('f','m','t',' ')) { - len = bytestream_get_le32(&header); - header += len; + while (bytestream2_get_le32(&gb) != MKTAG('f', 'm', 't', ' ')) { + len = bytestream2_get_le32(&gb); + bytestream2_skip(&gb, len); + if (bytestream2_get_bytes_left(&gb) < 16) { + av_log(avctx, AV_LOG_ERROR, "no fmt chunk found\n"); + return AVERROR_INVALIDDATA; + } } - len = bytestream_get_le32(&header); + len = bytestream2_get_le32(&gb); if (len < 16) { av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n"); - return -1; + return AVERROR_INVALIDDATA; } - wave_format = bytestream_get_le16(&header); + wave_format = bytestream2_get_le16(&gb); switch (wave_format) { - case WAVE_FORMAT_PCM: - break; - default: - av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n"); - return -1; + case WAVE_FORMAT_PCM: + break; + default: + av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n"); + return AVERROR(ENOSYS); } - header += 2; // skip channels (already got from shorten header) - avctx->sample_rate = bytestream_get_le32(&header); - header += 4; // skip bit rate (represents original uncompressed bit rate) - header += 2; // skip block align (not needed) - avctx->bits_per_coded_sample = bytestream_get_le16(&header); + bytestream2_skip(&gb, 2); // skip channels (already got from shorten header) + avctx->sample_rate = bytestream2_get_le32(&gb); + bytestream2_skip(&gb, 4); // skip bit rate (represents original uncompressed bit rate) + bytestream2_skip(&gb, 2); // skip block align (not needed) + avctx->bits_per_coded_sample = bytestream2_get_le16(&gb); if (avctx->bits_per_coded_sample != 16) { av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n"); - return -1; + return AVERROR(ENOSYS); } len -= 16; @@ -268,7 +273,8 @@ static void output_buffer(int16_t **samples, int nchan, int blocksize, } } -static const int fixed_coeffs[3][3] = { +static const int fixed_coeffs[][3] = { + { 0, 0, 0 }, { 1, 0, 0 }, { 2, -1, 0 }, { 3, -3, 1 } @@ -284,11 +290,12 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, /* read/validate prediction order */ pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE); if (pred_order > s->nwrap) { - av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n", pred_order); + av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n", + pred_order); return AVERROR(EINVAL); } /* read LPC coefficients */ - for (i=0; icoeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT); coeffs = s->coeffs; @@ -296,7 +303,12 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, } else { /* fixed LPC coeffs */ pred_order = command; - coeffs = fixed_coeffs[pred_order-1]; + if (pred_order >= FF_ARRAY_ELEMS(fixed_coeffs)) { + av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n", + pred_order); + return AVERROR_INVALIDDATA; + } + coeffs = fixed_coeffs[pred_order]; qshift = 0; } @@ -307,11 +319,12 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, /* decode residual and do LPC prediction */ init_sum = pred_order ? (command == FN_QLPC ? s->lpcqoffset : 0) : coffset; - for (i=0; i < s->blocksize; i++) { + for (i = 0; i < s->blocksize; i++) { sum = init_sum; - for (j=0; jdecoded[channel][i-j-1]; - s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + (sum >> qshift); + for (j = 0; j < pred_order; j++) + sum += coeffs[j] * s->decoded[channel][i - j - 1]; + s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + + (sum >> qshift); } /* add offset to current samples */ @@ -329,42 +342,47 @@ static int read_header(ShortenContext *s) /* shorten signature */ if (get_bits_long(&s->gb, 32) != AV_RB32("ajkg")) { av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n"); - return -1; + return AVERROR_INVALIDDATA; } - s->lpcqoffset = 0; - s->blocksize = DEFAULT_BLOCK_SIZE; - s->nmean = -1; - s->version = get_bits(&s->gb, 8); + s->lpcqoffset = 0; + s->blocksize = DEFAULT_BLOCK_SIZE; + s->nmean = -1; + s->version = get_bits(&s->gb, 8); s->internal_ftype = get_uint(s, TYPESIZE); s->channels = get_uint(s, CHANSIZE); - if (s->channels <= 0 || s->channels > MAX_CHANNELS) { + if (!s->channels) { + av_log(s->avctx, AV_LOG_ERROR, "No channels reported\n"); + return AVERROR_INVALIDDATA; + } + if (s->channels > MAX_CHANNELS) { av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels); s->channels = 0; - return -1; + return AVERROR_INVALIDDATA; } s->avctx->channels = s->channels; /* get blocksize if version > 0 */ if (s->version > 0) { - int skip_bytes, blocksize; + int skip_bytes; + unsigned blocksize; blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE)); if (!blocksize || blocksize > MAX_BLOCKSIZE) { - av_log(s->avctx, AV_LOG_ERROR, "invalid or unsupported block size: %d\n", + av_log(s->avctx, AV_LOG_ERROR, + "invalid or unsupported block size: %d\n", blocksize); return AVERROR(EINVAL); } s->blocksize = blocksize; - maxnlpc = get_uint(s, LPCQSIZE); + maxnlpc = get_uint(s, LPCQSIZE); s->nmean = get_uint(s, 0); skip_bytes = get_uint(s, NSKIPSIZE); - for (i=0; igb, 8); - } } s->nwrap = FFMAX(NWRAP, maxnlpc); @@ -378,21 +396,24 @@ static int read_header(ShortenContext *s) s->lpcqoffset = V2LPCQOFFSET; if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) { - av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at beginning of stream\n"); - return -1; + av_log(s->avctx, AV_LOG_ERROR, + "missing verbatim section at beginning of stream\n"); + return AVERROR_INVALIDDATA; } s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); - if (s->header_size >= OUT_BUFFER_SIZE || s->header_size < CANONICAL_HEADER_SIZE) { - av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", s->header_size); - return -1; + if (s->header_size >= OUT_BUFFER_SIZE || + s->header_size < CANONICAL_HEADER_SIZE) { + av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", + s->header_size); + return AVERROR_INVALIDDATA; } - for (i=0; iheader_size; i++) + for (i = 0; i < s->header_size; i++) s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); - if (decode_wave_header(s->avctx, s->header, s->header_size) < 0) - return -1; + if ((ret = decode_wave_header(s->avctx, s->header, s->header_size)) < 0) + return ret; s->cur_chan = 0; s->bitshift = 0; @@ -407,15 +428,15 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, { AVFrame *frame = data; const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - ShortenContext *s = avctx->priv_data; + int buf_size = avpkt->size; + ShortenContext *s = avctx->priv_data; int i, input_buf_size = 0; int ret; /* allocate internal bitstream buffer */ - if(s->max_framesize == 0){ + if (s->max_framesize == 0) { void *tmp_ptr; - s->max_framesize= 1024; // should hopefully be enough for the first header + s->max_framesize = 1024; // should hopefully be enough for the first header tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize); if (!tmp_ptr) { @@ -426,29 +447,32 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, } /* append current packet data to bitstream buffer */ - if(1 && s->max_framesize){//FIXME truncated - buf_size= FFMIN(buf_size, s->max_framesize - s->bitstream_size); - input_buf_size= buf_size; - - if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){ - memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size); - s->bitstream_index=0; + if (1 && s->max_framesize) { //FIXME truncated + buf_size = FFMIN(buf_size, s->max_framesize - s->bitstream_size); + input_buf_size = buf_size; + + if (s->bitstream_index + s->bitstream_size + buf_size > + s->allocated_bitstream_size) { + memmove(s->bitstream, &s->bitstream[s->bitstream_index], + s->bitstream_size); + s->bitstream_index = 0; } if (buf) - memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size); - buf= &s->bitstream[s->bitstream_index]; - buf_size += s->bitstream_size; - s->bitstream_size= buf_size; + memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, + buf_size); + buf = &s->bitstream[s->bitstream_index]; + buf_size += s->bitstream_size; + s->bitstream_size = buf_size; /* do not decode until buffer has at least max_framesize bytes or - the end of the file has been reached */ + * the end of the file has been reached */ if (buf_size < s->max_framesize && avpkt->data) { *got_frame_ptr = 0; return input_buf_size; } } /* init and position bitstream reader */ - init_get_bits(&s->gb, buf, buf_size*8); + init_get_bits(&s->gb, buf, buf_size * 8); skip_bits(&s->gb, s->bitindex); /* process header or next subblock */ @@ -470,7 +494,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, unsigned cmd; int len; - if (get_bits_left(&s->gb) < 3+FNSIZE) { + if (get_bits_left(&s->gb) < 3 + FNSIZE) { *got_frame_ptr = 0; break; } @@ -486,32 +510,32 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, if (!is_audio_command[cmd]) { /* process non-audio command */ switch (cmd) { - case FN_VERBATIM: - len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); - while (len--) { - get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); - } - break; - case FN_BITSHIFT: - s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE); - break; - case FN_BLOCKSIZE: { - int blocksize = get_uint(s, av_log2(s->blocksize)); - if (blocksize > s->blocksize) { - av_log(avctx, AV_LOG_ERROR, "Increasing block size is not supported\n"); - return AVERROR_PATCHWELCOME; - } - if (!blocksize || blocksize > MAX_BLOCKSIZE) { - av_log(avctx, AV_LOG_ERROR, "invalid or unsupported " - "block size: %d\n", blocksize); - return AVERROR(EINVAL); - } - s->blocksize = blocksize; - break; + case FN_VERBATIM: + len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); + while (len--) + get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); + break; + case FN_BITSHIFT: + s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE); + break; + case FN_BLOCKSIZE: { + unsigned blocksize = get_uint(s, av_log2(s->blocksize)); + if (blocksize > s->blocksize) { + av_log(avctx, AV_LOG_ERROR, + "Increasing block size is not supported\n"); + return AVERROR_PATCHWELCOME; } - case FN_QUIT: - s->got_quit_command = 1; - break; + if (!blocksize || blocksize > MAX_BLOCKSIZE) { + av_log(avctx, AV_LOG_ERROR, "invalid or unsupported " + "block size: %d\n", blocksize); + return AVERROR(EINVAL); + } + s->blocksize = blocksize; + break; + } + case FN_QUIT: + s->got_quit_command = 1; + break; } if (cmd == FN_BLOCKSIZE || cmd == FN_QUIT) { *got_frame_ptr = 0; @@ -537,7 +561,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, coffset = s->offset[channel][0]; else { int32_t sum = (s->version < 2) ? 0 : s->nmean / 2; - for (i=0; inmean; i++) + for (i = 0; i < s->nmean; i++) sum += s->offset[channel][i]; coffset = sum / s->nmean; if (s->version >= 2) @@ -546,21 +570,22 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, /* decode samples for this channel */ if (cmd == FN_ZERO) { - for (i=0; iblocksize; i++) + for (i = 0; i < s->blocksize; i++) s->decoded[channel][i] = 0; } else { - if ((ret = decode_subframe_lpc(s, cmd, channel, residual_size, coffset)) < 0) + if ((ret = decode_subframe_lpc(s, cmd, channel, + residual_size, coffset)) < 0) return ret; } /* update means with info from the current block */ if (s->nmean > 0) { int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2; - for (i=0; iblocksize; i++) + for (i = 0; i < s->blocksize; i++) sum += s->decoded[channel][i]; - for (i=1; inmean; i++) - s->offset[channel][i-1] = s->offset[channel][i]; + for (i = 1; i < s->nmean; i++) + s->offset[channel][i - 1] = s->offset[channel][i]; if (s->version < 2) s->offset[channel][s->nmean - 1] = sum / s->blocksize; @@ -569,11 +594,11 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, } /* copy wrap samples for use with next block */ - for (i=-s->nwrap; i<0; i++) + for (i = -s->nwrap; i < 0; i++) s->decoded[channel][i] = s->decoded[channel][i + s->blocksize]; /* shift samples to add in unused zero bits which were removed - during encoding */ + * during encoding */ fix_bitshift(s, s->decoded[channel]); /* if this is the last channel in the block, output the samples */ @@ -581,7 +606,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, if (s->cur_chan == s->channels) { /* get output buffer */ frame->nb_samples = s->blocksize; - if ((ret = ff_get_buffer(avctx, frame)) < 0) { + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -597,13 +622,13 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, *got_frame_ptr = 0; finish_frame: - s->bitindex = get_bits_count(&s->gb) - 8*((get_bits_count(&s->gb))/8); - i= (get_bits_count(&s->gb))/8; + s->bitindex = get_bits_count(&s->gb) - 8 * (get_bits_count(&s->gb) / 8); + i = get_bits_count(&s->gb) / 8; if (i > buf_size) { av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size); - s->bitstream_size=0; - s->bitstream_index=0; - return -1; + s->bitstream_size = 0; + s->bitstream_index = 0; + return AVERROR_INVALIDDATA; } if (s->bitstream_size) { s->bitstream_index += i; @@ -631,6 +656,7 @@ static av_cold int shorten_decode_close(AVCodecContext *avctx) AVCodec ff_shorten_decoder = { .name = "shorten", + .long_name = NULL_IF_CONFIG_SMALL("Shorten"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_SHORTEN, .priv_data_size = sizeof(ShortenContext), @@ -638,7 +664,6 @@ AVCodec ff_shorten_decoder = { .close = shorten_decode_close, .decode = shorten_decode_frame, .capabilities = CODEC_CAP_DELAY | CODEC_CAP_DR1, - .long_name = NULL_IF_CONFIG_SMALL("Shorten"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, AV_SAMPLE_FMT_NONE }, };