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