1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * WMA compatible encoder 3cabdff1aSopenharmony_ci * Copyright (c) 2007 Michael Niedermayer 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include "config_components.h" 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 25cabdff1aSopenharmony_ci#include "libavutil/ffmath.h" 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci#include "avcodec.h" 28cabdff1aSopenharmony_ci#include "codec_internal.h" 29cabdff1aSopenharmony_ci#include "encode.h" 30cabdff1aSopenharmony_ci#include "internal.h" 31cabdff1aSopenharmony_ci#include "wma.h" 32cabdff1aSopenharmony_ci#include "libavutil/avassert.h" 33cabdff1aSopenharmony_ci 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_cistatic av_cold int encode_init(AVCodecContext *avctx) 36cabdff1aSopenharmony_ci{ 37cabdff1aSopenharmony_ci WMACodecContext *s = avctx->priv_data; 38cabdff1aSopenharmony_ci int i, flags1, flags2, block_align; 39cabdff1aSopenharmony_ci uint8_t *extradata; 40cabdff1aSopenharmony_ci int ret; 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_ci s->avctx = avctx; 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_ci if (avctx->ch_layout.nb_channels > MAX_CHANNELS) { 45cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 46cabdff1aSopenharmony_ci "too many channels: got %i, need %i or fewer\n", 47cabdff1aSopenharmony_ci avctx->ch_layout.nb_channels, MAX_CHANNELS); 48cabdff1aSopenharmony_ci return AVERROR(EINVAL); 49cabdff1aSopenharmony_ci } 50cabdff1aSopenharmony_ci 51cabdff1aSopenharmony_ci if (avctx->sample_rate > 48000) { 52cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "sample rate is too high: %d > 48kHz\n", 53cabdff1aSopenharmony_ci avctx->sample_rate); 54cabdff1aSopenharmony_ci return AVERROR(EINVAL); 55cabdff1aSopenharmony_ci } 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_ci if (avctx->bit_rate < 24 * 1000) { 58cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, 59cabdff1aSopenharmony_ci "bitrate too low: got %"PRId64", need 24000 or higher\n", 60cabdff1aSopenharmony_ci avctx->bit_rate); 61cabdff1aSopenharmony_ci return AVERROR(EINVAL); 62cabdff1aSopenharmony_ci } 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci /* extract flag info */ 65cabdff1aSopenharmony_ci flags1 = 0; 66cabdff1aSopenharmony_ci flags2 = 1; 67cabdff1aSopenharmony_ci if (avctx->codec->id == AV_CODEC_ID_WMAV1) { 68cabdff1aSopenharmony_ci extradata = av_malloc(4); 69cabdff1aSopenharmony_ci if (!extradata) 70cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 71cabdff1aSopenharmony_ci avctx->extradata_size = 4; 72cabdff1aSopenharmony_ci AV_WL16(extradata, flags1); 73cabdff1aSopenharmony_ci AV_WL16(extradata + 2, flags2); 74cabdff1aSopenharmony_ci } else if (avctx->codec->id == AV_CODEC_ID_WMAV2) { 75cabdff1aSopenharmony_ci extradata = av_mallocz(10); 76cabdff1aSopenharmony_ci if (!extradata) 77cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 78cabdff1aSopenharmony_ci avctx->extradata_size = 10; 79cabdff1aSopenharmony_ci AV_WL32(extradata, flags1); 80cabdff1aSopenharmony_ci AV_WL16(extradata + 4, flags2); 81cabdff1aSopenharmony_ci } else { 82cabdff1aSopenharmony_ci av_assert0(0); 83cabdff1aSopenharmony_ci } 84cabdff1aSopenharmony_ci avctx->extradata = extradata; 85cabdff1aSopenharmony_ci s->use_exp_vlc = flags2 & 0x0001; 86cabdff1aSopenharmony_ci s->use_bit_reservoir = flags2 & 0x0002; 87cabdff1aSopenharmony_ci s->use_variable_block_len = flags2 & 0x0004; 88cabdff1aSopenharmony_ci if (avctx->ch_layout.nb_channels == 2) 89cabdff1aSopenharmony_ci s->ms_stereo = 1; 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci if ((ret = ff_wma_init(avctx, flags2)) < 0) 92cabdff1aSopenharmony_ci return ret; 93cabdff1aSopenharmony_ci 94cabdff1aSopenharmony_ci /* init MDCT */ 95cabdff1aSopenharmony_ci for (i = 0; i < s->nb_block_sizes; i++) { 96cabdff1aSopenharmony_ci ret = ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 0, 1.0); 97cabdff1aSopenharmony_ci if (ret < 0) 98cabdff1aSopenharmony_ci return ret; 99cabdff1aSopenharmony_ci } 100cabdff1aSopenharmony_ci 101cabdff1aSopenharmony_ci block_align = avctx->bit_rate * (int64_t) s->frame_len / 102cabdff1aSopenharmony_ci (avctx->sample_rate * 8); 103cabdff1aSopenharmony_ci block_align = FFMIN(block_align, MAX_CODED_SUPERFRAME_SIZE); 104cabdff1aSopenharmony_ci avctx->block_align = block_align; 105cabdff1aSopenharmony_ci avctx->frame_size = avctx->initial_padding = s->frame_len; 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci return 0; 108cabdff1aSopenharmony_ci} 109cabdff1aSopenharmony_ci 110cabdff1aSopenharmony_cistatic int apply_window_and_mdct(AVCodecContext *avctx, const AVFrame *frame) 111cabdff1aSopenharmony_ci{ 112cabdff1aSopenharmony_ci WMACodecContext *s = avctx->priv_data; 113cabdff1aSopenharmony_ci float **audio = (float **) frame->extended_data; 114cabdff1aSopenharmony_ci int len = frame->nb_samples; 115cabdff1aSopenharmony_ci int window_index = s->frame_len_bits - s->block_len_bits; 116cabdff1aSopenharmony_ci FFTContext *mdct = &s->mdct_ctx[window_index]; 117cabdff1aSopenharmony_ci int ch; 118cabdff1aSopenharmony_ci const float *win = s->windows[window_index]; 119cabdff1aSopenharmony_ci int window_len = 1 << s->block_len_bits; 120cabdff1aSopenharmony_ci float n = 2.0 * 32768.0 / window_len; 121cabdff1aSopenharmony_ci 122cabdff1aSopenharmony_ci for (ch = 0; ch < avctx->ch_layout.nb_channels; ch++) { 123cabdff1aSopenharmony_ci memcpy(s->output, s->frame_out[ch], window_len * sizeof(*s->output)); 124cabdff1aSopenharmony_ci s->fdsp->vector_fmul_scalar(s->frame_out[ch], audio[ch], n, len); 125cabdff1aSopenharmony_ci s->fdsp->vector_fmul_reverse(&s->output[window_len], s->frame_out[ch], 126cabdff1aSopenharmony_ci win, len); 127cabdff1aSopenharmony_ci s->fdsp->vector_fmul(s->frame_out[ch], s->frame_out[ch], win, len); 128cabdff1aSopenharmony_ci mdct->mdct_calc(mdct, s->coefs[ch], s->output); 129cabdff1aSopenharmony_ci if (!isfinite(s->coefs[ch][0])) { 130cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Input contains NaN/+-Inf\n"); 131cabdff1aSopenharmony_ci return AVERROR(EINVAL); 132cabdff1aSopenharmony_ci } 133cabdff1aSopenharmony_ci } 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_ci return 0; 136cabdff1aSopenharmony_ci} 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci// FIXME use for decoding too 139cabdff1aSopenharmony_cistatic void init_exp(WMACodecContext *s, int ch, const int *exp_param) 140cabdff1aSopenharmony_ci{ 141cabdff1aSopenharmony_ci int n; 142cabdff1aSopenharmony_ci const uint16_t *ptr; 143cabdff1aSopenharmony_ci float v, *q, max_scale, *q_end; 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_ci ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; 146cabdff1aSopenharmony_ci q = s->exponents[ch]; 147cabdff1aSopenharmony_ci q_end = q + s->block_len; 148cabdff1aSopenharmony_ci max_scale = 0; 149cabdff1aSopenharmony_ci while (q < q_end) { 150cabdff1aSopenharmony_ci /* XXX: use a table */ 151cabdff1aSopenharmony_ci v = ff_exp10(*exp_param++ *(1.0 / 16.0)); 152cabdff1aSopenharmony_ci max_scale = FFMAX(max_scale, v); 153cabdff1aSopenharmony_ci n = *ptr++; 154cabdff1aSopenharmony_ci do { 155cabdff1aSopenharmony_ci *q++ = v; 156cabdff1aSopenharmony_ci } while (--n); 157cabdff1aSopenharmony_ci } 158cabdff1aSopenharmony_ci s->max_exponent[ch] = max_scale; 159cabdff1aSopenharmony_ci} 160cabdff1aSopenharmony_ci 161cabdff1aSopenharmony_cistatic void encode_exp_vlc(WMACodecContext *s, int ch, const int *exp_param) 162cabdff1aSopenharmony_ci{ 163cabdff1aSopenharmony_ci int last_exp; 164cabdff1aSopenharmony_ci const uint16_t *ptr; 165cabdff1aSopenharmony_ci float *q, *q_end; 166cabdff1aSopenharmony_ci 167cabdff1aSopenharmony_ci ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; 168cabdff1aSopenharmony_ci q = s->exponents[ch]; 169cabdff1aSopenharmony_ci q_end = q + s->block_len; 170cabdff1aSopenharmony_ci if (s->version == 1) { 171cabdff1aSopenharmony_ci last_exp = *exp_param++; 172cabdff1aSopenharmony_ci av_assert0(last_exp - 10 >= 0 && last_exp - 10 < 32); 173cabdff1aSopenharmony_ci put_bits(&s->pb, 5, last_exp - 10); 174cabdff1aSopenharmony_ci q += *ptr++; 175cabdff1aSopenharmony_ci } else 176cabdff1aSopenharmony_ci last_exp = 36; 177cabdff1aSopenharmony_ci while (q < q_end) { 178cabdff1aSopenharmony_ci int exp = *exp_param++; 179cabdff1aSopenharmony_ci int code = exp - last_exp + 60; 180cabdff1aSopenharmony_ci av_assert1(code >= 0 && code < 120); 181cabdff1aSopenharmony_ci put_bits(&s->pb, ff_aac_scalefactor_bits[code], 182cabdff1aSopenharmony_ci ff_aac_scalefactor_code[code]); 183cabdff1aSopenharmony_ci /* XXX: use a table */ 184cabdff1aSopenharmony_ci q += *ptr++; 185cabdff1aSopenharmony_ci last_exp = exp; 186cabdff1aSopenharmony_ci } 187cabdff1aSopenharmony_ci} 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_cistatic int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], 190cabdff1aSopenharmony_ci int total_gain) 191cabdff1aSopenharmony_ci{ 192cabdff1aSopenharmony_ci int channels = s->avctx->ch_layout.nb_channels; 193cabdff1aSopenharmony_ci int v, bsize, ch, coef_nb_bits, parse_exponents; 194cabdff1aSopenharmony_ci float mdct_norm; 195cabdff1aSopenharmony_ci int nb_coefs[MAX_CHANNELS]; 196cabdff1aSopenharmony_ci static const int fixed_exp[25] = { 197cabdff1aSopenharmony_ci 20, 20, 20, 20, 20, 198cabdff1aSopenharmony_ci 20, 20, 20, 20, 20, 199cabdff1aSopenharmony_ci 20, 20, 20, 20, 20, 200cabdff1aSopenharmony_ci 20, 20, 20, 20, 20, 201cabdff1aSopenharmony_ci 20, 20, 20, 20, 20 202cabdff1aSopenharmony_ci }; 203cabdff1aSopenharmony_ci 204cabdff1aSopenharmony_ci // FIXME remove duplication relative to decoder 205cabdff1aSopenharmony_ci if (s->use_variable_block_len) { 206cabdff1aSopenharmony_ci av_assert0(0); // FIXME not implemented 207cabdff1aSopenharmony_ci } else { 208cabdff1aSopenharmony_ci /* fixed block len */ 209cabdff1aSopenharmony_ci s->next_block_len_bits = s->frame_len_bits; 210cabdff1aSopenharmony_ci s->prev_block_len_bits = s->frame_len_bits; 211cabdff1aSopenharmony_ci s->block_len_bits = s->frame_len_bits; 212cabdff1aSopenharmony_ci } 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_ci s->block_len = 1 << s->block_len_bits; 215cabdff1aSopenharmony_ci// av_assert0((s->block_pos + s->block_len) <= s->frame_len); 216cabdff1aSopenharmony_ci bsize = s->frame_len_bits - s->block_len_bits; 217cabdff1aSopenharmony_ci 218cabdff1aSopenharmony_ci // FIXME factor 219cabdff1aSopenharmony_ci v = s->coefs_end[bsize] - s->coefs_start; 220cabdff1aSopenharmony_ci for (ch = 0; ch < channels; ch++) 221cabdff1aSopenharmony_ci nb_coefs[ch] = v; 222cabdff1aSopenharmony_ci { 223cabdff1aSopenharmony_ci int n4 = s->block_len / 2; 224cabdff1aSopenharmony_ci mdct_norm = 1.0 / (float) n4; 225cabdff1aSopenharmony_ci if (s->version == 1) 226cabdff1aSopenharmony_ci mdct_norm *= sqrt(n4); 227cabdff1aSopenharmony_ci } 228cabdff1aSopenharmony_ci 229cabdff1aSopenharmony_ci if (channels == 2) 230cabdff1aSopenharmony_ci put_bits(&s->pb, 1, !!s->ms_stereo); 231cabdff1aSopenharmony_ci 232cabdff1aSopenharmony_ci for (ch = 0; ch < channels; ch++) { 233cabdff1aSopenharmony_ci // FIXME only set channel_coded when needed, instead of always 234cabdff1aSopenharmony_ci s->channel_coded[ch] = 1; 235cabdff1aSopenharmony_ci if (s->channel_coded[ch]) 236cabdff1aSopenharmony_ci init_exp(s, ch, fixed_exp); 237cabdff1aSopenharmony_ci } 238cabdff1aSopenharmony_ci 239cabdff1aSopenharmony_ci for (ch = 0; ch < channels; ch++) { 240cabdff1aSopenharmony_ci if (s->channel_coded[ch]) { 241cabdff1aSopenharmony_ci WMACoef *coefs1; 242cabdff1aSopenharmony_ci float *coefs, *exponents, mult; 243cabdff1aSopenharmony_ci int i, n; 244cabdff1aSopenharmony_ci 245cabdff1aSopenharmony_ci coefs1 = s->coefs1[ch]; 246cabdff1aSopenharmony_ci exponents = s->exponents[ch]; 247cabdff1aSopenharmony_ci mult = ff_exp10(total_gain * 0.05) / s->max_exponent[ch]; 248cabdff1aSopenharmony_ci mult *= mdct_norm; 249cabdff1aSopenharmony_ci coefs = src_coefs[ch]; 250cabdff1aSopenharmony_ci if (s->use_noise_coding && 0) { 251cabdff1aSopenharmony_ci av_assert0(0); // FIXME not implemented 252cabdff1aSopenharmony_ci } else { 253cabdff1aSopenharmony_ci coefs += s->coefs_start; 254cabdff1aSopenharmony_ci n = nb_coefs[ch]; 255cabdff1aSopenharmony_ci for (i = 0; i < n; i++) { 256cabdff1aSopenharmony_ci double t = *coefs++ / (exponents[i] * mult); 257cabdff1aSopenharmony_ci if (t < -32768 || t > 32767) 258cabdff1aSopenharmony_ci return -1; 259cabdff1aSopenharmony_ci 260cabdff1aSopenharmony_ci coefs1[i] = lrint(t); 261cabdff1aSopenharmony_ci } 262cabdff1aSopenharmony_ci } 263cabdff1aSopenharmony_ci } 264cabdff1aSopenharmony_ci } 265cabdff1aSopenharmony_ci 266cabdff1aSopenharmony_ci v = 0; 267cabdff1aSopenharmony_ci for (ch = 0; ch < channels; ch++) { 268cabdff1aSopenharmony_ci int a = s->channel_coded[ch]; 269cabdff1aSopenharmony_ci put_bits(&s->pb, 1, a); 270cabdff1aSopenharmony_ci v |= a; 271cabdff1aSopenharmony_ci } 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_ci if (!v) 274cabdff1aSopenharmony_ci return 1; 275cabdff1aSopenharmony_ci 276cabdff1aSopenharmony_ci for (v = total_gain - 1; v >= 127; v -= 127) 277cabdff1aSopenharmony_ci put_bits(&s->pb, 7, 127); 278cabdff1aSopenharmony_ci put_bits(&s->pb, 7, v); 279cabdff1aSopenharmony_ci 280cabdff1aSopenharmony_ci coef_nb_bits = ff_wma_total_gain_to_bits(total_gain); 281cabdff1aSopenharmony_ci 282cabdff1aSopenharmony_ci if (s->use_noise_coding) { 283cabdff1aSopenharmony_ci for (ch = 0; ch < channels; ch++) { 284cabdff1aSopenharmony_ci if (s->channel_coded[ch]) { 285cabdff1aSopenharmony_ci int i, n; 286cabdff1aSopenharmony_ci n = s->exponent_high_sizes[bsize]; 287cabdff1aSopenharmony_ci for (i = 0; i < n; i++) { 288cabdff1aSopenharmony_ci put_bits(&s->pb, 1, s->high_band_coded[ch][i] = 0); 289cabdff1aSopenharmony_ci if (0) 290cabdff1aSopenharmony_ci nb_coefs[ch] -= s->exponent_high_bands[bsize][i]; 291cabdff1aSopenharmony_ci } 292cabdff1aSopenharmony_ci } 293cabdff1aSopenharmony_ci } 294cabdff1aSopenharmony_ci } 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_ci parse_exponents = 1; 297cabdff1aSopenharmony_ci if (s->block_len_bits != s->frame_len_bits) 298cabdff1aSopenharmony_ci put_bits(&s->pb, 1, parse_exponents); 299cabdff1aSopenharmony_ci 300cabdff1aSopenharmony_ci if (parse_exponents) { 301cabdff1aSopenharmony_ci for (ch = 0; ch < channels; ch++) { 302cabdff1aSopenharmony_ci if (s->channel_coded[ch]) { 303cabdff1aSopenharmony_ci if (s->use_exp_vlc) { 304cabdff1aSopenharmony_ci encode_exp_vlc(s, ch, fixed_exp); 305cabdff1aSopenharmony_ci } else { 306cabdff1aSopenharmony_ci av_assert0(0); // FIXME not implemented 307cabdff1aSopenharmony_ci// encode_exp_lsp(s, ch); 308cabdff1aSopenharmony_ci } 309cabdff1aSopenharmony_ci } 310cabdff1aSopenharmony_ci } 311cabdff1aSopenharmony_ci } else 312cabdff1aSopenharmony_ci av_assert0(0); // FIXME not implemented 313cabdff1aSopenharmony_ci 314cabdff1aSopenharmony_ci for (ch = 0; ch < channels; ch++) { 315cabdff1aSopenharmony_ci if (s->channel_coded[ch]) { 316cabdff1aSopenharmony_ci int run, tindex; 317cabdff1aSopenharmony_ci WMACoef *ptr, *eptr; 318cabdff1aSopenharmony_ci tindex = (ch == 1 && s->ms_stereo); 319cabdff1aSopenharmony_ci ptr = &s->coefs1[ch][0]; 320cabdff1aSopenharmony_ci eptr = ptr + nb_coefs[ch]; 321cabdff1aSopenharmony_ci 322cabdff1aSopenharmony_ci run = 0; 323cabdff1aSopenharmony_ci for (; ptr < eptr; ptr++) { 324cabdff1aSopenharmony_ci if (*ptr) { 325cabdff1aSopenharmony_ci int level = *ptr; 326cabdff1aSopenharmony_ci int abs_level = FFABS(level); 327cabdff1aSopenharmony_ci int code = 0; 328cabdff1aSopenharmony_ci if (abs_level <= s->coef_vlcs[tindex]->max_level) 329cabdff1aSopenharmony_ci if (run < s->coef_vlcs[tindex]->levels[abs_level - 1]) 330cabdff1aSopenharmony_ci code = run + s->int_table[tindex][abs_level - 1]; 331cabdff1aSopenharmony_ci 332cabdff1aSopenharmony_ci av_assert2(code < s->coef_vlcs[tindex]->n); 333cabdff1aSopenharmony_ci put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[code], 334cabdff1aSopenharmony_ci s->coef_vlcs[tindex]->huffcodes[code]); 335cabdff1aSopenharmony_ci 336cabdff1aSopenharmony_ci if (code == 0) { 337cabdff1aSopenharmony_ci if (1 << coef_nb_bits <= abs_level) 338cabdff1aSopenharmony_ci return -1; 339cabdff1aSopenharmony_ci 340cabdff1aSopenharmony_ci put_bits(&s->pb, coef_nb_bits, abs_level); 341cabdff1aSopenharmony_ci put_bits(&s->pb, s->frame_len_bits, run); 342cabdff1aSopenharmony_ci } 343cabdff1aSopenharmony_ci // FIXME the sign is flipped somewhere 344cabdff1aSopenharmony_ci put_bits(&s->pb, 1, level < 0); 345cabdff1aSopenharmony_ci run = 0; 346cabdff1aSopenharmony_ci } else 347cabdff1aSopenharmony_ci run++; 348cabdff1aSopenharmony_ci } 349cabdff1aSopenharmony_ci if (run) 350cabdff1aSopenharmony_ci put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[1], 351cabdff1aSopenharmony_ci s->coef_vlcs[tindex]->huffcodes[1]); 352cabdff1aSopenharmony_ci } 353cabdff1aSopenharmony_ci if (s->version == 1 && channels >= 2) 354cabdff1aSopenharmony_ci align_put_bits(&s->pb); 355cabdff1aSopenharmony_ci } 356cabdff1aSopenharmony_ci return 0; 357cabdff1aSopenharmony_ci} 358cabdff1aSopenharmony_ci 359cabdff1aSopenharmony_cistatic int encode_frame(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], 360cabdff1aSopenharmony_ci uint8_t *buf, int buf_size, int total_gain) 361cabdff1aSopenharmony_ci{ 362cabdff1aSopenharmony_ci init_put_bits(&s->pb, buf, buf_size); 363cabdff1aSopenharmony_ci 364cabdff1aSopenharmony_ci if (s->use_bit_reservoir) 365cabdff1aSopenharmony_ci av_assert0(0); // FIXME not implemented 366cabdff1aSopenharmony_ci else if (encode_block(s, src_coefs, total_gain) < 0) 367cabdff1aSopenharmony_ci return INT_MAX; 368cabdff1aSopenharmony_ci 369cabdff1aSopenharmony_ci align_put_bits(&s->pb); 370cabdff1aSopenharmony_ci 371cabdff1aSopenharmony_ci return put_bits_count(&s->pb) / 8 - s->avctx->block_align; 372cabdff1aSopenharmony_ci} 373cabdff1aSopenharmony_ci 374cabdff1aSopenharmony_cistatic int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt, 375cabdff1aSopenharmony_ci const AVFrame *frame, int *got_packet_ptr) 376cabdff1aSopenharmony_ci{ 377cabdff1aSopenharmony_ci WMACodecContext *s = avctx->priv_data; 378cabdff1aSopenharmony_ci int i, total_gain, ret, error; 379cabdff1aSopenharmony_ci 380cabdff1aSopenharmony_ci s->block_len_bits = s->frame_len_bits; // required by non variable block len 381cabdff1aSopenharmony_ci s->block_len = 1 << s->block_len_bits; 382cabdff1aSopenharmony_ci 383cabdff1aSopenharmony_ci ret = apply_window_and_mdct(avctx, frame); 384cabdff1aSopenharmony_ci 385cabdff1aSopenharmony_ci if (ret < 0) 386cabdff1aSopenharmony_ci return ret; 387cabdff1aSopenharmony_ci 388cabdff1aSopenharmony_ci if (s->ms_stereo) { 389cabdff1aSopenharmony_ci float a, b; 390cabdff1aSopenharmony_ci int i; 391cabdff1aSopenharmony_ci 392cabdff1aSopenharmony_ci for (i = 0; i < s->block_len; i++) { 393cabdff1aSopenharmony_ci a = s->coefs[0][i] * 0.5; 394cabdff1aSopenharmony_ci b = s->coefs[1][i] * 0.5; 395cabdff1aSopenharmony_ci s->coefs[0][i] = a + b; 396cabdff1aSopenharmony_ci s->coefs[1][i] = a - b; 397cabdff1aSopenharmony_ci } 398cabdff1aSopenharmony_ci } 399cabdff1aSopenharmony_ci 400cabdff1aSopenharmony_ci if ((ret = ff_alloc_packet(avctx, avpkt, 2 * MAX_CODED_SUPERFRAME_SIZE)) < 0) 401cabdff1aSopenharmony_ci return ret; 402cabdff1aSopenharmony_ci 403cabdff1aSopenharmony_ci total_gain = 128; 404cabdff1aSopenharmony_ci for (i = 64; i; i >>= 1) { 405cabdff1aSopenharmony_ci error = encode_frame(s, s->coefs, avpkt->data, avpkt->size, 406cabdff1aSopenharmony_ci total_gain - i); 407cabdff1aSopenharmony_ci if (error <= 0) 408cabdff1aSopenharmony_ci total_gain -= i; 409cabdff1aSopenharmony_ci } 410cabdff1aSopenharmony_ci 411cabdff1aSopenharmony_ci while(total_gain <= 128 && error > 0) 412cabdff1aSopenharmony_ci error = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain++); 413cabdff1aSopenharmony_ci if (error > 0) { 414cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Invalid input data or requested bitrate too low, cannot encode\n"); 415cabdff1aSopenharmony_ci avpkt->size = 0; 416cabdff1aSopenharmony_ci return AVERROR(EINVAL); 417cabdff1aSopenharmony_ci } 418cabdff1aSopenharmony_ci av_assert0((put_bits_count(&s->pb) & 7) == 0); 419cabdff1aSopenharmony_ci i = avctx->block_align - put_bytes_count(&s->pb, 0); 420cabdff1aSopenharmony_ci av_assert0(i>=0); 421cabdff1aSopenharmony_ci while(i--) 422cabdff1aSopenharmony_ci put_bits(&s->pb, 8, 'N'); 423cabdff1aSopenharmony_ci 424cabdff1aSopenharmony_ci flush_put_bits(&s->pb); 425cabdff1aSopenharmony_ci av_assert0(put_bits_ptr(&s->pb) - s->pb.buf == avctx->block_align); 426cabdff1aSopenharmony_ci 427cabdff1aSopenharmony_ci if (frame->pts != AV_NOPTS_VALUE) 428cabdff1aSopenharmony_ci avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->initial_padding); 429cabdff1aSopenharmony_ci 430cabdff1aSopenharmony_ci avpkt->size = avctx->block_align; 431cabdff1aSopenharmony_ci *got_packet_ptr = 1; 432cabdff1aSopenharmony_ci return 0; 433cabdff1aSopenharmony_ci} 434cabdff1aSopenharmony_ci 435cabdff1aSopenharmony_ci#if CONFIG_WMAV1_ENCODER 436cabdff1aSopenharmony_ciconst FFCodec ff_wmav1_encoder = { 437cabdff1aSopenharmony_ci .p.name = "wmav1", 438cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), 439cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 440cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_WMAV1, 441cabdff1aSopenharmony_ci .priv_data_size = sizeof(WMACodecContext), 442cabdff1aSopenharmony_ci .init = encode_init, 443cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(encode_superframe), 444cabdff1aSopenharmony_ci .close = ff_wma_end, 445cabdff1aSopenharmony_ci .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, 446cabdff1aSopenharmony_ci AV_SAMPLE_FMT_NONE }, 447cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 448cabdff1aSopenharmony_ci}; 449cabdff1aSopenharmony_ci#endif 450cabdff1aSopenharmony_ci#if CONFIG_WMAV2_ENCODER 451cabdff1aSopenharmony_ciconst FFCodec ff_wmav2_encoder = { 452cabdff1aSopenharmony_ci .p.name = "wmav2", 453cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), 454cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_AUDIO, 455cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_WMAV2, 456cabdff1aSopenharmony_ci .priv_data_size = sizeof(WMACodecContext), 457cabdff1aSopenharmony_ci .init = encode_init, 458cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(encode_superframe), 459cabdff1aSopenharmony_ci .close = ff_wma_end, 460cabdff1aSopenharmony_ci .p.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, 461cabdff1aSopenharmony_ci AV_SAMPLE_FMT_NONE }, 462cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 463cabdff1aSopenharmony_ci}; 464cabdff1aSopenharmony_ci#endif 465