1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * WavPack lossless audio encoder 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#define BITSTREAM_WRITER_LE 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include "libavutil/channel_layout.h" 24cabdff1aSopenharmony_ci#include "libavutil/intreadwrite.h" 25cabdff1aSopenharmony_ci#include "libavutil/opt.h" 26cabdff1aSopenharmony_ci#include "avcodec.h" 27cabdff1aSopenharmony_ci#include "codec_internal.h" 28cabdff1aSopenharmony_ci#include "encode.h" 29cabdff1aSopenharmony_ci#include "internal.h" 30cabdff1aSopenharmony_ci#include "put_bits.h" 31cabdff1aSopenharmony_ci#include "bytestream.h" 32cabdff1aSopenharmony_ci#include "wavpackenc.h" 33cabdff1aSopenharmony_ci#include "wavpack.h" 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_ci#define UPDATE_WEIGHT(weight, delta, source, result) \ 36cabdff1aSopenharmony_ci if ((source) && (result)) { \ 37cabdff1aSopenharmony_ci int32_t s = (int32_t) ((source) ^ (result)) >> 31; \ 38cabdff1aSopenharmony_ci weight = ((delta) ^ s) + ((weight) - s); \ 39cabdff1aSopenharmony_ci } 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_ci#define APPLY_WEIGHT_F(weight, sample) ((((((sample) & 0xffff) * (weight)) >> 9) + \ 42cabdff1aSopenharmony_ci ((((sample) & ~0xffff) >> 9) * (weight)) + 1) >> 1) 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_ci#define APPLY_WEIGHT_I(weight, sample) (((weight) * (sample) + 512) >> 10) 45cabdff1aSopenharmony_ci 46cabdff1aSopenharmony_ci#define APPLY_WEIGHT(weight, sample) ((sample) != (short) (sample) ? \ 47cabdff1aSopenharmony_ci APPLY_WEIGHT_F(weight, sample) : APPLY_WEIGHT_I (weight, sample)) 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci#define CLEAR(destin) memset(&destin, 0, sizeof(destin)); 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_ci#define SHIFT_LSB 13 52cabdff1aSopenharmony_ci#define SHIFT_MASK (0x1FU << SHIFT_LSB) 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ci#define MAG_LSB 18 55cabdff1aSopenharmony_ci#define MAG_MASK (0x1FU << MAG_LSB) 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_ci#define SRATE_LSB 23 58cabdff1aSopenharmony_ci#define SRATE_MASK (0xFU << SRATE_LSB) 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_ci#define EXTRA_TRY_DELTAS 1 61cabdff1aSopenharmony_ci#define EXTRA_ADJUST_DELTAS 2 62cabdff1aSopenharmony_ci#define EXTRA_SORT_FIRST 4 63cabdff1aSopenharmony_ci#define EXTRA_BRANCHES 8 64cabdff1aSopenharmony_ci#define EXTRA_SORT_LAST 16 65cabdff1aSopenharmony_ci 66cabdff1aSopenharmony_citypedef struct WavPackExtraInfo { 67cabdff1aSopenharmony_ci struct Decorr dps[MAX_TERMS]; 68cabdff1aSopenharmony_ci int nterms, log_limit, gt16bit; 69cabdff1aSopenharmony_ci uint32_t best_bits; 70cabdff1aSopenharmony_ci} WavPackExtraInfo; 71cabdff1aSopenharmony_ci 72cabdff1aSopenharmony_citypedef struct WavPackWords { 73cabdff1aSopenharmony_ci int pend_data, holding_one, zeros_acc; 74cabdff1aSopenharmony_ci int holding_zero, pend_count; 75cabdff1aSopenharmony_ci WvChannel c[2]; 76cabdff1aSopenharmony_ci} WavPackWords; 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_citypedef struct WavPackEncodeContext { 79cabdff1aSopenharmony_ci AVClass *class; 80cabdff1aSopenharmony_ci AVCodecContext *avctx; 81cabdff1aSopenharmony_ci PutBitContext pb; 82cabdff1aSopenharmony_ci int block_samples; 83cabdff1aSopenharmony_ci int buffer_size; 84cabdff1aSopenharmony_ci int sample_index; 85cabdff1aSopenharmony_ci int stereo, stereo_in; 86cabdff1aSopenharmony_ci int ch_offset; 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ci int32_t *samples[2]; 89cabdff1aSopenharmony_ci int samples_size[2]; 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci int32_t *sampleptrs[MAX_TERMS+2][2]; 92cabdff1aSopenharmony_ci int sampleptrs_size[MAX_TERMS+2][2]; 93cabdff1aSopenharmony_ci 94cabdff1aSopenharmony_ci int32_t *temp_buffer[2][2]; 95cabdff1aSopenharmony_ci int temp_buffer_size[2][2]; 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci int32_t *best_buffer[2]; 98cabdff1aSopenharmony_ci int best_buffer_size[2]; 99cabdff1aSopenharmony_ci 100cabdff1aSopenharmony_ci int32_t *js_left, *js_right; 101cabdff1aSopenharmony_ci int js_left_size, js_right_size; 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_ci int32_t *orig_l, *orig_r; 104cabdff1aSopenharmony_ci int orig_l_size, orig_r_size; 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ci unsigned extra_flags; 107cabdff1aSopenharmony_ci int optimize_mono; 108cabdff1aSopenharmony_ci int decorr_filter; 109cabdff1aSopenharmony_ci int joint; 110cabdff1aSopenharmony_ci int num_branches; 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci uint32_t flags; 113cabdff1aSopenharmony_ci uint32_t crc_x; 114cabdff1aSopenharmony_ci WavPackWords w; 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci uint8_t int32_sent_bits, int32_zeros, int32_ones, int32_dups; 117cabdff1aSopenharmony_ci uint8_t float_flags, float_shift, float_max_exp, max_exp; 118cabdff1aSopenharmony_ci int32_t shifted_ones, shifted_zeros, shifted_both; 119cabdff1aSopenharmony_ci int32_t false_zeros, neg_zeros, ordata; 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci int num_terms, shift, joint_stereo, false_stereo; 122cabdff1aSopenharmony_ci int num_decorrs, num_passes, best_decorr, mask_decorr; 123cabdff1aSopenharmony_ci struct Decorr decorr_passes[MAX_TERMS]; 124cabdff1aSopenharmony_ci const WavPackDecorrSpec *decorr_specs; 125cabdff1aSopenharmony_ci float delta_decay; 126cabdff1aSopenharmony_ci} WavPackEncodeContext; 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_cistatic av_cold int wavpack_encode_init(AVCodecContext *avctx) 129cabdff1aSopenharmony_ci{ 130cabdff1aSopenharmony_ci WavPackEncodeContext *s = avctx->priv_data; 131cabdff1aSopenharmony_ci 132cabdff1aSopenharmony_ci s->avctx = avctx; 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_ci if (avctx->ch_layout.nb_channels > 255) { 135cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Invalid channel count: %d\n", avctx->ch_layout.nb_channels); 136cabdff1aSopenharmony_ci return AVERROR(EINVAL); 137cabdff1aSopenharmony_ci } 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ci if (!avctx->frame_size) { 140cabdff1aSopenharmony_ci int block_samples; 141cabdff1aSopenharmony_ci if (!(avctx->sample_rate & 1)) 142cabdff1aSopenharmony_ci block_samples = avctx->sample_rate / 2; 143cabdff1aSopenharmony_ci else 144cabdff1aSopenharmony_ci block_samples = avctx->sample_rate; 145cabdff1aSopenharmony_ci 146cabdff1aSopenharmony_ci while (block_samples * avctx->ch_layout.nb_channels > WV_MAX_SAMPLES) 147cabdff1aSopenharmony_ci block_samples /= 2; 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci while (block_samples * avctx->ch_layout.nb_channels < 40000) 150cabdff1aSopenharmony_ci block_samples *= 2; 151cabdff1aSopenharmony_ci avctx->frame_size = block_samples; 152cabdff1aSopenharmony_ci } else if (avctx->frame_size && (avctx->frame_size < 128 || 153cabdff1aSopenharmony_ci avctx->frame_size > WV_MAX_SAMPLES)) { 154cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "invalid block size: %d\n", avctx->frame_size); 155cabdff1aSopenharmony_ci return AVERROR(EINVAL); 156cabdff1aSopenharmony_ci } 157cabdff1aSopenharmony_ci 158cabdff1aSopenharmony_ci if (avctx->compression_level != FF_COMPRESSION_DEFAULT) { 159cabdff1aSopenharmony_ci if (avctx->compression_level >= 3) { 160cabdff1aSopenharmony_ci s->decorr_filter = 3; 161cabdff1aSopenharmony_ci s->num_passes = 9; 162cabdff1aSopenharmony_ci if (avctx->compression_level >= 8) { 163cabdff1aSopenharmony_ci s->num_branches = 4; 164cabdff1aSopenharmony_ci s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_SORT_LAST|EXTRA_BRANCHES; 165cabdff1aSopenharmony_ci } else if (avctx->compression_level >= 7) { 166cabdff1aSopenharmony_ci s->num_branches = 3; 167cabdff1aSopenharmony_ci s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES; 168cabdff1aSopenharmony_ci } else if (avctx->compression_level >= 6) { 169cabdff1aSopenharmony_ci s->num_branches = 2; 170cabdff1aSopenharmony_ci s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES; 171cabdff1aSopenharmony_ci } else if (avctx->compression_level >= 5) { 172cabdff1aSopenharmony_ci s->num_branches = 1; 173cabdff1aSopenharmony_ci s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES; 174cabdff1aSopenharmony_ci } else if (avctx->compression_level >= 4) { 175cabdff1aSopenharmony_ci s->num_branches = 1; 176cabdff1aSopenharmony_ci s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_BRANCHES; 177cabdff1aSopenharmony_ci } 178cabdff1aSopenharmony_ci } else if (avctx->compression_level == 2) { 179cabdff1aSopenharmony_ci s->decorr_filter = 2; 180cabdff1aSopenharmony_ci s->num_passes = 4; 181cabdff1aSopenharmony_ci } else if (avctx->compression_level == 1) { 182cabdff1aSopenharmony_ci s->decorr_filter = 1; 183cabdff1aSopenharmony_ci s->num_passes = 2; 184cabdff1aSopenharmony_ci } else if (avctx->compression_level < 1) { 185cabdff1aSopenharmony_ci s->decorr_filter = 0; 186cabdff1aSopenharmony_ci s->num_passes = 0; 187cabdff1aSopenharmony_ci } 188cabdff1aSopenharmony_ci } 189cabdff1aSopenharmony_ci 190cabdff1aSopenharmony_ci s->num_decorrs = decorr_filter_sizes[s->decorr_filter]; 191cabdff1aSopenharmony_ci s->decorr_specs = decorr_filters[s->decorr_filter]; 192cabdff1aSopenharmony_ci 193cabdff1aSopenharmony_ci s->delta_decay = 2.0; 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci return 0; 196cabdff1aSopenharmony_ci} 197cabdff1aSopenharmony_ci 198cabdff1aSopenharmony_cistatic void shift_mono(int32_t *samples, int nb_samples, int shift) 199cabdff1aSopenharmony_ci{ 200cabdff1aSopenharmony_ci int i; 201cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) 202cabdff1aSopenharmony_ci samples[i] >>= shift; 203cabdff1aSopenharmony_ci} 204cabdff1aSopenharmony_ci 205cabdff1aSopenharmony_cistatic void shift_stereo(int32_t *left, int32_t *right, 206cabdff1aSopenharmony_ci int nb_samples, int shift) 207cabdff1aSopenharmony_ci{ 208cabdff1aSopenharmony_ci int i; 209cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 210cabdff1aSopenharmony_ci left [i] >>= shift; 211cabdff1aSopenharmony_ci right[i] >>= shift; 212cabdff1aSopenharmony_ci } 213cabdff1aSopenharmony_ci} 214cabdff1aSopenharmony_ci 215cabdff1aSopenharmony_ci#define FLOAT_SHIFT_ONES 1 216cabdff1aSopenharmony_ci#define FLOAT_SHIFT_SAME 2 217cabdff1aSopenharmony_ci#define FLOAT_SHIFT_SENT 4 218cabdff1aSopenharmony_ci#define FLOAT_ZEROS_SENT 8 219cabdff1aSopenharmony_ci#define FLOAT_NEG_ZEROS 0x10 220cabdff1aSopenharmony_ci#define FLOAT_EXCEPTIONS 0x20 221cabdff1aSopenharmony_ci 222cabdff1aSopenharmony_ci#define get_mantissa(f) ((f) & 0x7fffff) 223cabdff1aSopenharmony_ci#define get_exponent(f) (((f) >> 23) & 0xff) 224cabdff1aSopenharmony_ci#define get_sign(f) (((f) >> 31) & 0x1) 225cabdff1aSopenharmony_ci 226cabdff1aSopenharmony_cistatic void process_float(WavPackEncodeContext *s, int32_t *sample) 227cabdff1aSopenharmony_ci{ 228cabdff1aSopenharmony_ci int32_t shift_count, value, f = *sample; 229cabdff1aSopenharmony_ci 230cabdff1aSopenharmony_ci if (get_exponent(f) == 255) { 231cabdff1aSopenharmony_ci s->float_flags |= FLOAT_EXCEPTIONS; 232cabdff1aSopenharmony_ci value = 0x1000000; 233cabdff1aSopenharmony_ci shift_count = 0; 234cabdff1aSopenharmony_ci } else if (get_exponent(f)) { 235cabdff1aSopenharmony_ci shift_count = s->max_exp - get_exponent(f); 236cabdff1aSopenharmony_ci value = 0x800000 + get_mantissa(f); 237cabdff1aSopenharmony_ci } else { 238cabdff1aSopenharmony_ci shift_count = s->max_exp ? s->max_exp - 1 : 0; 239cabdff1aSopenharmony_ci value = get_mantissa(f); 240cabdff1aSopenharmony_ci } 241cabdff1aSopenharmony_ci 242cabdff1aSopenharmony_ci if (shift_count < 25) 243cabdff1aSopenharmony_ci value >>= shift_count; 244cabdff1aSopenharmony_ci else 245cabdff1aSopenharmony_ci value = 0; 246cabdff1aSopenharmony_ci 247cabdff1aSopenharmony_ci if (!value) { 248cabdff1aSopenharmony_ci if (get_exponent(f) || get_mantissa(f)) 249cabdff1aSopenharmony_ci s->false_zeros++; 250cabdff1aSopenharmony_ci else if (get_sign(f)) 251cabdff1aSopenharmony_ci s->neg_zeros++; 252cabdff1aSopenharmony_ci } else if (shift_count) { 253cabdff1aSopenharmony_ci int32_t mask = (1 << shift_count) - 1; 254cabdff1aSopenharmony_ci 255cabdff1aSopenharmony_ci if (!(get_mantissa(f) & mask)) 256cabdff1aSopenharmony_ci s->shifted_zeros++; 257cabdff1aSopenharmony_ci else if ((get_mantissa(f) & mask) == mask) 258cabdff1aSopenharmony_ci s->shifted_ones++; 259cabdff1aSopenharmony_ci else 260cabdff1aSopenharmony_ci s->shifted_both++; 261cabdff1aSopenharmony_ci } 262cabdff1aSopenharmony_ci 263cabdff1aSopenharmony_ci s->ordata |= value; 264cabdff1aSopenharmony_ci *sample = get_sign(f) ? -value : value; 265cabdff1aSopenharmony_ci} 266cabdff1aSopenharmony_ci 267cabdff1aSopenharmony_cistatic int scan_float(WavPackEncodeContext *s, 268cabdff1aSopenharmony_ci int32_t *samples_l, int32_t *samples_r, 269cabdff1aSopenharmony_ci int nb_samples) 270cabdff1aSopenharmony_ci{ 271cabdff1aSopenharmony_ci uint32_t crc = 0xffffffffu; 272cabdff1aSopenharmony_ci int i; 273cabdff1aSopenharmony_ci 274cabdff1aSopenharmony_ci s->shifted_ones = s->shifted_zeros = s->shifted_both = s->ordata = 0; 275cabdff1aSopenharmony_ci s->float_shift = s->float_flags = 0; 276cabdff1aSopenharmony_ci s->false_zeros = s->neg_zeros = 0; 277cabdff1aSopenharmony_ci s->max_exp = 0; 278cabdff1aSopenharmony_ci 279cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) { 280cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 281cabdff1aSopenharmony_ci int32_t f = samples_l[i]; 282cabdff1aSopenharmony_ci crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f); 283cabdff1aSopenharmony_ci 284cabdff1aSopenharmony_ci if (get_exponent(f) > s->max_exp && get_exponent(f) < 255) 285cabdff1aSopenharmony_ci s->max_exp = get_exponent(f); 286cabdff1aSopenharmony_ci } 287cabdff1aSopenharmony_ci } else { 288cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 289cabdff1aSopenharmony_ci int32_t f; 290cabdff1aSopenharmony_ci 291cabdff1aSopenharmony_ci f = samples_l[i]; 292cabdff1aSopenharmony_ci crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f); 293cabdff1aSopenharmony_ci if (get_exponent(f) > s->max_exp && get_exponent(f) < 255) 294cabdff1aSopenharmony_ci s->max_exp = get_exponent(f); 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_ci f = samples_r[i]; 297cabdff1aSopenharmony_ci crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f); 298cabdff1aSopenharmony_ci 299cabdff1aSopenharmony_ci if (get_exponent(f) > s->max_exp && get_exponent(f) < 255) 300cabdff1aSopenharmony_ci s->max_exp = get_exponent(f); 301cabdff1aSopenharmony_ci } 302cabdff1aSopenharmony_ci } 303cabdff1aSopenharmony_ci 304cabdff1aSopenharmony_ci s->crc_x = crc; 305cabdff1aSopenharmony_ci 306cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) { 307cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) 308cabdff1aSopenharmony_ci process_float(s, &samples_l[i]); 309cabdff1aSopenharmony_ci } else { 310cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 311cabdff1aSopenharmony_ci process_float(s, &samples_l[i]); 312cabdff1aSopenharmony_ci process_float(s, &samples_r[i]); 313cabdff1aSopenharmony_ci } 314cabdff1aSopenharmony_ci } 315cabdff1aSopenharmony_ci 316cabdff1aSopenharmony_ci s->float_max_exp = s->max_exp; 317cabdff1aSopenharmony_ci 318cabdff1aSopenharmony_ci if (s->shifted_both) 319cabdff1aSopenharmony_ci s->float_flags |= FLOAT_SHIFT_SENT; 320cabdff1aSopenharmony_ci else if (s->shifted_ones && !s->shifted_zeros) 321cabdff1aSopenharmony_ci s->float_flags |= FLOAT_SHIFT_ONES; 322cabdff1aSopenharmony_ci else if (s->shifted_ones && s->shifted_zeros) 323cabdff1aSopenharmony_ci s->float_flags |= FLOAT_SHIFT_SAME; 324cabdff1aSopenharmony_ci else if (s->ordata && !(s->ordata & 1)) { 325cabdff1aSopenharmony_ci do { 326cabdff1aSopenharmony_ci s->float_shift++; 327cabdff1aSopenharmony_ci s->ordata >>= 1; 328cabdff1aSopenharmony_ci } while (!(s->ordata & 1)); 329cabdff1aSopenharmony_ci 330cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) 331cabdff1aSopenharmony_ci shift_mono(samples_l, nb_samples, s->float_shift); 332cabdff1aSopenharmony_ci else 333cabdff1aSopenharmony_ci shift_stereo(samples_l, samples_r, nb_samples, s->float_shift); 334cabdff1aSopenharmony_ci } 335cabdff1aSopenharmony_ci 336cabdff1aSopenharmony_ci s->flags &= ~MAG_MASK; 337cabdff1aSopenharmony_ci 338cabdff1aSopenharmony_ci while (s->ordata) { 339cabdff1aSopenharmony_ci s->flags += 1 << MAG_LSB; 340cabdff1aSopenharmony_ci s->ordata >>= 1; 341cabdff1aSopenharmony_ci } 342cabdff1aSopenharmony_ci 343cabdff1aSopenharmony_ci if (s->false_zeros || s->neg_zeros) 344cabdff1aSopenharmony_ci s->float_flags |= FLOAT_ZEROS_SENT; 345cabdff1aSopenharmony_ci 346cabdff1aSopenharmony_ci if (s->neg_zeros) 347cabdff1aSopenharmony_ci s->float_flags |= FLOAT_NEG_ZEROS; 348cabdff1aSopenharmony_ci 349cabdff1aSopenharmony_ci return s->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT | 350cabdff1aSopenharmony_ci FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME); 351cabdff1aSopenharmony_ci} 352cabdff1aSopenharmony_ci 353cabdff1aSopenharmony_cistatic void scan_int23(WavPackEncodeContext *s, 354cabdff1aSopenharmony_ci int32_t *samples_l, int32_t *samples_r, 355cabdff1aSopenharmony_ci int nb_samples) 356cabdff1aSopenharmony_ci{ 357cabdff1aSopenharmony_ci uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0; 358cabdff1aSopenharmony_ci int i, total_shift = 0; 359cabdff1aSopenharmony_ci 360cabdff1aSopenharmony_ci s->int32_sent_bits = s->int32_zeros = s->int32_ones = s->int32_dups = 0; 361cabdff1aSopenharmony_ci 362cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) { 363cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 364cabdff1aSopenharmony_ci int32_t M = samples_l[i]; 365cabdff1aSopenharmony_ci 366cabdff1aSopenharmony_ci magdata |= (M < 0) ? ~M : M; 367cabdff1aSopenharmony_ci xordata |= M ^ -(M & 1); 368cabdff1aSopenharmony_ci anddata &= M; 369cabdff1aSopenharmony_ci ordata |= M; 370cabdff1aSopenharmony_ci 371cabdff1aSopenharmony_ci if ((ordata & 1) && !(anddata & 1) && (xordata & 2)) 372cabdff1aSopenharmony_ci return; 373cabdff1aSopenharmony_ci } 374cabdff1aSopenharmony_ci } else { 375cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 376cabdff1aSopenharmony_ci int32_t L = samples_l[i]; 377cabdff1aSopenharmony_ci int32_t R = samples_r[i]; 378cabdff1aSopenharmony_ci 379cabdff1aSopenharmony_ci magdata |= (L < 0) ? ~L : L; 380cabdff1aSopenharmony_ci magdata |= (R < 0) ? ~R : R; 381cabdff1aSopenharmony_ci xordata |= L ^ -(L & 1); 382cabdff1aSopenharmony_ci xordata |= R ^ -(R & 1); 383cabdff1aSopenharmony_ci anddata &= L & R; 384cabdff1aSopenharmony_ci ordata |= L | R; 385cabdff1aSopenharmony_ci 386cabdff1aSopenharmony_ci if ((ordata & 1) && !(anddata & 1) && (xordata & 2)) 387cabdff1aSopenharmony_ci return; 388cabdff1aSopenharmony_ci } 389cabdff1aSopenharmony_ci } 390cabdff1aSopenharmony_ci 391cabdff1aSopenharmony_ci s->flags &= ~MAG_MASK; 392cabdff1aSopenharmony_ci 393cabdff1aSopenharmony_ci while (magdata) { 394cabdff1aSopenharmony_ci s->flags += 1 << MAG_LSB; 395cabdff1aSopenharmony_ci magdata >>= 1; 396cabdff1aSopenharmony_ci } 397cabdff1aSopenharmony_ci 398cabdff1aSopenharmony_ci if (!(s->flags & MAG_MASK)) 399cabdff1aSopenharmony_ci return; 400cabdff1aSopenharmony_ci 401cabdff1aSopenharmony_ci if (!(ordata & 1)) { 402cabdff1aSopenharmony_ci do { 403cabdff1aSopenharmony_ci s->flags -= 1 << MAG_LSB; 404cabdff1aSopenharmony_ci s->int32_zeros++; 405cabdff1aSopenharmony_ci total_shift++; 406cabdff1aSopenharmony_ci ordata >>= 1; 407cabdff1aSopenharmony_ci } while (!(ordata & 1)); 408cabdff1aSopenharmony_ci } else if (anddata & 1) { 409cabdff1aSopenharmony_ci do { 410cabdff1aSopenharmony_ci s->flags -= 1 << MAG_LSB; 411cabdff1aSopenharmony_ci s->int32_ones++; 412cabdff1aSopenharmony_ci total_shift++; 413cabdff1aSopenharmony_ci anddata >>= 1; 414cabdff1aSopenharmony_ci } while (anddata & 1); 415cabdff1aSopenharmony_ci } else if (!(xordata & 2)) { 416cabdff1aSopenharmony_ci do { 417cabdff1aSopenharmony_ci s->flags -= 1 << MAG_LSB; 418cabdff1aSopenharmony_ci s->int32_dups++; 419cabdff1aSopenharmony_ci total_shift++; 420cabdff1aSopenharmony_ci xordata >>= 1; 421cabdff1aSopenharmony_ci } while (!(xordata & 2)); 422cabdff1aSopenharmony_ci } 423cabdff1aSopenharmony_ci 424cabdff1aSopenharmony_ci if (total_shift) { 425cabdff1aSopenharmony_ci s->flags |= WV_INT32_DATA; 426cabdff1aSopenharmony_ci 427cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) 428cabdff1aSopenharmony_ci shift_mono(samples_l, nb_samples, total_shift); 429cabdff1aSopenharmony_ci else 430cabdff1aSopenharmony_ci shift_stereo(samples_l, samples_r, nb_samples, total_shift); 431cabdff1aSopenharmony_ci } 432cabdff1aSopenharmony_ci} 433cabdff1aSopenharmony_ci 434cabdff1aSopenharmony_cistatic int scan_int32(WavPackEncodeContext *s, 435cabdff1aSopenharmony_ci int32_t *samples_l, int32_t *samples_r, 436cabdff1aSopenharmony_ci int nb_samples) 437cabdff1aSopenharmony_ci{ 438cabdff1aSopenharmony_ci uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0; 439cabdff1aSopenharmony_ci uint32_t crc = 0xffffffffu; 440cabdff1aSopenharmony_ci int i, total_shift = 0; 441cabdff1aSopenharmony_ci 442cabdff1aSopenharmony_ci s->int32_sent_bits = s->int32_zeros = s->int32_ones = s->int32_dups = 0; 443cabdff1aSopenharmony_ci 444cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) { 445cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 446cabdff1aSopenharmony_ci int32_t M = samples_l[i]; 447cabdff1aSopenharmony_ci 448cabdff1aSopenharmony_ci crc = crc * 9 + (M & 0xffff) * 3 + ((M >> 16) & 0xffff); 449cabdff1aSopenharmony_ci magdata |= (M < 0) ? ~M : M; 450cabdff1aSopenharmony_ci xordata |= M ^ -(M & 1); 451cabdff1aSopenharmony_ci anddata &= M; 452cabdff1aSopenharmony_ci ordata |= M; 453cabdff1aSopenharmony_ci } 454cabdff1aSopenharmony_ci } else { 455cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 456cabdff1aSopenharmony_ci int32_t L = samples_l[i]; 457cabdff1aSopenharmony_ci int32_t R = samples_r[i]; 458cabdff1aSopenharmony_ci 459cabdff1aSopenharmony_ci crc = crc * 9 + (L & 0xffff) * 3 + ((L >> 16) & 0xffff); 460cabdff1aSopenharmony_ci crc = crc * 9 + (R & 0xffff) * 3 + ((R >> 16) & 0xffff); 461cabdff1aSopenharmony_ci magdata |= (L < 0) ? ~L : L; 462cabdff1aSopenharmony_ci magdata |= (R < 0) ? ~R : R; 463cabdff1aSopenharmony_ci xordata |= L ^ -(L & 1); 464cabdff1aSopenharmony_ci xordata |= R ^ -(R & 1); 465cabdff1aSopenharmony_ci anddata &= L & R; 466cabdff1aSopenharmony_ci ordata |= L | R; 467cabdff1aSopenharmony_ci } 468cabdff1aSopenharmony_ci } 469cabdff1aSopenharmony_ci 470cabdff1aSopenharmony_ci s->crc_x = crc; 471cabdff1aSopenharmony_ci s->flags &= ~MAG_MASK; 472cabdff1aSopenharmony_ci 473cabdff1aSopenharmony_ci while (magdata) { 474cabdff1aSopenharmony_ci s->flags += 1 << MAG_LSB; 475cabdff1aSopenharmony_ci magdata >>= 1; 476cabdff1aSopenharmony_ci } 477cabdff1aSopenharmony_ci 478cabdff1aSopenharmony_ci if (!((s->flags & MAG_MASK) >> MAG_LSB)) { 479cabdff1aSopenharmony_ci s->flags &= ~WV_INT32_DATA; 480cabdff1aSopenharmony_ci return 0; 481cabdff1aSopenharmony_ci } 482cabdff1aSopenharmony_ci 483cabdff1aSopenharmony_ci if (!(ordata & 1)) 484cabdff1aSopenharmony_ci do { 485cabdff1aSopenharmony_ci s->flags -= 1 << MAG_LSB; 486cabdff1aSopenharmony_ci s->int32_zeros++; 487cabdff1aSopenharmony_ci total_shift++; 488cabdff1aSopenharmony_ci ordata >>= 1; 489cabdff1aSopenharmony_ci } while (!(ordata & 1)); 490cabdff1aSopenharmony_ci else if (anddata & 1) 491cabdff1aSopenharmony_ci do { 492cabdff1aSopenharmony_ci s->flags -= 1 << MAG_LSB; 493cabdff1aSopenharmony_ci s->int32_ones++; 494cabdff1aSopenharmony_ci total_shift++; 495cabdff1aSopenharmony_ci anddata >>= 1; 496cabdff1aSopenharmony_ci } while (anddata & 1); 497cabdff1aSopenharmony_ci else if (!(xordata & 2)) 498cabdff1aSopenharmony_ci do { 499cabdff1aSopenharmony_ci s->flags -= 1 << MAG_LSB; 500cabdff1aSopenharmony_ci s->int32_dups++; 501cabdff1aSopenharmony_ci total_shift++; 502cabdff1aSopenharmony_ci xordata >>= 1; 503cabdff1aSopenharmony_ci } while (!(xordata & 2)); 504cabdff1aSopenharmony_ci 505cabdff1aSopenharmony_ci if (((s->flags & MAG_MASK) >> MAG_LSB) > 23) { 506cabdff1aSopenharmony_ci s->int32_sent_bits = (uint8_t)(((s->flags & MAG_MASK) >> MAG_LSB) - 23); 507cabdff1aSopenharmony_ci total_shift += s->int32_sent_bits; 508cabdff1aSopenharmony_ci s->flags &= ~MAG_MASK; 509cabdff1aSopenharmony_ci s->flags += 23 << MAG_LSB; 510cabdff1aSopenharmony_ci } 511cabdff1aSopenharmony_ci 512cabdff1aSopenharmony_ci if (total_shift) { 513cabdff1aSopenharmony_ci s->flags |= WV_INT32_DATA; 514cabdff1aSopenharmony_ci 515cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) 516cabdff1aSopenharmony_ci shift_mono(samples_l, nb_samples, total_shift); 517cabdff1aSopenharmony_ci else 518cabdff1aSopenharmony_ci shift_stereo(samples_l, samples_r, nb_samples, total_shift); 519cabdff1aSopenharmony_ci } 520cabdff1aSopenharmony_ci 521cabdff1aSopenharmony_ci return s->int32_sent_bits; 522cabdff1aSopenharmony_ci} 523cabdff1aSopenharmony_ci 524cabdff1aSopenharmony_cistatic int8_t store_weight(int weight) 525cabdff1aSopenharmony_ci{ 526cabdff1aSopenharmony_ci weight = av_clip(weight, -1024, 1024); 527cabdff1aSopenharmony_ci if (weight > 0) 528cabdff1aSopenharmony_ci weight -= (weight + 64) >> 7; 529cabdff1aSopenharmony_ci 530cabdff1aSopenharmony_ci return (weight + 4) >> 3; 531cabdff1aSopenharmony_ci} 532cabdff1aSopenharmony_ci 533cabdff1aSopenharmony_cistatic int restore_weight(int8_t weight) 534cabdff1aSopenharmony_ci{ 535cabdff1aSopenharmony_ci int result = 8 * weight; 536cabdff1aSopenharmony_ci 537cabdff1aSopenharmony_ci if (result > 0) 538cabdff1aSopenharmony_ci result += (result + 64) >> 7; 539cabdff1aSopenharmony_ci 540cabdff1aSopenharmony_ci return result; 541cabdff1aSopenharmony_ci} 542cabdff1aSopenharmony_ci 543cabdff1aSopenharmony_cistatic int log2s(int32_t value) 544cabdff1aSopenharmony_ci{ 545cabdff1aSopenharmony_ci return (value < 0) ? -wp_log2(-value) : wp_log2(value); 546cabdff1aSopenharmony_ci} 547cabdff1aSopenharmony_ci 548cabdff1aSopenharmony_cistatic void decorr_mono(int32_t *in_samples, int32_t *out_samples, 549cabdff1aSopenharmony_ci int nb_samples, struct Decorr *dpp, int dir) 550cabdff1aSopenharmony_ci{ 551cabdff1aSopenharmony_ci int m = 0, i; 552cabdff1aSopenharmony_ci 553cabdff1aSopenharmony_ci dpp->sumA = 0; 554cabdff1aSopenharmony_ci 555cabdff1aSopenharmony_ci if (dir < 0) { 556cabdff1aSopenharmony_ci out_samples += (nb_samples - 1); 557cabdff1aSopenharmony_ci in_samples += (nb_samples - 1); 558cabdff1aSopenharmony_ci } 559cabdff1aSopenharmony_ci 560cabdff1aSopenharmony_ci dpp->weightA = restore_weight(store_weight(dpp->weightA)); 561cabdff1aSopenharmony_ci 562cabdff1aSopenharmony_ci for (i = 0; i < MAX_TERM; i++) 563cabdff1aSopenharmony_ci dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i])); 564cabdff1aSopenharmony_ci 565cabdff1aSopenharmony_ci if (dpp->value > MAX_TERM) { 566cabdff1aSopenharmony_ci while (nb_samples--) { 567cabdff1aSopenharmony_ci int32_t left, sam_A; 568cabdff1aSopenharmony_ci 569cabdff1aSopenharmony_ci sam_A = ((3 - (dpp->value & 1)) * dpp->samplesA[0] - dpp->samplesA[1]) >> !(dpp->value & 1); 570cabdff1aSopenharmony_ci 571cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 572cabdff1aSopenharmony_ci dpp->samplesA[0] = left = in_samples[0]; 573cabdff1aSopenharmony_ci 574cabdff1aSopenharmony_ci left -= APPLY_WEIGHT(dpp->weightA, sam_A); 575cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam_A, left); 576cabdff1aSopenharmony_ci dpp->sumA += dpp->weightA; 577cabdff1aSopenharmony_ci out_samples[0] = left; 578cabdff1aSopenharmony_ci in_samples += dir; 579cabdff1aSopenharmony_ci out_samples += dir; 580cabdff1aSopenharmony_ci } 581cabdff1aSopenharmony_ci } else if (dpp->value > 0) { 582cabdff1aSopenharmony_ci while (nb_samples--) { 583cabdff1aSopenharmony_ci int k = (m + dpp->value) & (MAX_TERM - 1); 584cabdff1aSopenharmony_ci int32_t left, sam_A; 585cabdff1aSopenharmony_ci 586cabdff1aSopenharmony_ci sam_A = dpp->samplesA[m]; 587cabdff1aSopenharmony_ci dpp->samplesA[k] = left = in_samples[0]; 588cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 589cabdff1aSopenharmony_ci 590cabdff1aSopenharmony_ci left -= APPLY_WEIGHT(dpp->weightA, sam_A); 591cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam_A, left); 592cabdff1aSopenharmony_ci dpp->sumA += dpp->weightA; 593cabdff1aSopenharmony_ci out_samples[0] = left; 594cabdff1aSopenharmony_ci in_samples += dir; 595cabdff1aSopenharmony_ci out_samples += dir; 596cabdff1aSopenharmony_ci } 597cabdff1aSopenharmony_ci } 598cabdff1aSopenharmony_ci 599cabdff1aSopenharmony_ci if (m && dpp->value > 0 && dpp->value <= MAX_TERM) { 600cabdff1aSopenharmony_ci int32_t temp_A[MAX_TERM]; 601cabdff1aSopenharmony_ci 602cabdff1aSopenharmony_ci memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA)); 603cabdff1aSopenharmony_ci 604cabdff1aSopenharmony_ci for (i = 0; i < MAX_TERM; i++) { 605cabdff1aSopenharmony_ci dpp->samplesA[i] = temp_A[m]; 606cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 607cabdff1aSopenharmony_ci } 608cabdff1aSopenharmony_ci } 609cabdff1aSopenharmony_ci} 610cabdff1aSopenharmony_ci 611cabdff1aSopenharmony_cistatic void reverse_mono_decorr(struct Decorr *dpp) 612cabdff1aSopenharmony_ci{ 613cabdff1aSopenharmony_ci if (dpp->value > MAX_TERM) { 614cabdff1aSopenharmony_ci int32_t sam_A; 615cabdff1aSopenharmony_ci 616cabdff1aSopenharmony_ci if (dpp->value & 1) 617cabdff1aSopenharmony_ci sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1]; 618cabdff1aSopenharmony_ci else 619cabdff1aSopenharmony_ci sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1; 620cabdff1aSopenharmony_ci 621cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 622cabdff1aSopenharmony_ci dpp->samplesA[0] = sam_A; 623cabdff1aSopenharmony_ci 624cabdff1aSopenharmony_ci if (dpp->value & 1) 625cabdff1aSopenharmony_ci sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1]; 626cabdff1aSopenharmony_ci else 627cabdff1aSopenharmony_ci sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1; 628cabdff1aSopenharmony_ci 629cabdff1aSopenharmony_ci dpp->samplesA[1] = sam_A; 630cabdff1aSopenharmony_ci } else if (dpp->value > 1) { 631cabdff1aSopenharmony_ci int i, j, k; 632cabdff1aSopenharmony_ci 633cabdff1aSopenharmony_ci for (i = 0, j = dpp->value - 1, k = 0; k < dpp->value / 2; i++, j--, k++) { 634cabdff1aSopenharmony_ci i &= (MAX_TERM - 1); 635cabdff1aSopenharmony_ci j &= (MAX_TERM - 1); 636cabdff1aSopenharmony_ci dpp->samplesA[i] ^= dpp->samplesA[j]; 637cabdff1aSopenharmony_ci dpp->samplesA[j] ^= dpp->samplesA[i]; 638cabdff1aSopenharmony_ci dpp->samplesA[i] ^= dpp->samplesA[j]; 639cabdff1aSopenharmony_ci } 640cabdff1aSopenharmony_ci } 641cabdff1aSopenharmony_ci} 642cabdff1aSopenharmony_ci 643cabdff1aSopenharmony_ci#define count_bits(av) ((av) ? 32 - ff_clz(av) : 0) 644cabdff1aSopenharmony_ci 645cabdff1aSopenharmony_cistatic uint32_t log2sample(uint32_t v, int limit, uint32_t *result) 646cabdff1aSopenharmony_ci{ 647cabdff1aSopenharmony_ci uint32_t dbits = count_bits(v); 648cabdff1aSopenharmony_ci 649cabdff1aSopenharmony_ci if ((v += v >> 9) < (1 << 8)) { 650cabdff1aSopenharmony_ci *result += (dbits << 8) + ff_wp_log2_table[(v << (9 - dbits)) & 0xff]; 651cabdff1aSopenharmony_ci } else { 652cabdff1aSopenharmony_ci *result += dbits = (dbits << 8) + ff_wp_log2_table[(v >> (dbits - 9)) & 0xff]; 653cabdff1aSopenharmony_ci 654cabdff1aSopenharmony_ci if (limit && dbits >= limit) 655cabdff1aSopenharmony_ci return 1; 656cabdff1aSopenharmony_ci } 657cabdff1aSopenharmony_ci 658cabdff1aSopenharmony_ci return 0; 659cabdff1aSopenharmony_ci} 660cabdff1aSopenharmony_ci 661cabdff1aSopenharmony_cistatic uint32_t log2mono(int32_t *samples, int nb_samples, int limit) 662cabdff1aSopenharmony_ci{ 663cabdff1aSopenharmony_ci uint32_t result = 0; 664cabdff1aSopenharmony_ci while (nb_samples--) { 665cabdff1aSopenharmony_ci if (log2sample(abs(*samples++), limit, &result)) 666cabdff1aSopenharmony_ci return UINT32_MAX; 667cabdff1aSopenharmony_ci } 668cabdff1aSopenharmony_ci return result; 669cabdff1aSopenharmony_ci} 670cabdff1aSopenharmony_ci 671cabdff1aSopenharmony_cistatic uint32_t log2stereo(int32_t *samples_l, int32_t *samples_r, 672cabdff1aSopenharmony_ci int nb_samples, int limit) 673cabdff1aSopenharmony_ci{ 674cabdff1aSopenharmony_ci uint32_t result = 0; 675cabdff1aSopenharmony_ci while (nb_samples--) { 676cabdff1aSopenharmony_ci if (log2sample(abs(*samples_l++), limit, &result) || 677cabdff1aSopenharmony_ci log2sample(abs(*samples_r++), limit, &result)) 678cabdff1aSopenharmony_ci return UINT32_MAX; 679cabdff1aSopenharmony_ci } 680cabdff1aSopenharmony_ci return result; 681cabdff1aSopenharmony_ci} 682cabdff1aSopenharmony_ci 683cabdff1aSopenharmony_cistatic void decorr_mono_buffer(int32_t *samples, int32_t *outsamples, 684cabdff1aSopenharmony_ci int nb_samples, struct Decorr *dpp, 685cabdff1aSopenharmony_ci int tindex) 686cabdff1aSopenharmony_ci{ 687cabdff1aSopenharmony_ci struct Decorr dp, *dppi = dpp + tindex; 688cabdff1aSopenharmony_ci int delta = dppi->delta, pre_delta, term = dppi->value; 689cabdff1aSopenharmony_ci 690cabdff1aSopenharmony_ci if (delta == 7) 691cabdff1aSopenharmony_ci pre_delta = 7; 692cabdff1aSopenharmony_ci else if (delta < 2) 693cabdff1aSopenharmony_ci pre_delta = 3; 694cabdff1aSopenharmony_ci else 695cabdff1aSopenharmony_ci pre_delta = delta + 1; 696cabdff1aSopenharmony_ci 697cabdff1aSopenharmony_ci CLEAR(dp); 698cabdff1aSopenharmony_ci dp.value = term; 699cabdff1aSopenharmony_ci dp.delta = pre_delta; 700cabdff1aSopenharmony_ci decorr_mono(samples, outsamples, FFMIN(2048, nb_samples), &dp, -1); 701cabdff1aSopenharmony_ci dp.delta = delta; 702cabdff1aSopenharmony_ci 703cabdff1aSopenharmony_ci if (tindex == 0) 704cabdff1aSopenharmony_ci reverse_mono_decorr(&dp); 705cabdff1aSopenharmony_ci else 706cabdff1aSopenharmony_ci CLEAR(dp.samplesA); 707cabdff1aSopenharmony_ci 708cabdff1aSopenharmony_ci memcpy(dppi->samplesA, dp.samplesA, sizeof(dp.samplesA)); 709cabdff1aSopenharmony_ci dppi->weightA = dp.weightA; 710cabdff1aSopenharmony_ci 711cabdff1aSopenharmony_ci if (delta == 0) { 712cabdff1aSopenharmony_ci dp.delta = 1; 713cabdff1aSopenharmony_ci decorr_mono(samples, outsamples, nb_samples, &dp, 1); 714cabdff1aSopenharmony_ci dp.delta = 0; 715cabdff1aSopenharmony_ci memcpy(dp.samplesA, dppi->samplesA, sizeof(dp.samplesA)); 716cabdff1aSopenharmony_ci dppi->weightA = dp.weightA = dp.sumA / nb_samples; 717cabdff1aSopenharmony_ci } 718cabdff1aSopenharmony_ci 719cabdff1aSopenharmony_ci decorr_mono(samples, outsamples, nb_samples, &dp, 1); 720cabdff1aSopenharmony_ci} 721cabdff1aSopenharmony_ci 722cabdff1aSopenharmony_cistatic void recurse_mono(WavPackEncodeContext *s, WavPackExtraInfo *info, 723cabdff1aSopenharmony_ci int depth, int delta, uint32_t input_bits) 724cabdff1aSopenharmony_ci{ 725cabdff1aSopenharmony_ci int term, branches = s->num_branches - depth; 726cabdff1aSopenharmony_ci int32_t *samples, *outsamples; 727cabdff1aSopenharmony_ci uint32_t term_bits[22], bits; 728cabdff1aSopenharmony_ci 729cabdff1aSopenharmony_ci if (branches < 1 || depth + 1 == info->nterms) 730cabdff1aSopenharmony_ci branches = 1; 731cabdff1aSopenharmony_ci 732cabdff1aSopenharmony_ci CLEAR(term_bits); 733cabdff1aSopenharmony_ci samples = s->sampleptrs[depth][0]; 734cabdff1aSopenharmony_ci outsamples = s->sampleptrs[depth + 1][0]; 735cabdff1aSopenharmony_ci 736cabdff1aSopenharmony_ci for (term = 1; term <= 18; term++) { 737cabdff1aSopenharmony_ci if (term == 17 && branches == 1 && depth + 1 < info->nterms) 738cabdff1aSopenharmony_ci continue; 739cabdff1aSopenharmony_ci 740cabdff1aSopenharmony_ci if (term > 8 && term < 17) 741cabdff1aSopenharmony_ci continue; 742cabdff1aSopenharmony_ci 743cabdff1aSopenharmony_ci if (!s->extra_flags && (term > 4 && term < 17)) 744cabdff1aSopenharmony_ci continue; 745cabdff1aSopenharmony_ci 746cabdff1aSopenharmony_ci info->dps[depth].value = term; 747cabdff1aSopenharmony_ci info->dps[depth].delta = delta; 748cabdff1aSopenharmony_ci decorr_mono_buffer(samples, outsamples, s->block_samples, info->dps, depth); 749cabdff1aSopenharmony_ci bits = log2mono(outsamples, s->block_samples, info->log_limit); 750cabdff1aSopenharmony_ci 751cabdff1aSopenharmony_ci if (bits < info->best_bits) { 752cabdff1aSopenharmony_ci info->best_bits = bits; 753cabdff1aSopenharmony_ci CLEAR(s->decorr_passes); 754cabdff1aSopenharmony_ci memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * (depth + 1)); 755cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][0], 756cabdff1aSopenharmony_ci s->sampleptrs[depth + 1][0], s->block_samples * 4); 757cabdff1aSopenharmony_ci } 758cabdff1aSopenharmony_ci 759cabdff1aSopenharmony_ci term_bits[term + 3] = bits; 760cabdff1aSopenharmony_ci } 761cabdff1aSopenharmony_ci 762cabdff1aSopenharmony_ci while (depth + 1 < info->nterms && branches--) { 763cabdff1aSopenharmony_ci uint32_t local_best_bits = input_bits; 764cabdff1aSopenharmony_ci int best_term = 0, i; 765cabdff1aSopenharmony_ci 766cabdff1aSopenharmony_ci for (i = 0; i < 22; i++) 767cabdff1aSopenharmony_ci if (term_bits[i] && term_bits[i] < local_best_bits) { 768cabdff1aSopenharmony_ci local_best_bits = term_bits[i]; 769cabdff1aSopenharmony_ci best_term = i - 3; 770cabdff1aSopenharmony_ci } 771cabdff1aSopenharmony_ci 772cabdff1aSopenharmony_ci if (!best_term) 773cabdff1aSopenharmony_ci break; 774cabdff1aSopenharmony_ci 775cabdff1aSopenharmony_ci term_bits[best_term + 3] = 0; 776cabdff1aSopenharmony_ci 777cabdff1aSopenharmony_ci info->dps[depth].value = best_term; 778cabdff1aSopenharmony_ci info->dps[depth].delta = delta; 779cabdff1aSopenharmony_ci decorr_mono_buffer(samples, outsamples, s->block_samples, info->dps, depth); 780cabdff1aSopenharmony_ci 781cabdff1aSopenharmony_ci recurse_mono(s, info, depth + 1, delta, local_best_bits); 782cabdff1aSopenharmony_ci } 783cabdff1aSopenharmony_ci} 784cabdff1aSopenharmony_ci 785cabdff1aSopenharmony_cistatic void sort_mono(WavPackEncodeContext *s, WavPackExtraInfo *info) 786cabdff1aSopenharmony_ci{ 787cabdff1aSopenharmony_ci int reversed = 1; 788cabdff1aSopenharmony_ci uint32_t bits; 789cabdff1aSopenharmony_ci 790cabdff1aSopenharmony_ci while (reversed) { 791cabdff1aSopenharmony_ci int ri, i; 792cabdff1aSopenharmony_ci 793cabdff1aSopenharmony_ci memcpy(info->dps, s->decorr_passes, sizeof(s->decorr_passes)); 794cabdff1aSopenharmony_ci reversed = 0; 795cabdff1aSopenharmony_ci 796cabdff1aSopenharmony_ci for (ri = 0; ri < info->nterms && s->decorr_passes[ri].value; ri++) { 797cabdff1aSopenharmony_ci 798cabdff1aSopenharmony_ci if (ri + 1 >= info->nterms || !s->decorr_passes[ri+1].value) 799cabdff1aSopenharmony_ci break; 800cabdff1aSopenharmony_ci 801cabdff1aSopenharmony_ci if (s->decorr_passes[ri].value == s->decorr_passes[ri+1].value) { 802cabdff1aSopenharmony_ci decorr_mono_buffer(s->sampleptrs[ri][0], s->sampleptrs[ri+1][0], 803cabdff1aSopenharmony_ci s->block_samples, info->dps, ri); 804cabdff1aSopenharmony_ci continue; 805cabdff1aSopenharmony_ci } 806cabdff1aSopenharmony_ci 807cabdff1aSopenharmony_ci info->dps[ri ] = s->decorr_passes[ri+1]; 808cabdff1aSopenharmony_ci info->dps[ri+1] = s->decorr_passes[ri ]; 809cabdff1aSopenharmony_ci 810cabdff1aSopenharmony_ci for (i = ri; i < info->nterms && s->decorr_passes[i].value; i++) 811cabdff1aSopenharmony_ci decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0], 812cabdff1aSopenharmony_ci s->block_samples, info->dps, i); 813cabdff1aSopenharmony_ci 814cabdff1aSopenharmony_ci bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit); 815cabdff1aSopenharmony_ci if (bits < info->best_bits) { 816cabdff1aSopenharmony_ci reversed = 1; 817cabdff1aSopenharmony_ci info->best_bits = bits; 818cabdff1aSopenharmony_ci CLEAR(s->decorr_passes); 819cabdff1aSopenharmony_ci memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i); 820cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0], 821cabdff1aSopenharmony_ci s->block_samples * 4); 822cabdff1aSopenharmony_ci } else { 823cabdff1aSopenharmony_ci info->dps[ri ] = s->decorr_passes[ri]; 824cabdff1aSopenharmony_ci info->dps[ri+1] = s->decorr_passes[ri+1]; 825cabdff1aSopenharmony_ci decorr_mono_buffer(s->sampleptrs[ri][0], s->sampleptrs[ri+1][0], 826cabdff1aSopenharmony_ci s->block_samples, info->dps, ri); 827cabdff1aSopenharmony_ci } 828cabdff1aSopenharmony_ci } 829cabdff1aSopenharmony_ci } 830cabdff1aSopenharmony_ci} 831cabdff1aSopenharmony_ci 832cabdff1aSopenharmony_cistatic void delta_mono(WavPackEncodeContext *s, WavPackExtraInfo *info) 833cabdff1aSopenharmony_ci{ 834cabdff1aSopenharmony_ci int lower = 0, delta, d; 835cabdff1aSopenharmony_ci uint32_t bits; 836cabdff1aSopenharmony_ci 837cabdff1aSopenharmony_ci if (!s->decorr_passes[0].value) 838cabdff1aSopenharmony_ci return; 839cabdff1aSopenharmony_ci delta = s->decorr_passes[0].delta; 840cabdff1aSopenharmony_ci 841cabdff1aSopenharmony_ci for (d = delta - 1; d >= 0; d--) { 842cabdff1aSopenharmony_ci int i; 843cabdff1aSopenharmony_ci 844cabdff1aSopenharmony_ci for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) { 845cabdff1aSopenharmony_ci info->dps[i].value = s->decorr_passes[i].value; 846cabdff1aSopenharmony_ci info->dps[i].delta = d; 847cabdff1aSopenharmony_ci decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0], 848cabdff1aSopenharmony_ci s->block_samples, info->dps, i); 849cabdff1aSopenharmony_ci } 850cabdff1aSopenharmony_ci 851cabdff1aSopenharmony_ci bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit); 852cabdff1aSopenharmony_ci if (bits >= info->best_bits) 853cabdff1aSopenharmony_ci break; 854cabdff1aSopenharmony_ci 855cabdff1aSopenharmony_ci lower = 1; 856cabdff1aSopenharmony_ci info->best_bits = bits; 857cabdff1aSopenharmony_ci CLEAR(s->decorr_passes); 858cabdff1aSopenharmony_ci memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i); 859cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0], 860cabdff1aSopenharmony_ci s->block_samples * 4); 861cabdff1aSopenharmony_ci } 862cabdff1aSopenharmony_ci 863cabdff1aSopenharmony_ci for (d = delta + 1; !lower && d <= 7; d++) { 864cabdff1aSopenharmony_ci int i; 865cabdff1aSopenharmony_ci 866cabdff1aSopenharmony_ci for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) { 867cabdff1aSopenharmony_ci info->dps[i].value = s->decorr_passes[i].value; 868cabdff1aSopenharmony_ci info->dps[i].delta = d; 869cabdff1aSopenharmony_ci decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0], 870cabdff1aSopenharmony_ci s->block_samples, info->dps, i); 871cabdff1aSopenharmony_ci } 872cabdff1aSopenharmony_ci 873cabdff1aSopenharmony_ci bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit); 874cabdff1aSopenharmony_ci if (bits >= info->best_bits) 875cabdff1aSopenharmony_ci break; 876cabdff1aSopenharmony_ci 877cabdff1aSopenharmony_ci info->best_bits = bits; 878cabdff1aSopenharmony_ci CLEAR(s->decorr_passes); 879cabdff1aSopenharmony_ci memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i); 880cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0], 881cabdff1aSopenharmony_ci s->block_samples * 4); 882cabdff1aSopenharmony_ci } 883cabdff1aSopenharmony_ci} 884cabdff1aSopenharmony_ci 885cabdff1aSopenharmony_cistatic int allocate_buffers2(WavPackEncodeContext *s, int nterms) 886cabdff1aSopenharmony_ci{ 887cabdff1aSopenharmony_ci int i; 888cabdff1aSopenharmony_ci 889cabdff1aSopenharmony_ci for (i = 0; i < nterms + 2; i++) { 890cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->sampleptrs[i][0], &s->sampleptrs_size[i][0], 891cabdff1aSopenharmony_ci s->block_samples * 4); 892cabdff1aSopenharmony_ci if (!s->sampleptrs[i][0]) 893cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 894cabdff1aSopenharmony_ci if (!(s->flags & WV_MONO_DATA)) { 895cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->sampleptrs[i][1], &s->sampleptrs_size[i][1], 896cabdff1aSopenharmony_ci s->block_samples * 4); 897cabdff1aSopenharmony_ci if (!s->sampleptrs[i][1]) 898cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 899cabdff1aSopenharmony_ci } 900cabdff1aSopenharmony_ci } 901cabdff1aSopenharmony_ci 902cabdff1aSopenharmony_ci return 0; 903cabdff1aSopenharmony_ci} 904cabdff1aSopenharmony_ci 905cabdff1aSopenharmony_cistatic int allocate_buffers(WavPackEncodeContext *s) 906cabdff1aSopenharmony_ci{ 907cabdff1aSopenharmony_ci int i; 908cabdff1aSopenharmony_ci 909cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) { 910cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->best_buffer[0], &s->best_buffer_size[0], 911cabdff1aSopenharmony_ci s->block_samples * 4); 912cabdff1aSopenharmony_ci if (!s->best_buffer[0]) 913cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 914cabdff1aSopenharmony_ci 915cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->temp_buffer[i][0], &s->temp_buffer_size[i][0], 916cabdff1aSopenharmony_ci s->block_samples * 4); 917cabdff1aSopenharmony_ci if (!s->temp_buffer[i][0]) 918cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 919cabdff1aSopenharmony_ci if (!(s->flags & WV_MONO_DATA)) { 920cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->best_buffer[1], &s->best_buffer_size[1], 921cabdff1aSopenharmony_ci s->block_samples * 4); 922cabdff1aSopenharmony_ci if (!s->best_buffer[1]) 923cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 924cabdff1aSopenharmony_ci 925cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->temp_buffer[i][1], &s->temp_buffer_size[i][1], 926cabdff1aSopenharmony_ci s->block_samples * 4); 927cabdff1aSopenharmony_ci if (!s->temp_buffer[i][1]) 928cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 929cabdff1aSopenharmony_ci } 930cabdff1aSopenharmony_ci } 931cabdff1aSopenharmony_ci 932cabdff1aSopenharmony_ci return 0; 933cabdff1aSopenharmony_ci} 934cabdff1aSopenharmony_ci 935cabdff1aSopenharmony_cistatic void analyze_mono(WavPackEncodeContext *s, int32_t *samples, int do_samples) 936cabdff1aSopenharmony_ci{ 937cabdff1aSopenharmony_ci WavPackExtraInfo info; 938cabdff1aSopenharmony_ci int i; 939cabdff1aSopenharmony_ci 940cabdff1aSopenharmony_ci info.log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256; 941cabdff1aSopenharmony_ci info.log_limit = FFMIN(6912, info.log_limit); 942cabdff1aSopenharmony_ci 943cabdff1aSopenharmony_ci info.nterms = s->num_terms; 944cabdff1aSopenharmony_ci 945cabdff1aSopenharmony_ci if (allocate_buffers2(s, s->num_terms)) 946cabdff1aSopenharmony_ci return; 947cabdff1aSopenharmony_ci 948cabdff1aSopenharmony_ci memcpy(info.dps, s->decorr_passes, sizeof(info.dps)); 949cabdff1aSopenharmony_ci memcpy(s->sampleptrs[0][0], samples, s->block_samples * 4); 950cabdff1aSopenharmony_ci 951cabdff1aSopenharmony_ci for (i = 0; i < info.nterms && info.dps[i].value; i++) 952cabdff1aSopenharmony_ci decorr_mono(s->sampleptrs[i][0], s->sampleptrs[i + 1][0], 953cabdff1aSopenharmony_ci s->block_samples, info.dps + i, 1); 954cabdff1aSopenharmony_ci 955cabdff1aSopenharmony_ci info.best_bits = log2mono(s->sampleptrs[info.nterms][0], s->block_samples, 0) * 1; 956cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info.nterms + 1][0], s->sampleptrs[i][0], s->block_samples * 4); 957cabdff1aSopenharmony_ci 958cabdff1aSopenharmony_ci if (s->extra_flags & EXTRA_BRANCHES) 959cabdff1aSopenharmony_ci recurse_mono(s, &info, 0, (int) floor(s->delta_decay + 0.5), 960cabdff1aSopenharmony_ci log2mono(s->sampleptrs[0][0], s->block_samples, 0)); 961cabdff1aSopenharmony_ci 962cabdff1aSopenharmony_ci if (s->extra_flags & EXTRA_SORT_FIRST) 963cabdff1aSopenharmony_ci sort_mono(s, &info); 964cabdff1aSopenharmony_ci 965cabdff1aSopenharmony_ci if (s->extra_flags & EXTRA_TRY_DELTAS) { 966cabdff1aSopenharmony_ci delta_mono(s, &info); 967cabdff1aSopenharmony_ci 968cabdff1aSopenharmony_ci if ((s->extra_flags & EXTRA_ADJUST_DELTAS) && s->decorr_passes[0].value) 969cabdff1aSopenharmony_ci s->delta_decay = (float)((s->delta_decay * 2.0 + s->decorr_passes[0].delta) / 3.0); 970cabdff1aSopenharmony_ci else 971cabdff1aSopenharmony_ci s->delta_decay = 2.0; 972cabdff1aSopenharmony_ci } 973cabdff1aSopenharmony_ci 974cabdff1aSopenharmony_ci if (s->extra_flags & EXTRA_SORT_LAST) 975cabdff1aSopenharmony_ci sort_mono(s, &info); 976cabdff1aSopenharmony_ci 977cabdff1aSopenharmony_ci if (do_samples) 978cabdff1aSopenharmony_ci memcpy(samples, s->sampleptrs[info.nterms + 1][0], s->block_samples * 4); 979cabdff1aSopenharmony_ci 980cabdff1aSopenharmony_ci for (i = 0; i < info.nterms; i++) 981cabdff1aSopenharmony_ci if (!s->decorr_passes[i].value) 982cabdff1aSopenharmony_ci break; 983cabdff1aSopenharmony_ci 984cabdff1aSopenharmony_ci s->num_terms = i; 985cabdff1aSopenharmony_ci} 986cabdff1aSopenharmony_ci 987cabdff1aSopenharmony_cistatic void scan_word(WavPackEncodeContext *s, WvChannel *c, 988cabdff1aSopenharmony_ci int32_t *samples, int nb_samples, int dir) 989cabdff1aSopenharmony_ci{ 990cabdff1aSopenharmony_ci if (dir < 0) 991cabdff1aSopenharmony_ci samples += nb_samples - 1; 992cabdff1aSopenharmony_ci 993cabdff1aSopenharmony_ci while (nb_samples--) { 994cabdff1aSopenharmony_ci uint32_t low, value = labs(samples[0]); 995cabdff1aSopenharmony_ci 996cabdff1aSopenharmony_ci if (value < GET_MED(0)) { 997cabdff1aSopenharmony_ci DEC_MED(0); 998cabdff1aSopenharmony_ci } else { 999cabdff1aSopenharmony_ci low = GET_MED(0); 1000cabdff1aSopenharmony_ci INC_MED(0); 1001cabdff1aSopenharmony_ci 1002cabdff1aSopenharmony_ci if (value - low < GET_MED(1)) { 1003cabdff1aSopenharmony_ci DEC_MED(1); 1004cabdff1aSopenharmony_ci } else { 1005cabdff1aSopenharmony_ci low += GET_MED(1); 1006cabdff1aSopenharmony_ci INC_MED(1); 1007cabdff1aSopenharmony_ci 1008cabdff1aSopenharmony_ci if (value - low < GET_MED(2)) { 1009cabdff1aSopenharmony_ci DEC_MED(2); 1010cabdff1aSopenharmony_ci } else { 1011cabdff1aSopenharmony_ci INC_MED(2); 1012cabdff1aSopenharmony_ci } 1013cabdff1aSopenharmony_ci } 1014cabdff1aSopenharmony_ci } 1015cabdff1aSopenharmony_ci samples += dir; 1016cabdff1aSopenharmony_ci } 1017cabdff1aSopenharmony_ci} 1018cabdff1aSopenharmony_ci 1019cabdff1aSopenharmony_cistatic int wv_mono(WavPackEncodeContext *s, int32_t *samples, 1020cabdff1aSopenharmony_ci int no_history, int do_samples) 1021cabdff1aSopenharmony_ci{ 1022cabdff1aSopenharmony_ci struct Decorr temp_decorr_pass, save_decorr_passes[MAX_TERMS] = {{0}}; 1023cabdff1aSopenharmony_ci int nb_samples = s->block_samples; 1024cabdff1aSopenharmony_ci int buf_size = sizeof(int32_t) * nb_samples; 1025cabdff1aSopenharmony_ci uint32_t best_size = UINT32_MAX, size; 1026cabdff1aSopenharmony_ci int log_limit, pi, i, ret; 1027cabdff1aSopenharmony_ci 1028cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) 1029cabdff1aSopenharmony_ci if (samples[i]) 1030cabdff1aSopenharmony_ci break; 1031cabdff1aSopenharmony_ci 1032cabdff1aSopenharmony_ci if (i == nb_samples) { 1033cabdff1aSopenharmony_ci CLEAR(s->decorr_passes); 1034cabdff1aSopenharmony_ci CLEAR(s->w); 1035cabdff1aSopenharmony_ci s->num_terms = 0; 1036cabdff1aSopenharmony_ci return 0; 1037cabdff1aSopenharmony_ci } 1038cabdff1aSopenharmony_ci 1039cabdff1aSopenharmony_ci log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256; 1040cabdff1aSopenharmony_ci log_limit = FFMIN(6912, log_limit); 1041cabdff1aSopenharmony_ci 1042cabdff1aSopenharmony_ci if ((ret = allocate_buffers(s)) < 0) 1043cabdff1aSopenharmony_ci return ret; 1044cabdff1aSopenharmony_ci 1045cabdff1aSopenharmony_ci if (no_history || s->num_passes >= 7) 1046cabdff1aSopenharmony_ci s->best_decorr = s->mask_decorr = 0; 1047cabdff1aSopenharmony_ci 1048cabdff1aSopenharmony_ci for (pi = 0; pi < s->num_passes;) { 1049cabdff1aSopenharmony_ci const WavPackDecorrSpec *wpds; 1050cabdff1aSopenharmony_ci int nterms, c, j; 1051cabdff1aSopenharmony_ci 1052cabdff1aSopenharmony_ci if (!pi) { 1053cabdff1aSopenharmony_ci c = s->best_decorr; 1054cabdff1aSopenharmony_ci } else { 1055cabdff1aSopenharmony_ci if (s->mask_decorr == 0) 1056cabdff1aSopenharmony_ci c = 0; 1057cabdff1aSopenharmony_ci else 1058cabdff1aSopenharmony_ci c = (s->best_decorr & (s->mask_decorr - 1)) | s->mask_decorr; 1059cabdff1aSopenharmony_ci 1060cabdff1aSopenharmony_ci if (c == s->best_decorr) { 1061cabdff1aSopenharmony_ci s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1; 1062cabdff1aSopenharmony_ci continue; 1063cabdff1aSopenharmony_ci } 1064cabdff1aSopenharmony_ci } 1065cabdff1aSopenharmony_ci 1066cabdff1aSopenharmony_ci wpds = &s->decorr_specs[c]; 1067cabdff1aSopenharmony_ci nterms = decorr_filter_nterms[s->decorr_filter]; 1068cabdff1aSopenharmony_ci 1069cabdff1aSopenharmony_ci while (1) { 1070cabdff1aSopenharmony_ci memcpy(s->temp_buffer[0][0], samples, buf_size); 1071cabdff1aSopenharmony_ci CLEAR(save_decorr_passes); 1072cabdff1aSopenharmony_ci 1073cabdff1aSopenharmony_ci for (j = 0; j < nterms; j++) { 1074cabdff1aSopenharmony_ci CLEAR(temp_decorr_pass); 1075cabdff1aSopenharmony_ci temp_decorr_pass.delta = wpds->delta; 1076cabdff1aSopenharmony_ci temp_decorr_pass.value = wpds->terms[j]; 1077cabdff1aSopenharmony_ci 1078cabdff1aSopenharmony_ci if (temp_decorr_pass.value < 0) 1079cabdff1aSopenharmony_ci temp_decorr_pass.value = 1; 1080cabdff1aSopenharmony_ci 1081cabdff1aSopenharmony_ci decorr_mono(s->temp_buffer[j&1][0], s->temp_buffer[~j&1][0], 1082cabdff1aSopenharmony_ci FFMIN(nb_samples, 2048), &temp_decorr_pass, -1); 1083cabdff1aSopenharmony_ci 1084cabdff1aSopenharmony_ci if (j) { 1085cabdff1aSopenharmony_ci CLEAR(temp_decorr_pass.samplesA); 1086cabdff1aSopenharmony_ci } else { 1087cabdff1aSopenharmony_ci reverse_mono_decorr(&temp_decorr_pass); 1088cabdff1aSopenharmony_ci } 1089cabdff1aSopenharmony_ci 1090cabdff1aSopenharmony_ci memcpy(save_decorr_passes + j, &temp_decorr_pass, sizeof(struct Decorr)); 1091cabdff1aSopenharmony_ci decorr_mono(s->temp_buffer[j&1][0], s->temp_buffer[~j&1][0], 1092cabdff1aSopenharmony_ci nb_samples, &temp_decorr_pass, 1); 1093cabdff1aSopenharmony_ci } 1094cabdff1aSopenharmony_ci 1095cabdff1aSopenharmony_ci size = log2mono(s->temp_buffer[j&1][0], nb_samples, log_limit); 1096cabdff1aSopenharmony_ci if (size != UINT32_MAX || !nterms) 1097cabdff1aSopenharmony_ci break; 1098cabdff1aSopenharmony_ci nterms >>= 1; 1099cabdff1aSopenharmony_ci } 1100cabdff1aSopenharmony_ci 1101cabdff1aSopenharmony_ci if (size < best_size) { 1102cabdff1aSopenharmony_ci memcpy(s->best_buffer[0], s->temp_buffer[j&1][0], buf_size); 1103cabdff1aSopenharmony_ci memcpy(s->decorr_passes, save_decorr_passes, sizeof(struct Decorr) * MAX_TERMS); 1104cabdff1aSopenharmony_ci s->num_terms = nterms; 1105cabdff1aSopenharmony_ci s->best_decorr = c; 1106cabdff1aSopenharmony_ci best_size = size; 1107cabdff1aSopenharmony_ci } 1108cabdff1aSopenharmony_ci 1109cabdff1aSopenharmony_ci if (pi++) 1110cabdff1aSopenharmony_ci s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1; 1111cabdff1aSopenharmony_ci } 1112cabdff1aSopenharmony_ci 1113cabdff1aSopenharmony_ci if (s->extra_flags) 1114cabdff1aSopenharmony_ci analyze_mono(s, samples, do_samples); 1115cabdff1aSopenharmony_ci else if (do_samples) 1116cabdff1aSopenharmony_ci memcpy(samples, s->best_buffer[0], buf_size); 1117cabdff1aSopenharmony_ci 1118cabdff1aSopenharmony_ci if (no_history || s->extra_flags) { 1119cabdff1aSopenharmony_ci CLEAR(s->w); 1120cabdff1aSopenharmony_ci scan_word(s, &s->w.c[0], s->best_buffer[0], nb_samples, -1); 1121cabdff1aSopenharmony_ci } 1122cabdff1aSopenharmony_ci return 0; 1123cabdff1aSopenharmony_ci} 1124cabdff1aSopenharmony_ci 1125cabdff1aSopenharmony_cistatic void decorr_stereo(int32_t *in_left, int32_t *in_right, 1126cabdff1aSopenharmony_ci int32_t *out_left, int32_t *out_right, 1127cabdff1aSopenharmony_ci int nb_samples, struct Decorr *dpp, int dir) 1128cabdff1aSopenharmony_ci{ 1129cabdff1aSopenharmony_ci int m = 0, i; 1130cabdff1aSopenharmony_ci 1131cabdff1aSopenharmony_ci dpp->sumA = dpp->sumB = 0; 1132cabdff1aSopenharmony_ci 1133cabdff1aSopenharmony_ci if (dir < 0) { 1134cabdff1aSopenharmony_ci out_left += nb_samples - 1; 1135cabdff1aSopenharmony_ci out_right += nb_samples - 1; 1136cabdff1aSopenharmony_ci in_left += nb_samples - 1; 1137cabdff1aSopenharmony_ci in_right += nb_samples - 1; 1138cabdff1aSopenharmony_ci } 1139cabdff1aSopenharmony_ci 1140cabdff1aSopenharmony_ci dpp->weightA = restore_weight(store_weight(dpp->weightA)); 1141cabdff1aSopenharmony_ci dpp->weightB = restore_weight(store_weight(dpp->weightB)); 1142cabdff1aSopenharmony_ci 1143cabdff1aSopenharmony_ci for (i = 0; i < MAX_TERM; i++) { 1144cabdff1aSopenharmony_ci dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i])); 1145cabdff1aSopenharmony_ci dpp->samplesB[i] = wp_exp2(log2s(dpp->samplesB[i])); 1146cabdff1aSopenharmony_ci } 1147cabdff1aSopenharmony_ci 1148cabdff1aSopenharmony_ci switch (dpp->value) { 1149cabdff1aSopenharmony_ci case 2: 1150cabdff1aSopenharmony_ci while (nb_samples--) { 1151cabdff1aSopenharmony_ci int32_t sam, tmp; 1152cabdff1aSopenharmony_ci 1153cabdff1aSopenharmony_ci sam = dpp->samplesA[0]; 1154cabdff1aSopenharmony_ci dpp->samplesA[0] = dpp->samplesA[1]; 1155cabdff1aSopenharmony_ci out_left[0] = tmp = (dpp->samplesA[1] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam); 1156cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp); 1157cabdff1aSopenharmony_ci dpp->sumA += dpp->weightA; 1158cabdff1aSopenharmony_ci 1159cabdff1aSopenharmony_ci sam = dpp->samplesB[0]; 1160cabdff1aSopenharmony_ci dpp->samplesB[0] = dpp->samplesB[1]; 1161cabdff1aSopenharmony_ci out_right[0] = tmp = (dpp->samplesB[1] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam); 1162cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp); 1163cabdff1aSopenharmony_ci dpp->sumB += dpp->weightB; 1164cabdff1aSopenharmony_ci 1165cabdff1aSopenharmony_ci in_left += dir; 1166cabdff1aSopenharmony_ci out_left += dir; 1167cabdff1aSopenharmony_ci in_right += dir; 1168cabdff1aSopenharmony_ci out_right += dir; 1169cabdff1aSopenharmony_ci } 1170cabdff1aSopenharmony_ci break; 1171cabdff1aSopenharmony_ci case 17: 1172cabdff1aSopenharmony_ci while (nb_samples--) { 1173cabdff1aSopenharmony_ci int32_t sam, tmp; 1174cabdff1aSopenharmony_ci 1175cabdff1aSopenharmony_ci sam = 2 * dpp->samplesA[0] - dpp->samplesA[1]; 1176cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 1177cabdff1aSopenharmony_ci out_left[0] = tmp = (dpp->samplesA[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam); 1178cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp); 1179cabdff1aSopenharmony_ci dpp->sumA += dpp->weightA; 1180cabdff1aSopenharmony_ci 1181cabdff1aSopenharmony_ci sam = 2 * dpp->samplesB[0] - dpp->samplesB[1]; 1182cabdff1aSopenharmony_ci dpp->samplesB[1] = dpp->samplesB[0]; 1183cabdff1aSopenharmony_ci out_right[0] = tmp = (dpp->samplesB[0] = in_right[0]) - APPLY_WEIGHT (dpp->weightB, sam); 1184cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp); 1185cabdff1aSopenharmony_ci dpp->sumB += dpp->weightB; 1186cabdff1aSopenharmony_ci 1187cabdff1aSopenharmony_ci in_left += dir; 1188cabdff1aSopenharmony_ci out_left += dir; 1189cabdff1aSopenharmony_ci in_right += dir; 1190cabdff1aSopenharmony_ci out_right += dir; 1191cabdff1aSopenharmony_ci } 1192cabdff1aSopenharmony_ci break; 1193cabdff1aSopenharmony_ci case 18: 1194cabdff1aSopenharmony_ci while (nb_samples--) { 1195cabdff1aSopenharmony_ci int32_t sam, tmp; 1196cabdff1aSopenharmony_ci 1197cabdff1aSopenharmony_ci sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1); 1198cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 1199cabdff1aSopenharmony_ci out_left[0] = tmp = (dpp->samplesA[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam); 1200cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp); 1201cabdff1aSopenharmony_ci dpp->sumA += dpp->weightA; 1202cabdff1aSopenharmony_ci 1203cabdff1aSopenharmony_ci sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1); 1204cabdff1aSopenharmony_ci dpp->samplesB[1] = dpp->samplesB[0]; 1205cabdff1aSopenharmony_ci out_right[0] = tmp = (dpp->samplesB[0] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam); 1206cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp); 1207cabdff1aSopenharmony_ci dpp->sumB += dpp->weightB; 1208cabdff1aSopenharmony_ci 1209cabdff1aSopenharmony_ci in_left += dir; 1210cabdff1aSopenharmony_ci out_left += dir; 1211cabdff1aSopenharmony_ci in_right += dir; 1212cabdff1aSopenharmony_ci out_right += dir; 1213cabdff1aSopenharmony_ci } 1214cabdff1aSopenharmony_ci break; 1215cabdff1aSopenharmony_ci default: { 1216cabdff1aSopenharmony_ci int k = dpp->value & (MAX_TERM - 1); 1217cabdff1aSopenharmony_ci 1218cabdff1aSopenharmony_ci while (nb_samples--) { 1219cabdff1aSopenharmony_ci int32_t sam, tmp; 1220cabdff1aSopenharmony_ci 1221cabdff1aSopenharmony_ci sam = dpp->samplesA[m]; 1222cabdff1aSopenharmony_ci out_left[0] = tmp = (dpp->samplesA[k] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam); 1223cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp); 1224cabdff1aSopenharmony_ci dpp->sumA += dpp->weightA; 1225cabdff1aSopenharmony_ci 1226cabdff1aSopenharmony_ci sam = dpp->samplesB[m]; 1227cabdff1aSopenharmony_ci out_right[0] = tmp = (dpp->samplesB[k] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam); 1228cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp); 1229cabdff1aSopenharmony_ci dpp->sumB += dpp->weightB; 1230cabdff1aSopenharmony_ci 1231cabdff1aSopenharmony_ci in_left += dir; 1232cabdff1aSopenharmony_ci out_left += dir; 1233cabdff1aSopenharmony_ci in_right += dir; 1234cabdff1aSopenharmony_ci out_right += dir; 1235cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 1236cabdff1aSopenharmony_ci k = (k + 1) & (MAX_TERM - 1); 1237cabdff1aSopenharmony_ci } 1238cabdff1aSopenharmony_ci 1239cabdff1aSopenharmony_ci if (m) { 1240cabdff1aSopenharmony_ci int32_t temp_A[MAX_TERM], temp_B[MAX_TERM]; 1241cabdff1aSopenharmony_ci int k; 1242cabdff1aSopenharmony_ci 1243cabdff1aSopenharmony_ci memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA)); 1244cabdff1aSopenharmony_ci memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB)); 1245cabdff1aSopenharmony_ci 1246cabdff1aSopenharmony_ci for (k = 0; k < MAX_TERM; k++) { 1247cabdff1aSopenharmony_ci dpp->samplesA[k] = temp_A[m]; 1248cabdff1aSopenharmony_ci dpp->samplesB[k] = temp_B[m]; 1249cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 1250cabdff1aSopenharmony_ci } 1251cabdff1aSopenharmony_ci } 1252cabdff1aSopenharmony_ci break; 1253cabdff1aSopenharmony_ci } 1254cabdff1aSopenharmony_ci case -1: 1255cabdff1aSopenharmony_ci while (nb_samples--) { 1256cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 1257cabdff1aSopenharmony_ci 1258cabdff1aSopenharmony_ci sam_A = dpp->samplesA[0]; 1259cabdff1aSopenharmony_ci out_left[0] = tmp = (sam_B = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam_A); 1260cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp); 1261cabdff1aSopenharmony_ci dpp->sumA += dpp->weightA; 1262cabdff1aSopenharmony_ci 1263cabdff1aSopenharmony_ci out_right[0] = tmp = (dpp->samplesA[0] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam_B); 1264cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp); 1265cabdff1aSopenharmony_ci dpp->sumB += dpp->weightB; 1266cabdff1aSopenharmony_ci 1267cabdff1aSopenharmony_ci in_left += dir; 1268cabdff1aSopenharmony_ci out_left += dir; 1269cabdff1aSopenharmony_ci in_right += dir; 1270cabdff1aSopenharmony_ci out_right += dir; 1271cabdff1aSopenharmony_ci } 1272cabdff1aSopenharmony_ci break; 1273cabdff1aSopenharmony_ci case -2: 1274cabdff1aSopenharmony_ci while (nb_samples--) { 1275cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 1276cabdff1aSopenharmony_ci 1277cabdff1aSopenharmony_ci sam_B = dpp->samplesB[0]; 1278cabdff1aSopenharmony_ci out_right[0] = tmp = (sam_A = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam_B); 1279cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp); 1280cabdff1aSopenharmony_ci dpp->sumB += dpp->weightB; 1281cabdff1aSopenharmony_ci 1282cabdff1aSopenharmony_ci out_left[0] = tmp = (dpp->samplesB[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam_A); 1283cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp); 1284cabdff1aSopenharmony_ci dpp->sumA += dpp->weightA; 1285cabdff1aSopenharmony_ci 1286cabdff1aSopenharmony_ci in_left += dir; 1287cabdff1aSopenharmony_ci out_left += dir; 1288cabdff1aSopenharmony_ci in_right += dir; 1289cabdff1aSopenharmony_ci out_right += dir; 1290cabdff1aSopenharmony_ci } 1291cabdff1aSopenharmony_ci break; 1292cabdff1aSopenharmony_ci case -3: 1293cabdff1aSopenharmony_ci while (nb_samples--) { 1294cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 1295cabdff1aSopenharmony_ci 1296cabdff1aSopenharmony_ci sam_A = dpp->samplesA[0]; 1297cabdff1aSopenharmony_ci sam_B = dpp->samplesB[0]; 1298cabdff1aSopenharmony_ci 1299cabdff1aSopenharmony_ci dpp->samplesA[0] = tmp = in_right[0]; 1300cabdff1aSopenharmony_ci out_right[0] = tmp -= APPLY_WEIGHT(dpp->weightB, sam_B); 1301cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp); 1302cabdff1aSopenharmony_ci dpp->sumB += dpp->weightB; 1303cabdff1aSopenharmony_ci 1304cabdff1aSopenharmony_ci dpp->samplesB[0] = tmp = in_left[0]; 1305cabdff1aSopenharmony_ci out_left[0] = tmp -= APPLY_WEIGHT(dpp->weightA, sam_A); 1306cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp); 1307cabdff1aSopenharmony_ci dpp->sumA += dpp->weightA; 1308cabdff1aSopenharmony_ci 1309cabdff1aSopenharmony_ci in_left += dir; 1310cabdff1aSopenharmony_ci out_left += dir; 1311cabdff1aSopenharmony_ci in_right += dir; 1312cabdff1aSopenharmony_ci out_right += dir; 1313cabdff1aSopenharmony_ci } 1314cabdff1aSopenharmony_ci break; 1315cabdff1aSopenharmony_ci } 1316cabdff1aSopenharmony_ci} 1317cabdff1aSopenharmony_ci 1318cabdff1aSopenharmony_cistatic void reverse_decorr(struct Decorr *dpp) 1319cabdff1aSopenharmony_ci{ 1320cabdff1aSopenharmony_ci if (dpp->value > MAX_TERM) { 1321cabdff1aSopenharmony_ci int32_t sam_A, sam_B; 1322cabdff1aSopenharmony_ci 1323cabdff1aSopenharmony_ci if (dpp->value & 1) { 1324cabdff1aSopenharmony_ci sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1]; 1325cabdff1aSopenharmony_ci sam_B = 2 * dpp->samplesB[0] - dpp->samplesB[1]; 1326cabdff1aSopenharmony_ci } else { 1327cabdff1aSopenharmony_ci sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1; 1328cabdff1aSopenharmony_ci sam_B = (3 * dpp->samplesB[0] - dpp->samplesB[1]) >> 1; 1329cabdff1aSopenharmony_ci } 1330cabdff1aSopenharmony_ci 1331cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 1332cabdff1aSopenharmony_ci dpp->samplesB[1] = dpp->samplesB[0]; 1333cabdff1aSopenharmony_ci dpp->samplesA[0] = sam_A; 1334cabdff1aSopenharmony_ci dpp->samplesB[0] = sam_B; 1335cabdff1aSopenharmony_ci 1336cabdff1aSopenharmony_ci if (dpp->value & 1) { 1337cabdff1aSopenharmony_ci sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1]; 1338cabdff1aSopenharmony_ci sam_B = 2 * dpp->samplesB[0] - dpp->samplesB[1]; 1339cabdff1aSopenharmony_ci } else { 1340cabdff1aSopenharmony_ci sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1; 1341cabdff1aSopenharmony_ci sam_B = (3 * dpp->samplesB[0] - dpp->samplesB[1]) >> 1; 1342cabdff1aSopenharmony_ci } 1343cabdff1aSopenharmony_ci 1344cabdff1aSopenharmony_ci dpp->samplesA[1] = sam_A; 1345cabdff1aSopenharmony_ci dpp->samplesB[1] = sam_B; 1346cabdff1aSopenharmony_ci } else if (dpp->value > 1) { 1347cabdff1aSopenharmony_ci int i, j, k; 1348cabdff1aSopenharmony_ci 1349cabdff1aSopenharmony_ci for (i = 0, j = dpp->value - 1, k = 0; k < dpp->value / 2; i++, j--, k++) { 1350cabdff1aSopenharmony_ci i &= (MAX_TERM - 1); 1351cabdff1aSopenharmony_ci j &= (MAX_TERM - 1); 1352cabdff1aSopenharmony_ci dpp->samplesA[i] ^= dpp->samplesA[j]; 1353cabdff1aSopenharmony_ci dpp->samplesA[j] ^= dpp->samplesA[i]; 1354cabdff1aSopenharmony_ci dpp->samplesA[i] ^= dpp->samplesA[j]; 1355cabdff1aSopenharmony_ci dpp->samplesB[i] ^= dpp->samplesB[j]; 1356cabdff1aSopenharmony_ci dpp->samplesB[j] ^= dpp->samplesB[i]; 1357cabdff1aSopenharmony_ci dpp->samplesB[i] ^= dpp->samplesB[j]; 1358cabdff1aSopenharmony_ci } 1359cabdff1aSopenharmony_ci } 1360cabdff1aSopenharmony_ci} 1361cabdff1aSopenharmony_ci 1362cabdff1aSopenharmony_cistatic void decorr_stereo_quick(int32_t *in_left, int32_t *in_right, 1363cabdff1aSopenharmony_ci int32_t *out_left, int32_t *out_right, 1364cabdff1aSopenharmony_ci int nb_samples, struct Decorr *dpp) 1365cabdff1aSopenharmony_ci{ 1366cabdff1aSopenharmony_ci int m = 0, i; 1367cabdff1aSopenharmony_ci 1368cabdff1aSopenharmony_ci dpp->weightA = restore_weight(store_weight(dpp->weightA)); 1369cabdff1aSopenharmony_ci dpp->weightB = restore_weight(store_weight(dpp->weightB)); 1370cabdff1aSopenharmony_ci 1371cabdff1aSopenharmony_ci for (i = 0; i < MAX_TERM; i++) { 1372cabdff1aSopenharmony_ci dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i])); 1373cabdff1aSopenharmony_ci dpp->samplesB[i] = wp_exp2(log2s(dpp->samplesB[i])); 1374cabdff1aSopenharmony_ci } 1375cabdff1aSopenharmony_ci 1376cabdff1aSopenharmony_ci switch (dpp->value) { 1377cabdff1aSopenharmony_ci case 2: 1378cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 1379cabdff1aSopenharmony_ci int32_t sam, tmp; 1380cabdff1aSopenharmony_ci 1381cabdff1aSopenharmony_ci sam = dpp->samplesA[0]; 1382cabdff1aSopenharmony_ci dpp->samplesA[0] = dpp->samplesA[1]; 1383cabdff1aSopenharmony_ci out_left[i] = tmp = (dpp->samplesA[1] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam); 1384cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp); 1385cabdff1aSopenharmony_ci 1386cabdff1aSopenharmony_ci sam = dpp->samplesB[0]; 1387cabdff1aSopenharmony_ci dpp->samplesB[0] = dpp->samplesB[1]; 1388cabdff1aSopenharmony_ci out_right[i] = tmp = (dpp->samplesB[1] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam); 1389cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp); 1390cabdff1aSopenharmony_ci } 1391cabdff1aSopenharmony_ci break; 1392cabdff1aSopenharmony_ci case 17: 1393cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 1394cabdff1aSopenharmony_ci int32_t sam, tmp; 1395cabdff1aSopenharmony_ci 1396cabdff1aSopenharmony_ci sam = 2 * dpp->samplesA[0] - dpp->samplesA[1]; 1397cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 1398cabdff1aSopenharmony_ci out_left[i] = tmp = (dpp->samplesA[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam); 1399cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp); 1400cabdff1aSopenharmony_ci 1401cabdff1aSopenharmony_ci sam = 2 * dpp->samplesB[0] - dpp->samplesB[1]; 1402cabdff1aSopenharmony_ci dpp->samplesB[1] = dpp->samplesB[0]; 1403cabdff1aSopenharmony_ci out_right[i] = tmp = (dpp->samplesB[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam); 1404cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp); 1405cabdff1aSopenharmony_ci } 1406cabdff1aSopenharmony_ci break; 1407cabdff1aSopenharmony_ci case 18: 1408cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 1409cabdff1aSopenharmony_ci int32_t sam, tmp; 1410cabdff1aSopenharmony_ci 1411cabdff1aSopenharmony_ci sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1); 1412cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 1413cabdff1aSopenharmony_ci out_left[i] = tmp = (dpp->samplesA[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam); 1414cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp); 1415cabdff1aSopenharmony_ci 1416cabdff1aSopenharmony_ci sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1); 1417cabdff1aSopenharmony_ci dpp->samplesB[1] = dpp->samplesB[0]; 1418cabdff1aSopenharmony_ci out_right[i] = tmp = (dpp->samplesB[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam); 1419cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp); 1420cabdff1aSopenharmony_ci } 1421cabdff1aSopenharmony_ci break; 1422cabdff1aSopenharmony_ci default: { 1423cabdff1aSopenharmony_ci int k = dpp->value & (MAX_TERM - 1); 1424cabdff1aSopenharmony_ci 1425cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 1426cabdff1aSopenharmony_ci int32_t sam, tmp; 1427cabdff1aSopenharmony_ci 1428cabdff1aSopenharmony_ci sam = dpp->samplesA[m]; 1429cabdff1aSopenharmony_ci out_left[i] = tmp = (dpp->samplesA[k] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam); 1430cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp); 1431cabdff1aSopenharmony_ci 1432cabdff1aSopenharmony_ci sam = dpp->samplesB[m]; 1433cabdff1aSopenharmony_ci out_right[i] = tmp = (dpp->samplesB[k] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam); 1434cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp); 1435cabdff1aSopenharmony_ci 1436cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 1437cabdff1aSopenharmony_ci k = (k + 1) & (MAX_TERM - 1); 1438cabdff1aSopenharmony_ci } 1439cabdff1aSopenharmony_ci 1440cabdff1aSopenharmony_ci if (m) { 1441cabdff1aSopenharmony_ci int32_t temp_A[MAX_TERM], temp_B[MAX_TERM]; 1442cabdff1aSopenharmony_ci int k; 1443cabdff1aSopenharmony_ci 1444cabdff1aSopenharmony_ci memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA)); 1445cabdff1aSopenharmony_ci memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB)); 1446cabdff1aSopenharmony_ci 1447cabdff1aSopenharmony_ci for (k = 0; k < MAX_TERM; k++) { 1448cabdff1aSopenharmony_ci dpp->samplesA[k] = temp_A[m]; 1449cabdff1aSopenharmony_ci dpp->samplesB[k] = temp_B[m]; 1450cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 1451cabdff1aSopenharmony_ci } 1452cabdff1aSopenharmony_ci } 1453cabdff1aSopenharmony_ci break; 1454cabdff1aSopenharmony_ci } 1455cabdff1aSopenharmony_ci case -1: 1456cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 1457cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 1458cabdff1aSopenharmony_ci 1459cabdff1aSopenharmony_ci sam_A = dpp->samplesA[0]; 1460cabdff1aSopenharmony_ci out_left[i] = tmp = (sam_B = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A); 1461cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp); 1462cabdff1aSopenharmony_ci 1463cabdff1aSopenharmony_ci out_right[i] = tmp = (dpp->samplesA[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B); 1464cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp); 1465cabdff1aSopenharmony_ci } 1466cabdff1aSopenharmony_ci break; 1467cabdff1aSopenharmony_ci case -2: 1468cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 1469cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 1470cabdff1aSopenharmony_ci 1471cabdff1aSopenharmony_ci sam_B = dpp->samplesB[0]; 1472cabdff1aSopenharmony_ci out_right[i] = tmp = (sam_A = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B); 1473cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp); 1474cabdff1aSopenharmony_ci 1475cabdff1aSopenharmony_ci out_left[i] = tmp = (dpp->samplesB[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A); 1476cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp); 1477cabdff1aSopenharmony_ci } 1478cabdff1aSopenharmony_ci break; 1479cabdff1aSopenharmony_ci case -3: 1480cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 1481cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 1482cabdff1aSopenharmony_ci 1483cabdff1aSopenharmony_ci sam_A = dpp->samplesA[0]; 1484cabdff1aSopenharmony_ci sam_B = dpp->samplesB[0]; 1485cabdff1aSopenharmony_ci 1486cabdff1aSopenharmony_ci dpp->samplesA[0] = tmp = in_right[i]; 1487cabdff1aSopenharmony_ci out_right[i] = tmp -= APPLY_WEIGHT_I(dpp->weightB, sam_B); 1488cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp); 1489cabdff1aSopenharmony_ci 1490cabdff1aSopenharmony_ci dpp->samplesB[0] = tmp = in_left[i]; 1491cabdff1aSopenharmony_ci out_left[i] = tmp -= APPLY_WEIGHT_I(dpp->weightA, sam_A); 1492cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp); 1493cabdff1aSopenharmony_ci } 1494cabdff1aSopenharmony_ci break; 1495cabdff1aSopenharmony_ci } 1496cabdff1aSopenharmony_ci} 1497cabdff1aSopenharmony_ci 1498cabdff1aSopenharmony_cistatic void decorr_stereo_buffer(WavPackExtraInfo *info, 1499cabdff1aSopenharmony_ci int32_t *in_left, int32_t *in_right, 1500cabdff1aSopenharmony_ci int32_t *out_left, int32_t *out_right, 1501cabdff1aSopenharmony_ci int nb_samples, int tindex) 1502cabdff1aSopenharmony_ci{ 1503cabdff1aSopenharmony_ci struct Decorr dp = {0}, *dppi = info->dps + tindex; 1504cabdff1aSopenharmony_ci int delta = dppi->delta, pre_delta; 1505cabdff1aSopenharmony_ci int term = dppi->value; 1506cabdff1aSopenharmony_ci 1507cabdff1aSopenharmony_ci if (delta == 7) 1508cabdff1aSopenharmony_ci pre_delta = 7; 1509cabdff1aSopenharmony_ci else if (delta < 2) 1510cabdff1aSopenharmony_ci pre_delta = 3; 1511cabdff1aSopenharmony_ci else 1512cabdff1aSopenharmony_ci pre_delta = delta + 1; 1513cabdff1aSopenharmony_ci 1514cabdff1aSopenharmony_ci dp.value = term; 1515cabdff1aSopenharmony_ci dp.delta = pre_delta; 1516cabdff1aSopenharmony_ci decorr_stereo(in_left, in_right, out_left, out_right, 1517cabdff1aSopenharmony_ci FFMIN(2048, nb_samples), &dp, -1); 1518cabdff1aSopenharmony_ci dp.delta = delta; 1519cabdff1aSopenharmony_ci 1520cabdff1aSopenharmony_ci if (tindex == 0) { 1521cabdff1aSopenharmony_ci reverse_decorr(&dp); 1522cabdff1aSopenharmony_ci } else { 1523cabdff1aSopenharmony_ci CLEAR(dp.samplesA); 1524cabdff1aSopenharmony_ci CLEAR(dp.samplesB); 1525cabdff1aSopenharmony_ci } 1526cabdff1aSopenharmony_ci 1527cabdff1aSopenharmony_ci memcpy(dppi->samplesA, dp.samplesA, sizeof(dp.samplesA)); 1528cabdff1aSopenharmony_ci memcpy(dppi->samplesB, dp.samplesB, sizeof(dp.samplesB)); 1529cabdff1aSopenharmony_ci dppi->weightA = dp.weightA; 1530cabdff1aSopenharmony_ci dppi->weightB = dp.weightB; 1531cabdff1aSopenharmony_ci 1532cabdff1aSopenharmony_ci if (delta == 0) { 1533cabdff1aSopenharmony_ci dp.delta = 1; 1534cabdff1aSopenharmony_ci decorr_stereo(in_left, in_right, out_left, out_right, nb_samples, &dp, 1); 1535cabdff1aSopenharmony_ci dp.delta = 0; 1536cabdff1aSopenharmony_ci memcpy(dp.samplesA, dppi->samplesA, sizeof(dp.samplesA)); 1537cabdff1aSopenharmony_ci memcpy(dp.samplesB, dppi->samplesB, sizeof(dp.samplesB)); 1538cabdff1aSopenharmony_ci dppi->weightA = dp.weightA = dp.sumA / nb_samples; 1539cabdff1aSopenharmony_ci dppi->weightB = dp.weightB = dp.sumB / nb_samples; 1540cabdff1aSopenharmony_ci } 1541cabdff1aSopenharmony_ci 1542cabdff1aSopenharmony_ci if (info->gt16bit) 1543cabdff1aSopenharmony_ci decorr_stereo(in_left, in_right, out_left, out_right, 1544cabdff1aSopenharmony_ci nb_samples, &dp, 1); 1545cabdff1aSopenharmony_ci else 1546cabdff1aSopenharmony_ci decorr_stereo_quick(in_left, in_right, out_left, out_right, 1547cabdff1aSopenharmony_ci nb_samples, &dp); 1548cabdff1aSopenharmony_ci} 1549cabdff1aSopenharmony_ci 1550cabdff1aSopenharmony_cistatic void sort_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info) 1551cabdff1aSopenharmony_ci{ 1552cabdff1aSopenharmony_ci int reversed = 1; 1553cabdff1aSopenharmony_ci uint32_t bits; 1554cabdff1aSopenharmony_ci 1555cabdff1aSopenharmony_ci while (reversed) { 1556cabdff1aSopenharmony_ci int ri, i; 1557cabdff1aSopenharmony_ci 1558cabdff1aSopenharmony_ci memcpy(info->dps, s->decorr_passes, sizeof(s->decorr_passes)); 1559cabdff1aSopenharmony_ci reversed = 0; 1560cabdff1aSopenharmony_ci 1561cabdff1aSopenharmony_ci for (ri = 0; ri < info->nterms && s->decorr_passes[ri].value; ri++) { 1562cabdff1aSopenharmony_ci 1563cabdff1aSopenharmony_ci if (ri + 1 >= info->nterms || !s->decorr_passes[ri+1].value) 1564cabdff1aSopenharmony_ci break; 1565cabdff1aSopenharmony_ci 1566cabdff1aSopenharmony_ci if (s->decorr_passes[ri].value == s->decorr_passes[ri+1].value) { 1567cabdff1aSopenharmony_ci decorr_stereo_buffer(info, 1568cabdff1aSopenharmony_ci s->sampleptrs[ri ][0], s->sampleptrs[ri ][1], 1569cabdff1aSopenharmony_ci s->sampleptrs[ri+1][0], s->sampleptrs[ri+1][1], 1570cabdff1aSopenharmony_ci s->block_samples, ri); 1571cabdff1aSopenharmony_ci continue; 1572cabdff1aSopenharmony_ci } 1573cabdff1aSopenharmony_ci 1574cabdff1aSopenharmony_ci info->dps[ri ] = s->decorr_passes[ri+1]; 1575cabdff1aSopenharmony_ci info->dps[ri+1] = s->decorr_passes[ri ]; 1576cabdff1aSopenharmony_ci 1577cabdff1aSopenharmony_ci for (i = ri; i < info->nterms && s->decorr_passes[i].value; i++) 1578cabdff1aSopenharmony_ci decorr_stereo_buffer(info, 1579cabdff1aSopenharmony_ci s->sampleptrs[i ][0], s->sampleptrs[i ][1], 1580cabdff1aSopenharmony_ci s->sampleptrs[i+1][0], s->sampleptrs[i+1][1], 1581cabdff1aSopenharmony_ci s->block_samples, i); 1582cabdff1aSopenharmony_ci 1583cabdff1aSopenharmony_ci bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1], 1584cabdff1aSopenharmony_ci s->block_samples, info->log_limit); 1585cabdff1aSopenharmony_ci 1586cabdff1aSopenharmony_ci if (bits < info->best_bits) { 1587cabdff1aSopenharmony_ci reversed = 1; 1588cabdff1aSopenharmony_ci info->best_bits = bits; 1589cabdff1aSopenharmony_ci CLEAR(s->decorr_passes); 1590cabdff1aSopenharmony_ci memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i); 1591cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][0], 1592cabdff1aSopenharmony_ci s->sampleptrs[i][0], s->block_samples * 4); 1593cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][1], 1594cabdff1aSopenharmony_ci s->sampleptrs[i][1], s->block_samples * 4); 1595cabdff1aSopenharmony_ci } else { 1596cabdff1aSopenharmony_ci info->dps[ri ] = s->decorr_passes[ri ]; 1597cabdff1aSopenharmony_ci info->dps[ri+1] = s->decorr_passes[ri+1]; 1598cabdff1aSopenharmony_ci decorr_stereo_buffer(info, 1599cabdff1aSopenharmony_ci s->sampleptrs[ri ][0], s->sampleptrs[ri ][1], 1600cabdff1aSopenharmony_ci s->sampleptrs[ri+1][0], s->sampleptrs[ri+1][1], 1601cabdff1aSopenharmony_ci s->block_samples, ri); 1602cabdff1aSopenharmony_ci } 1603cabdff1aSopenharmony_ci } 1604cabdff1aSopenharmony_ci } 1605cabdff1aSopenharmony_ci} 1606cabdff1aSopenharmony_ci 1607cabdff1aSopenharmony_cistatic void delta_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info) 1608cabdff1aSopenharmony_ci{ 1609cabdff1aSopenharmony_ci int lower = 0, delta, d, i; 1610cabdff1aSopenharmony_ci uint32_t bits; 1611cabdff1aSopenharmony_ci 1612cabdff1aSopenharmony_ci if (!s->decorr_passes[0].value) 1613cabdff1aSopenharmony_ci return; 1614cabdff1aSopenharmony_ci delta = s->decorr_passes[0].delta; 1615cabdff1aSopenharmony_ci 1616cabdff1aSopenharmony_ci for (d = delta - 1; d >= 0; d--) { 1617cabdff1aSopenharmony_ci for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) { 1618cabdff1aSopenharmony_ci info->dps[i].value = s->decorr_passes[i].value; 1619cabdff1aSopenharmony_ci info->dps[i].delta = d; 1620cabdff1aSopenharmony_ci decorr_stereo_buffer(info, 1621cabdff1aSopenharmony_ci s->sampleptrs[i ][0], s->sampleptrs[i ][1], 1622cabdff1aSopenharmony_ci s->sampleptrs[i+1][0], s->sampleptrs[i+1][1], 1623cabdff1aSopenharmony_ci s->block_samples, i); 1624cabdff1aSopenharmony_ci } 1625cabdff1aSopenharmony_ci 1626cabdff1aSopenharmony_ci bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1], 1627cabdff1aSopenharmony_ci s->block_samples, info->log_limit); 1628cabdff1aSopenharmony_ci if (bits >= info->best_bits) 1629cabdff1aSopenharmony_ci break; 1630cabdff1aSopenharmony_ci lower = 1; 1631cabdff1aSopenharmony_ci info->best_bits = bits; 1632cabdff1aSopenharmony_ci CLEAR(s->decorr_passes); 1633cabdff1aSopenharmony_ci memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i); 1634cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0], 1635cabdff1aSopenharmony_ci s->block_samples * 4); 1636cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][1], s->sampleptrs[i][1], 1637cabdff1aSopenharmony_ci s->block_samples * 4); 1638cabdff1aSopenharmony_ci } 1639cabdff1aSopenharmony_ci 1640cabdff1aSopenharmony_ci for (d = delta + 1; !lower && d <= 7; d++) { 1641cabdff1aSopenharmony_ci for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) { 1642cabdff1aSopenharmony_ci info->dps[i].value = s->decorr_passes[i].value; 1643cabdff1aSopenharmony_ci info->dps[i].delta = d; 1644cabdff1aSopenharmony_ci decorr_stereo_buffer(info, 1645cabdff1aSopenharmony_ci s->sampleptrs[i ][0], s->sampleptrs[i ][1], 1646cabdff1aSopenharmony_ci s->sampleptrs[i+1][0], s->sampleptrs[i+1][1], 1647cabdff1aSopenharmony_ci s->block_samples, i); 1648cabdff1aSopenharmony_ci } 1649cabdff1aSopenharmony_ci 1650cabdff1aSopenharmony_ci bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1], 1651cabdff1aSopenharmony_ci s->block_samples, info->log_limit); 1652cabdff1aSopenharmony_ci 1653cabdff1aSopenharmony_ci if (bits < info->best_bits) { 1654cabdff1aSopenharmony_ci info->best_bits = bits; 1655cabdff1aSopenharmony_ci CLEAR(s->decorr_passes); 1656cabdff1aSopenharmony_ci memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i); 1657cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][0], 1658cabdff1aSopenharmony_ci s->sampleptrs[i][0], s->block_samples * 4); 1659cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][1], 1660cabdff1aSopenharmony_ci s->sampleptrs[i][1], s->block_samples * 4); 1661cabdff1aSopenharmony_ci } 1662cabdff1aSopenharmony_ci else 1663cabdff1aSopenharmony_ci break; 1664cabdff1aSopenharmony_ci } 1665cabdff1aSopenharmony_ci} 1666cabdff1aSopenharmony_ci 1667cabdff1aSopenharmony_cistatic void recurse_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info, 1668cabdff1aSopenharmony_ci int depth, int delta, uint32_t input_bits) 1669cabdff1aSopenharmony_ci{ 1670cabdff1aSopenharmony_ci int term, branches = s->num_branches - depth; 1671cabdff1aSopenharmony_ci int32_t *in_left, *in_right, *out_left, *out_right; 1672cabdff1aSopenharmony_ci uint32_t term_bits[22], bits; 1673cabdff1aSopenharmony_ci 1674cabdff1aSopenharmony_ci if (branches < 1 || depth + 1 == info->nterms) 1675cabdff1aSopenharmony_ci branches = 1; 1676cabdff1aSopenharmony_ci 1677cabdff1aSopenharmony_ci CLEAR(term_bits); 1678cabdff1aSopenharmony_ci in_left = s->sampleptrs[depth ][0]; 1679cabdff1aSopenharmony_ci in_right = s->sampleptrs[depth ][1]; 1680cabdff1aSopenharmony_ci out_left = s->sampleptrs[depth + 1][0]; 1681cabdff1aSopenharmony_ci out_right = s->sampleptrs[depth + 1][1]; 1682cabdff1aSopenharmony_ci 1683cabdff1aSopenharmony_ci for (term = -3; term <= 18; term++) { 1684cabdff1aSopenharmony_ci if (!term || (term > 8 && term < 17)) 1685cabdff1aSopenharmony_ci continue; 1686cabdff1aSopenharmony_ci 1687cabdff1aSopenharmony_ci if (term == 17 && branches == 1 && depth + 1 < info->nterms) 1688cabdff1aSopenharmony_ci continue; 1689cabdff1aSopenharmony_ci 1690cabdff1aSopenharmony_ci if (term == -1 || term == -2) 1691cabdff1aSopenharmony_ci if (!(s->flags & WV_CROSS_DECORR)) 1692cabdff1aSopenharmony_ci continue; 1693cabdff1aSopenharmony_ci 1694cabdff1aSopenharmony_ci if (!s->extra_flags && (term > 4 && term < 17)) 1695cabdff1aSopenharmony_ci continue; 1696cabdff1aSopenharmony_ci 1697cabdff1aSopenharmony_ci info->dps[depth].value = term; 1698cabdff1aSopenharmony_ci info->dps[depth].delta = delta; 1699cabdff1aSopenharmony_ci decorr_stereo_buffer(info, in_left, in_right, out_left, out_right, 1700cabdff1aSopenharmony_ci s->block_samples, depth); 1701cabdff1aSopenharmony_ci bits = log2stereo(out_left, out_right, s->block_samples, info->log_limit); 1702cabdff1aSopenharmony_ci 1703cabdff1aSopenharmony_ci if (bits < info->best_bits) { 1704cabdff1aSopenharmony_ci info->best_bits = bits; 1705cabdff1aSopenharmony_ci CLEAR(s->decorr_passes); 1706cabdff1aSopenharmony_ci memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * (depth + 1)); 1707cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[depth + 1][0], 1708cabdff1aSopenharmony_ci s->block_samples * 4); 1709cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info->nterms + 1][1], s->sampleptrs[depth + 1][1], 1710cabdff1aSopenharmony_ci s->block_samples * 4); 1711cabdff1aSopenharmony_ci } 1712cabdff1aSopenharmony_ci 1713cabdff1aSopenharmony_ci term_bits[term + 3] = bits; 1714cabdff1aSopenharmony_ci } 1715cabdff1aSopenharmony_ci 1716cabdff1aSopenharmony_ci while (depth + 1 < info->nterms && branches--) { 1717cabdff1aSopenharmony_ci uint32_t local_best_bits = input_bits; 1718cabdff1aSopenharmony_ci int best_term = 0, i; 1719cabdff1aSopenharmony_ci 1720cabdff1aSopenharmony_ci for (i = 0; i < 22; i++) 1721cabdff1aSopenharmony_ci if (term_bits[i] && term_bits[i] < local_best_bits) { 1722cabdff1aSopenharmony_ci local_best_bits = term_bits[i]; 1723cabdff1aSopenharmony_ci best_term = i - 3; 1724cabdff1aSopenharmony_ci } 1725cabdff1aSopenharmony_ci 1726cabdff1aSopenharmony_ci if (!best_term) 1727cabdff1aSopenharmony_ci break; 1728cabdff1aSopenharmony_ci 1729cabdff1aSopenharmony_ci term_bits[best_term + 3] = 0; 1730cabdff1aSopenharmony_ci 1731cabdff1aSopenharmony_ci info->dps[depth].value = best_term; 1732cabdff1aSopenharmony_ci info->dps[depth].delta = delta; 1733cabdff1aSopenharmony_ci decorr_stereo_buffer(info, in_left, in_right, out_left, out_right, 1734cabdff1aSopenharmony_ci s->block_samples, depth); 1735cabdff1aSopenharmony_ci 1736cabdff1aSopenharmony_ci recurse_stereo(s, info, depth + 1, delta, local_best_bits); 1737cabdff1aSopenharmony_ci } 1738cabdff1aSopenharmony_ci} 1739cabdff1aSopenharmony_ci 1740cabdff1aSopenharmony_cistatic void analyze_stereo(WavPackEncodeContext *s, 1741cabdff1aSopenharmony_ci int32_t *in_left, int32_t *in_right, 1742cabdff1aSopenharmony_ci int do_samples) 1743cabdff1aSopenharmony_ci{ 1744cabdff1aSopenharmony_ci WavPackExtraInfo info; 1745cabdff1aSopenharmony_ci int i; 1746cabdff1aSopenharmony_ci 1747cabdff1aSopenharmony_ci info.gt16bit = ((s->flags & MAG_MASK) >> MAG_LSB) >= 16; 1748cabdff1aSopenharmony_ci 1749cabdff1aSopenharmony_ci info.log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256; 1750cabdff1aSopenharmony_ci info.log_limit = FFMIN(6912, info.log_limit); 1751cabdff1aSopenharmony_ci 1752cabdff1aSopenharmony_ci info.nterms = s->num_terms; 1753cabdff1aSopenharmony_ci 1754cabdff1aSopenharmony_ci if (allocate_buffers2(s, s->num_terms)) 1755cabdff1aSopenharmony_ci return; 1756cabdff1aSopenharmony_ci 1757cabdff1aSopenharmony_ci memcpy(info.dps, s->decorr_passes, sizeof(info.dps)); 1758cabdff1aSopenharmony_ci memcpy(s->sampleptrs[0][0], in_left, s->block_samples * 4); 1759cabdff1aSopenharmony_ci memcpy(s->sampleptrs[0][1], in_right, s->block_samples * 4); 1760cabdff1aSopenharmony_ci 1761cabdff1aSopenharmony_ci for (i = 0; i < info.nterms && info.dps[i].value; i++) 1762cabdff1aSopenharmony_ci if (info.gt16bit) 1763cabdff1aSopenharmony_ci decorr_stereo(s->sampleptrs[i ][0], s->sampleptrs[i ][1], 1764cabdff1aSopenharmony_ci s->sampleptrs[i + 1][0], s->sampleptrs[i + 1][1], 1765cabdff1aSopenharmony_ci s->block_samples, info.dps + i, 1); 1766cabdff1aSopenharmony_ci else 1767cabdff1aSopenharmony_ci decorr_stereo_quick(s->sampleptrs[i ][0], s->sampleptrs[i ][1], 1768cabdff1aSopenharmony_ci s->sampleptrs[i + 1][0], s->sampleptrs[i + 1][1], 1769cabdff1aSopenharmony_ci s->block_samples, info.dps + i); 1770cabdff1aSopenharmony_ci 1771cabdff1aSopenharmony_ci info.best_bits = log2stereo(s->sampleptrs[info.nterms][0], s->sampleptrs[info.nterms][1], 1772cabdff1aSopenharmony_ci s->block_samples, 0); 1773cabdff1aSopenharmony_ci 1774cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info.nterms + 1][0], s->sampleptrs[i][0], s->block_samples * 4); 1775cabdff1aSopenharmony_ci memcpy(s->sampleptrs[info.nterms + 1][1], s->sampleptrs[i][1], s->block_samples * 4); 1776cabdff1aSopenharmony_ci 1777cabdff1aSopenharmony_ci if (s->extra_flags & EXTRA_BRANCHES) 1778cabdff1aSopenharmony_ci recurse_stereo(s, &info, 0, (int) floor(s->delta_decay + 0.5), 1779cabdff1aSopenharmony_ci log2stereo(s->sampleptrs[0][0], s->sampleptrs[0][1], 1780cabdff1aSopenharmony_ci s->block_samples, 0)); 1781cabdff1aSopenharmony_ci 1782cabdff1aSopenharmony_ci if (s->extra_flags & EXTRA_SORT_FIRST) 1783cabdff1aSopenharmony_ci sort_stereo(s, &info); 1784cabdff1aSopenharmony_ci 1785cabdff1aSopenharmony_ci if (s->extra_flags & EXTRA_TRY_DELTAS) { 1786cabdff1aSopenharmony_ci delta_stereo(s, &info); 1787cabdff1aSopenharmony_ci 1788cabdff1aSopenharmony_ci if ((s->extra_flags & EXTRA_ADJUST_DELTAS) && s->decorr_passes[0].value) 1789cabdff1aSopenharmony_ci s->delta_decay = (float)((s->delta_decay * 2.0 + s->decorr_passes[0].delta) / 3.0); 1790cabdff1aSopenharmony_ci else 1791cabdff1aSopenharmony_ci s->delta_decay = 2.0; 1792cabdff1aSopenharmony_ci } 1793cabdff1aSopenharmony_ci 1794cabdff1aSopenharmony_ci if (s->extra_flags & EXTRA_SORT_LAST) 1795cabdff1aSopenharmony_ci sort_stereo(s, &info); 1796cabdff1aSopenharmony_ci 1797cabdff1aSopenharmony_ci if (do_samples) { 1798cabdff1aSopenharmony_ci memcpy(in_left, s->sampleptrs[info.nterms + 1][0], s->block_samples * 4); 1799cabdff1aSopenharmony_ci memcpy(in_right, s->sampleptrs[info.nterms + 1][1], s->block_samples * 4); 1800cabdff1aSopenharmony_ci } 1801cabdff1aSopenharmony_ci 1802cabdff1aSopenharmony_ci for (i = 0; i < info.nterms; i++) 1803cabdff1aSopenharmony_ci if (!s->decorr_passes[i].value) 1804cabdff1aSopenharmony_ci break; 1805cabdff1aSopenharmony_ci 1806cabdff1aSopenharmony_ci s->num_terms = i; 1807cabdff1aSopenharmony_ci} 1808cabdff1aSopenharmony_ci 1809cabdff1aSopenharmony_cistatic int wv_stereo(WavPackEncodeContext *s, 1810cabdff1aSopenharmony_ci int32_t *samples_l, int32_t *samples_r, 1811cabdff1aSopenharmony_ci int no_history, int do_samples) 1812cabdff1aSopenharmony_ci{ 1813cabdff1aSopenharmony_ci struct Decorr temp_decorr_pass, save_decorr_passes[MAX_TERMS] = {{0}}; 1814cabdff1aSopenharmony_ci int nb_samples = s->block_samples, ret; 1815cabdff1aSopenharmony_ci int buf_size = sizeof(int32_t) * nb_samples; 1816cabdff1aSopenharmony_ci int log_limit, force_js = 0, force_ts = 0, got_js = 0, pi, i; 1817cabdff1aSopenharmony_ci uint32_t best_size = UINT32_MAX, size; 1818cabdff1aSopenharmony_ci 1819cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) 1820cabdff1aSopenharmony_ci if (samples_l[i] || samples_r[i]) 1821cabdff1aSopenharmony_ci break; 1822cabdff1aSopenharmony_ci 1823cabdff1aSopenharmony_ci if (i == nb_samples) { 1824cabdff1aSopenharmony_ci s->flags &= ~((uint32_t) WV_JOINT_STEREO); 1825cabdff1aSopenharmony_ci CLEAR(s->decorr_passes); 1826cabdff1aSopenharmony_ci CLEAR(s->w); 1827cabdff1aSopenharmony_ci s->num_terms = 0; 1828cabdff1aSopenharmony_ci return 0; 1829cabdff1aSopenharmony_ci } 1830cabdff1aSopenharmony_ci 1831cabdff1aSopenharmony_ci log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256; 1832cabdff1aSopenharmony_ci log_limit = FFMIN(6912, log_limit); 1833cabdff1aSopenharmony_ci 1834cabdff1aSopenharmony_ci if (s->joint != -1) { 1835cabdff1aSopenharmony_ci force_js = s->joint; 1836cabdff1aSopenharmony_ci force_ts = !s->joint; 1837cabdff1aSopenharmony_ci } 1838cabdff1aSopenharmony_ci 1839cabdff1aSopenharmony_ci if ((ret = allocate_buffers(s)) < 0) 1840cabdff1aSopenharmony_ci return ret; 1841cabdff1aSopenharmony_ci 1842cabdff1aSopenharmony_ci if (no_history || s->num_passes >= 7) 1843cabdff1aSopenharmony_ci s->best_decorr = s->mask_decorr = 0; 1844cabdff1aSopenharmony_ci 1845cabdff1aSopenharmony_ci for (pi = 0; pi < s->num_passes;) { 1846cabdff1aSopenharmony_ci const WavPackDecorrSpec *wpds; 1847cabdff1aSopenharmony_ci int nterms, c, j; 1848cabdff1aSopenharmony_ci 1849cabdff1aSopenharmony_ci if (!pi) 1850cabdff1aSopenharmony_ci c = s->best_decorr; 1851cabdff1aSopenharmony_ci else { 1852cabdff1aSopenharmony_ci if (s->mask_decorr == 0) 1853cabdff1aSopenharmony_ci c = 0; 1854cabdff1aSopenharmony_ci else 1855cabdff1aSopenharmony_ci c = (s->best_decorr & (s->mask_decorr - 1)) | s->mask_decorr; 1856cabdff1aSopenharmony_ci 1857cabdff1aSopenharmony_ci if (c == s->best_decorr) { 1858cabdff1aSopenharmony_ci s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1; 1859cabdff1aSopenharmony_ci continue; 1860cabdff1aSopenharmony_ci } 1861cabdff1aSopenharmony_ci } 1862cabdff1aSopenharmony_ci 1863cabdff1aSopenharmony_ci wpds = &s->decorr_specs[c]; 1864cabdff1aSopenharmony_ci nterms = decorr_filter_nterms[s->decorr_filter]; 1865cabdff1aSopenharmony_ci 1866cabdff1aSopenharmony_ci while (1) { 1867cabdff1aSopenharmony_ci if (force_js || (wpds->joint_stereo && !force_ts)) { 1868cabdff1aSopenharmony_ci if (!got_js) { 1869cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->js_left, &s->js_left_size, buf_size); 1870cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->js_right, &s->js_right_size, buf_size); 1871cabdff1aSopenharmony_ci memcpy(s->js_left, samples_l, buf_size); 1872cabdff1aSopenharmony_ci memcpy(s->js_right, samples_r, buf_size); 1873cabdff1aSopenharmony_ci 1874cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) 1875cabdff1aSopenharmony_ci s->js_right[i] += ((s->js_left[i] -= s->js_right[i]) >> 1); 1876cabdff1aSopenharmony_ci got_js = 1; 1877cabdff1aSopenharmony_ci } 1878cabdff1aSopenharmony_ci 1879cabdff1aSopenharmony_ci memcpy(s->temp_buffer[0][0], s->js_left, buf_size); 1880cabdff1aSopenharmony_ci memcpy(s->temp_buffer[0][1], s->js_right, buf_size); 1881cabdff1aSopenharmony_ci } else { 1882cabdff1aSopenharmony_ci memcpy(s->temp_buffer[0][0], samples_l, buf_size); 1883cabdff1aSopenharmony_ci memcpy(s->temp_buffer[0][1], samples_r, buf_size); 1884cabdff1aSopenharmony_ci } 1885cabdff1aSopenharmony_ci 1886cabdff1aSopenharmony_ci CLEAR(save_decorr_passes); 1887cabdff1aSopenharmony_ci 1888cabdff1aSopenharmony_ci for (j = 0; j < nterms; j++) { 1889cabdff1aSopenharmony_ci CLEAR(temp_decorr_pass); 1890cabdff1aSopenharmony_ci temp_decorr_pass.delta = wpds->delta; 1891cabdff1aSopenharmony_ci temp_decorr_pass.value = wpds->terms[j]; 1892cabdff1aSopenharmony_ci 1893cabdff1aSopenharmony_ci if (temp_decorr_pass.value < 0 && !(s->flags & WV_CROSS_DECORR)) 1894cabdff1aSopenharmony_ci temp_decorr_pass.value = -3; 1895cabdff1aSopenharmony_ci 1896cabdff1aSopenharmony_ci decorr_stereo(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1], 1897cabdff1aSopenharmony_ci s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1], 1898cabdff1aSopenharmony_ci FFMIN(2048, nb_samples), &temp_decorr_pass, -1); 1899cabdff1aSopenharmony_ci 1900cabdff1aSopenharmony_ci if (j) { 1901cabdff1aSopenharmony_ci CLEAR(temp_decorr_pass.samplesA); 1902cabdff1aSopenharmony_ci CLEAR(temp_decorr_pass.samplesB); 1903cabdff1aSopenharmony_ci } else { 1904cabdff1aSopenharmony_ci reverse_decorr(&temp_decorr_pass); 1905cabdff1aSopenharmony_ci } 1906cabdff1aSopenharmony_ci 1907cabdff1aSopenharmony_ci memcpy(save_decorr_passes + j, &temp_decorr_pass, sizeof(struct Decorr)); 1908cabdff1aSopenharmony_ci 1909cabdff1aSopenharmony_ci if (((s->flags & MAG_MASK) >> MAG_LSB) >= 16) 1910cabdff1aSopenharmony_ci decorr_stereo(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1], 1911cabdff1aSopenharmony_ci s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1], 1912cabdff1aSopenharmony_ci nb_samples, &temp_decorr_pass, 1); 1913cabdff1aSopenharmony_ci else 1914cabdff1aSopenharmony_ci decorr_stereo_quick(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1], 1915cabdff1aSopenharmony_ci s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1], 1916cabdff1aSopenharmony_ci nb_samples, &temp_decorr_pass); 1917cabdff1aSopenharmony_ci } 1918cabdff1aSopenharmony_ci 1919cabdff1aSopenharmony_ci size = log2stereo(s->temp_buffer[j&1][0], s->temp_buffer[j&1][1], 1920cabdff1aSopenharmony_ci nb_samples, log_limit); 1921cabdff1aSopenharmony_ci if (size != UINT32_MAX || !nterms) 1922cabdff1aSopenharmony_ci break; 1923cabdff1aSopenharmony_ci nterms >>= 1; 1924cabdff1aSopenharmony_ci } 1925cabdff1aSopenharmony_ci 1926cabdff1aSopenharmony_ci if (size < best_size) { 1927cabdff1aSopenharmony_ci memcpy(s->best_buffer[0], s->temp_buffer[j&1][0], buf_size); 1928cabdff1aSopenharmony_ci memcpy(s->best_buffer[1], s->temp_buffer[j&1][1], buf_size); 1929cabdff1aSopenharmony_ci memcpy(s->decorr_passes, save_decorr_passes, sizeof(struct Decorr) * MAX_TERMS); 1930cabdff1aSopenharmony_ci s->num_terms = nterms; 1931cabdff1aSopenharmony_ci s->best_decorr = c; 1932cabdff1aSopenharmony_ci best_size = size; 1933cabdff1aSopenharmony_ci } 1934cabdff1aSopenharmony_ci 1935cabdff1aSopenharmony_ci if (pi++) 1936cabdff1aSopenharmony_ci s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1; 1937cabdff1aSopenharmony_ci } 1938cabdff1aSopenharmony_ci 1939cabdff1aSopenharmony_ci if (force_js || (s->decorr_specs[s->best_decorr].joint_stereo && !force_ts)) 1940cabdff1aSopenharmony_ci s->flags |= WV_JOINT_STEREO; 1941cabdff1aSopenharmony_ci else 1942cabdff1aSopenharmony_ci s->flags &= ~((uint32_t) WV_JOINT_STEREO); 1943cabdff1aSopenharmony_ci 1944cabdff1aSopenharmony_ci if (s->extra_flags) { 1945cabdff1aSopenharmony_ci if (s->flags & WV_JOINT_STEREO) { 1946cabdff1aSopenharmony_ci analyze_stereo(s, s->js_left, s->js_right, do_samples); 1947cabdff1aSopenharmony_ci 1948cabdff1aSopenharmony_ci if (do_samples) { 1949cabdff1aSopenharmony_ci memcpy(samples_l, s->js_left, buf_size); 1950cabdff1aSopenharmony_ci memcpy(samples_r, s->js_right, buf_size); 1951cabdff1aSopenharmony_ci } 1952cabdff1aSopenharmony_ci } else 1953cabdff1aSopenharmony_ci analyze_stereo(s, samples_l, samples_r, do_samples); 1954cabdff1aSopenharmony_ci } else if (do_samples) { 1955cabdff1aSopenharmony_ci memcpy(samples_l, s->best_buffer[0], buf_size); 1956cabdff1aSopenharmony_ci memcpy(samples_r, s->best_buffer[1], buf_size); 1957cabdff1aSopenharmony_ci } 1958cabdff1aSopenharmony_ci 1959cabdff1aSopenharmony_ci if (s->extra_flags || no_history || 1960cabdff1aSopenharmony_ci s->joint_stereo != s->decorr_specs[s->best_decorr].joint_stereo) { 1961cabdff1aSopenharmony_ci s->joint_stereo = s->decorr_specs[s->best_decorr].joint_stereo; 1962cabdff1aSopenharmony_ci CLEAR(s->w); 1963cabdff1aSopenharmony_ci scan_word(s, &s->w.c[0], s->best_buffer[0], nb_samples, -1); 1964cabdff1aSopenharmony_ci scan_word(s, &s->w.c[1], s->best_buffer[1], nb_samples, -1); 1965cabdff1aSopenharmony_ci } 1966cabdff1aSopenharmony_ci return 0; 1967cabdff1aSopenharmony_ci} 1968cabdff1aSopenharmony_ci 1969cabdff1aSopenharmony_cistatic void encode_flush(WavPackEncodeContext *s) 1970cabdff1aSopenharmony_ci{ 1971cabdff1aSopenharmony_ci WavPackWords *w = &s->w; 1972cabdff1aSopenharmony_ci PutBitContext *pb = &s->pb; 1973cabdff1aSopenharmony_ci 1974cabdff1aSopenharmony_ci if (w->zeros_acc) { 1975cabdff1aSopenharmony_ci int cbits = count_bits(w->zeros_acc); 1976cabdff1aSopenharmony_ci 1977cabdff1aSopenharmony_ci do { 1978cabdff1aSopenharmony_ci if (cbits > 31) { 1979cabdff1aSopenharmony_ci put_bits(pb, 31, 0x7FFFFFFF); 1980cabdff1aSopenharmony_ci cbits -= 31; 1981cabdff1aSopenharmony_ci } else { 1982cabdff1aSopenharmony_ci put_bits(pb, cbits, (1U << cbits) - 1); 1983cabdff1aSopenharmony_ci cbits = 0; 1984cabdff1aSopenharmony_ci } 1985cabdff1aSopenharmony_ci } while (cbits); 1986cabdff1aSopenharmony_ci 1987cabdff1aSopenharmony_ci put_bits(pb, 1, 0); 1988cabdff1aSopenharmony_ci 1989cabdff1aSopenharmony_ci while (w->zeros_acc > 1) { 1990cabdff1aSopenharmony_ci put_bits(pb, 1, w->zeros_acc & 1); 1991cabdff1aSopenharmony_ci w->zeros_acc >>= 1; 1992cabdff1aSopenharmony_ci } 1993cabdff1aSopenharmony_ci 1994cabdff1aSopenharmony_ci w->zeros_acc = 0; 1995cabdff1aSopenharmony_ci } 1996cabdff1aSopenharmony_ci 1997cabdff1aSopenharmony_ci if (w->holding_one) { 1998cabdff1aSopenharmony_ci if (w->holding_one >= 16) { 1999cabdff1aSopenharmony_ci int cbits; 2000cabdff1aSopenharmony_ci 2001cabdff1aSopenharmony_ci put_bits(pb, 16, (1 << 16) - 1); 2002cabdff1aSopenharmony_ci put_bits(pb, 1, 0); 2003cabdff1aSopenharmony_ci w->holding_one -= 16; 2004cabdff1aSopenharmony_ci cbits = count_bits(w->holding_one); 2005cabdff1aSopenharmony_ci 2006cabdff1aSopenharmony_ci do { 2007cabdff1aSopenharmony_ci if (cbits > 31) { 2008cabdff1aSopenharmony_ci put_bits(pb, 31, 0x7FFFFFFF); 2009cabdff1aSopenharmony_ci cbits -= 31; 2010cabdff1aSopenharmony_ci } else { 2011cabdff1aSopenharmony_ci put_bits(pb, cbits, (1U << cbits) - 1); 2012cabdff1aSopenharmony_ci cbits = 0; 2013cabdff1aSopenharmony_ci } 2014cabdff1aSopenharmony_ci } while (cbits); 2015cabdff1aSopenharmony_ci 2016cabdff1aSopenharmony_ci put_bits(pb, 1, 0); 2017cabdff1aSopenharmony_ci 2018cabdff1aSopenharmony_ci while (w->holding_one > 1) { 2019cabdff1aSopenharmony_ci put_bits(pb, 1, w->holding_one & 1); 2020cabdff1aSopenharmony_ci w->holding_one >>= 1; 2021cabdff1aSopenharmony_ci } 2022cabdff1aSopenharmony_ci 2023cabdff1aSopenharmony_ci w->holding_zero = 0; 2024cabdff1aSopenharmony_ci } else { 2025cabdff1aSopenharmony_ci put_bits(pb, w->holding_one, (1 << w->holding_one) - 1); 2026cabdff1aSopenharmony_ci } 2027cabdff1aSopenharmony_ci 2028cabdff1aSopenharmony_ci w->holding_one = 0; 2029cabdff1aSopenharmony_ci } 2030cabdff1aSopenharmony_ci 2031cabdff1aSopenharmony_ci if (w->holding_zero) { 2032cabdff1aSopenharmony_ci put_bits(pb, 1, 0); 2033cabdff1aSopenharmony_ci w->holding_zero = 0; 2034cabdff1aSopenharmony_ci } 2035cabdff1aSopenharmony_ci 2036cabdff1aSopenharmony_ci if (w->pend_count) { 2037cabdff1aSopenharmony_ci put_bits(pb, w->pend_count, w->pend_data); 2038cabdff1aSopenharmony_ci w->pend_data = w->pend_count = 0; 2039cabdff1aSopenharmony_ci } 2040cabdff1aSopenharmony_ci} 2041cabdff1aSopenharmony_ci 2042cabdff1aSopenharmony_cistatic void wavpack_encode_sample(WavPackEncodeContext *s, WvChannel *c, int32_t sample) 2043cabdff1aSopenharmony_ci{ 2044cabdff1aSopenharmony_ci WavPackWords *w = &s->w; 2045cabdff1aSopenharmony_ci uint32_t ones_count, low, high; 2046cabdff1aSopenharmony_ci int sign = sample < 0; 2047cabdff1aSopenharmony_ci 2048cabdff1aSopenharmony_ci if (s->w.c[0].median[0] < 2 && !s->w.holding_zero && s->w.c[1].median[0] < 2) { 2049cabdff1aSopenharmony_ci if (w->zeros_acc) { 2050cabdff1aSopenharmony_ci if (sample) 2051cabdff1aSopenharmony_ci encode_flush(s); 2052cabdff1aSopenharmony_ci else { 2053cabdff1aSopenharmony_ci w->zeros_acc++; 2054cabdff1aSopenharmony_ci return; 2055cabdff1aSopenharmony_ci } 2056cabdff1aSopenharmony_ci } else if (sample) { 2057cabdff1aSopenharmony_ci put_bits(&s->pb, 1, 0); 2058cabdff1aSopenharmony_ci } else { 2059cabdff1aSopenharmony_ci CLEAR(s->w.c[0].median); 2060cabdff1aSopenharmony_ci CLEAR(s->w.c[1].median); 2061cabdff1aSopenharmony_ci w->zeros_acc = 1; 2062cabdff1aSopenharmony_ci return; 2063cabdff1aSopenharmony_ci } 2064cabdff1aSopenharmony_ci } 2065cabdff1aSopenharmony_ci 2066cabdff1aSopenharmony_ci if (sign) 2067cabdff1aSopenharmony_ci sample = ~sample; 2068cabdff1aSopenharmony_ci 2069cabdff1aSopenharmony_ci if (sample < (int32_t) GET_MED(0)) { 2070cabdff1aSopenharmony_ci ones_count = low = 0; 2071cabdff1aSopenharmony_ci high = GET_MED(0) - 1; 2072cabdff1aSopenharmony_ci DEC_MED(0); 2073cabdff1aSopenharmony_ci } else { 2074cabdff1aSopenharmony_ci low = GET_MED(0); 2075cabdff1aSopenharmony_ci INC_MED(0); 2076cabdff1aSopenharmony_ci 2077cabdff1aSopenharmony_ci if (sample - low < GET_MED(1)) { 2078cabdff1aSopenharmony_ci ones_count = 1; 2079cabdff1aSopenharmony_ci high = low + GET_MED(1) - 1; 2080cabdff1aSopenharmony_ci DEC_MED(1); 2081cabdff1aSopenharmony_ci } else { 2082cabdff1aSopenharmony_ci low += GET_MED(1); 2083cabdff1aSopenharmony_ci INC_MED(1); 2084cabdff1aSopenharmony_ci 2085cabdff1aSopenharmony_ci if (sample - low < GET_MED(2)) { 2086cabdff1aSopenharmony_ci ones_count = 2; 2087cabdff1aSopenharmony_ci high = low + GET_MED(2) - 1; 2088cabdff1aSopenharmony_ci DEC_MED(2); 2089cabdff1aSopenharmony_ci } else { 2090cabdff1aSopenharmony_ci ones_count = 2 + (sample - low) / GET_MED(2); 2091cabdff1aSopenharmony_ci low += (ones_count - 2) * GET_MED(2); 2092cabdff1aSopenharmony_ci high = low + GET_MED(2) - 1; 2093cabdff1aSopenharmony_ci INC_MED(2); 2094cabdff1aSopenharmony_ci } 2095cabdff1aSopenharmony_ci } 2096cabdff1aSopenharmony_ci } 2097cabdff1aSopenharmony_ci 2098cabdff1aSopenharmony_ci if (w->holding_zero) { 2099cabdff1aSopenharmony_ci if (ones_count) 2100cabdff1aSopenharmony_ci w->holding_one++; 2101cabdff1aSopenharmony_ci 2102cabdff1aSopenharmony_ci encode_flush(s); 2103cabdff1aSopenharmony_ci 2104cabdff1aSopenharmony_ci if (ones_count) { 2105cabdff1aSopenharmony_ci w->holding_zero = 1; 2106cabdff1aSopenharmony_ci ones_count--; 2107cabdff1aSopenharmony_ci } else 2108cabdff1aSopenharmony_ci w->holding_zero = 0; 2109cabdff1aSopenharmony_ci } else 2110cabdff1aSopenharmony_ci w->holding_zero = 1; 2111cabdff1aSopenharmony_ci 2112cabdff1aSopenharmony_ci w->holding_one = ones_count * 2; 2113cabdff1aSopenharmony_ci 2114cabdff1aSopenharmony_ci if (high != low) { 2115cabdff1aSopenharmony_ci uint32_t maxcode = high - low, code = sample - low; 2116cabdff1aSopenharmony_ci int bitcount = count_bits(maxcode); 2117cabdff1aSopenharmony_ci uint32_t extras = (1 << bitcount) - maxcode - 1; 2118cabdff1aSopenharmony_ci 2119cabdff1aSopenharmony_ci if (code < extras) { 2120cabdff1aSopenharmony_ci w->pend_data |= code << w->pend_count; 2121cabdff1aSopenharmony_ci w->pend_count += bitcount - 1; 2122cabdff1aSopenharmony_ci } else { 2123cabdff1aSopenharmony_ci w->pend_data |= ((code + extras) >> 1) << w->pend_count; 2124cabdff1aSopenharmony_ci w->pend_count += bitcount - 1; 2125cabdff1aSopenharmony_ci w->pend_data |= ((code + extras) & 1) << w->pend_count++; 2126cabdff1aSopenharmony_ci } 2127cabdff1aSopenharmony_ci } 2128cabdff1aSopenharmony_ci 2129cabdff1aSopenharmony_ci w->pend_data |= ((int32_t) sign << w->pend_count++); 2130cabdff1aSopenharmony_ci 2131cabdff1aSopenharmony_ci if (!w->holding_zero) 2132cabdff1aSopenharmony_ci encode_flush(s); 2133cabdff1aSopenharmony_ci} 2134cabdff1aSopenharmony_ci 2135cabdff1aSopenharmony_cistatic void pack_int32(WavPackEncodeContext *s, 2136cabdff1aSopenharmony_ci int32_t *samples_l, int32_t *samples_r, 2137cabdff1aSopenharmony_ci int nb_samples) 2138cabdff1aSopenharmony_ci{ 2139cabdff1aSopenharmony_ci const int sent_bits = s->int32_sent_bits; 2140cabdff1aSopenharmony_ci PutBitContext *pb = &s->pb; 2141cabdff1aSopenharmony_ci int i, pre_shift; 2142cabdff1aSopenharmony_ci 2143cabdff1aSopenharmony_ci pre_shift = s->int32_zeros + s->int32_ones + s->int32_dups; 2144cabdff1aSopenharmony_ci 2145cabdff1aSopenharmony_ci if (!sent_bits) 2146cabdff1aSopenharmony_ci return; 2147cabdff1aSopenharmony_ci 2148cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) { 2149cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2150cabdff1aSopenharmony_ci put_sbits(pb, sent_bits, samples_l[i] >> pre_shift); 2151cabdff1aSopenharmony_ci } 2152cabdff1aSopenharmony_ci } else { 2153cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2154cabdff1aSopenharmony_ci put_sbits(pb, sent_bits, samples_l[i] >> pre_shift); 2155cabdff1aSopenharmony_ci put_sbits(pb, sent_bits, samples_r[i] >> pre_shift); 2156cabdff1aSopenharmony_ci } 2157cabdff1aSopenharmony_ci } 2158cabdff1aSopenharmony_ci} 2159cabdff1aSopenharmony_ci 2160cabdff1aSopenharmony_cistatic void pack_float_sample(WavPackEncodeContext *s, int32_t *sample) 2161cabdff1aSopenharmony_ci{ 2162cabdff1aSopenharmony_ci const int max_exp = s->float_max_exp; 2163cabdff1aSopenharmony_ci PutBitContext *pb = &s->pb; 2164cabdff1aSopenharmony_ci int32_t value, shift_count; 2165cabdff1aSopenharmony_ci 2166cabdff1aSopenharmony_ci if (get_exponent(*sample) == 255) { 2167cabdff1aSopenharmony_ci if (get_mantissa(*sample)) { 2168cabdff1aSopenharmony_ci put_bits(pb, 1, 1); 2169cabdff1aSopenharmony_ci put_bits(pb, 23, get_mantissa(*sample)); 2170cabdff1aSopenharmony_ci } else { 2171cabdff1aSopenharmony_ci put_bits(pb, 1, 0); 2172cabdff1aSopenharmony_ci } 2173cabdff1aSopenharmony_ci 2174cabdff1aSopenharmony_ci value = 0x1000000; 2175cabdff1aSopenharmony_ci shift_count = 0; 2176cabdff1aSopenharmony_ci } else if (get_exponent(*sample)) { 2177cabdff1aSopenharmony_ci shift_count = max_exp - get_exponent(*sample); 2178cabdff1aSopenharmony_ci value = 0x800000 + get_mantissa(*sample); 2179cabdff1aSopenharmony_ci } else { 2180cabdff1aSopenharmony_ci shift_count = max_exp ? max_exp - 1 : 0; 2181cabdff1aSopenharmony_ci value = get_mantissa(*sample); 2182cabdff1aSopenharmony_ci } 2183cabdff1aSopenharmony_ci 2184cabdff1aSopenharmony_ci if (shift_count < 25) 2185cabdff1aSopenharmony_ci value >>= shift_count; 2186cabdff1aSopenharmony_ci else 2187cabdff1aSopenharmony_ci value = 0; 2188cabdff1aSopenharmony_ci 2189cabdff1aSopenharmony_ci if (!value) { 2190cabdff1aSopenharmony_ci if (s->float_flags & FLOAT_ZEROS_SENT) { 2191cabdff1aSopenharmony_ci if (get_exponent(*sample) || get_mantissa(*sample)) { 2192cabdff1aSopenharmony_ci put_bits(pb, 1, 1); 2193cabdff1aSopenharmony_ci put_bits(pb, 23, get_mantissa(*sample)); 2194cabdff1aSopenharmony_ci 2195cabdff1aSopenharmony_ci if (max_exp >= 25) 2196cabdff1aSopenharmony_ci put_bits(pb, 8, get_exponent(*sample)); 2197cabdff1aSopenharmony_ci 2198cabdff1aSopenharmony_ci put_bits(pb, 1, get_sign(*sample)); 2199cabdff1aSopenharmony_ci } else { 2200cabdff1aSopenharmony_ci put_bits(pb, 1, 0); 2201cabdff1aSopenharmony_ci 2202cabdff1aSopenharmony_ci if (s->float_flags & FLOAT_NEG_ZEROS) 2203cabdff1aSopenharmony_ci put_bits(pb, 1, get_sign(*sample)); 2204cabdff1aSopenharmony_ci } 2205cabdff1aSopenharmony_ci } 2206cabdff1aSopenharmony_ci } else if (shift_count) { 2207cabdff1aSopenharmony_ci if (s->float_flags & FLOAT_SHIFT_SENT) { 2208cabdff1aSopenharmony_ci put_sbits(pb, shift_count, get_mantissa(*sample)); 2209cabdff1aSopenharmony_ci } else if (s->float_flags & FLOAT_SHIFT_SAME) { 2210cabdff1aSopenharmony_ci put_bits(pb, 1, get_mantissa(*sample) & 1); 2211cabdff1aSopenharmony_ci } 2212cabdff1aSopenharmony_ci } 2213cabdff1aSopenharmony_ci} 2214cabdff1aSopenharmony_ci 2215cabdff1aSopenharmony_cistatic void pack_float(WavPackEncodeContext *s, 2216cabdff1aSopenharmony_ci int32_t *samples_l, int32_t *samples_r, 2217cabdff1aSopenharmony_ci int nb_samples) 2218cabdff1aSopenharmony_ci{ 2219cabdff1aSopenharmony_ci int i; 2220cabdff1aSopenharmony_ci 2221cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) { 2222cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) 2223cabdff1aSopenharmony_ci pack_float_sample(s, &samples_l[i]); 2224cabdff1aSopenharmony_ci } else { 2225cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2226cabdff1aSopenharmony_ci pack_float_sample(s, &samples_l[i]); 2227cabdff1aSopenharmony_ci pack_float_sample(s, &samples_r[i]); 2228cabdff1aSopenharmony_ci } 2229cabdff1aSopenharmony_ci } 2230cabdff1aSopenharmony_ci} 2231cabdff1aSopenharmony_ci 2232cabdff1aSopenharmony_cistatic void decorr_stereo_pass2(struct Decorr *dpp, 2233cabdff1aSopenharmony_ci int32_t *samples_l, int32_t *samples_r, 2234cabdff1aSopenharmony_ci int nb_samples) 2235cabdff1aSopenharmony_ci{ 2236cabdff1aSopenharmony_ci int i, m, k; 2237cabdff1aSopenharmony_ci 2238cabdff1aSopenharmony_ci switch (dpp->value) { 2239cabdff1aSopenharmony_ci case 17: 2240cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2241cabdff1aSopenharmony_ci int32_t sam, tmp; 2242cabdff1aSopenharmony_ci 2243cabdff1aSopenharmony_ci sam = 2 * dpp->samplesA[0] - dpp->samplesA[1]; 2244cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 2245cabdff1aSopenharmony_ci samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam); 2246cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp); 2247cabdff1aSopenharmony_ci 2248cabdff1aSopenharmony_ci sam = 2 * dpp->samplesB[0] - dpp->samplesB[1]; 2249cabdff1aSopenharmony_ci dpp->samplesB[1] = dpp->samplesB[0]; 2250cabdff1aSopenharmony_ci samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam); 2251cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp); 2252cabdff1aSopenharmony_ci } 2253cabdff1aSopenharmony_ci break; 2254cabdff1aSopenharmony_ci case 18: 2255cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2256cabdff1aSopenharmony_ci int32_t sam, tmp; 2257cabdff1aSopenharmony_ci 2258cabdff1aSopenharmony_ci sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1); 2259cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 2260cabdff1aSopenharmony_ci samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam); 2261cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp); 2262cabdff1aSopenharmony_ci 2263cabdff1aSopenharmony_ci sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1); 2264cabdff1aSopenharmony_ci dpp->samplesB[1] = dpp->samplesB[0]; 2265cabdff1aSopenharmony_ci samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam); 2266cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp); 2267cabdff1aSopenharmony_ci } 2268cabdff1aSopenharmony_ci break; 2269cabdff1aSopenharmony_ci default: 2270cabdff1aSopenharmony_ci for (m = 0, k = dpp->value & (MAX_TERM - 1), i = 0; i < nb_samples; i++) { 2271cabdff1aSopenharmony_ci int32_t sam, tmp; 2272cabdff1aSopenharmony_ci 2273cabdff1aSopenharmony_ci sam = dpp->samplesA[m]; 2274cabdff1aSopenharmony_ci samples_l[i] = tmp = (dpp->samplesA[k] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam); 2275cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp); 2276cabdff1aSopenharmony_ci 2277cabdff1aSopenharmony_ci sam = dpp->samplesB[m]; 2278cabdff1aSopenharmony_ci samples_r[i] = tmp = (dpp->samplesB[k] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam); 2279cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp); 2280cabdff1aSopenharmony_ci 2281cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 2282cabdff1aSopenharmony_ci k = (k + 1) & (MAX_TERM - 1); 2283cabdff1aSopenharmony_ci } 2284cabdff1aSopenharmony_ci if (m) { 2285cabdff1aSopenharmony_ci int32_t temp_A[MAX_TERM], temp_B[MAX_TERM]; 2286cabdff1aSopenharmony_ci 2287cabdff1aSopenharmony_ci memcpy(temp_A, dpp->samplesA, sizeof (dpp->samplesA)); 2288cabdff1aSopenharmony_ci memcpy(temp_B, dpp->samplesB, sizeof (dpp->samplesB)); 2289cabdff1aSopenharmony_ci 2290cabdff1aSopenharmony_ci for (k = 0; k < MAX_TERM; k++) { 2291cabdff1aSopenharmony_ci dpp->samplesA[k] = temp_A[m]; 2292cabdff1aSopenharmony_ci dpp->samplesB[k] = temp_B[m]; 2293cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 2294cabdff1aSopenharmony_ci } 2295cabdff1aSopenharmony_ci } 2296cabdff1aSopenharmony_ci break; 2297cabdff1aSopenharmony_ci case -1: 2298cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2299cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 2300cabdff1aSopenharmony_ci 2301cabdff1aSopenharmony_ci sam_A = dpp->samplesA[0]; 2302cabdff1aSopenharmony_ci samples_l[i] = tmp = (sam_B = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam_A); 2303cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp); 2304cabdff1aSopenharmony_ci 2305cabdff1aSopenharmony_ci samples_r[i] = tmp = (dpp->samplesA[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam_B); 2306cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp); 2307cabdff1aSopenharmony_ci } 2308cabdff1aSopenharmony_ci break; 2309cabdff1aSopenharmony_ci case -2: 2310cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2311cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 2312cabdff1aSopenharmony_ci 2313cabdff1aSopenharmony_ci sam_B = dpp->samplesB[0]; 2314cabdff1aSopenharmony_ci samples_r[i] = tmp = (sam_A = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam_B); 2315cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp); 2316cabdff1aSopenharmony_ci 2317cabdff1aSopenharmony_ci samples_l[i] = tmp = (dpp->samplesB[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam_A); 2318cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp); 2319cabdff1aSopenharmony_ci } 2320cabdff1aSopenharmony_ci break; 2321cabdff1aSopenharmony_ci case -3: 2322cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2323cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 2324cabdff1aSopenharmony_ci 2325cabdff1aSopenharmony_ci sam_A = dpp->samplesA[0]; 2326cabdff1aSopenharmony_ci sam_B = dpp->samplesB[0]; 2327cabdff1aSopenharmony_ci 2328cabdff1aSopenharmony_ci dpp->samplesA[0] = tmp = samples_r[i]; 2329cabdff1aSopenharmony_ci samples_r[i] = tmp -= APPLY_WEIGHT(dpp->weightB, sam_B); 2330cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp); 2331cabdff1aSopenharmony_ci 2332cabdff1aSopenharmony_ci dpp->samplesB[0] = tmp = samples_l[i]; 2333cabdff1aSopenharmony_ci samples_l[i] = tmp -= APPLY_WEIGHT(dpp->weightA, sam_A); 2334cabdff1aSopenharmony_ci UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp); 2335cabdff1aSopenharmony_ci } 2336cabdff1aSopenharmony_ci break; 2337cabdff1aSopenharmony_ci } 2338cabdff1aSopenharmony_ci} 2339cabdff1aSopenharmony_ci 2340cabdff1aSopenharmony_ci#define update_weight_d2(weight, delta, source, result) \ 2341cabdff1aSopenharmony_ci if (source && result) \ 2342cabdff1aSopenharmony_ci weight -= (((source ^ result) >> 29) & 4) - 2; 2343cabdff1aSopenharmony_ci 2344cabdff1aSopenharmony_ci#define update_weight_clip_d2(weight, delta, source, result) \ 2345cabdff1aSopenharmony_ci if (source && result) { \ 2346cabdff1aSopenharmony_ci const int32_t s = (source ^ result) >> 31; \ 2347cabdff1aSopenharmony_ci if ((weight = (weight ^ s) + (2 - s)) > 1024) weight = 1024; \ 2348cabdff1aSopenharmony_ci weight = (weight ^ s) - s; \ 2349cabdff1aSopenharmony_ci } 2350cabdff1aSopenharmony_ci 2351cabdff1aSopenharmony_cistatic void decorr_stereo_pass_id2(struct Decorr *dpp, 2352cabdff1aSopenharmony_ci int32_t *samples_l, int32_t *samples_r, 2353cabdff1aSopenharmony_ci int nb_samples) 2354cabdff1aSopenharmony_ci{ 2355cabdff1aSopenharmony_ci int i, m, k; 2356cabdff1aSopenharmony_ci 2357cabdff1aSopenharmony_ci switch (dpp->value) { 2358cabdff1aSopenharmony_ci case 17: 2359cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2360cabdff1aSopenharmony_ci int32_t sam, tmp; 2361cabdff1aSopenharmony_ci 2362cabdff1aSopenharmony_ci sam = 2 * dpp->samplesA[0] - dpp->samplesA[1]; 2363cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 2364cabdff1aSopenharmony_ci samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam); 2365cabdff1aSopenharmony_ci update_weight_d2(dpp->weightA, dpp->delta, sam, tmp); 2366cabdff1aSopenharmony_ci 2367cabdff1aSopenharmony_ci sam = 2 * dpp->samplesB[0] - dpp->samplesB[1]; 2368cabdff1aSopenharmony_ci dpp->samplesB[1] = dpp->samplesB[0]; 2369cabdff1aSopenharmony_ci samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam); 2370cabdff1aSopenharmony_ci update_weight_d2(dpp->weightB, dpp->delta, sam, tmp); 2371cabdff1aSopenharmony_ci } 2372cabdff1aSopenharmony_ci break; 2373cabdff1aSopenharmony_ci case 18: 2374cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2375cabdff1aSopenharmony_ci int32_t sam, tmp; 2376cabdff1aSopenharmony_ci 2377cabdff1aSopenharmony_ci sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1); 2378cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 2379cabdff1aSopenharmony_ci samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam); 2380cabdff1aSopenharmony_ci update_weight_d2(dpp->weightA, dpp->delta, sam, tmp); 2381cabdff1aSopenharmony_ci 2382cabdff1aSopenharmony_ci sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1); 2383cabdff1aSopenharmony_ci dpp->samplesB[1] = dpp->samplesB[0]; 2384cabdff1aSopenharmony_ci samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam); 2385cabdff1aSopenharmony_ci update_weight_d2(dpp->weightB, dpp->delta, sam, tmp); 2386cabdff1aSopenharmony_ci } 2387cabdff1aSopenharmony_ci break; 2388cabdff1aSopenharmony_ci default: 2389cabdff1aSopenharmony_ci for (m = 0, k = dpp->value & (MAX_TERM - 1), i = 0; i < nb_samples; i++) { 2390cabdff1aSopenharmony_ci int32_t sam, tmp; 2391cabdff1aSopenharmony_ci 2392cabdff1aSopenharmony_ci sam = dpp->samplesA[m]; 2393cabdff1aSopenharmony_ci samples_l[i] = tmp = (dpp->samplesA[k] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam); 2394cabdff1aSopenharmony_ci update_weight_d2(dpp->weightA, dpp->delta, sam, tmp); 2395cabdff1aSopenharmony_ci 2396cabdff1aSopenharmony_ci sam = dpp->samplesB[m]; 2397cabdff1aSopenharmony_ci samples_r[i] = tmp = (dpp->samplesB[k] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam); 2398cabdff1aSopenharmony_ci update_weight_d2(dpp->weightB, dpp->delta, sam, tmp); 2399cabdff1aSopenharmony_ci 2400cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 2401cabdff1aSopenharmony_ci k = (k + 1) & (MAX_TERM - 1); 2402cabdff1aSopenharmony_ci } 2403cabdff1aSopenharmony_ci 2404cabdff1aSopenharmony_ci if (m) { 2405cabdff1aSopenharmony_ci int32_t temp_A[MAX_TERM], temp_B[MAX_TERM]; 2406cabdff1aSopenharmony_ci 2407cabdff1aSopenharmony_ci memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA)); 2408cabdff1aSopenharmony_ci memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB)); 2409cabdff1aSopenharmony_ci 2410cabdff1aSopenharmony_ci for (k = 0; k < MAX_TERM; k++) { 2411cabdff1aSopenharmony_ci dpp->samplesA[k] = temp_A[m]; 2412cabdff1aSopenharmony_ci dpp->samplesB[k] = temp_B[m]; 2413cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 2414cabdff1aSopenharmony_ci } 2415cabdff1aSopenharmony_ci } 2416cabdff1aSopenharmony_ci break; 2417cabdff1aSopenharmony_ci case -1: 2418cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2419cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 2420cabdff1aSopenharmony_ci 2421cabdff1aSopenharmony_ci sam_A = dpp->samplesA[0]; 2422cabdff1aSopenharmony_ci samples_l[i] = tmp = (sam_B = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A); 2423cabdff1aSopenharmony_ci update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp); 2424cabdff1aSopenharmony_ci 2425cabdff1aSopenharmony_ci samples_r[i] = tmp = (dpp->samplesA[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B); 2426cabdff1aSopenharmony_ci update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp); 2427cabdff1aSopenharmony_ci } 2428cabdff1aSopenharmony_ci break; 2429cabdff1aSopenharmony_ci case -2: 2430cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2431cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 2432cabdff1aSopenharmony_ci 2433cabdff1aSopenharmony_ci sam_B = dpp->samplesB[0]; 2434cabdff1aSopenharmony_ci samples_r[i] = tmp = (sam_A = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B); 2435cabdff1aSopenharmony_ci update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp); 2436cabdff1aSopenharmony_ci 2437cabdff1aSopenharmony_ci samples_l[i] = tmp = (dpp->samplesB[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A); 2438cabdff1aSopenharmony_ci update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp); 2439cabdff1aSopenharmony_ci } 2440cabdff1aSopenharmony_ci break; 2441cabdff1aSopenharmony_ci case -3: 2442cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2443cabdff1aSopenharmony_ci int32_t sam_A, sam_B, tmp; 2444cabdff1aSopenharmony_ci 2445cabdff1aSopenharmony_ci sam_A = dpp->samplesA[0]; 2446cabdff1aSopenharmony_ci sam_B = dpp->samplesB[0]; 2447cabdff1aSopenharmony_ci 2448cabdff1aSopenharmony_ci dpp->samplesA[0] = tmp = samples_r[i]; 2449cabdff1aSopenharmony_ci samples_r[i] = tmp -= APPLY_WEIGHT_I(dpp->weightB, sam_B); 2450cabdff1aSopenharmony_ci update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp); 2451cabdff1aSopenharmony_ci 2452cabdff1aSopenharmony_ci dpp->samplesB[0] = tmp = samples_l[i]; 2453cabdff1aSopenharmony_ci samples_l[i] = tmp -= APPLY_WEIGHT_I(dpp->weightA, sam_A); 2454cabdff1aSopenharmony_ci update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp); 2455cabdff1aSopenharmony_ci } 2456cabdff1aSopenharmony_ci break; 2457cabdff1aSopenharmony_ci } 2458cabdff1aSopenharmony_ci} 2459cabdff1aSopenharmony_ci 2460cabdff1aSopenharmony_cistatic void put_metadata_block(PutByteContext *pb, int flags, int size) 2461cabdff1aSopenharmony_ci{ 2462cabdff1aSopenharmony_ci if (size & 1) 2463cabdff1aSopenharmony_ci flags |= WP_IDF_ODD; 2464cabdff1aSopenharmony_ci 2465cabdff1aSopenharmony_ci bytestream2_put_byte(pb, flags); 2466cabdff1aSopenharmony_ci bytestream2_put_byte(pb, (size + 1) >> 1); 2467cabdff1aSopenharmony_ci} 2468cabdff1aSopenharmony_ci 2469cabdff1aSopenharmony_cistatic int wavpack_encode_block(WavPackEncodeContext *s, 2470cabdff1aSopenharmony_ci int32_t *samples_l, int32_t *samples_r, 2471cabdff1aSopenharmony_ci uint8_t *out, int out_size) 2472cabdff1aSopenharmony_ci{ 2473cabdff1aSopenharmony_ci int block_size, start, end, data_size, tcount, temp, m = 0; 2474cabdff1aSopenharmony_ci int i, j, ret = 0, got_extra = 0, nb_samples = s->block_samples; 2475cabdff1aSopenharmony_ci uint32_t crc = 0xffffffffu; 2476cabdff1aSopenharmony_ci struct Decorr *dpp; 2477cabdff1aSopenharmony_ci PutByteContext pb; 2478cabdff1aSopenharmony_ci 2479cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) { 2480cabdff1aSopenharmony_ci CLEAR(s->w); 2481cabdff1aSopenharmony_ci } 2482cabdff1aSopenharmony_ci if (!(s->flags & WV_MONO) && s->optimize_mono) { 2483cabdff1aSopenharmony_ci int32_t lor = 0, diff = 0; 2484cabdff1aSopenharmony_ci 2485cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2486cabdff1aSopenharmony_ci lor |= samples_l[i] | samples_r[i]; 2487cabdff1aSopenharmony_ci diff |= samples_l[i] - samples_r[i]; 2488cabdff1aSopenharmony_ci 2489cabdff1aSopenharmony_ci if (lor && diff) 2490cabdff1aSopenharmony_ci break; 2491cabdff1aSopenharmony_ci } 2492cabdff1aSopenharmony_ci 2493cabdff1aSopenharmony_ci if (i == nb_samples && lor && !diff) { 2494cabdff1aSopenharmony_ci s->flags &= ~(WV_JOINT_STEREO | WV_CROSS_DECORR); 2495cabdff1aSopenharmony_ci s->flags |= WV_FALSE_STEREO; 2496cabdff1aSopenharmony_ci 2497cabdff1aSopenharmony_ci if (!s->false_stereo) { 2498cabdff1aSopenharmony_ci s->false_stereo = 1; 2499cabdff1aSopenharmony_ci s->num_terms = 0; 2500cabdff1aSopenharmony_ci CLEAR(s->w); 2501cabdff1aSopenharmony_ci } 2502cabdff1aSopenharmony_ci } else if (s->false_stereo) { 2503cabdff1aSopenharmony_ci s->false_stereo = 0; 2504cabdff1aSopenharmony_ci s->num_terms = 0; 2505cabdff1aSopenharmony_ci CLEAR(s->w); 2506cabdff1aSopenharmony_ci } 2507cabdff1aSopenharmony_ci } 2508cabdff1aSopenharmony_ci 2509cabdff1aSopenharmony_ci if (s->flags & SHIFT_MASK) { 2510cabdff1aSopenharmony_ci int shift = (s->flags & SHIFT_MASK) >> SHIFT_LSB; 2511cabdff1aSopenharmony_ci int mag = (s->flags & MAG_MASK) >> MAG_LSB; 2512cabdff1aSopenharmony_ci 2513cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) 2514cabdff1aSopenharmony_ci shift_mono(samples_l, nb_samples, shift); 2515cabdff1aSopenharmony_ci else 2516cabdff1aSopenharmony_ci shift_stereo(samples_l, samples_r, nb_samples, shift); 2517cabdff1aSopenharmony_ci 2518cabdff1aSopenharmony_ci if ((mag -= shift) < 0) 2519cabdff1aSopenharmony_ci s->flags &= ~MAG_MASK; 2520cabdff1aSopenharmony_ci else 2521cabdff1aSopenharmony_ci s->flags -= (1 << MAG_LSB) * shift; 2522cabdff1aSopenharmony_ci } 2523cabdff1aSopenharmony_ci 2524cabdff1aSopenharmony_ci if ((s->flags & WV_FLOAT_DATA) || (s->flags & MAG_MASK) >> MAG_LSB >= 24) { 2525cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->orig_l, &s->orig_l_size, sizeof(int32_t) * nb_samples); 2526cabdff1aSopenharmony_ci memcpy(s->orig_l, samples_l, sizeof(int32_t) * nb_samples); 2527cabdff1aSopenharmony_ci if (!(s->flags & WV_MONO_DATA)) { 2528cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->orig_r, &s->orig_r_size, sizeof(int32_t) * nb_samples); 2529cabdff1aSopenharmony_ci memcpy(s->orig_r, samples_r, sizeof(int32_t) * nb_samples); 2530cabdff1aSopenharmony_ci } 2531cabdff1aSopenharmony_ci 2532cabdff1aSopenharmony_ci if (s->flags & WV_FLOAT_DATA) 2533cabdff1aSopenharmony_ci got_extra = scan_float(s, samples_l, samples_r, nb_samples); 2534cabdff1aSopenharmony_ci else 2535cabdff1aSopenharmony_ci got_extra = scan_int32(s, samples_l, samples_r, nb_samples); 2536cabdff1aSopenharmony_ci s->num_terms = 0; 2537cabdff1aSopenharmony_ci } else { 2538cabdff1aSopenharmony_ci scan_int23(s, samples_l, samples_r, nb_samples); 2539cabdff1aSopenharmony_ci if (s->shift != s->int32_zeros + s->int32_ones + s->int32_dups) { 2540cabdff1aSopenharmony_ci s->shift = s->int32_zeros + s->int32_ones + s->int32_dups; 2541cabdff1aSopenharmony_ci s->num_terms = 0; 2542cabdff1aSopenharmony_ci } 2543cabdff1aSopenharmony_ci } 2544cabdff1aSopenharmony_ci 2545cabdff1aSopenharmony_ci if (!s->num_passes && !s->num_terms) { 2546cabdff1aSopenharmony_ci s->num_passes = 1; 2547cabdff1aSopenharmony_ci 2548cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) 2549cabdff1aSopenharmony_ci ret = wv_mono(s, samples_l, 1, 0); 2550cabdff1aSopenharmony_ci else 2551cabdff1aSopenharmony_ci ret = wv_stereo(s, samples_l, samples_r, 1, 0); 2552cabdff1aSopenharmony_ci 2553cabdff1aSopenharmony_ci s->num_passes = 0; 2554cabdff1aSopenharmony_ci } 2555cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) { 2556cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) 2557cabdff1aSopenharmony_ci crc += (crc << 1) + samples_l[i]; 2558cabdff1aSopenharmony_ci 2559cabdff1aSopenharmony_ci if (s->num_passes) 2560cabdff1aSopenharmony_ci ret = wv_mono(s, samples_l, !s->num_terms, 1); 2561cabdff1aSopenharmony_ci } else { 2562cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) 2563cabdff1aSopenharmony_ci crc += (crc << 3) + ((uint32_t)samples_l[i] << 1) + samples_l[i] + samples_r[i]; 2564cabdff1aSopenharmony_ci 2565cabdff1aSopenharmony_ci if (s->num_passes) 2566cabdff1aSopenharmony_ci ret = wv_stereo(s, samples_l, samples_r, !s->num_terms, 1); 2567cabdff1aSopenharmony_ci } 2568cabdff1aSopenharmony_ci if (ret < 0) 2569cabdff1aSopenharmony_ci return ret; 2570cabdff1aSopenharmony_ci 2571cabdff1aSopenharmony_ci if (!s->ch_offset) 2572cabdff1aSopenharmony_ci s->flags |= WV_INITIAL_BLOCK; 2573cabdff1aSopenharmony_ci 2574cabdff1aSopenharmony_ci s->ch_offset += 1 + !(s->flags & WV_MONO); 2575cabdff1aSopenharmony_ci 2576cabdff1aSopenharmony_ci if (s->ch_offset == s->avctx->ch_layout.nb_channels) 2577cabdff1aSopenharmony_ci s->flags |= WV_FINAL_BLOCK; 2578cabdff1aSopenharmony_ci 2579cabdff1aSopenharmony_ci bytestream2_init_writer(&pb, out, out_size); 2580cabdff1aSopenharmony_ci bytestream2_put_le32(&pb, MKTAG('w', 'v', 'p', 'k')); 2581cabdff1aSopenharmony_ci bytestream2_put_le32(&pb, 0); 2582cabdff1aSopenharmony_ci bytestream2_put_le16(&pb, 0x410); 2583cabdff1aSopenharmony_ci bytestream2_put_le16(&pb, 0); 2584cabdff1aSopenharmony_ci bytestream2_put_le32(&pb, 0); 2585cabdff1aSopenharmony_ci bytestream2_put_le32(&pb, s->sample_index); 2586cabdff1aSopenharmony_ci bytestream2_put_le32(&pb, nb_samples); 2587cabdff1aSopenharmony_ci bytestream2_put_le32(&pb, s->flags); 2588cabdff1aSopenharmony_ci bytestream2_put_le32(&pb, crc); 2589cabdff1aSopenharmony_ci 2590cabdff1aSopenharmony_ci if (s->flags & WV_INITIAL_BLOCK && 2591cabdff1aSopenharmony_ci s->avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE && 2592cabdff1aSopenharmony_ci s->avctx->ch_layout.u.mask != AV_CH_LAYOUT_MONO && 2593cabdff1aSopenharmony_ci s->avctx->ch_layout.u.mask != AV_CH_LAYOUT_STEREO) { 2594cabdff1aSopenharmony_ci put_metadata_block(&pb, WP_ID_CHANINFO, 5); 2595cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, s->avctx->ch_layout.nb_channels); 2596cabdff1aSopenharmony_ci bytestream2_put_le32(&pb, s->avctx->ch_layout.u.mask); 2597cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, 0); 2598cabdff1aSopenharmony_ci } 2599cabdff1aSopenharmony_ci 2600cabdff1aSopenharmony_ci if ((s->flags & SRATE_MASK) == SRATE_MASK) { 2601cabdff1aSopenharmony_ci put_metadata_block(&pb, WP_ID_SAMPLE_RATE, 3); 2602cabdff1aSopenharmony_ci bytestream2_put_le24(&pb, s->avctx->sample_rate); 2603cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, 0); 2604cabdff1aSopenharmony_ci } 2605cabdff1aSopenharmony_ci 2606cabdff1aSopenharmony_ci put_metadata_block(&pb, WP_ID_DECTERMS, s->num_terms); 2607cabdff1aSopenharmony_ci for (i = 0; i < s->num_terms; i++) { 2608cabdff1aSopenharmony_ci struct Decorr *dpp = &s->decorr_passes[i]; 2609cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, ((dpp->value + 5) & 0x1f) | ((dpp->delta << 5) & 0xe0)); 2610cabdff1aSopenharmony_ci } 2611cabdff1aSopenharmony_ci if (s->num_terms & 1) 2612cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, 0); 2613cabdff1aSopenharmony_ci 2614cabdff1aSopenharmony_ci#define WRITE_DECWEIGHT(type) do { \ 2615cabdff1aSopenharmony_ci temp = store_weight(type); \ 2616cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, temp); \ 2617cabdff1aSopenharmony_ci type = restore_weight(temp); \ 2618cabdff1aSopenharmony_ci } while (0) 2619cabdff1aSopenharmony_ci 2620cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, WP_ID_DECWEIGHTS); 2621cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, 0); 2622cabdff1aSopenharmony_ci start = bytestream2_tell_p(&pb); 2623cabdff1aSopenharmony_ci for (i = s->num_terms - 1; i >= 0; --i) { 2624cabdff1aSopenharmony_ci struct Decorr *dpp = &s->decorr_passes[i]; 2625cabdff1aSopenharmony_ci 2626cabdff1aSopenharmony_ci if (store_weight(dpp->weightA) || 2627cabdff1aSopenharmony_ci (!(s->flags & WV_MONO_DATA) && store_weight(dpp->weightB))) 2628cabdff1aSopenharmony_ci break; 2629cabdff1aSopenharmony_ci } 2630cabdff1aSopenharmony_ci tcount = i + 1; 2631cabdff1aSopenharmony_ci for (i = 0; i < s->num_terms; i++) { 2632cabdff1aSopenharmony_ci struct Decorr *dpp = &s->decorr_passes[i]; 2633cabdff1aSopenharmony_ci if (i < tcount) { 2634cabdff1aSopenharmony_ci WRITE_DECWEIGHT(dpp->weightA); 2635cabdff1aSopenharmony_ci if (!(s->flags & WV_MONO_DATA)) 2636cabdff1aSopenharmony_ci WRITE_DECWEIGHT(dpp->weightB); 2637cabdff1aSopenharmony_ci } else { 2638cabdff1aSopenharmony_ci dpp->weightA = dpp->weightB = 0; 2639cabdff1aSopenharmony_ci } 2640cabdff1aSopenharmony_ci } 2641cabdff1aSopenharmony_ci end = bytestream2_tell_p(&pb); 2642cabdff1aSopenharmony_ci out[start - 2] = WP_ID_DECWEIGHTS | (((end - start) & 1) ? WP_IDF_ODD: 0); 2643cabdff1aSopenharmony_ci out[start - 1] = (end - start + 1) >> 1; 2644cabdff1aSopenharmony_ci if ((end - start) & 1) 2645cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, 0); 2646cabdff1aSopenharmony_ci 2647cabdff1aSopenharmony_ci#define WRITE_DECSAMPLE(type) do { \ 2648cabdff1aSopenharmony_ci temp = log2s(type); \ 2649cabdff1aSopenharmony_ci type = wp_exp2(temp); \ 2650cabdff1aSopenharmony_ci bytestream2_put_le16(&pb, temp); \ 2651cabdff1aSopenharmony_ci } while (0) 2652cabdff1aSopenharmony_ci 2653cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, WP_ID_DECSAMPLES); 2654cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, 0); 2655cabdff1aSopenharmony_ci start = bytestream2_tell_p(&pb); 2656cabdff1aSopenharmony_ci for (i = 0; i < s->num_terms; i++) { 2657cabdff1aSopenharmony_ci struct Decorr *dpp = &s->decorr_passes[i]; 2658cabdff1aSopenharmony_ci if (i == 0) { 2659cabdff1aSopenharmony_ci if (dpp->value > MAX_TERM) { 2660cabdff1aSopenharmony_ci WRITE_DECSAMPLE(dpp->samplesA[0]); 2661cabdff1aSopenharmony_ci WRITE_DECSAMPLE(dpp->samplesA[1]); 2662cabdff1aSopenharmony_ci if (!(s->flags & WV_MONO_DATA)) { 2663cabdff1aSopenharmony_ci WRITE_DECSAMPLE(dpp->samplesB[0]); 2664cabdff1aSopenharmony_ci WRITE_DECSAMPLE(dpp->samplesB[1]); 2665cabdff1aSopenharmony_ci } 2666cabdff1aSopenharmony_ci } else if (dpp->value < 0) { 2667cabdff1aSopenharmony_ci WRITE_DECSAMPLE(dpp->samplesA[0]); 2668cabdff1aSopenharmony_ci WRITE_DECSAMPLE(dpp->samplesB[0]); 2669cabdff1aSopenharmony_ci } else { 2670cabdff1aSopenharmony_ci for (j = 0; j < dpp->value; j++) { 2671cabdff1aSopenharmony_ci WRITE_DECSAMPLE(dpp->samplesA[j]); 2672cabdff1aSopenharmony_ci if (!(s->flags & WV_MONO_DATA)) 2673cabdff1aSopenharmony_ci WRITE_DECSAMPLE(dpp->samplesB[j]); 2674cabdff1aSopenharmony_ci } 2675cabdff1aSopenharmony_ci } 2676cabdff1aSopenharmony_ci } else { 2677cabdff1aSopenharmony_ci CLEAR(dpp->samplesA); 2678cabdff1aSopenharmony_ci CLEAR(dpp->samplesB); 2679cabdff1aSopenharmony_ci } 2680cabdff1aSopenharmony_ci } 2681cabdff1aSopenharmony_ci end = bytestream2_tell_p(&pb); 2682cabdff1aSopenharmony_ci out[start - 1] = (end - start) >> 1; 2683cabdff1aSopenharmony_ci 2684cabdff1aSopenharmony_ci#define WRITE_CHAN_ENTROPY(chan) do { \ 2685cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) { \ 2686cabdff1aSopenharmony_ci temp = wp_log2(s->w.c[chan].median[i]); \ 2687cabdff1aSopenharmony_ci bytestream2_put_le16(&pb, temp); \ 2688cabdff1aSopenharmony_ci s->w.c[chan].median[i] = wp_exp2(temp); \ 2689cabdff1aSopenharmony_ci } \ 2690cabdff1aSopenharmony_ci } while (0) 2691cabdff1aSopenharmony_ci 2692cabdff1aSopenharmony_ci put_metadata_block(&pb, WP_ID_ENTROPY, 6 * (1 + (!(s->flags & WV_MONO_DATA)))); 2693cabdff1aSopenharmony_ci WRITE_CHAN_ENTROPY(0); 2694cabdff1aSopenharmony_ci if (!(s->flags & WV_MONO_DATA)) 2695cabdff1aSopenharmony_ci WRITE_CHAN_ENTROPY(1); 2696cabdff1aSopenharmony_ci 2697cabdff1aSopenharmony_ci if (s->flags & WV_FLOAT_DATA) { 2698cabdff1aSopenharmony_ci put_metadata_block(&pb, WP_ID_FLOATINFO, 4); 2699cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, s->float_flags); 2700cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, s->float_shift); 2701cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, s->float_max_exp); 2702cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, 127); 2703cabdff1aSopenharmony_ci } 2704cabdff1aSopenharmony_ci 2705cabdff1aSopenharmony_ci if (s->flags & WV_INT32_DATA) { 2706cabdff1aSopenharmony_ci put_metadata_block(&pb, WP_ID_INT32INFO, 4); 2707cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, s->int32_sent_bits); 2708cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, s->int32_zeros); 2709cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, s->int32_ones); 2710cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, s->int32_dups); 2711cabdff1aSopenharmony_ci } 2712cabdff1aSopenharmony_ci 2713cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA && !s->num_passes) { 2714cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2715cabdff1aSopenharmony_ci int32_t code = samples_l[i]; 2716cabdff1aSopenharmony_ci 2717cabdff1aSopenharmony_ci for (tcount = s->num_terms, dpp = s->decorr_passes; tcount--; dpp++) { 2718cabdff1aSopenharmony_ci int32_t sam; 2719cabdff1aSopenharmony_ci 2720cabdff1aSopenharmony_ci if (dpp->value > MAX_TERM) { 2721cabdff1aSopenharmony_ci if (dpp->value & 1) 2722cabdff1aSopenharmony_ci sam = 2 * dpp->samplesA[0] - dpp->samplesA[1]; 2723cabdff1aSopenharmony_ci else 2724cabdff1aSopenharmony_ci sam = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1; 2725cabdff1aSopenharmony_ci 2726cabdff1aSopenharmony_ci dpp->samplesA[1] = dpp->samplesA[0]; 2727cabdff1aSopenharmony_ci dpp->samplesA[0] = code; 2728cabdff1aSopenharmony_ci } else { 2729cabdff1aSopenharmony_ci sam = dpp->samplesA[m]; 2730cabdff1aSopenharmony_ci dpp->samplesA[(m + dpp->value) & (MAX_TERM - 1)] = code; 2731cabdff1aSopenharmony_ci } 2732cabdff1aSopenharmony_ci 2733cabdff1aSopenharmony_ci code -= APPLY_WEIGHT(dpp->weightA, sam); 2734cabdff1aSopenharmony_ci UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, code); 2735cabdff1aSopenharmony_ci } 2736cabdff1aSopenharmony_ci 2737cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 2738cabdff1aSopenharmony_ci samples_l[i] = code; 2739cabdff1aSopenharmony_ci } 2740cabdff1aSopenharmony_ci if (m) { 2741cabdff1aSopenharmony_ci for (tcount = s->num_terms, dpp = s->decorr_passes; tcount--; dpp++) 2742cabdff1aSopenharmony_ci if (dpp->value > 0 && dpp->value <= MAX_TERM) { 2743cabdff1aSopenharmony_ci int32_t temp_A[MAX_TERM], temp_B[MAX_TERM]; 2744cabdff1aSopenharmony_ci int k; 2745cabdff1aSopenharmony_ci 2746cabdff1aSopenharmony_ci memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA)); 2747cabdff1aSopenharmony_ci memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB)); 2748cabdff1aSopenharmony_ci 2749cabdff1aSopenharmony_ci for (k = 0; k < MAX_TERM; k++) { 2750cabdff1aSopenharmony_ci dpp->samplesA[k] = temp_A[m]; 2751cabdff1aSopenharmony_ci dpp->samplesB[k] = temp_B[m]; 2752cabdff1aSopenharmony_ci m = (m + 1) & (MAX_TERM - 1); 2753cabdff1aSopenharmony_ci } 2754cabdff1aSopenharmony_ci } 2755cabdff1aSopenharmony_ci } 2756cabdff1aSopenharmony_ci } else if (!s->num_passes) { 2757cabdff1aSopenharmony_ci if (s->flags & WV_JOINT_STEREO) { 2758cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) 2759cabdff1aSopenharmony_ci samples_r[i] += ((samples_l[i] -= samples_r[i]) >> 1); 2760cabdff1aSopenharmony_ci } 2761cabdff1aSopenharmony_ci 2762cabdff1aSopenharmony_ci for (i = 0; i < s->num_terms; i++) { 2763cabdff1aSopenharmony_ci struct Decorr *dpp = &s->decorr_passes[i]; 2764cabdff1aSopenharmony_ci if (((s->flags & MAG_MASK) >> MAG_LSB) >= 16 || dpp->delta != 2) 2765cabdff1aSopenharmony_ci decorr_stereo_pass2(dpp, samples_l, samples_r, nb_samples); 2766cabdff1aSopenharmony_ci else 2767cabdff1aSopenharmony_ci decorr_stereo_pass_id2(dpp, samples_l, samples_r, nb_samples); 2768cabdff1aSopenharmony_ci } 2769cabdff1aSopenharmony_ci } 2770cabdff1aSopenharmony_ci 2771cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, WP_ID_DATA | WP_IDF_LONG); 2772cabdff1aSopenharmony_ci init_put_bits(&s->pb, pb.buffer + 3, bytestream2_get_bytes_left_p(&pb)); 2773cabdff1aSopenharmony_ci if (s->flags & WV_MONO_DATA) { 2774cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) 2775cabdff1aSopenharmony_ci wavpack_encode_sample(s, &s->w.c[0], s->samples[0][i]); 2776cabdff1aSopenharmony_ci } else { 2777cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) { 2778cabdff1aSopenharmony_ci wavpack_encode_sample(s, &s->w.c[0], s->samples[0][i]); 2779cabdff1aSopenharmony_ci wavpack_encode_sample(s, &s->w.c[1], s->samples[1][i]); 2780cabdff1aSopenharmony_ci } 2781cabdff1aSopenharmony_ci } 2782cabdff1aSopenharmony_ci encode_flush(s); 2783cabdff1aSopenharmony_ci flush_put_bits(&s->pb); 2784cabdff1aSopenharmony_ci data_size = put_bytes_output(&s->pb); 2785cabdff1aSopenharmony_ci bytestream2_put_le24(&pb, (data_size + 1) >> 1); 2786cabdff1aSopenharmony_ci bytestream2_skip_p(&pb, data_size); 2787cabdff1aSopenharmony_ci if (data_size & 1) 2788cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, 0); 2789cabdff1aSopenharmony_ci 2790cabdff1aSopenharmony_ci if (got_extra) { 2791cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, WP_ID_EXTRABITS | WP_IDF_LONG); 2792cabdff1aSopenharmony_ci init_put_bits(&s->pb, pb.buffer + 7, bytestream2_get_bytes_left_p(&pb)); 2793cabdff1aSopenharmony_ci if (s->flags & WV_FLOAT_DATA) 2794cabdff1aSopenharmony_ci pack_float(s, s->orig_l, s->orig_r, nb_samples); 2795cabdff1aSopenharmony_ci else 2796cabdff1aSopenharmony_ci pack_int32(s, s->orig_l, s->orig_r, nb_samples); 2797cabdff1aSopenharmony_ci flush_put_bits(&s->pb); 2798cabdff1aSopenharmony_ci data_size = put_bytes_output(&s->pb); 2799cabdff1aSopenharmony_ci bytestream2_put_le24(&pb, (data_size + 5) >> 1); 2800cabdff1aSopenharmony_ci bytestream2_put_le32(&pb, s->crc_x); 2801cabdff1aSopenharmony_ci bytestream2_skip_p(&pb, data_size); 2802cabdff1aSopenharmony_ci if (data_size & 1) 2803cabdff1aSopenharmony_ci bytestream2_put_byte(&pb, 0); 2804cabdff1aSopenharmony_ci } 2805cabdff1aSopenharmony_ci 2806cabdff1aSopenharmony_ci block_size = bytestream2_tell_p(&pb); 2807cabdff1aSopenharmony_ci AV_WL32(out + 4, block_size - 8); 2808cabdff1aSopenharmony_ci 2809cabdff1aSopenharmony_ci av_assert0(!bytestream2_get_eof(&pb)); 2810cabdff1aSopenharmony_ci 2811cabdff1aSopenharmony_ci return block_size; 2812cabdff1aSopenharmony_ci} 2813cabdff1aSopenharmony_ci 2814cabdff1aSopenharmony_cistatic void fill_buffer(WavPackEncodeContext *s, 2815cabdff1aSopenharmony_ci const int8_t *src, int32_t *dst, 2816cabdff1aSopenharmony_ci int nb_samples) 2817cabdff1aSopenharmony_ci{ 2818cabdff1aSopenharmony_ci int i; 2819cabdff1aSopenharmony_ci 2820cabdff1aSopenharmony_ci#define COPY_SAMPLES(type, offset, shift) do { \ 2821cabdff1aSopenharmony_ci const type *sptr = (const type *)src; \ 2822cabdff1aSopenharmony_ci for (i = 0; i < nb_samples; i++) \ 2823cabdff1aSopenharmony_ci dst[i] = (sptr[i] - offset) >> shift; \ 2824cabdff1aSopenharmony_ci } while (0) 2825cabdff1aSopenharmony_ci 2826cabdff1aSopenharmony_ci switch (s->avctx->sample_fmt) { 2827cabdff1aSopenharmony_ci case AV_SAMPLE_FMT_U8P: 2828cabdff1aSopenharmony_ci COPY_SAMPLES(int8_t, 0x80, 0); 2829cabdff1aSopenharmony_ci break; 2830cabdff1aSopenharmony_ci case AV_SAMPLE_FMT_S16P: 2831cabdff1aSopenharmony_ci COPY_SAMPLES(int16_t, 0, 0); 2832cabdff1aSopenharmony_ci break; 2833cabdff1aSopenharmony_ci case AV_SAMPLE_FMT_S32P: 2834cabdff1aSopenharmony_ci if (s->avctx->bits_per_raw_sample <= 24) { 2835cabdff1aSopenharmony_ci COPY_SAMPLES(int32_t, 0, 8); 2836cabdff1aSopenharmony_ci break; 2837cabdff1aSopenharmony_ci } 2838cabdff1aSopenharmony_ci case AV_SAMPLE_FMT_FLTP: 2839cabdff1aSopenharmony_ci memcpy(dst, src, nb_samples * 4); 2840cabdff1aSopenharmony_ci } 2841cabdff1aSopenharmony_ci} 2842cabdff1aSopenharmony_ci 2843cabdff1aSopenharmony_cistatic void set_samplerate(WavPackEncodeContext *s) 2844cabdff1aSopenharmony_ci{ 2845cabdff1aSopenharmony_ci int i; 2846cabdff1aSopenharmony_ci 2847cabdff1aSopenharmony_ci for (i = 0; i < 15; i++) { 2848cabdff1aSopenharmony_ci if (wv_rates[i] == s->avctx->sample_rate) 2849cabdff1aSopenharmony_ci break; 2850cabdff1aSopenharmony_ci } 2851cabdff1aSopenharmony_ci 2852cabdff1aSopenharmony_ci s->flags = i << SRATE_LSB; 2853cabdff1aSopenharmony_ci} 2854cabdff1aSopenharmony_ci 2855cabdff1aSopenharmony_cistatic int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, 2856cabdff1aSopenharmony_ci const AVFrame *frame, int *got_packet_ptr) 2857cabdff1aSopenharmony_ci{ 2858cabdff1aSopenharmony_ci WavPackEncodeContext *s = avctx->priv_data; 2859cabdff1aSopenharmony_ci int buf_size, ret; 2860cabdff1aSopenharmony_ci uint8_t *buf; 2861cabdff1aSopenharmony_ci 2862cabdff1aSopenharmony_ci s->block_samples = frame->nb_samples; 2863cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->samples[0], &s->samples_size[0], 2864cabdff1aSopenharmony_ci sizeof(int32_t) * s->block_samples); 2865cabdff1aSopenharmony_ci if (!s->samples[0]) 2866cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 2867cabdff1aSopenharmony_ci if (avctx->ch_layout.nb_channels > 1) { 2868cabdff1aSopenharmony_ci av_fast_padded_malloc(&s->samples[1], &s->samples_size[1], 2869cabdff1aSopenharmony_ci sizeof(int32_t) * s->block_samples); 2870cabdff1aSopenharmony_ci if (!s->samples[1]) 2871cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 2872cabdff1aSopenharmony_ci } 2873cabdff1aSopenharmony_ci 2874cabdff1aSopenharmony_ci buf_size = s->block_samples * avctx->ch_layout.nb_channels * 8 2875cabdff1aSopenharmony_ci + 200 * avctx->ch_layout.nb_channels /* for headers */; 2876cabdff1aSopenharmony_ci if ((ret = ff_alloc_packet(avctx, avpkt, buf_size)) < 0) 2877cabdff1aSopenharmony_ci return ret; 2878cabdff1aSopenharmony_ci buf = avpkt->data; 2879cabdff1aSopenharmony_ci 2880cabdff1aSopenharmony_ci for (s->ch_offset = 0; s->ch_offset < avctx->ch_layout.nb_channels;) { 2881cabdff1aSopenharmony_ci set_samplerate(s); 2882cabdff1aSopenharmony_ci 2883cabdff1aSopenharmony_ci switch (s->avctx->sample_fmt) { 2884cabdff1aSopenharmony_ci case AV_SAMPLE_FMT_S16P: s->flags |= 1; break; 2885cabdff1aSopenharmony_ci case AV_SAMPLE_FMT_S32P: s->flags |= 3 - (s->avctx->bits_per_raw_sample <= 24); break; 2886cabdff1aSopenharmony_ci case AV_SAMPLE_FMT_FLTP: s->flags |= 3 | WV_FLOAT_DATA; 2887cabdff1aSopenharmony_ci } 2888cabdff1aSopenharmony_ci 2889cabdff1aSopenharmony_ci fill_buffer(s, frame->extended_data[s->ch_offset], s->samples[0], s->block_samples); 2890cabdff1aSopenharmony_ci if (avctx->ch_layout.nb_channels - s->ch_offset == 1) { 2891cabdff1aSopenharmony_ci s->flags |= WV_MONO; 2892cabdff1aSopenharmony_ci } else { 2893cabdff1aSopenharmony_ci s->flags |= WV_CROSS_DECORR; 2894cabdff1aSopenharmony_ci fill_buffer(s, frame->extended_data[s->ch_offset + 1], s->samples[1], s->block_samples); 2895cabdff1aSopenharmony_ci } 2896cabdff1aSopenharmony_ci 2897cabdff1aSopenharmony_ci s->flags += (1 << MAG_LSB) * ((s->flags & 3) * 8 + 7); 2898cabdff1aSopenharmony_ci 2899cabdff1aSopenharmony_ci if ((ret = wavpack_encode_block(s, s->samples[0], s->samples[1], 2900cabdff1aSopenharmony_ci buf, buf_size)) < 0) 2901cabdff1aSopenharmony_ci return ret; 2902cabdff1aSopenharmony_ci 2903cabdff1aSopenharmony_ci buf += ret; 2904cabdff1aSopenharmony_ci buf_size -= ret; 2905cabdff1aSopenharmony_ci } 2906cabdff1aSopenharmony_ci s->sample_index += frame->nb_samples; 2907cabdff1aSopenharmony_ci 2908cabdff1aSopenharmony_ci avpkt->pts = frame->pts; 2909cabdff1aSopenharmony_ci avpkt->size = buf - avpkt->data; 2910cabdff1aSopenharmony_ci avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples); 2911cabdff1aSopenharmony_ci *got_packet_ptr = 1; 2912cabdff1aSopenharmony_ci return 0; 2913cabdff1aSopenharmony_ci} 2914cabdff1aSopenharmony_ci 2915cabdff1aSopenharmony_cistatic av_cold int wavpack_encode_close(AVCodecContext *avctx) 2916cabdff1aSopenharmony_ci{ 2917cabdff1aSopenharmony_ci WavPackEncodeContext *s = avctx->priv_data; 2918cabdff1aSopenharmony_ci int i; 2919cabdff1aSopenharmony_ci 2920cabdff1aSopenharmony_ci for (i = 0; i < MAX_TERMS + 2; i++) { 2921cabdff1aSopenharmony_ci av_freep(&s->sampleptrs[i][0]); 2922cabdff1aSopenharmony_ci av_freep(&s->sampleptrs[i][1]); 2923cabdff1aSopenharmony_ci s->sampleptrs_size[i][0] = s->sampleptrs_size[i][1] = 0; 2924cabdff1aSopenharmony_ci } 2925cabdff1aSopenharmony_ci 2926cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) { 2927cabdff1aSopenharmony_ci av_freep(&s->samples[i]); 2928cabdff1aSopenharmony_ci s->samples_size[i] = 0; 2929cabdff1aSopenharmony_ci 2930cabdff1aSopenharmony_ci av_freep(&s->best_buffer[i]); 2931cabdff1aSopenharmony_ci s->best_buffer_size[i] = 0; 2932cabdff1aSopenharmony_ci 2933cabdff1aSopenharmony_ci av_freep(&s->temp_buffer[i][0]); 2934cabdff1aSopenharmony_ci av_freep(&s->temp_buffer[i][1]); 2935cabdff1aSopenharmony_ci s->temp_buffer_size[i][0] = s->temp_buffer_size[i][1] = 0; 2936cabdff1aSopenharmony_ci } 2937cabdff1aSopenharmony_ci 2938cabdff1aSopenharmony_ci av_freep(&s->js_left); 2939cabdff1aSopenharmony_ci av_freep(&s->js_right); 2940cabdff1aSopenharmony_ci s->js_left_size = s->js_right_size = 0; 2941cabdff1aSopenharmony_ci 2942cabdff1aSopenharmony_ci av_freep(&s->orig_l); 2943cabdff1aSopenharmony_ci av_freep(&s->orig_r); 2944cabdff1aSopenharmony_ci s->orig_l_size = s->orig_r_size = 0; 2945cabdff1aSopenharmony_ci 2946cabdff1aSopenharmony_ci return 0; 2947cabdff1aSopenharmony_ci} 2948cabdff1aSopenharmony_ci 2949cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(WavPackEncodeContext, x) 2950cabdff1aSopenharmony_ci#define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM 2951cabdff1aSopenharmony_cistatic const AVOption options[] = { 2952cabdff1aSopenharmony_ci { "joint_stereo", "", OFFSET(joint), AV_OPT_TYPE_BOOL, {.i64=-1}, -1, 1, FLAGS }, 2953cabdff1aSopenharmony_ci { "optimize_mono", "", OFFSET(optimize_mono), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS }, 2954cabdff1aSopenharmony_ci { NULL }, 2955cabdff1aSopenharmony_ci}; 2956cabdff1aSopenharmony_ci 2957cabdff1aSopenharmony_cistatic const AVClass wavpack_encoder_class = { 2958cabdff1aSopenharmony_ci .class_name = "WavPack encoder", 2959cabdff1aSopenharmony_ci .item_name = av_default_item_name, 2960cabdff1aSopenharmony_ci .option = options, 2961cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 2962cabdff1aSopenharmony_ci}; 2963cabdff1aSopenharmony_ci 2964cabdff1aSopenharmony_ciconst FFCodec ff_wavpack_encoder = { 2965cabdff1aSopenharmony_ci .p.name = "wavpack", 2966cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("WavPack"), 2967cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 2968cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_WAVPACK, 2969cabdff1aSopenharmony_ci .priv_data_size = sizeof(WavPackEncodeContext), 2970cabdff1aSopenharmony_ci .p.priv_class = &wavpack_encoder_class, 2971cabdff1aSopenharmony_ci .init = wavpack_encode_init, 2972cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(wavpack_encode_frame), 2973cabdff1aSopenharmony_ci .close = wavpack_encode_close, 2974cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME, 2975cabdff1aSopenharmony_ci .p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_U8P, 2976cabdff1aSopenharmony_ci AV_SAMPLE_FMT_S16P, 2977cabdff1aSopenharmony_ci AV_SAMPLE_FMT_S32P, 2978cabdff1aSopenharmony_ci AV_SAMPLE_FMT_FLTP, 2979cabdff1aSopenharmony_ci AV_SAMPLE_FMT_NONE }, 2980cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 2981cabdff1aSopenharmony_ci}; 2982