1cabdff1aSopenharmony_ci/** 2cabdff1aSopenharmony_ci * @file 3cabdff1aSopenharmony_ci * Common code for Vorbis I encoder and decoder 4cabdff1aSopenharmony_ci * @author Denes Balatoni ( dbalatoni programozo hu ) 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci/** 24cabdff1aSopenharmony_ci * @file 25cabdff1aSopenharmony_ci * Common code for Vorbis I encoder and decoder 26cabdff1aSopenharmony_ci * @author Denes Balatoni ( dbalatoni programozo hu ) 27cabdff1aSopenharmony_ci */ 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#include "libavutil/common.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#include "avcodec.h" 32cabdff1aSopenharmony_ci#include "vorbis.h" 33cabdff1aSopenharmony_ci 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_ci/* Helper functions */ 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_ci// x^(1/n) 38cabdff1aSopenharmony_ciunsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n) 39cabdff1aSopenharmony_ci{ 40cabdff1aSopenharmony_ci unsigned int ret = 0, i, j; 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_ci do { 43cabdff1aSopenharmony_ci ++ret; 44cabdff1aSopenharmony_ci for (i = 0, j = ret; i < n - 1; i++) 45cabdff1aSopenharmony_ci j *= ret; 46cabdff1aSopenharmony_ci } while (j <= x); 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_ci return ret - 1; 49cabdff1aSopenharmony_ci} 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_ci// Generate vlc codes from vorbis huffman code lengths 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_ci// the two bits[p] > 32 checks should be redundant, all calling code should 54cabdff1aSopenharmony_ci// already ensure that, but since it allows overwriting the stack it seems 55cabdff1aSopenharmony_ci// reasonable to check redundantly. 56cabdff1aSopenharmony_ciint ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num) 57cabdff1aSopenharmony_ci{ 58cabdff1aSopenharmony_ci uint32_t exit_at_level[33] = { 404 }; 59cabdff1aSopenharmony_ci unsigned i, j, p, code; 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci for (p = 0; (p < num) && (bits[p] == 0); ++p) 62cabdff1aSopenharmony_ci ; 63cabdff1aSopenharmony_ci if (p == num) 64cabdff1aSopenharmony_ci return 0; 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_ci codes[p] = 0; 67cabdff1aSopenharmony_ci if (bits[p] > 32) 68cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 69cabdff1aSopenharmony_ci for (i = 0; i < bits[p]; ++i) 70cabdff1aSopenharmony_ci exit_at_level[i+1] = 1u << i; 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_ci ++p; 73cabdff1aSopenharmony_ci 74cabdff1aSopenharmony_ci for (i = p; (i < num) && (bits[i] == 0); ++i) 75cabdff1aSopenharmony_ci ; 76cabdff1aSopenharmony_ci if (i == num) 77cabdff1aSopenharmony_ci return 0; 78cabdff1aSopenharmony_ci 79cabdff1aSopenharmony_ci for (; p < num; ++p) { 80cabdff1aSopenharmony_ci if (bits[p] > 32) 81cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 82cabdff1aSopenharmony_ci if (bits[p] == 0) 83cabdff1aSopenharmony_ci continue; 84cabdff1aSopenharmony_ci // find corresponding exit(node which the tree can grow further from) 85cabdff1aSopenharmony_ci for (i = bits[p]; i > 0; --i) 86cabdff1aSopenharmony_ci if (exit_at_level[i]) 87cabdff1aSopenharmony_ci break; 88cabdff1aSopenharmony_ci if (!i) // overspecified tree 89cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 90cabdff1aSopenharmony_ci code = exit_at_level[i]; 91cabdff1aSopenharmony_ci exit_at_level[i] = 0; 92cabdff1aSopenharmony_ci // construct code (append 0s to end) and introduce new exits 93cabdff1aSopenharmony_ci for (j = i + 1 ;j <= bits[p]; ++j) 94cabdff1aSopenharmony_ci exit_at_level[j] = code + (1u << (j - 1)); 95cabdff1aSopenharmony_ci codes[p] = code; 96cabdff1aSopenharmony_ci } 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_ci //no exits should be left (underspecified tree - ie. unused valid vlcs - not allowed by SPEC) 99cabdff1aSopenharmony_ci for (p = 1; p < 33; p++) 100cabdff1aSopenharmony_ci if (exit_at_level[p]) 101cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci return 0; 104cabdff1aSopenharmony_ci} 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ciint ff_vorbis_ready_floor1_list(AVCodecContext *avctx, 107cabdff1aSopenharmony_ci vorbis_floor1_entry *list, int values) 108cabdff1aSopenharmony_ci{ 109cabdff1aSopenharmony_ci int i; 110cabdff1aSopenharmony_ci list[0].sort = 0; 111cabdff1aSopenharmony_ci list[1].sort = 1; 112cabdff1aSopenharmony_ci for (i = 2; i < values; i++) { 113cabdff1aSopenharmony_ci int j; 114cabdff1aSopenharmony_ci list[i].low = 0; 115cabdff1aSopenharmony_ci list[i].high = 1; 116cabdff1aSopenharmony_ci list[i].sort = i; 117cabdff1aSopenharmony_ci for (j = 2; j < i; j++) { 118cabdff1aSopenharmony_ci int tmp = list[j].x; 119cabdff1aSopenharmony_ci if (tmp < list[i].x) { 120cabdff1aSopenharmony_ci if (tmp > list[list[i].low].x) 121cabdff1aSopenharmony_ci list[i].low = j; 122cabdff1aSopenharmony_ci } else { 123cabdff1aSopenharmony_ci if (tmp < list[list[i].high].x) 124cabdff1aSopenharmony_ci list[i].high = j; 125cabdff1aSopenharmony_ci } 126cabdff1aSopenharmony_ci } 127cabdff1aSopenharmony_ci } 128cabdff1aSopenharmony_ci for (i = 0; i < values - 1; i++) { 129cabdff1aSopenharmony_ci int j; 130cabdff1aSopenharmony_ci for (j = i + 1; j < values; j++) { 131cabdff1aSopenharmony_ci if (list[i].x == list[j].x) { 132cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 133cabdff1aSopenharmony_ci "Duplicate value found in floor 1 X coordinates\n"); 134cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 135cabdff1aSopenharmony_ci } 136cabdff1aSopenharmony_ci if (list[list[i].sort].x > list[list[j].sort].x) { 137cabdff1aSopenharmony_ci int tmp = list[i].sort; 138cabdff1aSopenharmony_ci list[i].sort = list[j].sort; 139cabdff1aSopenharmony_ci list[j].sort = tmp; 140cabdff1aSopenharmony_ci } 141cabdff1aSopenharmony_ci } 142cabdff1aSopenharmony_ci } 143cabdff1aSopenharmony_ci return 0; 144cabdff1aSopenharmony_ci} 145cabdff1aSopenharmony_ci 146cabdff1aSopenharmony_cistatic inline void render_line_unrolled(intptr_t x, int y, int x1, 147cabdff1aSopenharmony_ci intptr_t sy, int ady, int adx, 148cabdff1aSopenharmony_ci float *buf) 149cabdff1aSopenharmony_ci{ 150cabdff1aSopenharmony_ci int err = -adx; 151cabdff1aSopenharmony_ci x -= x1 - 1; 152cabdff1aSopenharmony_ci buf += x1 - 1; 153cabdff1aSopenharmony_ci while (++x < 0) { 154cabdff1aSopenharmony_ci err += ady; 155cabdff1aSopenharmony_ci if (err >= 0) { 156cabdff1aSopenharmony_ci err += ady - adx; 157cabdff1aSopenharmony_ci y += sy; 158cabdff1aSopenharmony_ci buf[x++] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; 159cabdff1aSopenharmony_ci } 160cabdff1aSopenharmony_ci buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; 161cabdff1aSopenharmony_ci } 162cabdff1aSopenharmony_ci if (x <= 0) { 163cabdff1aSopenharmony_ci if (err + ady >= 0) 164cabdff1aSopenharmony_ci y += sy; 165cabdff1aSopenharmony_ci buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; 166cabdff1aSopenharmony_ci } 167cabdff1aSopenharmony_ci} 168cabdff1aSopenharmony_ci 169cabdff1aSopenharmony_cistatic void render_line(int x0, int y0, int x1, int y1, float *buf) 170cabdff1aSopenharmony_ci{ 171cabdff1aSopenharmony_ci int dy = y1 - y0; 172cabdff1aSopenharmony_ci int adx = x1 - x0; 173cabdff1aSopenharmony_ci int ady = FFABS(dy); 174cabdff1aSopenharmony_ci int sy = dy < 0 ? -1 : 1; 175cabdff1aSopenharmony_ci buf[x0] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y0)]; 176cabdff1aSopenharmony_ci if (ady*2 <= adx) { // optimized common case 177cabdff1aSopenharmony_ci render_line_unrolled(x0, y0, x1, sy, ady, adx, buf); 178cabdff1aSopenharmony_ci } else { 179cabdff1aSopenharmony_ci int base = dy / adx; 180cabdff1aSopenharmony_ci int x = x0; 181cabdff1aSopenharmony_ci int y = y0; 182cabdff1aSopenharmony_ci int err = -adx; 183cabdff1aSopenharmony_ci ady -= FFABS(base) * adx; 184cabdff1aSopenharmony_ci while (++x < x1) { 185cabdff1aSopenharmony_ci y += base; 186cabdff1aSopenharmony_ci err += ady; 187cabdff1aSopenharmony_ci if (err >= 0) { 188cabdff1aSopenharmony_ci err -= adx; 189cabdff1aSopenharmony_ci y += sy; 190cabdff1aSopenharmony_ci } 191cabdff1aSopenharmony_ci buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; 192cabdff1aSopenharmony_ci } 193cabdff1aSopenharmony_ci } 194cabdff1aSopenharmony_ci} 195cabdff1aSopenharmony_ci 196cabdff1aSopenharmony_civoid ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values, 197cabdff1aSopenharmony_ci uint16_t *y_list, int *flag, 198cabdff1aSopenharmony_ci int multiplier, float *out, int samples) 199cabdff1aSopenharmony_ci{ 200cabdff1aSopenharmony_ci int lx, ly, i; 201cabdff1aSopenharmony_ci lx = 0; 202cabdff1aSopenharmony_ci ly = y_list[0] * multiplier; 203cabdff1aSopenharmony_ci for (i = 1; i < values; i++) { 204cabdff1aSopenharmony_ci int pos = list[i].sort; 205cabdff1aSopenharmony_ci if (flag[pos]) { 206cabdff1aSopenharmony_ci int x1 = list[pos].x; 207cabdff1aSopenharmony_ci int y1 = y_list[pos] * multiplier; 208cabdff1aSopenharmony_ci if (lx < samples) 209cabdff1aSopenharmony_ci render_line(lx, ly, FFMIN(x1,samples), y1, out); 210cabdff1aSopenharmony_ci lx = x1; 211cabdff1aSopenharmony_ci ly = y1; 212cabdff1aSopenharmony_ci } 213cabdff1aSopenharmony_ci if (lx >= samples) 214cabdff1aSopenharmony_ci break; 215cabdff1aSopenharmony_ci } 216cabdff1aSopenharmony_ci if (lx < samples) 217cabdff1aSopenharmony_ci render_line(lx, ly, samples, ly, out); 218cabdff1aSopenharmony_ci} 219