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