GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/ra144enc.c Lines: 216 225 96.0 %
Date: 2020-08-14 10:39:37 Branches: 102 108 94.4 %

Line Branch Exec Source
1
/*
2
 * Real Audio 1.0 (14.4K) encoder
3
 * Copyright (c) 2010 Francesco Lavra <francescolavra@interfree.it>
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
/**
23
 * @file
24
 * Real Audio 1.0 (14.4K) encoder
25
 * @author Francesco Lavra <francescolavra@interfree.it>
26
 */
27
28
#include <float.h>
29
30
#include "avcodec.h"
31
#include "audio_frame_queue.h"
32
#include "celp_filters.h"
33
#include "internal.h"
34
#include "mathops.h"
35
#include "put_bits.h"
36
#include "ra144.h"
37
38
1
static av_cold int ra144_encode_close(AVCodecContext *avctx)
39
{
40
1
    RA144Context *ractx = avctx->priv_data;
41
1
    ff_lpc_end(&ractx->lpc_ctx);
42
1
    ff_af_queue_close(&ractx->afq);
43
1
    return 0;
44
}
45
46
47
1
static av_cold int ra144_encode_init(AVCodecContext * avctx)
48
{
49
    RA144Context *ractx;
50
    int ret;
51
52
1
    if (avctx->channels != 1) {
53
        av_log(avctx, AV_LOG_ERROR, "invalid number of channels: %d\n",
54
               avctx->channels);
55
        return -1;
56
    }
57
1
    avctx->frame_size = NBLOCKS * BLOCKSIZE;
58
1
    avctx->initial_padding = avctx->frame_size;
59
1
    avctx->bit_rate = 8000;
60
1
    ractx = avctx->priv_data;
61
1
    ractx->lpc_coef[0] = ractx->lpc_tables[0];
62
1
    ractx->lpc_coef[1] = ractx->lpc_tables[1];
63
1
    ractx->avctx = avctx;
64
1
    ff_audiodsp_init(&ractx->adsp);
65
1
    ret = ff_lpc_init(&ractx->lpc_ctx, avctx->frame_size, LPC_ORDER,
66
                      FF_LPC_TYPE_LEVINSON);
67
1
    if (ret < 0)
68
        goto error;
69
70
1
    ff_af_queue_init(avctx, &ractx->afq);
71
72
1
    return 0;
73
error:
74
    ra144_encode_close(avctx);
75
    return ret;
76
}
77
78
79
/**
80
 * Quantize a value by searching a sorted table for the element with the
81
 * nearest value
82
 *
83
 * @param value value to quantize
84
 * @param table array containing the quantization table
85
 * @param size size of the quantization table
86
 * @return index of the quantization table corresponding to the element with the
87
 *         nearest value
88
 */
89
3612
static int quantize(int value, const int16_t *table, unsigned int size)
90
{
91
3612
    unsigned int low = 0, high = size - 1;
92
93
14245
    while (1) {
94
17857
        int index = (low + high) >> 1;
95
17857
        int error = table[index] - value;
96
97
17857
        if (index == low)
98
3612
            return table[high] + error > value ? low : high;
99
14245
        if (error > 0) {
100
5875
            high = index;
101
        } else {
102
8370
            low = index;
103
        }
104
    }
105
}
106
107
108
/**
109
 * Orthogonalize a vector to another vector
110
 *
111
 * @param v vector to orthogonalize
112
 * @param u vector against which orthogonalization is performed
113
 */
114
461357
static void orthogonalize(float *v, const float *u)
115
{
116
    int i;
117
461357
    float num = 0, den = 0;
118
119
18915637
    for (i = 0; i < BLOCKSIZE; i++) {
120
18454280
        num += v[i] * u[i];
121
18454280
        den += u[i] * u[i];
122
    }
123
461357
    num /= den;
124
18915637
    for (i = 0; i < BLOCKSIZE; i++)
125
18454280
        v[i] -= num * u[i];
126
461357
}
127
128
129
/**
130
 * Calculate match score and gain of an LPC-filtered vector with respect to
131
 * input data, possibly orthogonalizing it to up to two other vectors.
132
 *
133
 * @param work array used to calculate the filtered vector
134
 * @param coefs coefficients of the LPC filter
135
 * @param vect original vector
136
 * @param ortho1 first vector against which orthogonalization is performed
137
 * @param ortho2 second vector against which orthogonalization is performed
138
 * @param data input data
139
 * @param score pointer to variable where match score is returned
140
 * @param gain pointer to variable where gain is returned
141
 */
