diff options
| author | Tim Redfern <tim@eclectronics.org> | 2013-12-29 12:19:38 +0000 |
|---|---|---|
| committer | Tim Redfern <tim@eclectronics.org> | 2013-12-29 12:19:38 +0000 |
| commit | f7813a5324be39d13ab536c245d15dfc602a7849 (patch) | |
| tree | fad99148b88823d34a5df2f0a25881a002eb291b /ffmpeg/libavcodec/wmaprodec.c | |
| parent | b7a5a477b8ff4d4e3028b9dfb9a9df0a41463f92 (diff) | |
basic type mechanism working
Diffstat (limited to 'ffmpeg/libavcodec/wmaprodec.c')
| -rw-r--r-- | ffmpeg/libavcodec/wmaprodec.c | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/ffmpeg/libavcodec/wmaprodec.c b/ffmpeg/libavcodec/wmaprodec.c index 07cc223..d57c24d 100644 --- a/ffmpeg/libavcodec/wmaprodec.c +++ b/ffmpeg/libavcodec/wmaprodec.c @@ -106,6 +106,7 @@ #define WMAPRO_BLOCK_MIN_BITS 6 ///< log2 of min block size #define WMAPRO_BLOCK_MAX_BITS 13 ///< log2 of max block size +#define WMAPRO_BLOCK_MIN_SIZE (1 << WMAPRO_BLOCK_MIN_BITS) ///< minimum block size #define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) ///< maximum block size #define WMAPRO_BLOCK_SIZES (WMAPRO_BLOCK_MAX_BITS - WMAPRO_BLOCK_MIN_BITS + 1) ///< possible block sizes @@ -124,7 +125,7 @@ static VLC vec4_vlc; ///< 4 coefficients per symbol static VLC vec2_vlc; ///< 2 coefficients per symbol static VLC vec1_vlc; ///< 1 coefficient per symbol static VLC coef_vlc[2]; ///< coefficient run length vlc codes -static float sin64[33]; ///< sinus table for decorrelation +static float sin64[33]; ///< sine table for decorrelation /** * @brief frame specific decoder context for a single channel @@ -305,6 +306,10 @@ static av_cold int decode_init(AVCodecContext *avctx) /** generic init */ s->log2_frame_size = av_log2(avctx->block_align) + 4; + if (s->log2_frame_size > 25) { + avpriv_request_sample(avctx, "Large block align"); + return AVERROR_PATCHWELCOME; + } /** frame info */ s->skip_frame = 1; /* skip first frame */ @@ -336,7 +341,7 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - if (s->min_samples_per_subframe < (1<<WMAPRO_BLOCK_MIN_BITS)) { + if (s->min_samples_per_subframe < WMAPRO_BLOCK_MIN_SIZE) { av_log(avctx, AV_LOG_ERROR, "min_samples_per_subframe of %d too small\n", s->min_samples_per_subframe); return AVERROR_INVALIDDATA; @@ -438,8 +443,10 @@ static av_cold int decode_init(AVCodecContext *avctx) + s->sfb_offsets[i][b + 1] - 1) << i) >> 1; for (x = 0; x < num_possible_block_sizes; x++) { int v = 0; - while (s->sfb_offsets[x][v + 1] << x < offset) - ++v; + while (s->sfb_offsets[x][v + 1] << x < offset) { + v++; + av_assert0(v < MAX_BANDS); + } s->sf_offsets[i][x][b] = v; } } @@ -451,7 +458,7 @@ static av_cold int decode_init(AVCodecContext *avctx) 1.0 / (1 << (WMAPRO_BLOCK_MIN_BITS + i - 1)) / (1 << (s->bits_per_sample - 1))); - /** init MDCT windows: simple sinus window */ + /** init MDCT windows: simple sine window */ for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) { const int win_idx = WMAPRO_BLOCK_MAX_BITS - i; ff_init_ff_sine_windows(win_idx); @@ -493,6 +500,9 @@ static int decode_subframe_length(WMAProDecodeCtx *s, int offset) if (offset == s->samples_per_frame - s->min_samples_per_subframe) return s->min_samples_per_subframe; + if (get_bits_left(&s->gb) < 1) + return AVERROR_INVALIDDATA; + /** 1 bit indicates if the subframe is of maximum length */ if (s->max_subframe_len_bit) { if (get_bits1(&s->gb)) @@ -671,7 +681,7 @@ static void decode_decorrelation_matrix(WMAProDecodeCtx *s, /** *@brief Decode channel transformation parameters *@param s codec context - *@return 0 in case of success, < 0 in case of bitstream errors + *@return >= 0 in case of success, < 0 in case of bitstream errors */ static int decode_channel_transform(WMAProDecodeCtx* s) { @@ -726,6 +736,7 @@ static int decode_channel_transform(WMAProDecodeCtx* s) if (get_bits1(&s->gb)) { avpriv_request_sample(s->avctx, "Unknown channel transform type"); + return AVERROR_PATCHWELCOME; } } else { chgroup->transform = 1; @@ -1128,11 +1139,12 @@ static int decode_subframe(WMAProDecodeCtx *s) cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx]; /** configure the decoder for the current subframe */ + offset += s->samples_per_frame >> 1; + for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; - s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1) - + offset]; + s->channel[c].coeffs = &s->channel[c].out[offset]; } s->subframe_len = subframe_len; @@ -1188,6 +1200,7 @@ static int decode_subframe(WMAProDecodeCtx *s) av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs); return AVERROR_INVALIDDATA; } + av_assert0(num_vec_coeffs + offset <= FF_ARRAY_ELEMS(s->channel[c].out)); s->channel[c].num_vec_coeffs = num_vec_coeffs; } } else { @@ -1469,6 +1482,8 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, return; } + av_assert0(len <= put_bits_left(&s->pb)); + s->num_saved_bits += len; if (!append) { avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), @@ -1581,7 +1596,8 @@ static int decode_packet(AVCodecContext *avctx, void *data, (frame_size = show_bits(gb, s->log2_frame_size)) && frame_size <= remaining_bits(s, gb)) { save_bits(s, gb, frame_size, 0); - s->packet_done = !decode_frame(s, data, got_frame_ptr); + if (!s->packet_loss) + s->packet_done = !decode_frame(s, data, got_frame_ptr); } else if (!s->len_prefix && s->num_saved_bits > get_bits_count(&s->gb)) { /** when the frames do not have a length prefix, we don't know @@ -1632,6 +1648,7 @@ static void flush(AVCodecContext *avctx) */ AVCodec ff_wmapro_decoder = { .name = "wmapro", + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"), .type = AVMEDIA_TYPE_AUDIO, .id = AV_CODEC_ID_WMAPRO, .priv_data_size = sizeof(WMAProDecodeCtx), @@ -1640,7 +1657,6 @@ AVCodec ff_wmapro_decoder = { .decode = decode_packet, .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, .flush = flush, - .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"), .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, }; |
