summaryrefslogtreecommitdiff
path: root/ffmpeg/libavcodec/wmaprodec.c
diff options
context:
space:
mode:
Diffstat (limited to 'ffmpeg/libavcodec/wmaprodec.c')
-rw-r--r--ffmpeg/libavcodec/wmaprodec.c36
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 },
};