142
461132
static void get_match_score(float *work, const float *coefs, float *vect,
143
                            const float *ortho1, const float *ortho2,
144
                            const float *data, float *score, float *gain)
145
{
146
    float c, g;
147
    int i;
148
149
461132
    ff_celp_lp_synthesis_filterf(work, coefs, vect, BLOCKSIZE, LPC_ORDER);
150
461132
    if (ortho1)
151
306432
        orthogonalize(work, ortho1);
152
461132
    if (ortho2)
153
153728
        orthogonalize(work, ortho2);
154
461132
    c = g = 0;
155
18906412
    for (i = 0; i < BLOCKSIZE; i++) {
156
18445280
        g += work[i] * work[i];
157
18445280
        c += data[i] * work[i];
158
    }
159
461132
    if (c <= 0) {
160
232992
        *score = 0;
161
232992
        return;
162
    }
163
228140
    *gain = c / g;
164
228140
    *score = *gain * c;
165
}
166
167
168
/**
169
 * Create a vector from the adaptive codebook at a given lag value
170
 *
171
 * @param vect array where vector is stored
172
 * @param cb adaptive codebook
173
 * @param lag lag value
174
 */
175
154105
static void create_adapt_vect(float *vect, const int16_t *cb, int lag)
176
{
177
    int i;
178
179
154105
    cb += BUFFERSIZE - lag;
180
6061026
    for (i = 0; i < FFMIN(BLOCKSIZE, lag); i++)
181
5906921
        vect[i] = cb[i];
182
154105
    if (lag < BLOCKSIZE)
183
281796
        for (i = 0; i < BLOCKSIZE - lag; i++)
184
257279
            vect[lag + i] = cb[i];
185
154105
}
186
187
188
/**
189
 * Search the adaptive codebook for the best entry and gain and remove its
190
 * contribution from input data
191
 *
192
 * @param adapt_cb array from which the adaptive codebook is extracted
193
 * @param work array used to calculate LPC-filtered vectors
194
 * @param coefs coefficients of the LPC filter
195
 * @param data input data
196
 * @return index of the best entry of the adaptive codebook
197
 */
198
1204
static int adaptive_cb_search(const int16_t *adapt_cb, float *work,
199
                              const float *coefs, float *data)
200
{
201
1204
    int i, av_uninit(best_vect);
202
1204
    float score, gain, best_score, av_uninit(best_gain);
203
    float exc[BLOCKSIZE];
204
205
1204
    gain = best_score = 0;
206
154112
    for (i = BLOCKSIZE / 2; i <= BUFFERSIZE; i++) {
207
152908
        create_adapt_vect(exc, adapt_cb, i);
208
152908
        get_match_score(work, coefs, exc, NULL, NULL, data, &score, &gain);
209
152908
        if (score > best_score) {
210
5528
            best_score = score;
211
5528
            best_vect = i;
212
5528
            best_gain = gain;
213
        }
214
    }
215
1204
    if (!best_score)
216
7
        return 0;
217
218
    /**
219
     * Re-calculate the filtered vector from the vector with maximum match score
220
     * and remove its contribution from input data.
221
     */
222
1197
    create_adapt_vect(exc, adapt_cb, best_vect);
223
1197
    ff_celp_lp_synthesis_filterf(work, coefs, exc, BLOCKSIZE, LPC_ORDER);
224
49077
    for (i = 0; i < BLOCKSIZE; i++)
225
47880
        data[i] -= best_gain * work[i];
226
1197
    return best_vect - BLOCKSIZE / 2 + 1;
227
}
228
229
230
/**
231
 * Find the best vector of a fixed codebook by applying an LPC filter to
232
 * codebook entries, possibly orthogonalizing them to up to two other vectors
233
 * and matching the results with input data.
234
 *
235
 * @param work array used to calculate the filtered vectors
236
 * @param coefs coefficients of the LPC filter
237
 * @param cb fixed codebook
238
 * @param ortho1 first vector against which orthogonalization is performed
239
 * @param ortho2 second vector against which orthogonalization is performed
240
 * @param data input data
241
 * @param idx pointer to variable where the index of the best codebook entry is
242
 *        returned
243
 * @param gain pointer to variable where the gain of the best codebook entry is
244
 *        returned
245
 */
