diff options
Diffstat (limited to 'chromium/third_party/ffmpeg/libavcodec/vorbisdec.c')
-rw-r--r-- | chromium/third_party/ffmpeg/libavcodec/vorbisdec.c | 56 |
1 files changed, 36 insertions, 20 deletions
diff --git a/chromium/third_party/ffmpeg/libavcodec/vorbisdec.c b/chromium/third_party/ffmpeg/libavcodec/vorbisdec.c index a2f7dd27f8e..87d1bbb97a3 100644 --- a/chromium/third_party/ffmpeg/libavcodec/vorbisdec.c +++ b/chromium/third_party/ffmpeg/libavcodec/vorbisdec.c @@ -151,7 +151,7 @@ typedef struct vorbis_context_s { uint8_t mode_count; vorbis_mode *modes; uint8_t mode_number; // mode number for the current packet - uint8_t previous_window; + int8_t previous_window; float *channel_residues; float *saved; } vorbis_context; @@ -378,7 +378,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) } // Weed out unused vlcs and build codevector vector - codebook_setup->codevectors = used_entries ? av_mallocz(used_entries * + codebook_setup->codevectors = used_entries ? av_mallocz_array(used_entries, codebook_setup->dimensions * sizeof(*codebook_setup->codevectors)) : NULL; @@ -561,7 +561,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) for (j = 0; j < floor_setup->data.t1.partitions; ++j) floor_setup->data.t1.x_list_dim+=floor_setup->data.t1.class_dimensions[floor_setup->data.t1.partition_class[j]]; - floor_setup->data.t1.list = av_mallocz(floor_setup->data.t1.x_list_dim * + floor_setup->data.t1.list = av_mallocz_array(floor_setup->data.t1.x_list_dim, sizeof(*floor_setup->data.t1.list)); if (!floor_setup->data.t1.list) return AVERROR(ENOMEM); @@ -640,8 +640,8 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) /* codebook dim is for padding if codebook dim doesn't * * divide order+1 then we need to read more data */ floor_setup->data.t0.lsp = - av_malloc((floor_setup->data.t0.order + 1 + max_codebook_dim) - * sizeof(*floor_setup->data.t0.lsp)); + av_malloc_array((floor_setup->data.t0.order + 1 + max_codebook_dim), + sizeof(*floor_setup->data.t0.lsp)); if (!floor_setup->data.t0.lsp) return AVERROR(ENOMEM); @@ -701,8 +701,7 @@ static int vorbis_parse_setup_hdr_residues(vorbis_context *vc) res_setup->partition_size = get_bits(gb, 24) + 1; /* Validations to prevent a buffer overflow later. */ if (res_setup->begin>res_setup->end || - res_setup->end > (res_setup->type == 2 ? vc->audio_channels : 1) * vc->blocksize[1] / 2 || - (res_setup->end-res_setup->begin) / res_setup->partition_size > V_MAX_PARTITIONS) { + (res_setup->end-res_setup->begin) / res_setup->partition_size > FFMIN(V_MAX_PARTITIONS, 65535)) { av_log(vc->avctx, AV_LOG_ERROR, "partition out of bounds: type, begin, end, size, blocksize: %"PRIu16", %"PRIu32", %"PRIu32", %u, %"PRIu32"\n", res_setup->type, res_setup->begin, res_setup->end, @@ -715,7 +714,7 @@ static int vorbis_parse_setup_hdr_residues(vorbis_context *vc) res_setup->ptns_to_read = (res_setup->end - res_setup->begin) / res_setup->partition_size; - res_setup->classifs = av_malloc(res_setup->ptns_to_read * + res_setup->classifs = av_malloc_array(res_setup->ptns_to_read, vc->audio_channels * sizeof(*res_setup->classifs)); if (!res_setup->classifs) @@ -808,7 +807,7 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc) } if (mapping_setup->submaps>1) { - mapping_setup->mux = av_mallocz(vc->audio_channels * + mapping_setup->mux = av_mallocz_array(vc->audio_channels, sizeof(*mapping_setup->mux)); if (!mapping_setup->mux) return AVERROR(ENOMEM); @@ -843,7 +842,7 @@ static int create_map(vorbis_context *vc, unsigned floor_number) for (blockflag = 0; blockflag < 2; ++blockflag) { n = vc->blocksize[blockflag] / 2; floors[floor_number].data.t0.map[blockflag] = - av_malloc((n + 1) * sizeof(int32_t)); // n + sentinel + av_malloc_array(n + 1, sizeof(int32_t)); // n + sentinel if (!floors[floor_number].data.t0.map[blockflag]) return AVERROR(ENOMEM); @@ -984,12 +983,12 @@ static int vorbis_parse_id_hdr(vorbis_context *vc) return AVERROR_INVALIDDATA; } - vc->channel_residues = av_malloc((vc->blocksize[1] / 2) * vc->audio_channels * sizeof(*vc->channel_residues)); - vc->saved = av_mallocz((vc->blocksize[1] / 4) * vc->audio_channels * sizeof(*vc->saved)); + vc->channel_residues = av_malloc_array(vc->blocksize[1] / 2, vc->audio_channels * sizeof(*vc->channel_residues)); + vc->saved = av_mallocz_array(vc->blocksize[1] / 4, vc->audio_channels * sizeof(*vc->saved)); if (!vc->channel_residues || !vc->saved) return AVERROR(ENOMEM); - vc->previous_window = 0; + vc->previous_window = -1; ff_mdct_init(&vc->mdct[0], bl0, 1, -1.0); ff_mdct_init(&vc->mdct[1], bl1, 1, -1.0); @@ -1372,6 +1371,7 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, unsigned pass, ch_used, i, j, k, l; unsigned max_output = (ch - 1) * vlen; int ptns_to_read = vr->ptns_to_read; + int libvorbis_bug = 0; if (vr_type == 2) { for (j = 1; j < ch; ++j) @@ -1386,8 +1386,13 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, } if (max_output > ch_left * vlen) { - av_log(vc->avctx, AV_LOG_ERROR, "Insufficient output buffer\n"); - return AVERROR_INVALIDDATA; + if (max_output <= ch_left * vlen + vr->partition_size*ch_used/ch) { + ptns_to_read--; + libvorbis_bug = 1; + } else { + av_log(vc->avctx, AV_LOG_ERROR, "Insufficient output buffer\n"); + return AVERROR_INVALIDDATA; + } } av_dlog(NULL, " residue type 0/1/2 decode begin, ch: %d cpc %d \n", ch, c_p_c); @@ -1496,6 +1501,14 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, voffset += vr->partition_size; } } + if (libvorbis_bug && !pass) { + for (j = 0; j < ch_used; ++j) { + if (!do_not_decode[j]) { + get_vlc2(&vc->gb, vc->codebooks[vr->classbook].vlc.table, + vc->codebooks[vr->classbook].nb_bits, 3); + } + } + } } return 0; } @@ -1548,7 +1561,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr) { GetBitContext *gb = &vc->gb; FFTContext *mdct; - unsigned previous_window = vc->previous_window; + int previous_window = vc->previous_window; unsigned mode_number, blockflag, blocksize; int i, j; uint8_t no_residue[255]; @@ -1581,9 +1594,11 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr) blocksize = vc->blocksize[blockflag]; vlen = blocksize / 2; if (blockflag) { - previous_window = get_bits(gb, 1); - skip_bits1(gb); // next_window - } + int code = get_bits(gb, 2); + if (previous_window < 0) + previous_window = code>>1; + } else if (previous_window < 0) + previous_window = 0; memset(ch_res_ptr, 0, sizeof(float) * vc->audio_channels * vlen); //FIXME can this be removed ? for (i = 0; i < vc->audio_channels; ++i) @@ -1812,7 +1827,8 @@ static av_cold void vorbis_decode_flush(AVCodecContext *avctx) memset(vc->saved, 0, (vc->blocksize[1] / 4) * vc->audio_channels * sizeof(*vc->saved)); } - vc->previous_window = 0; + vc->previous_window = -1; + vc->first_frame = 0; } AVCodec ff_vorbis_decoder = { |