summaryrefslogtreecommitdiff
path: root/ffmpeg/libavcodec/vorbisdec.c
diff options
context:
space:
mode:
authorTim Redfern <tim@eclectronics.org>2013-12-29 12:19:38 +0000
committerTim Redfern <tim@eclectronics.org>2013-12-29 12:19:38 +0000
commitf7813a5324be39d13ab536c245d15dfc602a7849 (patch)
treefad99148b88823d34a5df2f0a25881a002eb291b /ffmpeg/libavcodec/vorbisdec.c
parentb7a5a477b8ff4d4e3028b9dfb9a9df0a41463f92 (diff)
basic type mechanism working
Diffstat (limited to 'ffmpeg/libavcodec/vorbisdec.c')
-rw-r--r--ffmpeg/libavcodec/vorbisdec.c84
1 files changed, 57 insertions, 27 deletions
diff --git a/ffmpeg/libavcodec/vorbisdec.c b/ffmpeg/libavcodec/vorbisdec.c
index f30745d..a2f7dd2 100644
--- a/ffmpeg/libavcodec/vorbisdec.c
+++ b/ffmpeg/libavcodec/vorbisdec.c
@@ -1230,8 +1230,11 @@ static int vorbis_floor1_decode(vorbis_context *vc,
cval = cval >> cbits;
if (book > -1) {
- floor1_Y[offset+j] = get_vlc2(gb, vc->codebooks[book].vlc.table,
- vc->codebooks[book].nb_bits, 3);
+ int v = get_vlc2(gb, vc->codebooks[book].vlc.table,
+ vc->codebooks[book].nb_bits, 3);
+ if (v < 0)
+ return AVERROR_INVALIDDATA;
+ floor1_Y[offset+j] = v;
} else {
floor1_Y[offset+j] = 0;
}
@@ -1308,6 +1311,50 @@ static int vorbis_floor1_decode(vorbis_context *vc,
return 0;
}
+static av_always_inline int setup_classifs(vorbis_context *vc,
+ vorbis_residue *vr,
+ uint8_t *do_not_decode,
+ unsigned ch_used,
+ int partition_count)
+{
+ int p, j, i;
+ unsigned c_p_c = vc->codebooks[vr->classbook].dimensions;
+ unsigned inverse_class = ff_inverse[vr->classifications];
+ unsigned temp, temp2;
+ for (p = 0, j = 0; j < ch_used; ++j) {
+ if (!do_not_decode[j]) {
+ temp = get_vlc2(&vc->gb, vc->codebooks[vr->classbook].vlc.table,
+ vc->codebooks[vr->classbook].nb_bits, 3);
+
+ av_dlog(NULL, "Classword: %u\n", temp);
+
+ if ((int)temp < 0)
+ return temp;
+
+ av_assert0(vr->classifications > 1); //needed for inverse[]
+
+ if (temp <= 65536) {
+ for (i = partition_count + c_p_c - 1; i >= partition_count; i--) {
+ temp2 = (((uint64_t)temp) * inverse_class) >> 32;
+
+ if (i < vr->ptns_to_read)
+ vr->classifs[p + i] = temp - temp2 * vr->classifications;
+ temp = temp2;
+ }
+ } else {
+ for (i = partition_count + c_p_c - 1; i >= partition_count; i--) {
+ temp2 = temp / vr->classifications;
+
+ if (i < vr->ptns_to_read)
+ vr->classifs[p + i] = temp - temp2 * vr->classifications;
+ temp = temp2;
+ }
+ }
+ }
+ p += vr->ptns_to_read;
+ }
+ return 0;
+}
// Read and decode residue
static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc,
@@ -1321,10 +1368,10 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc,
{
GetBitContext *gb = &vc->gb;
unsigned c_p_c = vc->codebooks[vr->classbook].dimensions;
- unsigned ptns_to_read = vr->ptns_to_read;
uint8_t *classifs = vr->classifs;
unsigned pass, ch_used, i, j, k, l;
unsigned max_output = (ch - 1) * vlen;
+ int ptns_to_read = vr->ptns_to_read;
if (vr_type == 2) {
for (j = 1; j < ch; ++j)
@@ -1340,37 +1387,20 @@ 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 -1;
+ return AVERROR_INVALIDDATA;
}
av_dlog(NULL, " residue type 0/1/2 decode begin, ch: %d cpc %d \n", ch, c_p_c);
for (pass = 0; pass <= vr->maxpass; ++pass) { // FIXME OPTIMIZE?
- uint16_t voffset, partition_count, j_times_ptns_to_read;
+ int voffset, partition_count, j_times_ptns_to_read;
voffset = vr->begin;
for (partition_count = 0; partition_count < ptns_to_read;) { // SPEC error
if (!pass) {
- unsigned inverse_class = ff_inverse[vr->classifications];
- for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) {
- if (!do_not_decode[j]) {
- unsigned temp = get_vlc2(gb, vc->codebooks[vr->classbook].vlc.table,
- vc->codebooks[vr->classbook].nb_bits, 3);
-
- av_dlog(NULL, "Classword: %u\n", temp);
-
- av_assert0(vr->classifications > 1 && temp <= 65536); //needed for inverse[]
- for (i = 0; i < c_p_c; ++i) {
- unsigned temp2;
-
- temp2 = (((uint64_t)temp) * inverse_class) >> 32;
- if (partition_count + c_p_c - 1 - i < ptns_to_read)
- classifs[j_times_ptns_to_read + partition_count + c_p_c - 1 - i] = temp - temp2 * vr->classifications;
- temp = temp2;
- }
- }
- j_times_ptns_to_read += ptns_to_read;
- }
+ int ret;
+ if ((ret = setup_classifs(vc, vr, do_not_decode, ch_used, partition_count)) < 0)
+ return ret;
}
for (i = 0; (i < c_p_c) && (partition_count < ptns_to_read); ++i) {
for (j_times_ptns_to_read = 0, j = 0; j < ch_used; ++j) {
@@ -1610,7 +1640,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr)
residue = &vc->residues[mapping->submap_residue[i]];
if (ch_left < ch) {
av_log(vc->avctx, AV_LOG_ERROR, "Too many channels in vorbis_floor_decode.\n");
- return -1;
+ return AVERROR_INVALIDDATA;
}
if (ch) {
ret = vorbis_residue_decode(vc, residue, ch, do_not_decode, ch_res_ptr, vlen, ch_left);
@@ -1787,6 +1817,7 @@ static av_cold void vorbis_decode_flush(AVCodecContext *avctx)
AVCodec ff_vorbis_decoder = {
.name = "vorbis",
+ .long_name = NULL_IF_CONFIG_SMALL("Vorbis"),
.type = AVMEDIA_TYPE_AUDIO,
.id = AV_CODEC_ID_VORBIS,
.priv_data_size = sizeof(vorbis_context),
@@ -1795,7 +1826,6 @@ AVCodec ff_vorbis_decoder = {
.decode = vorbis_decode_frame,
.flush = vorbis_decode_flush,
.capabilities = CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("Vorbis"),
.channel_layouts = ff_vorbis_channel_layouts,
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
AV_SAMPLE_FMT_NONE },