246
2408
static void find_best_vect(float *work, const float *coefs,
247
                           const int8_t cb[][BLOCKSIZE], const float *ortho1,
248
                           const float *ortho2, float *data, int *idx,
249
                           float *gain)
250
{
251
    int i, j;
252
    float g, score, best_score;
253
    float vect[BLOCKSIZE];
254
255
2408
    *idx = *gain = best_score = 0;
256
310632
    for (i = 0; i < FIXED_CB_SIZE; i++) {
257
12637184
        for (j = 0; j < BLOCKSIZE; j++)
258
12328960
            vect[j] = cb[i][j];
259
308224
        get_match_score(work, coefs, vect, ortho1, ortho2, data, &score, &g);
260
308224
        if (score > best_score) {
261
14127
            best_score = score;
262
14127
            *idx = i;
263
14127
            *gain = g;
264
        }
265
    }
266
2408
}
267
268
269
/**
270
 * Search the two fixed codebooks for the best entry and gain
271
 *
272
 * @param work array used to calculate LPC-filtered vectors
273
 * @param coefs coefficients of the LPC filter
274
 * @param data input data
275
 * @param cba_idx index of the best entry of the adaptive codebook
276
 * @param cb1_idx pointer to variable where the index of the best entry of the
277
 *        first fixed codebook is returned
278
 * @param cb2_idx pointer to variable where the index of the best entry of the
279
 *        second fixed codebook is returned
280
 */
281
1204
static void fixed_cb_search(float *work, const float *coefs, float *data,
282
                            int cba_idx, int *cb1_idx, int *cb2_idx)
283
{
284
    int i, ortho_cb1;
285
    float gain;
286
    float cba_vect[BLOCKSIZE], cb1_vect[BLOCKSIZE];
287
    float vect[BLOCKSIZE];
288
289
    /**
290
     * The filtered vector from the adaptive codebook can be retrieved from
291
     * work, because this function is called just after adaptive_cb_search().
292
     */
293
1204
    if (cba_idx)
294
1197
        memcpy(cba_vect, work, sizeof(cba_vect));
295
296
1204
    find_best_vect(work, coefs, ff_cb1_vects, cba_idx ? cba_vect : NULL, NULL,
297
                   data, cb1_idx, &gain);
298
299
    /**
300
     * Re-calculate the filtered vector from the vector with maximum match score
301
     * and remove its contribution from input data.
302
     */
303
1204
    if (gain) {
304
49241
        for (i = 0; i < BLOCKSIZE; i++)
305
48040
            vect[i] = ff_cb1_vects[*cb1_idx][i];
306
1201
        ff_celp_lp_synthesis_filterf(work, coefs, vect, BLOCKSIZE, LPC_ORDER);
307
1201
        if (cba_idx)
308
1197
            orthogonalize(work, cba_vect);
309
49241
        for (i = 0; i < BLOCKSIZE; i++)
310
48040
            data[i] -= gain * work[i];
311
1201
        memcpy(cb1_vect, work, sizeof(cb1_vect));
312
1201
        ortho_cb1 = 1;
313
    } else
314
3
        ortho_cb1 = 0;
315
316

1204
    find_best_vect(work, coefs, ff_cb2_vects, cba_idx ? cba_vect : NULL,
317
                   ortho_cb1 ? cb1_vect : NULL, data, cb2_idx, &gain);
318
1204
}
319
320
321
/**
322
 * Encode a subblock of the current frame
323
 *
324
 * @param ractx encoder context
325
 * @param sblock_data input data of the subblock
326
 * @param lpc_coefs coefficients of the LPC filter
327
 * @param rms RMS of the reflection coefficients
328
 * @param pb pointer to PutBitContext of the current frame
329
 */
330
1204
static void ra144_encode_subblock(RA144Context *ractx,
331
                                  const int16_t *sblock_data,
332
                                  const int16_t *lpc_coefs, unsigned int rms,
333
                                  PutBitContext *pb)
334
{
335
1204
    float data[BLOCKSIZE] = { 0 }, work[LPC_ORDER + BLOCKSIZE];
336
    float coefs[LPC_ORDER];
337
    float zero[BLOCKSIZE], cba[BLOCKSIZE], cb1[BLOCKSIZE], cb2[BLOCKSIZE];
338
    int cba_idx, cb1_idx, cb2_idx, gain;
339
    int i, n;
340
    unsigned m[3];
341
    float g[3];
342
    float error, best_error;
343
344
13244
    for (i = 0; i < LPC_ORDER; i++) {
345
12040
        work[i] = ractx->curr_sblock[BLOCKSIZE + i];
346
12040
        coefs[i] = lpc_coefs[i] * (1/4096.0);
347
    }
348
349
    /**
350
     * Calculate the zero-input response of the LPC filter and subtract it from
351
     * input data.
352
     */
353
1204
    ff_celp_lp_synthesis_filterf(work + LPC_ORDER, coefs, data, BLOCKSIZE,
354
                                 LPC_ORDER);
355
49364
    for (i = 0; i < BLOCKSIZE; i++) {
356
48160
        zero[i] = work[LPC_ORDER + i];
357
48160
        data[i] = sblock_data[i] - zero[i];
358
    }
359
360
    /**
361
     * Codebook search is performed without taking into account the contribution
362
     * of the previous subblock, since it has been just subtracted from input
363
     * data.
364
     */
365
1204
    memset(work, 0, LPC_ORDER * sizeof(*work));
366
367
1204
    cba_idx = adaptive_cb_search(ractx->adapt_cb, work + LPC_ORDER, coefs,
368
                                 data);
369
1204
    if (cba_idx) {
370
        /**
371
         * The filtered vector from the adaptive codebook can be retrieved from
372
         * work, see implementation of adaptive_cb_search().
373
         */
374
1197
        memcpy(cba, work + LPC_ORDER, sizeof(cba));
375
376
1197
        ff_copy_and_dup(ractx->buffer_a, ractx->adapt_cb, cba_idx + BLOCKSIZE / 2 - 1);
377
1197
        m[0] = (ff_irms(&ractx->adsp, ractx->buffer_a) * rms) >> 12;
378
    }
379
1204
    fixed_cb_search(work + LPC_ORDER, coefs, data, cba_idx, &cb1_idx, &cb2_idx);
380
49364
    for (i = 0; i < BLOCKSIZE; i++) {
381
48160
        cb1[i] = ff_cb1_vects[cb1_idx][i];
382
48160
        cb2[i] = ff_cb2_vects[cb2_idx][i];
383
    }
384
1204
    ff_celp_lp_synthesis_filterf(work + LPC_ORDER, coefs, cb1, BLOCKSIZE,
385
                                 LPC_ORDER);
386
1204
    memcpy(cb1, work + LPC_ORDER, sizeof(cb1));
387
1204
    m[1] = (ff_cb1_base[cb1_idx] * rms) >> 8;
388
1204
    ff_celp_lp_synthesis_filterf(work + LPC_ORDER, coefs, cb2, BLOCKSIZE,
389
                                 LPC_ORDER);
390
1204
    memcpy(cb2, work + LPC_ORDER, sizeof(cb2));
391
1204
    m[2] = (ff_cb2_base[cb2_idx] * rms) >> 8;
392
1204
    best_error = FLT_MAX;
393
1204
    gain = 0;
394
309428
    for (n = 0; n < 256; n++) {
395
308224
        g[1] = ((ff_gain_val_tab[n][1] * m[1]) >> ff_gain_exp_tab[n]) *
396
               (1/4096.0);
397
308224
        g[2] = ((ff_gain_val_tab[n][2] * m[2]) >> ff_gain_exp_tab[n]) *
398
               (1/4096.0);
399
308224
        error = 0;
400
308224
        if (cba_idx) {
401
306432
            g[0] = ((ff_gain_val_tab[n][0] * m[0]) >> ff_gain_exp_tab[n]) *
402
                   (1/4096.0);
403
12563712
            for (i = 0; i < BLOCKSIZE; i++) {
404
12257280
                data[i] = zero[i] + g[0] * cba[i] + g[1] * cb1[i] +
405
12257280
                          g[2] * cb2[i];
406
12257280
                error += (data[i] - sblock_data[i]) *
407
12257280
                         (data[i] - sblock_data[i]);
408
            }
409
        } else {
410
73472
            for (i = 0; i < BLOCKSIZE; i++) {
411
71680
                data[i] = zero[i] + g[1] * cb1[i] + g[2] * cb2[i];
412
71680
                error += (data[i] - sblock_data[i]) *
413
71680
                         (data[i] - sblock_data[i]);
414
            }
415
        }
416
308224
        if (error < best_error) {
417
45662
            best_error = error;
418
45662
            gain = n;
419
        }
420
    }
421
1204
    put_bits(pb, 7, cba_idx);
422
1204
    put_bits(pb, 8, gain);
423
1204
    put_bits(pb, 7, cb1_idx);
424
1204
    put_bits(pb, 7, cb2_idx);
425
1204
    ff_subblock_synthesis(ractx, lpc_coefs, cba_idx, cb1_idx, cb2_idx, rms,
426
                          gain);
427
1204
}
428
429
430
302
static int ra144_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
431
                              const AVFrame *frame, int *got_packet_ptr)
432
{
433
    static const uint8_t sizes[LPC_ORDER] = {64, 32, 32, 16, 16, 8, 8, 8, 8, 4};
434
    static const uint8_t bit_sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
435
302
    RA144Context *ractx = avctx->priv_data;
436
    PutBitContext pb;
437
    int32_t lpc_data[NBLOCKS * BLOCKSIZE];
438
    int32_t lpc_coefs[LPC_ORDER][MAX_LPC_ORDER];
439
    int shift[LPC_ORDER];
440
    int16_t block_coefs[NBLOCKS][LPC_ORDER];
441
    int lpc_refl[LPC_ORDER];    /**< reflection coefficients of the frame */
442
    unsigned int refl_rms[NBLOCKS]; /**< RMS of the reflection coefficients */
443
302
    const int16_t *samples = frame ? (const int16_t *)frame->data[0] : NULL;
444
302
    int energy = 0;
445
    int i, idx, ret;
446
447
302
    if (ractx->last_frame)
448
1
        return 0;
449
450
301
    if ((ret = ff_alloc_packet2(avctx, avpkt, FRAME_SIZE, 0)) < 0)
451
        return ret;
452
453
    /**
454
     * Since the LPC coefficients are calculated on a frame centered over the
455
     * fourth subframe, to encode a given frame, data from the next frame is
456
     * needed. In each call to this function, the previous frame (whose data are
457
     * saved in the encoder context) is encoded, and data from the current frame
458
     * are saved in the encoder context to be used in the next function call.
459
     */
460
30401
    for (i = 0; i < (2 * BLOCKSIZE + BLOCKSIZE / 2); i++) {
461
30100
        lpc_data[i] = ractx->curr_block[BLOCKSIZE + BLOCKSIZE / 2 + i];
462
30100
        energy += (lpc_data[i] * lpc_data[i]) >> 4;
463
    }
464
301
    if (frame) {
465
        int j;
466

18300
        for (j = 0; j < frame->nb_samples && i < NBLOCKS * BLOCKSIZE; i++, j++) {
467
18000
            lpc_data[i] = samples[j] >> 2;
468
18000
            energy += (lpc_data[i] * lpc_data[i]) >> 4;
469
        }
470
    }
471
301
    if (i < NBLOCKS * BLOCKSIZE)
472
1
        memset(&lpc_data[i], 0, (NBLOCKS * BLOCKSIZE - i) * sizeof(*lpc_data));
473
301
    energy = ff_energy_tab[quantize(ff_t_sqrt(energy >> 5) >> 10, ff_energy_tab,
474
                                    32)];
475
476
301
    ff_lpc_calc_coefs(&ractx->lpc_ctx, lpc_data, NBLOCKS * BLOCKSIZE, LPC_ORDER,
477
                      LPC_ORDER, 16, lpc_coefs, shift, FF_LPC_TYPE_LEVINSON,
478
                      0, ORDER_METHOD_EST, 0, 12, 0);
479
3311
    for (i = 0; i < LPC_ORDER; i++)
480
3010
        block_coefs[NBLOCKS - 1][i] = -lpc_coefs[LPC_ORDER - 1][i]
481
3010
                                       * (1 << (12 - shift[LPC_ORDER - 1]));
482
483
    /**
484
     * TODO: apply perceptual weighting of the input speech through bandwidth
485
     * expansion of the LPC filter.
486
     */
487
488
301
    if (ff_eval_refl(lpc_refl, block_coefs[NBLOCKS - 1], avctx)) {
489
        /**
490
         * The filter is unstable: use the coefficients of the previous frame.
491
         */
492
73
        ff_int_to_int16(block_coefs[NBLOCKS - 1], ractx->lpc_coef[1]);
493
73
        if (ff_eval_refl(lpc_refl, block_coefs[NBLOCKS - 1], avctx)) {
494
            /* the filter is still unstable. set reflection coeffs to zero. */
495
            memset(lpc_refl, 0, sizeof(lpc_refl));
496
        }
497
    }
498
301
    init_put_bits(&pb, avpkt->data, avpkt->size);
499
3311
    for (i = 0; i < LPC_ORDER; i++) {
500
3010
        idx = quantize(lpc_refl[i], ff_lpc_refl_cb[i], sizes[i]);
501
3010
        put_bits(&pb, bit_sizes[i], idx);
502
3010
        lpc_refl[i] = ff_lpc_refl_cb[i][idx];
503
    }
504
301
    ractx->lpc_refl_rms[0] = ff_rms(lpc_refl);
505
301
    ff_eval_coefs(ractx->lpc_coef[0], lpc_refl);
506
301
    refl_rms[0] = ff_interp(ractx, block_coefs[0], 1, 1, ractx->old_energy);
507
602
    refl_rms[1] = ff_interp(ractx, block_coefs[1], 2,
508
301
                            energy <= ractx->old_energy,
509
301
                            ff_t_sqrt(energy * ractx->old_energy) >> 12);
510
301
    refl_rms[2] = ff_interp(ractx, block_coefs[2], 3, 0, energy);
511
301
    refl_rms[3] = ff_rescale_rms(ractx->lpc_refl_rms[0], energy);
512
301
    ff_int_to_int16(block_coefs[NBLOCKS - 1], ractx->lpc_coef[0]);
513
301
    put_bits(&pb, 5, quantize(energy, ff_energy_tab, 32));
514
1505
    for (i = 0; i < NBLOCKS; i++)
515
1204
        ra144_encode_subblock(ractx, ractx->curr_block + i * BLOCKSIZE,
516
1204
                              block_coefs[i], refl_rms[i], &pb);
517
301
    flush_put_bits(&pb);
518
301
    ractx->old_energy = energy;
519
301
    ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0];
520
301
    FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]);
521
522
    /* copy input samples to current block for processing in next call */
523
301
    i = 0;
524
301
    if (frame) {
525
48300
        for (; i < frame->nb_samples; i++)
526
48000
            ractx->curr_block[i] = samples[i] >> 2;
527
528
300
        if ((ret = ff_af_queue_add(&ractx->afq, frame)) < 0)
529
            return ret;
530
    } else
531
1
        ractx->last_frame = 1;
532
301
    memset(&ractx->curr_block[i], 0,
533
301
           (NBLOCKS * BLOCKSIZE - i) * sizeof(*ractx->curr_block));
534
535
    /* Get the next frame pts/duration */
536
301
    ff_af_queue_remove(&ractx->afq, avctx->frame_size, &avpkt->pts,
537
                       &avpkt->duration);
538
539
301
    avpkt->size = FRAME_SIZE;
540
301
    *got_packet_ptr = 1;
541
301
    return 0;
542
}
543
544
545
AVCodec ff_ra_144_encoder = {
546
    .name           = "real_144",
547
    .long_name      = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
548
    .type           = AVMEDIA_TYPE_AUDIO,
549
    .id             = AV_CODEC_ID_RA_144,
550
    .priv_data_size = sizeof(RA144Context),
551
    .init           = ra144_encode_init,
552
    .encode2        = ra144_encode_frame,
553
    .close          = ra144_encode_close,
554
    .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SMALL_LAST_FRAME,
555
    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
556
                                                     AV_SAMPLE_FMT_NONE },
557
    .supported_samplerates = (const int[]){ 8000, 0 },
558
    .channel_layouts = (const uint64_t[]) { AV_CH_LAYOUT_MONO, 0 },
559
};