This commit is contained in:
2025-08-27 15:09:05 +09:00
parent 57961d84de
commit a13f66d917
9896 changed files with 2193048 additions and 730 deletions
+30
View File
@@ -0,0 +1,30 @@
clean::
$(RM) $(CLEANSUFFIXES:%=libavcodec/opus/%)
OBJS-$(CONFIG_OPUS_DECODER) += \
opus/dec.o \
opus/dec_celt.o \
opus/celt.o \
opus/pvq.o \
opus/silk.o \
opus/tab.o \
opus/dsp.o \
opus/parse.o \
opus/rc.o \
OBJS-$(CONFIG_OPUS_PARSER) += \
opus/parser.o \
opus/parse.o \
OBJS-$(CONFIG_OPUS_ENCODER) += \
opus/enc.o \
opus/enc_psy.o \
opus/celt.o \
opus/pvq.o \
opus/rc.o \
opus/tab.o \
libavcodec/opus/%.o: CPPFLAGS += -I$(SRC_PATH)/libavcodec/
+484
View File
@@ -0,0 +1,484 @@
/*
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdint.h>
#include "celt.h"
#include "pvq.h"
#include "tab.h"
void ff_celt_quant_bands(CeltFrame *f, OpusRangeCoder *rc)
{
float lowband_scratch[8 * 22];
float norm1[2 * 8 * 100];
float *norm2 = norm1 + 8 * 100;
int totalbits = (f->framebits << 3) - f->anticollapse_needed;
int update_lowband = 1;
int lowband_offset = 0;
int i, j;
for (i = f->start_band; i < f->end_band; i++) {
uint32_t cm[2] = { (1 << f->blocks) - 1, (1 << f->blocks) - 1 };
int band_offset = ff_celt_freq_bands[i] << f->size;
int band_size = ff_celt_freq_range[i] << f->size;
float *X = f->block[0].coeffs + band_offset;
float *Y = (f->channels == 2) ? f->block[1].coeffs + band_offset : NULL;
float *norm_loc1, *norm_loc2;
int consumed = opus_rc_tell_frac(rc);
int effective_lowband = -1;
int b = 0;
/* Compute how many bits we want to allocate to this band */
if (i != f->start_band)
f->remaining -= consumed;
f->remaining2 = totalbits - consumed - 1;
if (i <= f->coded_bands - 1) {
int curr_balance = f->remaining / FFMIN(3, f->coded_bands-i);
b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[i] + curr_balance), 14);
}
if ((ff_celt_freq_bands[i] - ff_celt_freq_range[i] >= ff_celt_freq_bands[f->start_band] ||
i == f->start_band + 1) && (update_lowband || lowband_offset == 0))
lowband_offset = i;
if (i == f->start_band + 1) {
/* Special Hybrid Folding (RFC 8251 section 9). Copy the first band into
the second to ensure the second band never has to use the LCG. */
int count = (ff_celt_freq_range[i] - ff_celt_freq_range[i-1]) << f->size;
memcpy(&norm1[band_offset], &norm1[band_offset - count], count * sizeof(float));
if (f->channels == 2)
memcpy(&norm2[band_offset], &norm2[band_offset - count], count * sizeof(float));
}
/* Get a conservative estimate of the collapse_mask's for the bands we're
going to be folding from. */
if (lowband_offset != 0 && (f->spread != CELT_SPREAD_AGGRESSIVE ||
f->blocks > 1 || f->tf_change[i] < 0)) {
int foldstart, foldend;
/* This ensures we never repeat spectral content within one band */
effective_lowband = FFMAX(ff_celt_freq_bands[f->start_band],
ff_celt_freq_bands[lowband_offset] - ff_celt_freq_range[i]);
foldstart = lowband_offset;
while (ff_celt_freq_bands[--foldstart] > effective_lowband);
foldend = lowband_offset - 1;
while (++foldend < i && ff_celt_freq_bands[foldend] < effective_lowband + ff_celt_freq_range[i]);
cm[0] = cm[1] = 0;
for (j = foldstart; j < foldend; j++) {
cm[0] |= f->block[0].collapse_masks[j];
cm[1] |= f->block[f->channels - 1].collapse_masks[j];
}
}
if (f->dual_stereo && i == f->intensity_stereo) {
/* Switch off dual stereo to do intensity */
f->dual_stereo = 0;
for (j = ff_celt_freq_bands[f->start_band] << f->size; j < band_offset; j++)
norm1[j] = (norm1[j] + norm2[j]) / 2;
}
norm_loc1 = effective_lowband != -1 ? norm1 + (effective_lowband << f->size) : NULL;
norm_loc2 = effective_lowband != -1 ? norm2 + (effective_lowband << f->size) : NULL;
if (f->dual_stereo) {
cm[0] = f->pvq->quant_band(f->pvq, f, rc, i, X, NULL, band_size, b >> 1,
f->blocks, norm_loc1, f->size,
norm1 + band_offset, 0, 1.0f,
lowband_scratch, cm[0]);
cm[1] = f->pvq->quant_band(f->pvq, f, rc, i, Y, NULL, band_size, b >> 1,
f->blocks, norm_loc2, f->size,
norm2 + band_offset, 0, 1.0f,
lowband_scratch, cm[1]);
} else {
cm[0] = f->pvq->quant_band(f->pvq, f, rc, i, X, Y, band_size, b >> 0,
f->blocks, norm_loc1, f->size,
norm1 + band_offset, 0, 1.0f,
lowband_scratch, cm[0] | cm[1]);
cm[1] = cm[0];
}
f->block[0].collapse_masks[i] = (uint8_t)cm[0];
f->block[f->channels - 1].collapse_masks[i] = (uint8_t)cm[1];
f->remaining += f->pulses[i] + consumed;
/* Update the folding position only as long as we have 1 bit/sample depth */
update_lowband = (b > band_size << 3);
}
}
#define NORMC(bits) ((bits) << (f->channels - 1) << f->size >> 2)
void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode)
{
int i, j, low, high, total, done, bandbits, remaining, tbits_8ths;
int skip_startband = f->start_band;
int skip_bit = 0;
int intensitystereo_bit = 0;
int dualstereo_bit = 0;
int dynalloc = 6;
int extrabits = 0;
int boost[CELT_MAX_BANDS] = { 0 };
int trim_offset[CELT_MAX_BANDS];
int threshold[CELT_MAX_BANDS];
int bits1[CELT_MAX_BANDS];
int bits2[CELT_MAX_BANDS];
/* Spread */
if (opus_rc_tell(rc) + 4 <= f->framebits) {
if (encode)
ff_opus_rc_enc_cdf(rc, f->spread, ff_celt_model_spread);
else
f->spread = ff_opus_rc_dec_cdf(rc, ff_celt_model_spread);
} else {
f->spread = CELT_SPREAD_NORMAL;
}
/* Initialize static allocation caps */
for (i = 0; i < CELT_MAX_BANDS; i++)
f->caps[i] = NORMC((ff_celt_static_caps[f->size][f->channels - 1][i] + 64) * ff_celt_freq_range[i]);
/* Band boosts */
tbits_8ths = f->framebits << 3;
for (i = f->start_band; i < f->end_band; i++) {
int quanta = ff_celt_freq_range[i] << (f->channels - 1) << f->size;
int b_dynalloc = dynalloc;
int boost_amount = f->alloc_boost[i];
quanta = FFMIN(quanta << 3, FFMAX(6 << 3, quanta));
while (opus_rc_tell_frac(rc) + (b_dynalloc << 3) < tbits_8ths && boost[i] < f->caps[i]) {
int is_boost;
if (encode) {
is_boost = boost_amount--;
ff_opus_rc_enc_log(rc, is_boost, b_dynalloc);
} else {
is_boost = ff_opus_rc_dec_log(rc, b_dynalloc);
}
if (!is_boost)
break;
boost[i] += quanta;
tbits_8ths -= quanta;
b_dynalloc = 1;
}
if (boost[i])
dynalloc = FFMAX(dynalloc - 1, 2);
}
/* Allocation trim */
if (!encode)
f->alloc_trim = 5;
if (opus_rc_tell_frac(rc) + (6 << 3) <= tbits_8ths)
if (encode)
ff_opus_rc_enc_cdf(rc, f->alloc_trim, ff_celt_model_alloc_trim);
else
f->alloc_trim = ff_opus_rc_dec_cdf(rc, ff_celt_model_alloc_trim);
/* Anti-collapse bit reservation */
tbits_8ths = (f->framebits << 3) - opus_rc_tell_frac(rc) - 1;
f->anticollapse_needed = 0;
if (f->transient && f->size >= 2 && tbits_8ths >= ((f->size + 2) << 3))
f->anticollapse_needed = 1 << 3;
tbits_8ths -= f->anticollapse_needed;
/* Band skip bit reservation */
if (tbits_8ths >= 1 << 3)
skip_bit = 1 << 3;
tbits_8ths -= skip_bit;
/* Intensity/dual stereo bit reservation */
if (f->channels == 2) {
intensitystereo_bit = ff_celt_log2_frac[f->end_band - f->start_band];
if (intensitystereo_bit <= tbits_8ths) {
tbits_8ths -= intensitystereo_bit;
if (tbits_8ths >= 1 << 3) {
dualstereo_bit = 1 << 3;
tbits_8ths -= 1 << 3;
}
} else {
intensitystereo_bit = 0;
}
}
/* Trim offsets */
for (i = f->start_band; i < f->end_band; i++) {
int trim = f->alloc_trim - 5 - f->size;
int band = ff_celt_freq_range[i] * (f->end_band - i - 1);
int duration = f->size + 3;
int scale = duration + f->channels - 1;
/* PVQ minimum allocation threshold, below this value the band is
* skipped */
threshold[i] = FFMAX(3 * ff_celt_freq_range[i] << duration >> 4,
f->channels << 3);
trim_offset[i] = trim * (band << scale) >> 6;
if (ff_celt_freq_range[i] << f->size == 1)
trim_offset[i] -= f->channels << 3;
}
/* Bisection */
low = 1;
high = CELT_VECTORS - 1;
while (low <= high) {
int center = (low + high) >> 1;
done = total = 0;
for (i = f->end_band - 1; i >= f->start_band; i--) {
bandbits = NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[center][i]);
if (bandbits)
bandbits = FFMAX(bandbits + trim_offset[i], 0);
bandbits += boost[i];
if (bandbits >= threshold[i] || done) {
done = 1;
total += FFMIN(bandbits, f->caps[i]);
} else if (bandbits >= f->channels << 3) {
total += f->channels << 3;
}
}
if (total > tbits_8ths)
high = center - 1;
else
low = center + 1;
}
high = low--;
/* Bisection */
for (i = f->start_band; i < f->end_band; i++) {
bits1[i] = NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[low][i]);
bits2[i] = high >= CELT_VECTORS ? f->caps[i] :
NORMC(ff_celt_freq_range[i] * ff_celt_static_alloc[high][i]);
if (bits1[i])
bits1[i] = FFMAX(bits1[i] + trim_offset[i], 0);
if (bits2[i])
bits2[i] = FFMAX(bits2[i] + trim_offset[i], 0);
if (low)
bits1[i] += boost[i];
bits2[i] += boost[i];
if (boost[i])
skip_startband = i;
bits2[i] = FFMAX(bits2[i] - bits1[i], 0);
}
/* Bisection */
low = 0;
high = 1 << CELT_ALLOC_STEPS;
for (i = 0; i < CELT_ALLOC_STEPS; i++) {
int center = (low + high) >> 1;
done = total = 0;
for (j = f->end_band - 1; j >= f->start_band; j--) {
bandbits = bits1[j] + (center * bits2[j] >> CELT_ALLOC_STEPS);
if (bandbits >= threshold[j] || done) {
done = 1;
total += FFMIN(bandbits, f->caps[j]);
} else if (bandbits >= f->channels << 3)
total += f->channels << 3;
}
if (total > tbits_8ths)
high = center;
else
low = center;
}
/* Bisection */
done = total = 0;
for (i = f->end_band - 1; i >= f->start_band; i--) {
bandbits = bits1[i] + (low * bits2[i] >> CELT_ALLOC_STEPS);
if (bandbits >= threshold[i] || done)
done = 1;
else
bandbits = (bandbits >= f->channels << 3) ?
f->channels << 3 : 0;
bandbits = FFMIN(bandbits, f->caps[i]);
f->pulses[i] = bandbits;
total += bandbits;
}
/* Band skipping */
for (f->coded_bands = f->end_band; ; f->coded_bands--) {
int allocation;
j = f->coded_bands - 1;
if (j == skip_startband) {
/* all remaining bands are not skipped */
tbits_8ths += skip_bit;
break;
}
/* determine the number of bits available for coding "do not skip" markers */
remaining = tbits_8ths - total;
bandbits = remaining / (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[f->start_band]);
remaining -= bandbits * (ff_celt_freq_bands[j+1] - ff_celt_freq_bands[f->start_band]);
allocation = f->pulses[j] + bandbits * ff_celt_freq_range[j];
allocation += FFMAX(remaining - (ff_celt_freq_bands[j] - ff_celt_freq_bands[f->start_band]), 0);
/* a "do not skip" marker is only coded if the allocation is
* above the chosen threshold */
if (allocation >= FFMAX(threshold[j], (f->channels + 1) << 3)) {
int do_not_skip;
if (encode) {
do_not_skip = f->coded_bands <= f->skip_band_floor;
ff_opus_rc_enc_log(rc, do_not_skip, 1);
} else {
do_not_skip = ff_opus_rc_dec_log(rc, 1);
}
if (do_not_skip)
break;
total += 1 << 3;
allocation -= 1 << 3;
}
/* the band is skipped, so reclaim its bits */
total -= f->pulses[j];
if (intensitystereo_bit) {
total -= intensitystereo_bit;
intensitystereo_bit = ff_celt_log2_frac[j - f->start_band];
total += intensitystereo_bit;
}
total += f->pulses[j] = (allocation >= f->channels << 3) ? f->channels << 3 : 0;
}
/* IS start band */
if (encode) {
if (intensitystereo_bit) {
f->intensity_stereo = FFMIN(f->intensity_stereo, f->coded_bands);
ff_opus_rc_enc_uint(rc, f->intensity_stereo, f->coded_bands + 1 - f->start_band);
}
} else {
f->intensity_stereo = f->dual_stereo = 0;
if (intensitystereo_bit)
f->intensity_stereo = f->start_band + ff_opus_rc_dec_uint(rc, f->coded_bands + 1 - f->start_band);
}
/* DS flag */
if (f->intensity_stereo <= f->start_band)
tbits_8ths += dualstereo_bit; /* no intensity stereo means no dual stereo */
else if (dualstereo_bit)
if (encode)
ff_opus_rc_enc_log(rc, f->dual_stereo, 1);
else
f->dual_stereo = ff_opus_rc_dec_log(rc, 1);
/* Supply the remaining bits in this frame to lower bands */
remaining = tbits_8ths - total;
bandbits = remaining / (ff_celt_freq_bands[f->coded_bands] - ff_celt_freq_bands[f->start_band]);
remaining -= bandbits * (ff_celt_freq_bands[f->coded_bands] - ff_celt_freq_bands[f->start_band]);
for (i = f->start_band; i < f->coded_bands; i++) {
const int bits = FFMIN(remaining, ff_celt_freq_range[i]);
f->pulses[i] += bits + bandbits * ff_celt_freq_range[i];
remaining -= bits;
}
/* Finally determine the allocation */
for (i = f->start_band; i < f->coded_bands; i++) {
int N = ff_celt_freq_range[i] << f->size;
int prev_extra = extrabits;
f->pulses[i] += extrabits;
if (N > 1) {
int dof; /* degrees of freedom */
int temp; /* dof * channels * log(dof) */
int fine_bits;
int max_bits;
int offset; /* fine energy quantization offset, i.e.
* extra bits assigned over the standard
* totalbits/dof */
extrabits = FFMAX(f->pulses[i] - f->caps[i], 0);
f->pulses[i] -= extrabits;
/* intensity stereo makes use of an extra degree of freedom */
dof = N * f->channels + (f->channels == 2 && N > 2 && !f->dual_stereo && i < f->intensity_stereo);
temp = dof * (ff_celt_log_freq_range[i] + (f->size << 3));
offset = (temp >> 1) - dof * CELT_FINE_OFFSET;
if (N == 2) /* dof=2 is the only case that doesn't fit the model */
offset += dof << 1;
/* grant an additional bias for the first and second pulses */
if (f->pulses[i] + offset < 2 * (dof << 3))
offset += temp >> 2;
else if (f->pulses[i] + offset < 3 * (dof << 3))
offset += temp >> 3;
fine_bits = (f->pulses[i] + offset + (dof << 2)) / (dof << 3);
max_bits = FFMIN((f->pulses[i] >> 3) >> (f->channels - 1), CELT_MAX_FINE_BITS);
max_bits = FFMAX(max_bits, 0);
f->fine_bits[i] = av_clip(fine_bits, 0, max_bits);
/* If fine_bits was rounded down or capped,
* give priority for the final fine energy pass */
f->fine_priority[i] = (f->fine_bits[i] * (dof << 3) >= f->pulses[i] + offset);
/* the remaining bits are assigned to PVQ */
f->pulses[i] -= f->fine_bits[i] << (f->channels - 1) << 3;
} else {
/* all bits go to fine energy except for the sign bit */
extrabits = FFMAX(f->pulses[i] - (f->channels << 3), 0);
f->pulses[i] -= extrabits;
f->fine_bits[i] = 0;
f->fine_priority[i] = 1;
}
/* hand back a limited number of extra fine energy bits to this band */
if (extrabits > 0) {
int fineextra = FFMIN(extrabits >> (f->channels + 2),
CELT_MAX_FINE_BITS - f->fine_bits[i]);
f->fine_bits[i] += fineextra;
fineextra <<= f->channels + 2;
f->fine_priority[i] = (fineextra >= extrabits - prev_extra);
extrabits -= fineextra;
}
}
f->remaining = extrabits;
/* skipped bands dedicate all of their bits for fine energy */
for (; i < f->end_band; i++) {
f->fine_bits[i] = f->pulses[i] >> (f->channels - 1) >> 3;
f->pulses[i] = 0;
f->fine_priority[i] = f->fine_bits[i] < 1;
}
}
+184
View File
@@ -0,0 +1,184 @@
/*
* Opus decoder/encoder CELT functions
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
* Copyright (c) 2016 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_OPUS_CELT_H
#define AVCODEC_OPUS_CELT_H
#include <stdint.h>
#include "libavcodec/avcodec.h"
#include "dsp.h"
#include "rc.h"
#include "libavutil/float_dsp.h"
#include "libavutil/libm.h"
#include "libavutil/mem_internal.h"
#include "libavutil/tx.h"
#define CELT_SHORT_BLOCKSIZE 120
#define CELT_OVERLAP CELT_SHORT_BLOCKSIZE
#define CELT_MAX_LOG_BLOCKS 3
#define CELT_MAX_FRAME_SIZE (CELT_SHORT_BLOCKSIZE * (1 << CELT_MAX_LOG_BLOCKS))
#define CELT_MAX_BANDS 21
#define CELT_VECTORS 11
#define CELT_ALLOC_STEPS 6
#define CELT_FINE_OFFSET 21
#define CELT_MAX_FINE_BITS 8
#define CELT_NORM_SCALE 16384
#define CELT_QTHETA_OFFSET 4
#define CELT_QTHETA_OFFSET_TWOPHASE 16
#define CELT_POSTFILTER_MINPERIOD 15
#define CELT_ENERGY_SILENCE (-28.0f)
enum CeltSpread {
CELT_SPREAD_NONE,
CELT_SPREAD_LIGHT,
CELT_SPREAD_NORMAL,
CELT_SPREAD_AGGRESSIVE
};
enum CeltBlockSize {
CELT_BLOCK_120,
CELT_BLOCK_240,
CELT_BLOCK_480,
CELT_BLOCK_960,
CELT_BLOCK_NB
};
typedef struct CeltBlock {
float energy[CELT_MAX_BANDS];
float lin_energy[CELT_MAX_BANDS];
float error_energy[CELT_MAX_BANDS];
float prev_energy[2][CELT_MAX_BANDS];
uint8_t collapse_masks[CELT_MAX_BANDS];
/* buffer for mdct output + postfilter */
DECLARE_ALIGNED(32, float, buf)[2048];
DECLARE_ALIGNED(32, float, coeffs)[CELT_MAX_FRAME_SIZE];
/* Used by the encoder */
DECLARE_ALIGNED(32, float, overlap)[FFALIGN(CELT_OVERLAP, 16)];
DECLARE_ALIGNED(32, float, samples)[FFALIGN(CELT_MAX_FRAME_SIZE, 16)];
/* postfilter parameters */
int pf_period_new;
float pf_gains_new[3];
int pf_period;
float pf_gains[3];
int pf_period_old;
float pf_gains_old[3];
float emph_coeff;
} CeltBlock;
typedef struct CeltFrame {
// constant values that do not change during context lifetime
AVCodecContext *avctx;
AVTXContext *tx[4];
av_tx_fn tx_fn[4];
AVFloatDSPContext *dsp;
CeltBlock block[2];
struct CeltPVQ *pvq;
OpusDSP opusdsp;
int channels;
int output_channels;
int apply_phase_inv;
enum CeltBlockSize size;
int start_band;
int end_band;
int coded_bands;
int transient;
int pfilter;
int skip_band_floor;
int tf_select;
int alloc_trim;
int alloc_boost[CELT_MAX_BANDS];
int blocks; /* number of iMDCT blocks in the frame, depends on transient */
int blocksize; /* size of each block */
int silence; /* Frame is filled with silence */
int anticollapse_needed; /* Whether to expect an anticollapse bit */
int anticollapse; /* Encoded anticollapse bit */
int intensity_stereo;
int dual_stereo;
int flushed;
uint32_t seed;
enum CeltSpread spread;
/* Encoder PF coeffs */
int pf_octave;
int pf_period;
int pf_tapset;
float pf_gain;
/* Bit allocation */
int framebits;
int remaining;
int remaining2;
int caps [CELT_MAX_BANDS];
int fine_bits [CELT_MAX_BANDS];
int fine_priority[CELT_MAX_BANDS];
int pulses [CELT_MAX_BANDS];
int tf_change [CELT_MAX_BANDS];
} CeltFrame;
/* LCG for noise generation */
static av_always_inline uint32_t celt_rng(CeltFrame *f)
{
f->seed = 1664525 * f->seed + 1013904223;
return f->seed;
}
static av_always_inline void celt_renormalize_vector(float *X, int N, float gain)
{
int i;
float g = 1e-15f;
for (i = 0; i < N; i++)
g += X[i] * X[i];
g = gain / sqrtf(g);
for (i = 0; i < N; i++)
X[i] *= g;
}
int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels,
int apply_phase_inv);
void ff_celt_free(CeltFrame **f);
void ff_celt_flush(CeltFrame *f);
int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc, float **output,
int coded_channels, int frame_size, int startband, int endband);
/* Encode or decode CELT bands */
void ff_celt_quant_bands(CeltFrame *f, OpusRangeCoder *rc);
/* Encode or decode CELT bitallocation */
void ff_celt_bitalloc(CeltFrame *f, OpusRangeCoder *rc, int encode);
#endif /* AVCODEC_OPUS_CELT_H */
+785
View File
@@ -0,0 +1,785 @@
/*
* Opus decoder
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Opus decoder
* @author Andrew D'Addesio, Anton Khirnov
*
* Codec homepage: http://opus-codec.org/
* Specification: http://tools.ietf.org/html/rfc6716
* Ogg Opus specification: https://tools.ietf.org/html/draft-ietf-codec-oggopus-03
*
* Ogg-contained .opus files can be produced with opus-tools:
* http://git.xiph.org/?p=opus-tools.git
*/
#include <stdint.h>
#include "libavutil/attributes.h"
#include "libavutil/audio_fifo.h"
#include "libavutil/channel_layout.h"
#include "libavutil/ffmath.h"
#include "libavutil/float_dsp.h"
#include "libavutil/frame.h"
#include "libavutil/mem.h"
#include "libavutil/mem_internal.h"
#include "libavutil/opt.h"
#include "libswresample/swresample.h"
#include "avcodec.h"
#include "codec_internal.h"
#include "decode.h"
#include "opus.h"
#include "tab.h"
#include "celt.h"
#include "parse.h"
#include "rc.h"
#include "silk.h"
static const uint16_t silk_frame_duration_ms[16] = {
10, 20, 40, 60,
10, 20, 40, 60,
10, 20, 40, 60,
10, 20,
10, 20,
};
/* number of samples of silence to feed to the resampler
* at the beginning */
static const int silk_resample_delay[] = {
4, 8, 11, 11, 11
};
typedef struct OpusStreamContext {
AVCodecContext *avctx;
int output_channels;
/* number of decoded samples for this stream */
int decoded_samples;
/* current output buffers for this stream */
float *out[2];
int out_size;
/* Buffer with samples from this stream for synchronizing
* the streams when they have different resampling delays */
AVAudioFifo *sync_buffer;
OpusRangeCoder rc;
OpusRangeCoder redundancy_rc;
SilkContext *silk;
CeltFrame *celt;
AVFloatDSPContext *fdsp;
float silk_buf[2][960];
float *silk_output[2];
DECLARE_ALIGNED(32, float, celt_buf)[2][960];
float *celt_output[2];
DECLARE_ALIGNED(32, float, redundancy_buf)[2][960];
float *redundancy_output[2];
/* buffers for the next samples to be decoded */
float *cur_out[2];
int remaining_out_size;
float *out_dummy;
int out_dummy_allocated_size;
SwrContext *swr;
AVAudioFifo *celt_delay;
int silk_samplerate;
/* number of samples we still want to get from the resampler */
int delayed_samples;
OpusPacket packet;
int redundancy_idx;
} OpusStreamContext;
typedef struct OpusContext {
AVClass *av_class;
struct OpusStreamContext *streams;
int apply_phase_inv;
AVFloatDSPContext *fdsp;
float gain;
OpusParseContext p;
} OpusContext;
static int get_silk_samplerate(int config)
{
if (config < 4)
return 8000;
else if (config < 8)
return 12000;
return 16000;
}
static void opus_fade(float *out,
const float *in1, const float *in2,
const float *window, int len)
{
int i;
for (i = 0; i < len; i++)
out[i] = in2[i] * window[i] + in1[i] * (1.0 - window[i]);
}
static int opus_flush_resample(OpusStreamContext *s, int nb_samples)
{
int celt_size = av_audio_fifo_size(s->celt_delay);
int ret, i;
ret = swr_convert(s->swr,
(uint8_t**)s->cur_out, nb_samples,
NULL, 0);
if (ret < 0)
return ret;
else if (ret != nb_samples) {
av_log(s->avctx, AV_LOG_ERROR, "Wrong number of flushed samples: %d\n",
ret);
return AVERROR_BUG;
}
if (celt_size) {
if (celt_size != nb_samples) {
av_log(s->avctx, AV_LOG_ERROR, "Wrong number of CELT delay samples.\n");
return AVERROR_BUG;
}
av_audio_fifo_read(s->celt_delay, (void**)s->celt_output, nb_samples);
for (i = 0; i < s->output_channels; i++) {
s->fdsp->vector_fmac_scalar(s->cur_out[i],
s->celt_output[i], 1.0,
nb_samples);
}
}
if (s->redundancy_idx) {
for (i = 0; i < s->output_channels; i++)
opus_fade(s->cur_out[i], s->cur_out[i],
s->redundancy_output[i] + 120 + s->redundancy_idx,
ff_celt_window2 + s->redundancy_idx, 120 - s->redundancy_idx);
s->redundancy_idx = 0;
}
s->cur_out[0] += nb_samples;
s->cur_out[1] += nb_samples;
s->remaining_out_size -= nb_samples * sizeof(float);
return 0;
}
static int opus_init_resample(OpusStreamContext *s)
{
static const float delay[16] = { 0.0 };
const uint8_t *delayptr[2] = { (uint8_t*)delay, (uint8_t*)delay };
int ret;
av_opt_set_int(s->swr, "in_sample_rate", s->silk_samplerate, 0);
ret = swr_init(s->swr);
if (ret < 0) {
av_log(s->avctx, AV_LOG_ERROR, "Error opening the resampler.\n");
return ret;
}
ret = swr_convert(s->swr,
NULL, 0,
delayptr, silk_resample_delay[s->packet.bandwidth]);
if (ret < 0) {
av_log(s->avctx, AV_LOG_ERROR,
"Error feeding initial silence to the resampler.\n");
return ret;
}
return 0;
}
static int opus_decode_redundancy(OpusStreamContext *s, const uint8_t *data, int size)
{
int ret = ff_opus_rc_dec_init(&s->redundancy_rc, data, size);
if (ret < 0)
goto fail;
ff_opus_rc_dec_raw_init(&s->redundancy_rc, data + size, size);
ret = ff_celt_decode_frame(s->celt, &s->redundancy_rc,
s->redundancy_output,
s->packet.stereo + 1, 240,
0, ff_celt_band_end[s->packet.bandwidth]);
if (ret < 0)
goto fail;
return 0;
fail:
av_log(s->avctx, AV_LOG_ERROR, "Error decoding the redundancy frame.\n");
return ret;
}
static int opus_decode_frame(OpusStreamContext *s, const uint8_t *data, int size)
{
int samples = s->packet.frame_duration;
int redundancy = 0;
int redundancy_size, redundancy_pos;
int ret, i, consumed;
int delayed_samples = s->delayed_samples;
ret = ff_opus_rc_dec_init(&s->rc, data, size);
if (ret < 0)
return ret;
/* decode the silk frame */
if (s->packet.mode == OPUS_MODE_SILK || s->packet.mode == OPUS_MODE_HYBRID) {
if (!swr_is_initialized(s->swr)) {
ret = opus_init_resample(s);
if (ret < 0)
return ret;
}
samples = ff_silk_decode_superframe(s->silk, &s->rc, s->silk_output,
FFMIN(s->packet.bandwidth, OPUS_BANDWIDTH_WIDEBAND),
s->packet.stereo + 1,
silk_frame_duration_ms[s->packet.config]);
if (samples < 0) {
av_log(s->avctx, AV_LOG_ERROR, "Error decoding a SILK frame.\n");
return samples;
}
samples = swr_convert(s->swr,
(uint8_t**)s->cur_out, s->packet.frame_duration,
(const uint8_t**)s->silk_output, samples);
if (samples < 0) {
av_log(s->avctx, AV_LOG_ERROR, "Error resampling SILK data.\n");
return samples;
}
av_assert2((samples & 7) == 0);
s->delayed_samples += s->packet.frame_duration - samples;
} else
ff_silk_flush(s->silk);
// decode redundancy information
consumed = opus_rc_tell(&s->rc);
if (s->packet.mode == OPUS_MODE_HYBRID && consumed + 37 <= size * 8)
redundancy = ff_opus_rc_dec_log(&s->rc, 12);
else if (s->packet.mode == OPUS_MODE_SILK && consumed + 17 <= size * 8)
redundancy = 1;
if (redundancy) {
redundancy_pos = ff_opus_rc_dec_log(&s->rc, 1);
if (s->packet.mode == OPUS_MODE_HYBRID)
redundancy_size = ff_opus_rc_dec_uint(&s->rc, 256) + 2;
else
redundancy_size = size - (consumed + 7) / 8;
size -= redundancy_size;
if (size < 0) {
av_log(s->avctx, AV_LOG_ERROR, "Invalid redundancy frame size.\n");
return AVERROR_INVALIDDATA;
}
if (redundancy_pos) {
ret = opus_decode_redundancy(s, data + size, redundancy_size);
if (ret < 0)
return ret;
ff_celt_flush(s->celt);
}
}
/* decode the CELT frame */
if (s->packet.mode == OPUS_MODE_CELT || s->packet.mode == OPUS_MODE_HYBRID) {
float *out_tmp[2] = { s->cur_out[0], s->cur_out[1] };
float **dst = (s->packet.mode == OPUS_MODE_CELT) ?
out_tmp : s->celt_output;
int celt_output_samples = samples;
int delay_samples = av_audio_fifo_size(s->celt_delay);
if (delay_samples) {
if (s->packet.mode == OPUS_MODE_HYBRID) {
av_audio_fifo_read(s->celt_delay, (void**)s->celt_output, delay_samples);
for (i = 0; i < s->output_channels; i++) {
s->fdsp->vector_fmac_scalar(out_tmp[i], s->celt_output[i], 1.0,
delay_samples);
out_tmp[i] += delay_samples;
}
celt_output_samples -= delay_samples;
} else {
av_log(s->avctx, AV_LOG_WARNING,
"Spurious CELT delay samples present.\n");
av_audio_fifo_reset(s->celt_delay);
if (s->avctx->err_recognition & AV_EF_EXPLODE)
return AVERROR_BUG;
}
}
ff_opus_rc_dec_raw_init(&s->rc, data + size, size);
ret = ff_celt_decode_frame(s->celt, &s->rc, dst,
s->packet.stereo + 1,
s->packet.frame_duration,
(s->packet.mode == OPUS_MODE_HYBRID) ? 17 : 0,
ff_celt_band_end[s->packet.bandwidth]);
if (ret < 0)
return ret;
if (s->packet.mode == OPUS_MODE_HYBRID) {
int celt_delay = s->packet.frame_duration - celt_output_samples;
void *delaybuf[2] = { s->celt_output[0] + celt_output_samples,
s->celt_output[1] + celt_output_samples };
for (i = 0; i < s->output_channels; i++) {
s->fdsp->vector_fmac_scalar(out_tmp[i],
s->celt_output[i], 1.0,
celt_output_samples);
}
ret = av_audio_fifo_write(s->celt_delay, delaybuf, celt_delay);
if (ret < 0)
return ret;
}
} else
ff_celt_flush(s->celt);
if (s->redundancy_idx) {
for (i = 0; i < s->output_channels; i++)
opus_fade(s->cur_out[i], s->cur_out[i],
s->redundancy_output[i] + 120 + s->redundancy_idx,
ff_celt_window2 + s->redundancy_idx, 120 - s->redundancy_idx);
s->redundancy_idx = 0;
}
if (redundancy) {
if (!redundancy_pos) {
ff_celt_flush(s->celt);
ret = opus_decode_redundancy(s, data + size, redundancy_size);
if (ret < 0)
return ret;
for (i = 0; i < s->output_channels; i++) {
opus_fade(s->cur_out[i] + samples - 120 + delayed_samples,
s->cur_out[i] + samples - 120 + delayed_samples,
s->redundancy_output[i] + 120,
ff_celt_window2, 120 - delayed_samples);
if (delayed_samples)
s->redundancy_idx = 120 - delayed_samples;
}
} else {
for (i = 0; i < s->output_channels; i++) {
memcpy(s->cur_out[i] + delayed_samples, s->redundancy_output[i], 120 * sizeof(float));
opus_fade(s->cur_out[i] + 120 + delayed_samples,
s->redundancy_output[i] + 120,
s->cur_out[i] + 120 + delayed_samples,
ff_celt_window2, 120);
}
}
}
return samples;
}
static int opus_decode_subpacket(OpusStreamContext *s, const uint8_t *buf)
{
int output_samples = 0;
int flush_needed = 0;
int i, j, ret;
s->cur_out[0] = s->out[0];
s->cur_out[1] = s->out[1];
s->remaining_out_size = s->out_size;
/* check if we need to flush the resampler */
if (swr_is_initialized(s->swr)) {
if (buf) {
int64_t cur_samplerate;
av_opt_get_int(s->swr, "in_sample_rate", 0, &cur_samplerate);
flush_needed = (s->packet.mode == OPUS_MODE_CELT) || (cur_samplerate != s->silk_samplerate);
} else {
flush_needed = !!s->delayed_samples;
}
}
if (!buf && !flush_needed)
return 0;
/* use dummy output buffers if the channel is not mapped to anything */
if (!s->cur_out[0] ||
(s->output_channels == 2 && !s->cur_out[1])) {
av_fast_malloc(&s->out_dummy, &s->out_dummy_allocated_size,
s->remaining_out_size);
if (!s->out_dummy)
return AVERROR(ENOMEM);
if (!s->cur_out[0])
s->cur_out[0] = s->out_dummy;
if (!s->cur_out[1])
s->cur_out[1] = s->out_dummy;
}
/* flush the resampler if necessary */
if (flush_needed) {
ret = opus_flush_resample(s, s->delayed_samples);
if (ret < 0) {
av_log(s->avctx, AV_LOG_ERROR, "Error flushing the resampler.\n");
return ret;
}
swr_close(s->swr);
output_samples += s->delayed_samples;
s->delayed_samples = 0;
if (!buf)
goto finish;
}
/* decode all the frames in the packet */
for (i = 0; i < s->packet.frame_count; i++) {
int size = s->packet.frame_size[i];
int samples = opus_decode_frame(s, buf + s->packet.frame_offset[i], size);
if (samples < 0) {
av_log(s->avctx, AV_LOG_ERROR, "Error decoding an Opus frame.\n");
if (s->avctx->err_recognition & AV_EF_EXPLODE)
return samples;
for (j = 0; j < s->output_channels; j++)
memset(s->cur_out[j], 0, s->packet.frame_duration * sizeof(float));
samples = s->packet.frame_duration;
}
output_samples += samples;
for (j = 0; j < s->output_channels; j++)
s->cur_out[j] += samples;
s->remaining_out_size -= samples * sizeof(float);
}
finish:
s->cur_out[0] = s->cur_out[1] = NULL;
s->remaining_out_size = 0;
return output_samples;
}
static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame,
int *got_frame_ptr, AVPacket *avpkt)
{
OpusContext *c = avctx->priv_data;
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
int coded_samples = 0;
int decoded_samples = INT_MAX;
int delayed_samples = 0;
int i, ret;
/* calculate the number of delayed samples */
for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];
s->out[0] =
s->out[1] = NULL;
int fifo_samples = av_audio_fifo_size(s->sync_buffer);
delayed_samples = FFMAX(delayed_samples,
s->delayed_samples + fifo_samples);
}
/* decode the header of the first sub-packet to find out the sample count */
if (buf) {
OpusPacket *pkt = &c->streams[0].packet;
ret = ff_opus_parse_packet(pkt, buf, buf_size, c->p.nb_streams > 1);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error parsing the packet header.\n");
return ret;
}
coded_samples += pkt->frame_count * pkt->frame_duration;
c->streams[0].silk_samplerate = get_silk_samplerate(pkt->config);
}
frame->nb_samples = coded_samples + delayed_samples;
/* no input or buffered data => nothing to do */
if (!frame->nb_samples) {
*got_frame_ptr = 0;
return 0;
}
/* setup the data buffers */
ret = ff_get_buffer(avctx, frame, 0);
if (ret < 0)
return ret;
frame->nb_samples = 0;
for (i = 0; i < avctx->ch_layout.nb_channels; i++) {
ChannelMap *map = &c->p.channel_maps[i];
if (!map->copy)
c->streams[map->stream_idx].out[map->channel_idx] = (float*)frame->extended_data[i];
}
/* read the data from the sync buffers */
for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];
float **out = s->out;
int sync_size = av_audio_fifo_size(s->sync_buffer);
float sync_dummy[32];
int out_dummy = (!out[0]) | ((!out[1]) << 1);
if (!out[0])
out[0] = sync_dummy;
if (!out[1])
out[1] = sync_dummy;
if (out_dummy && sync_size > FF_ARRAY_ELEMS(sync_dummy))
return AVERROR_BUG;
ret = av_audio_fifo_read(s->sync_buffer, (void**)out, sync_size);
if (ret < 0)
return ret;
if (out_dummy & 1)
out[0] = NULL;
else
out[0] += ret;
if (out_dummy & 2)
out[1] = NULL;
else
out[1] += ret;
s->out_size = frame->linesize[0] - ret * sizeof(float);
}
/* decode each sub-packet */
for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];
if (i && buf) {
ret = ff_opus_parse_packet(&s->packet, buf, buf_size, i != c->p.nb_streams - 1);
if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error parsing the packet header.\n");
return ret;
}
if (coded_samples != s->packet.frame_count * s->packet.frame_duration) {
av_log(avctx, AV_LOG_ERROR,
"Mismatching coded sample count in substream %d.\n", i);
return AVERROR_INVALIDDATA;
}
s->silk_samplerate = get_silk_samplerate(s->packet.config);
}
ret = opus_decode_subpacket(&c->streams[i], buf);
if (ret < 0)
return ret;
s->decoded_samples = ret;
decoded_samples = FFMIN(decoded_samples, ret);
if (!buf)
continue;
buf += s->packet.packet_size;
buf_size -= s->packet.packet_size;
}
/* buffer the extra samples */
for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];
int buffer_samples = s->decoded_samples - decoded_samples;
if (buffer_samples) {
float *buf[2] = { s->out[0] ? s->out[0] : (float*)frame->extended_data[0],
s->out[1] ? s->out[1] : (float*)frame->extended_data[0] };
buf[0] += decoded_samples;
buf[1] += decoded_samples;
ret = av_audio_fifo_write(s->sync_buffer, (void**)buf, buffer_samples);
if (ret < 0)
return ret;
}
}
for (i = 0; i < avctx->ch_layout.nb_channels; i++) {
ChannelMap *map = &c->p.channel_maps[i];
/* handle copied channels */
if (map->copy) {
memcpy(frame->extended_data[i],
frame->extended_data[map->copy_idx],
frame->linesize[0]);
} else if (map->silence) {
memset(frame->extended_data[i], 0, frame->linesize[0]);
}
if (c->p.gain_i && decoded_samples > 0) {
c->fdsp->vector_fmul_scalar((float*)frame->extended_data[i],
(float*)frame->extended_data[i],
c->gain, FFALIGN(decoded_samples, 8));
}
}
frame->nb_samples = decoded_samples;
*got_frame_ptr = !!decoded_samples;
return avpkt->size;
}
static av_cold void opus_decode_flush(AVCodecContext *ctx)
{
OpusContext *c = ctx->priv_data;
for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];
memset(&s->packet, 0, sizeof(s->packet));
s->delayed_samples = 0;
av_audio_fifo_reset(s->celt_delay);
swr_close(s->swr);
av_audio_fifo_reset(s->sync_buffer);
ff_silk_flush(s->silk);
ff_celt_flush(s->celt);
}
}
static av_cold int opus_decode_close(AVCodecContext *avctx)
{
OpusContext *c = avctx->priv_data;
for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];
ff_silk_free(&s->silk);
ff_celt_free(&s->celt);
av_freep(&s->out_dummy);
s->out_dummy_allocated_size = 0;
av_audio_fifo_free(s->sync_buffer);
av_audio_fifo_free(s->celt_delay);
swr_free(&s->swr);
}
av_freep(&c->streams);
c->p.nb_streams = 0;
av_freep(&c->p.channel_maps);
av_freep(&c->fdsp);
return 0;
}
static av_cold int opus_decode_init(AVCodecContext *avctx)
{
OpusContext *c = avctx->priv_data;
int ret;
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
avctx->sample_rate = 48000;
c->fdsp = avpriv_float_dsp_alloc(0);
if (!c->fdsp)
return AVERROR(ENOMEM);
/* find out the channel configuration */
ret = ff_opus_parse_extradata(avctx, &c->p);
if (ret < 0)
return ret;
if (c->p.gain_i)
c->gain = ff_exp10(c->p.gain_i / (20.0 * 256));
/* allocate and init each independent decoder */
c->streams = av_calloc(c->p.nb_streams, sizeof(*c->streams));
if (!c->streams) {
c->p.nb_streams = 0;
return AVERROR(ENOMEM);
}
for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];
AVChannelLayout layout;
s->output_channels = (i < c->p.nb_stereo_streams) ? 2 : 1;
s->avctx = avctx;
for (int j = 0; j < s->output_channels; j++) {
s->silk_output[j] = s->silk_buf[j];
s->celt_output[j] = s->celt_buf[j];
s->redundancy_output[j] = s->redundancy_buf[j];
}
s->fdsp = c->fdsp;
s->swr =swr_alloc();
if (!s->swr)
return AVERROR(ENOMEM);
layout = (s->output_channels == 1) ? (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO :
(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
av_opt_set_int(s->swr, "in_sample_fmt", avctx->sample_fmt, 0);
av_opt_set_int(s->swr, "out_sample_fmt", avctx->sample_fmt, 0);
av_opt_set_chlayout(s->swr, "in_chlayout", &layout, 0);
av_opt_set_chlayout(s->swr, "out_chlayout", &layout, 0);
av_opt_set_int(s->swr, "out_sample_rate", avctx->sample_rate, 0);
av_opt_set_int(s->swr, "filter_size", 16, 0);
ret = ff_silk_init(avctx, &s->silk, s->output_channels);
if (ret < 0)
return ret;
ret = ff_celt_init(avctx, &s->celt, s->output_channels, c->apply_phase_inv);
if (ret < 0)
return ret;
s->celt_delay = av_audio_fifo_alloc(avctx->sample_fmt,
s->output_channels, 1024);
if (!s->celt_delay)
return AVERROR(ENOMEM);
s->sync_buffer = av_audio_fifo_alloc(avctx->sample_fmt,
s->output_channels, 32);
if (!s->sync_buffer)
return AVERROR(ENOMEM);
}
return 0;
}
#define OFFSET(x) offsetof(OpusContext, x)
#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption opus_options[] = {
{ "apply_phase_inv", "Apply intensity stereo phase inversion", OFFSET(apply_phase_inv), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, AD },
{ NULL },
};
static const AVClass opus_class = {
.class_name = "Opus Decoder",
.item_name = av_default_item_name,
.option = opus_options,
.version = LIBAVUTIL_VERSION_INT,
};
const FFCodec ff_opus_decoder = {
.p.name = "opus",
CODEC_LONG_NAME("Opus"),
.p.priv_class = &opus_class,
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_OPUS,
.priv_data_size = sizeof(OpusContext),
.init = opus_decode_init,
.close = opus_decode_close,
FF_CODEC_DECODE_CB(opus_decode_packet),
.flush = opus_decode_flush,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_CHANNEL_CONF,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
};
+589
View File
@@ -0,0 +1,589 @@
/*
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
* Copyright (c) 2016 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Opus CELT decoder
*/
#include <float.h>
#include "libavutil/mem.h"
#include "celt.h"
#include "tab.h"
#include "pvq.h"
/* Use the 2D z-transform to apply prediction in both the time domain (alpha)
* and the frequency domain (beta) */
static void celt_decode_coarse_energy(CeltFrame *f, OpusRangeCoder *rc)
{
int i, j;
float prev[2] = { 0 };
float alpha = ff_celt_alpha_coef[f->size];
float beta = ff_celt_beta_coef[f->size];
const uint8_t *model = ff_celt_coarse_energy_dist[f->size][0];
/* intra frame */
if (opus_rc_tell(rc) + 3 <= f->framebits && ff_opus_rc_dec_log(rc, 3)) {
alpha = 0.0f;
beta = 1.0f - (4915.0f/32768.0f);
model = ff_celt_coarse_energy_dist[f->size][1];
}
for (i = 0; i < CELT_MAX_BANDS; i++) {
for (j = 0; j < f->channels; j++) {
CeltBlock *block = &f->block[j];
float value;
int available;
if (i < f->start_band || i >= f->end_band) {
block->energy[i] = 0.0;
continue;
}
available = f->framebits - opus_rc_tell(rc);
if (available >= 15) {
/* decode using a Laplace distribution */
int k = FFMIN(i, 20) << 1;
value = ff_opus_rc_dec_laplace(rc, model[k] << 7, model[k+1] << 6);
} else if (available >= 2) {
int x = ff_opus_rc_dec_cdf(rc, ff_celt_model_energy_small);
value = (x>>1) ^ -(x&1);
} else if (available >= 1) {
value = -(float)ff_opus_rc_dec_log(rc, 1);
} else value = -1;
block->energy[i] = FFMAX(-9.0f, block->energy[i]) * alpha + prev[j] + value;
prev[j] += beta * value;
}
}
}
static void celt_decode_fine_energy(CeltFrame *f, OpusRangeCoder *rc)
{
int i;
for (i = f->start_band; i < f->end_band; i++) {
int j;
if (!f->fine_bits[i])
continue;
for (j = 0; j < f->channels; j++) {
CeltBlock *block = &f->block[j];
int q2;
float offset;
q2 = ff_opus_rc_get_raw(rc, f->fine_bits[i]);
offset = (q2 + 0.5f) * (1 << (14 - f->fine_bits[i])) / 16384.0f - 0.5f;
block->energy[i] += offset;
}
}
}
static void celt_decode_final_energy(CeltFrame *f, OpusRangeCoder *rc)
{
int priority, i, j;
int bits_left = f->framebits - opus_rc_tell(rc);
for (priority = 0; priority < 2; priority++) {
for (i = f->start_band; i < f->end_band && bits_left >= f->channels; i++) {
if (f->fine_priority[i] != priority || f->fine_bits[i] >= CELT_MAX_FINE_BITS)
continue;
for (j = 0; j < f->channels; j++) {
int q2;
float offset;
q2 = ff_opus_rc_get_raw(rc, 1);
offset = (q2 - 0.5f) * (1 << (14 - f->fine_bits[i] - 1)) / 16384.0f;
f->block[j].energy[i] += offset;
bits_left--;
}
}
}
}
static void celt_decode_tf_changes(CeltFrame *f, OpusRangeCoder *rc)
{
int i, diff = 0, tf_select = 0, tf_changed = 0, tf_select_bit;
int consumed, bits = f->transient ? 2 : 4;
consumed = opus_rc_tell(rc);
tf_select_bit = (f->size != 0 && consumed+bits+1 <= f->framebits);
for (i = f->start_band; i < f->end_band; i++) {
if (consumed+bits+tf_select_bit <= f->framebits) {
diff ^= ff_opus_rc_dec_log(rc, bits);
consumed = opus_rc_tell(rc);
tf_changed |= diff;
}
f->tf_change[i] = diff;
bits = f->transient ? 4 : 5;
}
if (tf_select_bit && ff_celt_tf_select[f->size][f->transient][0][tf_changed] !=
ff_celt_tf_select[f->size][f->transient][1][tf_changed])
tf_select = ff_opus_rc_dec_log(rc, 1);
for (i = f->start_band; i < f->end_band; i++) {
f->tf_change[i] = ff_celt_tf_select[f->size][f->transient][tf_select][f->tf_change[i]];
}
}
static void celt_denormalize(CeltFrame *f, CeltBlock *block, float *data)
{
int i, j;
for (i = f->start_band; i < f->end_band; i++) {
float *dst = data + (ff_celt_freq_bands[i] << f->size);
float log_norm = block->energy[i] + ff_celt_mean_energy[i];
float norm = exp2f(FFMIN(log_norm, 32.0f));
for (j = 0; j < ff_celt_freq_range[i] << f->size; j++)
dst[j] *= norm;
}
}
static void celt_postfilter_apply_transition(CeltBlock *block, float *data)
{
const int T0 = block->pf_period_old;
const int T1 = block->pf_period;
float g00, g01, g02;
float g10, g11, g12;
float x0, x1, x2, x3, x4;
int i;
if (block->pf_gains[0] == 0.0 &&
block->pf_gains_old[0] == 0.0)
return;
g00 = block->pf_gains_old[0];
g01 = block->pf_gains_old[1];
g02 = block->pf_gains_old[2];
g10 = block->pf_gains[0];
g11 = block->pf_gains[1];
g12 = block->pf_gains[2];
x1 = data[-T1 + 1];
x2 = data[-T1];
x3 = data[-T1 - 1];
x4 = data[-T1 - 2];
for (i = 0; i < CELT_OVERLAP; i++) {
float w = ff_celt_window2[i];
x0 = data[i - T1 + 2];
data[i] += (1.0 - w) * g00 * data[i - T0] +
(1.0 - w) * g01 * (data[i - T0 - 1] + data[i - T0 + 1]) +
(1.0 - w) * g02 * (data[i - T0 - 2] + data[i - T0 + 2]) +
w * g10 * x2 +
w * g11 * (x1 + x3) +
w * g12 * (x0 + x4);
x4 = x3;
x3 = x2;
x2 = x1;
x1 = x0;
}
}
static void celt_postfilter(CeltFrame *f, CeltBlock *block)
{
int len = f->blocksize * f->blocks;
const int filter_len = len - 2 * CELT_OVERLAP;
celt_postfilter_apply_transition(block, block->buf + 1024);
block->pf_period_old = block->pf_period;
memcpy(block->pf_gains_old, block->pf_gains, sizeof(block->pf_gains));
block->pf_period = block->pf_period_new;
memcpy(block->pf_gains, block->pf_gains_new, sizeof(block->pf_gains));
if (len > CELT_OVERLAP) {
celt_postfilter_apply_transition(block, block->buf + 1024 + CELT_OVERLAP);
if (block->pf_gains[0] > FLT_EPSILON && filter_len > 0)
f->opusdsp.postfilter(block->buf + 1024 + 2 * CELT_OVERLAP,
block->pf_period, block->pf_gains,
filter_len);
block->pf_period_old = block->pf_period;
memcpy(block->pf_gains_old, block->pf_gains, sizeof(block->pf_gains));
}
memmove(block->buf, block->buf + len, (1024 + CELT_OVERLAP / 2) * sizeof(float));
}
static int parse_postfilter(CeltFrame *f, OpusRangeCoder *rc, int consumed)
{
int i;
memset(f->block[0].pf_gains_new, 0, sizeof(f->block[0].pf_gains_new));
memset(f->block[1].pf_gains_new, 0, sizeof(f->block[1].pf_gains_new));
if (f->start_band == 0 && consumed + 16 <= f->framebits) {
int has_postfilter = ff_opus_rc_dec_log(rc, 1);
if (has_postfilter) {
float gain;
int tapset, octave, period;
octave = ff_opus_rc_dec_uint(rc, 6);
period = (16 << octave) + ff_opus_rc_get_raw(rc, 4 + octave) - 1;
gain = 0.09375f * (ff_opus_rc_get_raw(rc, 3) + 1);
tapset = (opus_rc_tell(rc) + 2 <= f->framebits) ?
ff_opus_rc_dec_cdf(rc, ff_celt_model_tapset) : 0;
for (i = 0; i < 2; i++) {
CeltBlock *block = &f->block[i];
block->pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD);
block->pf_gains_new[0] = gain * ff_celt_postfilter_taps[tapset][0];
block->pf_gains_new[1] = gain * ff_celt_postfilter_taps[tapset][1];
block->pf_gains_new[2] = gain * ff_celt_postfilter_taps[tapset][2];
}
}
consumed = opus_rc_tell(rc);
}
return consumed;
}
static void process_anticollapse(CeltFrame *f, CeltBlock *block, float *X)
{
int i, j, k;
for (i = f->start_band; i < f->end_band; i++) {
int renormalize = 0;
float *xptr;
float prev[2];
float Ediff, r;
float thresh, sqrt_1;
int depth;
/* depth in 1/8 bits */
depth = (1 + f->pulses[i]) / (ff_celt_freq_range[i] << f->size);
thresh = exp2f(-1.0 - 0.125f * depth);
sqrt_1 = 1.0f / sqrtf(ff_celt_freq_range[i] << f->size);
xptr = X + (ff_celt_freq_bands[i] << f->size);
prev[0] = block->prev_energy[0][i];
prev[1] = block->prev_energy[1][i];
if (f->channels == 1) {
CeltBlock *block1 = &f->block[1];
prev[0] = FFMAX(prev[0], block1->prev_energy[0][i]);
prev[1] = FFMAX(prev[1], block1->prev_energy[1][i]);
}
Ediff = block->energy[i] - FFMIN(prev[0], prev[1]);
Ediff = FFMAX(0, Ediff);
/* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because
short blocks don't have the same energy as long */
r = exp2f(1 - Ediff);
if (f->size == 3)
r *= M_SQRT2;
r = FFMIN(thresh, r) * sqrt_1;
for (k = 0; k < 1 << f->size; k++) {
/* Detect collapse */
if (!(block->collapse_masks[i] & 1 << k)) {
/* Fill with noise */
for (j = 0; j < ff_celt_freq_range[i]; j++)
xptr[(j << f->size) + k] = (celt_rng(f) & 0x8000) ? r : -r;
renormalize = 1;
}
}
/* We just added some energy, so we need to renormalize */
if (renormalize)
celt_renormalize_vector(xptr, ff_celt_freq_range[i] << f->size, 1.0f);
}
}
int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
float **output, int channels, int frame_size,
int start_band, int end_band)
{
int i, j, downmix = 0;
int consumed; // bits of entropy consumed thus far for this frame
AVTXContext *imdct;
av_tx_fn imdct_fn;
if (channels != 1 && channels != 2) {
av_log(f->avctx, AV_LOG_ERROR, "Invalid number of coded channels: %d\n",
channels);
return AVERROR_INVALIDDATA;
}
if (start_band < 0 || start_band > end_band || end_band > CELT_MAX_BANDS) {
av_log(f->avctx, AV_LOG_ERROR, "Invalid start/end band: %d %d\n",
start_band, end_band);
return AVERROR_INVALIDDATA;
}
f->silence = 0;
f->transient = 0;
f->anticollapse = 0;
f->flushed = 0;
f->channels = channels;
f->start_band = start_band;
f->end_band = end_band;
f->framebits = rc->rb.bytes * 8;
f->size = av_log2(frame_size / CELT_SHORT_BLOCKSIZE);
if (f->size > CELT_MAX_LOG_BLOCKS ||
frame_size != CELT_SHORT_BLOCKSIZE * (1 << f->size)) {
av_log(f->avctx, AV_LOG_ERROR, "Invalid CELT frame size: %d\n",
frame_size);
return AVERROR_INVALIDDATA;
}
if (!f->output_channels)
f->output_channels = channels;
for (i = 0; i < f->channels; i++) {
memset(f->block[i].coeffs, 0, sizeof(f->block[i].coeffs));
memset(f->block[i].collapse_masks, 0, sizeof(f->block[i].collapse_masks));
}
consumed = opus_rc_tell(rc);
/* obtain silence flag */
if (consumed >= f->framebits)
f->silence = 1;
else if (consumed == 1)
f->silence = ff_opus_rc_dec_log(rc, 15);
if (f->silence) {
consumed = f->framebits;
rc->total_bits += f->framebits - opus_rc_tell(rc);
}
/* obtain post-filter options */
consumed = parse_postfilter(f, rc, consumed);
/* obtain transient flag */
if (f->size != 0 && consumed+3 <= f->framebits)
f->transient = ff_opus_rc_dec_log(rc, 3);
f->blocks = f->transient ? 1 << f->size : 1;
f->blocksize = frame_size / f->blocks;
imdct = f->tx[f->transient ? 0 : f->size];
imdct_fn = f->tx_fn[f->transient ? 0 : f->size];
if (channels == 1) {
for (i = 0; i < CELT_MAX_BANDS; i++)
f->block[0].energy[i] = FFMAX(f->block[0].energy[i], f->block[1].energy[i]);
}
celt_decode_coarse_energy(f, rc);
celt_decode_tf_changes (f, rc);
ff_celt_bitalloc (f, rc, 0);
celt_decode_fine_energy (f, rc);
ff_celt_quant_bands (f, rc);
if (f->anticollapse_needed)
f->anticollapse = ff_opus_rc_get_raw(rc, 1);
celt_decode_final_energy(f, rc);
/* apply anti-collapse processing and denormalization to
* each coded channel */
for (i = 0; i < f->channels; i++) {
CeltBlock *block = &f->block[i];
if (f->anticollapse)
process_anticollapse(f, block, f->block[i].coeffs);
celt_denormalize(f, block, f->block[i].coeffs);
}
/* stereo -> mono downmix */
if (f->output_channels < f->channels) {
f->dsp->vector_fmac_scalar(f->block[0].coeffs, f->block[1].coeffs, 1.0, FFALIGN(frame_size, 16));
downmix = 1;
} else if (f->output_channels > f->channels)
memcpy(f->block[1].coeffs, f->block[0].coeffs, frame_size * sizeof(float));
if (f->silence) {
for (i = 0; i < 2; i++) {
CeltBlock *block = &f->block[i];
for (j = 0; j < FF_ARRAY_ELEMS(block->energy); j++)
block->energy[j] = CELT_ENERGY_SILENCE;
}
memset(f->block[0].coeffs, 0, sizeof(f->block[0].coeffs));
memset(f->block[1].coeffs, 0, sizeof(f->block[1].coeffs));
}
/* transform and output for each output channel */
for (i = 0; i < f->output_channels; i++) {
CeltBlock *block = &f->block[i];
/* iMDCT and overlap-add */
for (j = 0; j < f->blocks; j++) {
float *dst = block->buf + 1024 + j * f->blocksize;
imdct_fn(imdct, dst + CELT_OVERLAP / 2, f->block[i].coeffs + j,
sizeof(float)*f->blocks);
f->dsp->vector_fmul_window(dst, dst, dst + CELT_OVERLAP / 2,
ff_celt_window, CELT_OVERLAP / 2);
}
if (downmix)
f->dsp->vector_fmul_scalar(&block->buf[1024], &block->buf[1024], 0.5f, frame_size);
/* postfilter */
celt_postfilter(f, block);
/* deemphasis */
block->emph_coeff = f->opusdsp.deemphasis(output[i],
&block->buf[1024 - frame_size],
block->emph_coeff,
ff_opus_deemph_weights,
frame_size);
}
if (channels == 1)
memcpy(f->block[1].energy, f->block[0].energy, sizeof(f->block[0].energy));
for (i = 0; i < 2; i++ ) {
CeltBlock *block = &f->block[i];
if (!f->transient) {
memcpy(block->prev_energy[1], block->prev_energy[0], sizeof(block->prev_energy[0]));
memcpy(block->prev_energy[0], block->energy, sizeof(block->prev_energy[0]));
} else {
for (j = 0; j < CELT_MAX_BANDS; j++)
block->prev_energy[0][j] = FFMIN(block->prev_energy[0][j], block->energy[j]);
}
for (j = 0; j < f->start_band; j++) {
block->prev_energy[0][j] = CELT_ENERGY_SILENCE;
block->energy[j] = 0.0;
}
for (j = f->end_band; j < CELT_MAX_BANDS; j++) {
block->prev_energy[0][j] = CELT_ENERGY_SILENCE;
block->energy[j] = 0.0;
}
}
f->seed = rc->range;
return 0;
}
void ff_celt_flush(CeltFrame *f)
{
int i, j;
if (f->flushed)
return;
for (i = 0; i < 2; i++) {
CeltBlock *block = &f->block[i];
for (j = 0; j < CELT_MAX_BANDS; j++)
block->prev_energy[0][j] = block->prev_energy[1][j] = CELT_ENERGY_SILENCE;
memset(block->energy, 0, sizeof(block->energy));
memset(block->buf, 0, sizeof(block->buf));
memset(block->pf_gains, 0, sizeof(block->pf_gains));
memset(block->pf_gains_old, 0, sizeof(block->pf_gains_old));
memset(block->pf_gains_new, 0, sizeof(block->pf_gains_new));
/* libopus uses CELT_EMPH_COEFF on init, but 0 is better since there's
* a lesser discontinuity when seeking.
* The deemphasis functions differ from libopus in that they require
* an initial state divided by the coefficient. */
block->emph_coeff = 0.0f / ff_opus_deemph_weights[0];
}
f->seed = 0;
f->flushed = 1;
}
void ff_celt_free(CeltFrame **f)
{
CeltFrame *frm = *f;
int i;
if (!frm)
return;
for (i = 0; i < FF_ARRAY_ELEMS(frm->tx); i++)
av_tx_uninit(&frm->tx[i]);
ff_celt_pvq_uninit(&frm->pvq);
av_freep(&frm->dsp);
av_freep(f);
}
int ff_celt_init(AVCodecContext *avctx, CeltFrame **f, int output_channels,
int apply_phase_inv)
{
CeltFrame *frm;
int i, ret;
if (output_channels != 1 && output_channels != 2) {
av_log(avctx, AV_LOG_ERROR, "Invalid number of output channels: %d\n",
output_channels);
return AVERROR(EINVAL);
}
frm = av_mallocz(sizeof(*frm));
if (!frm)
return AVERROR(ENOMEM);
frm->avctx = avctx;
frm->output_channels = output_channels;
frm->apply_phase_inv = apply_phase_inv;
for (i = 0; i < FF_ARRAY_ELEMS(frm->tx); i++) {
const float scale = -1.0f/32768;
if ((ret = av_tx_init(&frm->tx[i], &frm->tx_fn[i], AV_TX_FLOAT_MDCT, 1, 15 << (i + 3), &scale, 0)) < 0)
goto fail;
}
if ((ret = ff_celt_pvq_init(&frm->pvq, 0)) < 0)
goto fail;
frm->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
if (!frm->dsp) {
ret = AVERROR(ENOMEM);
goto fail;
}
ff_opus_dsp_init(&frm->opusdsp);
ff_celt_flush(frm);
*f = frm;
return 0;
fail:
ff_celt_free(&frm);
return ret;
}
+68
View File
@@ -0,0 +1,68 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#include "libavutil/attributes.h"
#include "libavutil/mem_internal.h"
#include "dsp.h"
static void postfilter_c(float *data, int period, float *gains, int len)
{
const float g0 = gains[0];
const float g1 = gains[1];
const float g2 = gains[2];
float x4 = data[-period - 2];
float x3 = data[-period - 1];
float x2 = data[-period + 0];
float x1 = data[-period + 1];
for (int i = 0; i < len; i++) {
float x0 = data[i - period + 2];
data[i] += g0 * x2 +
g1 * (x1 + x3) +
g2 * (x0 + x4);
x4 = x3;
x3 = x2;
x2 = x1;
x1 = x0;
}
}
static float deemphasis_c(float *y, float *x, float coeff, const float *weights, int len)
{
const float c = weights[0];
for (int i = 0; i < len; i++)
coeff = y[i] = x[i] + coeff*c;
return coeff;
}
av_cold void ff_opus_dsp_init(OpusDSP *ctx)
{
ctx->postfilter = postfilter_c;
ctx->deemphasis = deemphasis_c;
#if ARCH_AARCH64
ff_opus_dsp_init_aarch64(ctx);
#elif ARCH_RISCV
ff_opus_dsp_init_riscv(ctx);
#elif ARCH_X86
ff_opus_dsp_init_x86(ctx);
#endif
}
+33
View File
@@ -0,0 +1,33 @@
/*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_OPUS_DSP_H
#define AVCODEC_OPUS_DSP_H
typedef struct OpusDSP {
void (*postfilter)(float *data, int period, float *gains, int len);
float (*deemphasis)(float *out, float *in, float coeff, const float *weights, int len);
} OpusDSP;
void ff_opus_dsp_init(OpusDSP *ctx);
void ff_opus_dsp_init_x86(OpusDSP *ctx);
void ff_opus_dsp_init_aarch64(OpusDSP *ctx);
void ff_opus_dsp_init_riscv(OpusDSP *ctx);
#endif /* AVCODEC_OPUS_DSP_H */
+752
View File
@@ -0,0 +1,752 @@
/*
* Opus encoder
* Copyright (c) 2017 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <float.h>
#include "encode.h"
#include "enc.h"
#include "pvq.h"
#include "enc_psy.h"
#include "tab.h"
#include "libavutil/channel_layout.h"
#include "libavutil/float_dsp.h"
#include "libavutil/mem.h"
#include "libavutil/mem_internal.h"
#include "libavutil/opt.h"
#include "bytestream.h"
#include "audio_frame_queue.h"
#include "codec_internal.h"
typedef struct OpusEncContext {
AVClass *av_class;
OpusEncOptions options;
OpusPsyContext psyctx;
AVCodecContext *avctx;
AudioFrameQueue afq;
AVFloatDSPContext *dsp;
AVTXContext *tx[CELT_BLOCK_NB];
av_tx_fn tx_fn[CELT_BLOCK_NB];
CeltPVQ *pvq;
struct FFBufQueue bufqueue;
uint8_t enc_id[64];
int enc_id_bits;
OpusPacketInfo packet;
int channels;
CeltFrame *frame;
OpusRangeCoder *rc;
/* Actual energy the decoder will have */
float last_quantized_energy[OPUS_MAX_CHANNELS][CELT_MAX_BANDS];
DECLARE_ALIGNED(32, float, scratch)[2048];
} OpusEncContext;
static void opus_write_extradata(AVCodecContext *avctx)
{
uint8_t *bs = avctx->extradata;
bytestream_put_buffer(&bs, "OpusHead", 8);
bytestream_put_byte (&bs, 0x1);
bytestream_put_byte (&bs, avctx->ch_layout.nb_channels);
bytestream_put_le16 (&bs, avctx->initial_padding);
bytestream_put_le32 (&bs, avctx->sample_rate);
bytestream_put_le16 (&bs, 0x0);
bytestream_put_byte (&bs, 0x0); /* Default layout */
}
static int opus_gen_toc(OpusEncContext *s, uint8_t *toc, int *size, int *fsize_needed)
{
int tmp = 0x0, extended_toc = 0;
static const int toc_cfg[][OPUS_MODE_NB][OPUS_BANDWITH_NB] = {
/* Silk Hybrid Celt Layer */
/* NB MB WB SWB FB NB MB WB SWB FB NB MB WB SWB FB Bandwidth */
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 17, 0, 21, 25, 29 } }, /* 2.5 ms */
{ { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 }, { 18, 0, 22, 26, 30 } }, /* 5 ms */
{ { 1, 5, 9, 0, 0 }, { 0, 0, 0, 13, 15 }, { 19, 0, 23, 27, 31 } }, /* 10 ms */
{ { 2, 6, 10, 0, 0 }, { 0, 0, 0, 14, 16 }, { 20, 0, 24, 28, 32 } }, /* 20 ms */
{ { 3, 7, 11, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }, /* 40 ms */
{ { 4, 8, 12, 0, 0 }, { 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0 } }, /* 60 ms */
};
int cfg = toc_cfg[s->packet.framesize][s->packet.mode][s->packet.bandwidth];
*fsize_needed = 0;
if (!cfg)
return 1;
if (s->packet.frames == 2) { /* 2 packets */
if (s->frame[0].framebits == s->frame[1].framebits) { /* same size */
tmp = 0x1;
} else { /* different size */
tmp = 0x2;
*fsize_needed = 1; /* put frame sizes in the packet */
}
} else if (s->packet.frames > 2) {
tmp = 0x3;
extended_toc = 1;
}
tmp |= (s->channels > 1) << 2; /* Stereo or mono */
tmp |= (cfg - 1) << 3; /* codec configuration */
*toc++ = tmp;
if (extended_toc) {
for (int i = 0; i < (s->packet.frames - 1); i++)
*fsize_needed |= (s->frame[i].framebits != s->frame[i + 1].framebits);
tmp = (*fsize_needed) << 7; /* vbr flag */
tmp |= (0) << 6; /* padding flag */
tmp |= s->packet.frames;
*toc++ = tmp;
}
*size = 1 + extended_toc;
return 0;
}
static void celt_frame_setup_input(OpusEncContext *s, CeltFrame *f)
{
AVFrame *cur = NULL;
const int subframesize = s->avctx->frame_size;
int subframes = OPUS_BLOCK_SIZE(s->packet.framesize) / subframesize;
cur = ff_bufqueue_get(&s->bufqueue);
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *b = &f->block[ch];
const void *input = cur->extended_data[ch];
size_t bps = av_get_bytes_per_sample(cur->format);
memcpy(b->overlap, input, bps*cur->nb_samples);
}
av_frame_free(&cur);
for (int sf = 0; sf < subframes; sf++) {
if (sf != (subframes - 1))
cur = ff_bufqueue_get(&s->bufqueue);
else
cur = ff_bufqueue_peek(&s->bufqueue, 0);
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *b = &f->block[ch];
const void *input = cur->extended_data[ch];
const size_t bps = av_get_bytes_per_sample(cur->format);
const size_t left = (subframesize - cur->nb_samples)*bps;
const size_t len = FFMIN(subframesize, cur->nb_samples)*bps;
memcpy(&b->samples[sf*subframesize], input, len);
memset(&b->samples[cur->nb_samples], 0, left);
}
/* Last frame isn't popped off and freed yet - we need it for overlap */
if (sf != (subframes - 1))
av_frame_free(&cur);
}
}
/* Apply the pre emphasis filter */
static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f)
{
const int subframesize = s->avctx->frame_size;
const int subframes = OPUS_BLOCK_SIZE(s->packet.framesize) / subframesize;
const float c = ff_opus_deemph_weights[0];
/* Filter overlap */
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *b = &f->block[ch];
float m = b->emph_coeff;
for (int i = 0; i < CELT_OVERLAP; i++) {
float sample = b->overlap[i];
b->overlap[i] = sample - m;
m = sample * c;
}
b->emph_coeff = m;
}
/* Filter the samples but do not update the last subframe's coeff - overlap ^^^ */
for (int sf = 0; sf < subframes; sf++) {
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *b = &f->block[ch];
float m = b->emph_coeff;
for (int i = 0; i < subframesize; i++) {
float sample = b->samples[sf*subframesize + i];
b->samples[sf*subframesize + i] = sample - m;
m = sample * c;
}
if (sf != (subframes - 1))
b->emph_coeff = m;
}
}
}
/* Create the window and do the mdct */
static void celt_frame_mdct(OpusEncContext *s, CeltFrame *f)
{
float *win = s->scratch, *temp = s->scratch + 1920;
if (f->transient) {
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *b = &f->block[ch];
float *src1 = b->overlap;
for (int t = 0; t < f->blocks; t++) {
float *src2 = &b->samples[CELT_OVERLAP*t];
s->dsp->vector_fmul(win, src1, ff_celt_window, 128);
s->dsp->vector_fmul_reverse(&win[CELT_OVERLAP], src2,
ff_celt_window_padded, 128);
src1 = src2;
s->tx_fn[0](s->tx[0], b->coeffs + t, win, sizeof(float)*f->blocks);
}
}
} else {
int blk_len = OPUS_BLOCK_SIZE(f->size), wlen = OPUS_BLOCK_SIZE(f->size + 1);
int rwin = blk_len - CELT_OVERLAP, lap_dst = (wlen - blk_len - CELT_OVERLAP) >> 1;
memset(win, 0, wlen*sizeof(float));
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *b = &f->block[ch];
/* Overlap */
s->dsp->vector_fmul(temp, b->overlap, ff_celt_window, 128);
memcpy(win + lap_dst, temp, CELT_OVERLAP*sizeof(float));
/* Samples, flat top window */
memcpy(&win[lap_dst + CELT_OVERLAP], b->samples, rwin*sizeof(float));
/* Samples, windowed */
s->dsp->vector_fmul_reverse(temp, b->samples + rwin,
ff_celt_window_padded, 128);
memcpy(win + lap_dst + blk_len, temp, CELT_OVERLAP*sizeof(float));
s->tx_fn[f->size](s->tx[f->size], b->coeffs, win, sizeof(float));
}
}
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *block = &f->block[ch];
for (int i = 0; i < CELT_MAX_BANDS; i++) {
float ener = 0.0f;
int band_offset = ff_celt_freq_bands[i] << f->size;
int band_size = ff_celt_freq_range[i] << f->size;
float *coeffs = &block->coeffs[band_offset];
for (int j = 0; j < band_size; j++)
ener += coeffs[j]*coeffs[j];
block->lin_energy[i] = sqrtf(ener) + FLT_EPSILON;
ener = 1.0f/block->lin_energy[i];
for (int j = 0; j < band_size; j++)
coeffs[j] *= ener;
block->energy[i] = log2f(block->lin_energy[i]) - ff_celt_mean_energy[i];
/* CELT_ENERGY_SILENCE is what the decoder uses and its not -infinity */
block->energy[i] = FFMAX(block->energy[i], CELT_ENERGY_SILENCE);
}
}
}
static void celt_enc_tf(CeltFrame *f, OpusRangeCoder *rc)
{
int tf_select = 0, diff = 0, tf_changed = 0, tf_select_needed;
int bits = f->transient ? 2 : 4;
tf_select_needed = ((f->size && (opus_rc_tell(rc) + bits + 1) <= f->framebits));
for (int i = f->start_band; i < f->end_band; i++) {
if ((opus_rc_tell(rc) + bits + tf_select_needed) <= f->framebits) {
const int tbit = (diff ^ 1) == f->tf_change[i];
ff_opus_rc_enc_log(rc, tbit, bits);
diff ^= tbit;
tf_changed |= diff;
}
bits = f->transient ? 4 : 5;
}
if (tf_select_needed && ff_celt_tf_select[f->size][f->transient][0][tf_changed] !=
ff_celt_tf_select[f->size][f->transient][1][tf_changed]) {
ff_opus_rc_enc_log(rc, f->tf_select, 1);
tf_select = f->tf_select;
}
for (int i = f->start_band; i < f->end_band; i++)
f->tf_change[i] = ff_celt_tf_select[f->size][f->transient][tf_select][f->tf_change[i]];
}
static void celt_enc_quant_pfilter(OpusRangeCoder *rc, CeltFrame *f)
{
float gain = f->pf_gain;
int txval, octave = f->pf_octave, period = f->pf_period, tapset = f->pf_tapset;
ff_opus_rc_enc_log(rc, f->pfilter, 1);
if (!f->pfilter)
return;
/* Octave */
txval = FFMIN(octave, 6);
ff_opus_rc_enc_uint(rc, txval, 6);
octave = txval;
/* Period */
txval = av_clip(period - (16 << octave) + 1, 0, (1 << (4 + octave)) - 1);
ff_opus_rc_put_raw(rc, period, 4 + octave);
period = txval + (16 << octave) - 1;
/* Gain */
txval = FFMIN(((int)(gain / 0.09375f)) - 1, 7);
ff_opus_rc_put_raw(rc, txval, 3);
gain = 0.09375f * (txval + 1);
/* Tapset */
if ((opus_rc_tell(rc) + 2) <= f->framebits)
ff_opus_rc_enc_cdf(rc, tapset, ff_celt_model_tapset);
else
tapset = 0;
/* Finally create the coeffs */
for (int i = 0; i < 2; i++) {
CeltBlock *block = &f->block[i];
block->pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD);
block->pf_gains_new[0] = gain * ff_celt_postfilter_taps[tapset][0];
block->pf_gains_new[1] = gain * ff_celt_postfilter_taps[tapset][1];
block->pf_gains_new[2] = gain * ff_celt_postfilter_taps[tapset][2];
}
}
static void exp_quant_coarse(OpusRangeCoder *rc, CeltFrame *f,
float last_energy[][CELT_MAX_BANDS], int intra)
{
float alpha, beta, prev[2] = { 0, 0 };
const uint8_t *pmod = ff_celt_coarse_energy_dist[f->size][intra];
/* Inter is really just differential coding */
if (opus_rc_tell(rc) + 3 <= f->framebits)
ff_opus_rc_enc_log(rc, intra, 3);
else
intra = 0;
if (intra) {
alpha = 0.0f;
beta = 1.0f - (4915.0f/32768.0f);
} else {
alpha = ff_celt_alpha_coef[f->size];
beta = ff_celt_beta_coef[f->size];
}
for (int i = f->start_band; i < f->end_band; i++) {
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *block = &f->block[ch];
const int left = f->framebits - opus_rc_tell(rc);
const float last = FFMAX(-9.0f, last_energy[ch][i]);
float diff = block->energy[i] - prev[ch] - last*alpha;
int q_en = lrintf(diff);
if (left >= 15) {
ff_opus_rc_enc_laplace(rc, &q_en, pmod[i << 1] << 7, pmod[(i << 1) + 1] << 6);
} else if (left >= 2) {
q_en = av_clip(q_en, -1, 1);
ff_opus_rc_enc_cdf(rc, 2*q_en + 3*(q_en < 0), ff_celt_model_energy_small);
} else if (left >= 1) {
q_en = av_clip(q_en, -1, 0);
ff_opus_rc_enc_log(rc, (q_en & 1), 1);
} else q_en = -1;
block->error_energy[i] = q_en - diff;
prev[ch] += beta * q_en;
}
}
}
static void celt_quant_coarse(CeltFrame *f, OpusRangeCoder *rc,
float last_energy[][CELT_MAX_BANDS])
{
uint32_t inter, intra;
OPUS_RC_CHECKPOINT_SPAWN(rc);
exp_quant_coarse(rc, f, last_energy, 1);
intra = OPUS_RC_CHECKPOINT_BITS(rc);
OPUS_RC_CHECKPOINT_ROLLBACK(rc);
exp_quant_coarse(rc, f, last_energy, 0);
inter = OPUS_RC_CHECKPOINT_BITS(rc);
if (inter > intra) { /* Unlikely */
OPUS_RC_CHECKPOINT_ROLLBACK(rc);
exp_quant_coarse(rc, f, last_energy, 1);
}
}
static void celt_quant_fine(CeltFrame *f, OpusRangeCoder *rc)
{
for (int i = f->start_band; i < f->end_band; i++) {
if (!f->fine_bits[i])
continue;
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *block = &f->block[ch];
int quant, lim = (1 << f->fine_bits[i]);
float offset, diff = 0.5f - block->error_energy[i];
quant = av_clip(floor(diff*lim), 0, lim - 1);
ff_opus_rc_put_raw(rc, quant, f->fine_bits[i]);
offset = 0.5f - ((quant + 0.5f) * (1 << (14 - f->fine_bits[i])) / 16384.0f);
block->error_energy[i] -= offset;
}
}
}
static void celt_quant_final(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame *f)
{
for (int priority = 0; priority < 2; priority++) {
for (int i = f->start_band; i < f->end_band && (f->framebits - opus_rc_tell(rc)) >= f->channels; i++) {
if (f->fine_priority[i] != priority || f->fine_bits[i] >= CELT_MAX_FINE_BITS)
continue;
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *block = &f->block[ch];
const float err = block->error_energy[i];
const float offset = 0.5f * (1 << (14 - f->fine_bits[i] - 1)) / 16384.0f;
const int sign = FFABS(err + offset) < FFABS(err - offset);
ff_opus_rc_put_raw(rc, sign, 1);
block->error_energy[i] -= offset*(1 - 2*sign);
}
}
}
}
static void celt_encode_frame(OpusEncContext *s, OpusRangeCoder *rc,
CeltFrame *f, int index)
{
ff_opus_rc_enc_init(rc);
ff_opus_psy_celt_frame_init(&s->psyctx, f, index);
celt_frame_setup_input(s, f);
if (f->silence) {
if (f->framebits >= 16)
ff_opus_rc_enc_log(rc, 1, 15); /* Silence (if using explicit signalling) */
for (int ch = 0; ch < s->channels; ch++)
memset(s->last_quantized_energy[ch], 0.0f, sizeof(float)*CELT_MAX_BANDS);
return;
}
/* Filters */
celt_apply_preemph_filter(s, f);
if (f->pfilter) {
ff_opus_rc_enc_log(rc, 0, 15);
celt_enc_quant_pfilter(rc, f);
}
/* Transform */
celt_frame_mdct(s, f);
/* Need to handle transient/non-transient switches at any point during analysis */
while (ff_opus_psy_celt_frame_process(&s->psyctx, f, index))
celt_frame_mdct(s, f);
ff_opus_rc_enc_init(rc);
/* Silence */
ff_opus_rc_enc_log(rc, 0, 15);
/* Pitch filter */
if (!f->start_band && opus_rc_tell(rc) + 16 <= f->framebits)
celt_enc_quant_pfilter(rc, f);
/* Transient flag */
if (f->size && opus_rc_tell(rc) + 3 <= f->framebits)
ff_opus_rc_enc_log(rc, f->transient, 3);
/* Main encoding */
celt_quant_coarse (f, rc, s->last_quantized_energy);
celt_enc_tf (f, rc);
ff_celt_bitalloc (f, rc, 1);
celt_quant_fine (f, rc);
ff_celt_quant_bands(f, rc);
/* Anticollapse bit */
if (f->anticollapse_needed)
ff_opus_rc_put_raw(rc, f->anticollapse, 1);
/* Final per-band energy adjustments from leftover bits */
celt_quant_final(s, rc, f);
for (int ch = 0; ch < f->channels; ch++) {
CeltBlock *block = &f->block[ch];
for (int i = 0; i < CELT_MAX_BANDS; i++)
s->last_quantized_energy[ch][i] = block->energy[i] + block->error_energy[i];
}
}
static inline int write_opuslacing(uint8_t *dst, int v)
{
dst[0] = FFMIN(v - FFALIGN(v - 255, 4), v);
dst[1] = v - dst[0] >> 2;
return 1 + (v >= 252);
}
static void opus_packet_assembler(OpusEncContext *s, AVPacket *avpkt)
{
int offset, fsize_needed;
/* Write toc */
opus_gen_toc(s, avpkt->data, &offset, &fsize_needed);
/* Frame sizes if needed */
if (fsize_needed) {
for (int i = 0; i < s->packet.frames - 1; i++) {
offset += write_opuslacing(avpkt->data + offset,
s->frame[i].framebits >> 3);
}
}
/* Packets */
for (int i = 0; i < s->packet.frames; i++) {
ff_opus_rc_enc_end(&s->rc[i], avpkt->data + offset,
s->frame[i].framebits >> 3);
offset += s->frame[i].framebits >> 3;
}
avpkt->size = offset;
}
/* Used as overlap for the first frame and padding for the last encoded packet */
static AVFrame *spawn_empty_frame(OpusEncContext *s)
{
AVFrame *f = av_frame_alloc();
int ret;
if (!f)
return NULL;
f->format = s->avctx->sample_fmt;
f->nb_samples = s->avctx->frame_size;
ret = av_channel_layout_copy(&f->ch_layout, &s->avctx->ch_layout);
if (ret < 0) {
av_frame_free(&f);
return NULL;
}
if (av_frame_get_buffer(f, 4)) {
av_frame_free(&f);
return NULL;
}
for (int i = 0; i < s->channels; i++) {
size_t bps = av_get_bytes_per_sample(f->format);
memset(f->extended_data[i], 0, bps*f->nb_samples);
}
return f;
}
static int opus_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
const AVFrame *frame, int *got_packet_ptr)
{
OpusEncContext *s = avctx->priv_data;
int ret, frame_size, alloc_size = 0;
if (frame) { /* Add new frame to queue */
if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
return ret;
ff_bufqueue_add(avctx, &s->bufqueue, av_frame_clone(frame));
} else {
ff_opus_psy_signal_eof(&s->psyctx);
if (!s->afq.remaining_samples || !avctx->frame_num)
return 0; /* We've been flushed and there's nothing left to encode */
}
/* Run the psychoacoustic system */
if (ff_opus_psy_process(&s->psyctx, &s->packet))
return 0;
frame_size = OPUS_BLOCK_SIZE(s->packet.framesize);
if (!frame) {
/* This can go negative, that's not a problem, we only pad if positive */
int pad_empty = s->packet.frames*(frame_size/s->avctx->frame_size) - s->bufqueue.available + 1;
/* Pad with empty 2.5 ms frames to whatever framesize was decided,
* this should only happen at the very last flush frame. The frames
* allocated here will be freed (because they have no other references)
* after they get used by celt_frame_setup_input() */
for (int i = 0; i < pad_empty; i++) {
AVFrame *empty = spawn_empty_frame(s);
if (!empty)
return AVERROR(ENOMEM);
ff_bufqueue_add(avctx, &s->bufqueue, empty);
}
}
for (int i = 0; i < s->packet.frames; i++) {
celt_encode_frame(s, &s->rc[i], &s->frame[i], i);
alloc_size += s->frame[i].framebits >> 3;
}
/* Worst case toc + the frame lengths if needed */
alloc_size += 2 + s->packet.frames*2;
if ((ret = ff_alloc_packet(avctx, avpkt, alloc_size)) < 0)
return ret;
/* Assemble packet */
opus_packet_assembler(s, avpkt);
/* Update the psychoacoustic system */
ff_opus_psy_postencode_update(&s->psyctx, s->frame);
/* Remove samples from queue and skip if needed */
ff_af_queue_remove(&s->afq, s->packet.frames*frame_size, &avpkt->pts, &avpkt->duration);
if (s->packet.frames*frame_size > avpkt->duration) {
uint8_t *side = av_packet_new_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
if (!side)
return AVERROR(ENOMEM);
AV_WL32(&side[4], s->packet.frames*frame_size - avpkt->duration + 120);
}
*got_packet_ptr = 1;
return 0;
}
static av_cold int opus_encode_end(AVCodecContext *avctx)
{
OpusEncContext *s = avctx->priv_data;
for (int i = 0; i < CELT_BLOCK_NB; i++)
av_tx_uninit(&s->tx[i]);
ff_celt_pvq_uninit(&s->pvq);
av_freep(&s->dsp);
av_freep(&s->frame);
av_freep(&s->rc);
ff_af_queue_close(&s->afq);
ff_opus_psy_end(&s->psyctx);
ff_bufqueue_discard_all(&s->bufqueue);
return 0;
}
static av_cold int opus_encode_init(AVCodecContext *avctx)
{
int ret, max_frames;
OpusEncContext *s = avctx->priv_data;
s->avctx = avctx;
s->channels = avctx->ch_layout.nb_channels;
/* Opus allows us to change the framesize on each packet (and each packet may
* have multiple frames in it) but we can't change the codec's frame size on
* runtime, so fix it to the lowest possible number of samples and use a queue
* to accumulate AVFrames until we have enough to encode whatever the encoder
* decides is the best */
avctx->frame_size = 120;
/* Initial padding will change if SILK is ever supported */
avctx->initial_padding = 120;
if (!avctx->bit_rate) {
int coupled = ff_opus_default_coupled_streams[s->channels - 1];
avctx->bit_rate = coupled*(96000) + (s->channels - coupled*2)*(48000);
} else if (avctx->bit_rate < 6000 || avctx->bit_rate > 255000 * s->channels) {
int64_t clipped_rate = av_clip(avctx->bit_rate, 6000, 255000 * s->channels);
av_log(avctx, AV_LOG_ERROR, "Unsupported bitrate %"PRId64" kbps, clipping to %"PRId64" kbps\n",
avctx->bit_rate/1000, clipped_rate/1000);
avctx->bit_rate = clipped_rate;
}
/* Extradata */
avctx->extradata_size = 19;
avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
if (!avctx->extradata)
return AVERROR(ENOMEM);
opus_write_extradata(avctx);
ff_af_queue_init(avctx, &s->afq);
if ((ret = ff_celt_pvq_init(&s->pvq, 1)) < 0)
return ret;
if (!(s->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT)))
return AVERROR(ENOMEM);
/* I have no idea why a base scaling factor of 68 works, could be the twiddles */
for (int i = 0; i < CELT_BLOCK_NB; i++) {
const float scale = 68 << (CELT_BLOCK_NB - 1 - i);
if ((ret = av_tx_init(&s->tx[i], &s->tx_fn[i], AV_TX_FLOAT_MDCT, 0, 15 << (i + 3), &scale, 0)))
return AVERROR(ENOMEM);
}
/* Zero out previous energy (matters for inter first frame) */
for (int ch = 0; ch < s->channels; ch++)
memset(s->last_quantized_energy[ch], 0.0f, sizeof(float)*CELT_MAX_BANDS);
/* Allocate an empty frame to use as overlap for the first frame of audio */
ff_bufqueue_add(avctx, &s->bufqueue, spawn_empty_frame(s));
if (!ff_bufqueue_peek(&s->bufqueue, 0))
return AVERROR(ENOMEM);
if ((ret = ff_opus_psy_init(&s->psyctx, s->avctx, &s->bufqueue, &s->options)))
return ret;
/* Frame structs and range coder buffers */
max_frames = ceilf(FFMIN(s->options.max_delay_ms, 120.0f)/2.5f);
s->frame = av_malloc(max_frames*sizeof(CeltFrame));
if (!s->frame)
return AVERROR(ENOMEM);
s->rc = av_malloc(max_frames*sizeof(OpusRangeCoder));
if (!s->rc)
return AVERROR(ENOMEM);
for (int i = 0; i < max_frames; i++) {
s->frame[i].dsp = s->dsp;
s->frame[i].avctx = s->avctx;
s->frame[i].seed = 0;
s->frame[i].pvq = s->pvq;
s->frame[i].apply_phase_inv = s->options.apply_phase_inv;
s->frame[i].block[0].emph_coeff = s->frame[i].block[1].emph_coeff = 0.0f;
}
return 0;
}
#define OPUSENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption opusenc_options[] = {
{ "opus_delay", "Maximum delay in milliseconds", offsetof(OpusEncContext, options.max_delay_ms), AV_OPT_TYPE_FLOAT, { .dbl = OPUS_MAX_LOOKAHEAD }, 2.5f, OPUS_MAX_LOOKAHEAD, OPUSENC_FLAGS, .unit = "max_delay_ms" },
{ "apply_phase_inv", "Apply intensity stereo phase inversion", offsetof(OpusEncContext, options.apply_phase_inv), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, OPUSENC_FLAGS, .unit = "apply_phase_inv" },
{ NULL },
};
static const AVClass opusenc_class = {
.class_name = "Opus encoder",
.item_name = av_default_item_name,
.option = opusenc_options,
.version = LIBAVUTIL_VERSION_INT,
};
static const FFCodecDefault opusenc_defaults[] = {
{ "b", "0" },
{ "compression_level", "10" },
{ NULL },
};
const FFCodec ff_opus_encoder = {
.p.name = "opus",
CODEC_LONG_NAME("Opus"),
.p.type = AVMEDIA_TYPE_AUDIO,
.p.id = AV_CODEC_ID_OPUS,
.p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_EXPERIMENTAL,
.defaults = opusenc_defaults,
.p.priv_class = &opusenc_class,
.priv_data_size = sizeof(OpusEncContext),
.init = opus_encode_init,
FF_CODEC_ENCODE_CB(opus_encode_frame),
.close = opus_encode_end,
.caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
CODEC_SAMPLERATES(48000),
CODEC_CH_LAYOUTS(AV_CHANNEL_LAYOUT_MONO, AV_CHANNEL_LAYOUT_STEREO),
CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP),
};
+55
View File
@@ -0,0 +1,55 @@
/*
* Opus encoder
* Copyright (c) 2017 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_OPUS_ENC_H
#define AVCODEC_OPUS_ENC_H
#include "libavutil/intmath.h"
#include "opus.h"
/* Determines the maximum delay the psychoacoustic system will use for lookahead */
#define FF_BUFQUEUE_SIZE 145
#include "libavfilter/bufferqueue.h"
#define OPUS_MAX_LOOKAHEAD ((FF_BUFQUEUE_SIZE - 1)*2.5f)
#define OPUS_MAX_CHANNELS 2
/* 120 ms / 2.5 ms = 48 frames (extremely improbable, but the encoder'll work) */
#define OPUS_MAX_FRAMES_PER_PACKET 48
#define OPUS_BLOCK_SIZE(x) (2 * 15 * (1 << ((x) + 2)))
#define OPUS_SAMPLES_TO_BLOCK_SIZE(x) (ff_log2((x) / (2 * 15)) - 2)
typedef struct OpusEncOptions {
float max_delay_ms;
int apply_phase_inv;
} OpusEncOptions;
typedef struct OpusPacketInfo {
enum OpusMode mode;
enum OpusBandwidth bandwidth;
int framesize;
int frames;
} OpusPacketInfo;
#endif /* AVCODEC_OPUS_ENC_H */
+614
View File
@@ -0,0 +1,614 @@
/*
* Opus encoder
* Copyright (c) 2017 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <float.h>
#include "libavutil/mem.h"
#include "enc_psy.h"
#include "celt.h"
#include "pvq.h"
#include "tab.h"
#include "libavfilter/window_func.h"
static float pvq_band_cost(CeltPVQ *pvq, CeltFrame *f, OpusRangeCoder *rc, int band,
float *bits, float lambda)
{
int i, b = 0;
uint32_t cm[2] = { (1 << f->blocks) - 1, (1 << f->blocks) - 1 };
const int band_size = ff_celt_freq_range[band] << f->size;
float buf[176 * 2], lowband_scratch[176], norm1[176], norm2[176];
float dist, cost, err_x = 0.0f, err_y = 0.0f;
float *X = buf;
float *X_orig = f->block[0].coeffs + (ff_celt_freq_bands[band] << f->size);
float *Y = (f->channels == 2) ? &buf[176] : NULL;
float *Y_orig = f->block[1].coeffs + (ff_celt_freq_bands[band] << f->size);
OPUS_RC_CHECKPOINT_SPAWN(rc);
memcpy(X, X_orig, band_size*sizeof(float));
if (Y)
memcpy(Y, Y_orig, band_size*sizeof(float));
f->remaining2 = ((f->framebits << 3) - f->anticollapse_needed) - opus_rc_tell_frac(rc) - 1;
if (band <= f->coded_bands - 1) {
int curr_balance = f->remaining / FFMIN(3, f->coded_bands - band);
b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[band] + curr_balance), 14);
}
if (f->dual_stereo) {
pvq->quant_band(pvq, f, rc, band, X, NULL, band_size, b / 2, f->blocks, NULL,
f->size, norm1, 0, 1.0f, lowband_scratch, cm[0]);
pvq->quant_band(pvq, f, rc, band, Y, NULL, band_size, b / 2, f->blocks, NULL,
f->size, norm2, 0, 1.0f, lowband_scratch, cm[1]);
} else {
pvq->quant_band(pvq, f, rc, band, X, Y, band_size, b, f->blocks, NULL, f->size,
norm1, 0, 1.0f, lowband_scratch, cm[0] | cm[1]);
}
for (i = 0; i < band_size; i++) {
err_x += (X[i] - X_orig[i])*(X[i] - X_orig[i]);
if (Y)
err_y += (Y[i] - Y_orig[i])*(Y[i] - Y_orig[i]);
}
dist = sqrtf(err_x) + sqrtf(err_y);
cost = OPUS_RC_CHECKPOINT_BITS(rc)/8.0f;
*bits += cost;
OPUS_RC_CHECKPOINT_ROLLBACK(rc);
return lambda*dist*cost;
}
/* Populate metrics without taking into consideration neighbouring steps */
static void step_collect_psy_metrics(OpusPsyContext *s, int index)
{
int silence = 0, ch, i, j;
OpusPsyStep *st = s->steps[index];
st->index = index;
for (ch = 0; ch < s->avctx->ch_layout.nb_channels; ch++) {
const int lap_size = (1 << s->bsize_analysis);
for (i = 1; i <= FFMIN(lap_size, index); i++) {
const int offset = i*120;
AVFrame *cur = ff_bufqueue_peek(s->bufqueue, index - i);
memcpy(&s->scratch[offset], cur->extended_data[ch], cur->nb_samples*sizeof(float));
}
for (i = 0; i < lap_size; i++) {
const int offset = i*120 + lap_size;
AVFrame *cur = ff_bufqueue_peek(s->bufqueue, index + i);
memcpy(&s->scratch[offset], cur->extended_data[ch], cur->nb_samples*sizeof(float));
}
s->dsp->vector_fmul(s->scratch, s->scratch, s->window[s->bsize_analysis],
(OPUS_BLOCK_SIZE(s->bsize_analysis) << 1));
s->mdct_fn[s->bsize_analysis](s->mdct[s->bsize_analysis], st->coeffs[ch],
s->scratch, sizeof(float));
for (i = 0; i < CELT_MAX_BANDS; i++)
st->bands[ch][i] = &st->coeffs[ch][ff_celt_freq_bands[i] << s->bsize_analysis];
}
for (ch = 0; ch < s->avctx->ch_layout.nb_channels; ch++) {
for (i = 0; i < CELT_MAX_BANDS; i++) {
float avg_c_s, energy = 0.0f, dist_dev = 0.0f;
const int range = ff_celt_freq_range[i] << s->bsize_analysis;
const float *coeffs = st->bands[ch][i];
for (j = 0; j < range; j++)
energy += coeffs[j]*coeffs[j];
st->energy[ch][i] += sqrtf(energy);
silence |= !!st->energy[ch][i];
avg_c_s = energy / range;
for (j = 0; j < range; j++) {
const float c_s = coeffs[j]*coeffs[j];
dist_dev += (avg_c_s - c_s)*(avg_c_s - c_s);
}
st->tone[ch][i] += sqrtf(dist_dev);
}
}
st->silence = !silence;
if (s->avctx->ch_layout.nb_channels > 1) {
for (i = 0; i < CELT_MAX_BANDS; i++) {
float incompat = 0.0f;
const float *coeffs1 = st->bands[0][i];
const float *coeffs2 = st->bands[1][i];
const int range = ff_celt_freq_range[i] << s->bsize_analysis;
for (j = 0; j < range; j++)
incompat += (coeffs1[j] - coeffs2[j])*(coeffs1[j] - coeffs2[j]);
st->stereo[i] = sqrtf(incompat);
}
}
for (ch = 0; ch < s->avctx->ch_layout.nb_channels; ch++) {
for (i = 0; i < CELT_MAX_BANDS; i++) {
OpusBandExcitation *ex = &s->ex[ch][i];
float bp_e = bessel_filter(&s->bfilter_lo[ch][i], st->energy[ch][i]);
bp_e = bessel_filter(&s->bfilter_hi[ch][i], bp_e);
bp_e *= bp_e;
if (bp_e > ex->excitation) {
st->change_amp[ch][i] = bp_e - ex->excitation;
st->total_change += st->change_amp[ch][i];
ex->excitation = ex->excitation_init = bp_e;
ex->excitation_dist = 0.0f;
}
if (ex->excitation > 0.0f) {
ex->excitation -= av_clipf((1/expf(ex->excitation_dist)), ex->excitation_init/20, ex->excitation_init/1.09);
ex->excitation = FFMAX(ex->excitation, 0.0f);
ex->excitation_dist += 1.0f;
}
}
}
}
static void search_for_change_points(OpusPsyContext *s, float tgt_change,
int offset_s, int offset_e, int resolution,
int level)
{
int i;
float c_change = 0.0f;
if ((offset_e - offset_s) <= resolution)
return;
for (i = offset_s; i < offset_e; i++) {
c_change += s->steps[i]->total_change;
if (c_change > tgt_change)
break;
}
if (i == offset_e)
return;
search_for_change_points(s, tgt_change / 2.0f, offset_s, i + 0, resolution, level + 1);
s->inflection_points[s->inflection_points_count++] = i;
search_for_change_points(s, tgt_change / 2.0f, i + 1, offset_e, resolution, level + 1);
}
static int flush_silent_frames(OpusPsyContext *s)
{
int fsize, silent_frames;
for (silent_frames = 0; silent_frames < s->buffered_steps; silent_frames++)
if (!s->steps[silent_frames]->silence)
break;
if (--silent_frames < 0)
return 0;
for (fsize = CELT_BLOCK_960; fsize > CELT_BLOCK_120; fsize--) {
if ((1 << fsize) > silent_frames)
continue;
s->p.frames = FFMIN(silent_frames / (1 << fsize), 48 >> fsize);
s->p.framesize = fsize;
return 1;
}
return 0;
}
/* Main function which decides frame size and frames per current packet */
static void psy_output_groups(OpusPsyContext *s)
{
int max_delay_samples = (s->options->max_delay_ms*s->avctx->sample_rate)/1000;
int max_bsize = FFMIN(OPUS_SAMPLES_TO_BLOCK_SIZE(max_delay_samples), CELT_BLOCK_960);
/* These don't change for now */
s->p.mode = OPUS_MODE_CELT;
s->p.bandwidth = OPUS_BANDWIDTH_FULLBAND;
/* Flush silent frames ASAP */
if (s->steps[0]->silence && flush_silent_frames(s))
return;
s->p.framesize = FFMIN(max_bsize, CELT_BLOCK_960);
s->p.frames = 1;
}
int ff_opus_psy_process(OpusPsyContext *s, OpusPacketInfo *p)
{
int i;
float total_energy_change = 0.0f;
if (s->buffered_steps < s->max_steps && !s->eof) {
const int awin = (1 << s->bsize_analysis);
if (++s->steps_to_process >= awin) {
step_collect_psy_metrics(s, s->buffered_steps - awin + 1);
s->steps_to_process = 0;
}
if ((++s->buffered_steps) < s->max_steps)
return 1;
}
for (i = 0; i < s->buffered_steps; i++)
total_energy_change += s->steps[i]->total_change;
search_for_change_points(s, total_energy_change / 2.0f, 0,
s->buffered_steps, 1, 0);
psy_output_groups(s);
p->frames = s->p.frames;
p->framesize = s->p.framesize;
p->mode = s->p.mode;
p->bandwidth = s->p.bandwidth;
return 0;
}
void ff_opus_psy_celt_frame_init(OpusPsyContext *s, CeltFrame *f, int index)
{
int i, neighbouring_points = 0, start_offset = 0;
int radius = (1 << s->p.framesize), step_offset = radius*index;
int silence = 1;
f->start_band = (s->p.mode == OPUS_MODE_HYBRID) ? 17 : 0;
f->end_band = ff_celt_band_end[s->p.bandwidth];
f->channels = s->avctx->ch_layout.nb_channels;
f->size = s->p.framesize;
for (i = 0; i < (1 << f->size); i++)
silence &= s->steps[index*(1 << f->size) + i]->silence;
f->silence = silence;
if (f->silence) {
f->framebits = 0; /* Otherwise the silence flag eats up 16(!) bits */
return;
}
for (i = 0; i < s->inflection_points_count; i++) {
if (s->inflection_points[i] >= step_offset) {
start_offset = i;
break;
}
}
for (i = start_offset; i < FFMIN(radius, s->inflection_points_count - start_offset); i++) {
if (s->inflection_points[i] < (step_offset + radius)) {
neighbouring_points++;
}
}
/* Transient flagging */
f->transient = neighbouring_points > 0;
f->blocks = f->transient ? OPUS_BLOCK_SIZE(s->p.framesize)/CELT_OVERLAP : 1;
/* Some sane defaults */
f->pfilter = 0;
f->pf_gain = 0.5f;
f->pf_octave = 2;
f->pf_period = 1;
f->pf_tapset = 2;
/* More sane defaults */
f->tf_select = 0;
f->anticollapse = 1;
f->alloc_trim = 5;
f->skip_band_floor = f->end_band;
f->intensity_stereo = f->end_band;
f->dual_stereo = 0;
f->spread = CELT_SPREAD_NORMAL;
memset(f->tf_change, 0, sizeof(int)*CELT_MAX_BANDS);
memset(f->alloc_boost, 0, sizeof(int)*CELT_MAX_BANDS);
}
static void celt_gauge_psy_weight(OpusPsyContext *s, OpusPsyStep **start,
CeltFrame *f_out)
{
int i, f, ch;
int frame_size = OPUS_BLOCK_SIZE(s->p.framesize);
float rate, frame_bits = 0;
/* Used for the global ROTATE flag */
float tonal = 0.0f;
/* Pseudo-weights */
float band_score[CELT_MAX_BANDS] = { 0 };
float max_score = 1.0f;
/* Pass one - one loop around each band, computing unquant stuff */
for (i = 0; i < CELT_MAX_BANDS; i++) {
float weight = 0.0f;
float tonal_contrib = 0.0f;
for (f = 0; f < (1 << s->p.framesize); f++) {
weight = start[f]->stereo[i];
for (ch = 0; ch < s->avctx->ch_layout.nb_channels; ch++) {
weight += start[f]->change_amp[ch][i] + start[f]->tone[ch][i] + start[f]->energy[ch][i];
tonal_contrib += start[f]->tone[ch][i];
}
}
tonal += tonal_contrib;
band_score[i] = weight;
}
tonal /= (float)CELT_MAX_BANDS;
for (i = 0; i < CELT_MAX_BANDS; i++) {
if (band_score[i] > max_score)
max_score = band_score[i];
}
for (i = 0; i < CELT_MAX_BANDS; i++) {
f_out->alloc_boost[i] = (int)((band_score[i]/max_score)*3.0f);
frame_bits += band_score[i]*8.0f;
}
tonal /= 1333136.0f;
f_out->spread = av_clip_uintp2(lrintf(tonal), 2);
rate = ((float)s->avctx->bit_rate) + frame_bits*frame_size*16;
rate *= s->lambda;
rate /= s->avctx->sample_rate/frame_size;
f_out->framebits = lrintf(rate);
f_out->framebits = FFMIN(f_out->framebits, OPUS_MAX_FRAME_SIZE * 8);
f_out->framebits = FFALIGN(f_out->framebits, 8);
}
static int bands_dist(OpusPsyContext *s, CeltFrame *f, float *total_dist)
{
int i, tdist = 0.0f;
OpusRangeCoder dump;
ff_opus_rc_enc_init(&dump);
ff_celt_bitalloc(f, &dump, 1);
for (i = 0; i < CELT_MAX_BANDS; i++) {
float bits = 0.0f;
float dist = pvq_band_cost(f->pvq, f, &dump, i, &bits, s->lambda);
tdist += dist;
}
*total_dist = tdist;
return 0;
}
static void celt_search_for_dual_stereo(OpusPsyContext *s, CeltFrame *f)
{
float td1, td2;
f->dual_stereo = 0;
if (s->avctx->ch_layout.nb_channels < 2)
return;
bands_dist(s, f, &td1);
f->dual_stereo = 1;
bands_dist(s, f, &td2);
f->dual_stereo = td2 < td1;
s->dual_stereo_used += td2 < td1;
}
static void celt_search_for_intensity(OpusPsyContext *s, CeltFrame *f)
{
int i, best_band = CELT_MAX_BANDS - 1;
float dist, best_dist = FLT_MAX;
/* TODO: fix, make some heuristic up here using the lambda value */
float end_band = 0;
if (s->avctx->ch_layout.nb_channels < 2)
return;
for (i = f->end_band; i >= end_band; i--) {
f->intensity_stereo = i;
bands_dist(s, f, &dist);
if (best_dist > dist) {
best_dist = dist;
best_band = i;
}
}
f->intensity_stereo = best_band;
s->avg_is_band = (s->avg_is_band + f->intensity_stereo)/2.0f;
}
static int celt_search_for_tf(OpusPsyContext *s, OpusPsyStep **start, CeltFrame *f)
{
int i, j, k, cway, config[2][CELT_MAX_BANDS] = { { 0 } };
float score[2] = { 0 };
for (cway = 0; cway < 2; cway++) {
int mag[2];
int base = f->transient ? 120 : 960;
for (i = 0; i < 2; i++) {
int c = ff_celt_tf_select[f->size][f->transient][cway][i];
mag[i] = c < 0 ? base >> FFABS(c) : base << FFABS(c);
}
for (i = 0; i < CELT_MAX_BANDS; i++) {
float iscore0 = 0.0f;
float iscore1 = 0.0f;
for (j = 0; j < (1 << f->size); j++) {
for (k = 0; k < s->avctx->ch_layout.nb_channels; k++) {
iscore0 += start[j]->tone[k][i]*start[j]->change_amp[k][i]/mag[0];
iscore1 += start[j]->tone[k][i]*start[j]->change_amp[k][i]/mag[1];
}
}
config[cway][i] = FFABS(iscore0 - 1.0f) < FFABS(iscore1 - 1.0f);
score[cway] += config[cway][i] ? iscore1 : iscore0;
}
}
f->tf_select = score[0] < score[1];
memcpy(f->tf_change, config[f->tf_select], sizeof(int)*CELT_MAX_BANDS);
return 0;
}
int ff_opus_psy_celt_frame_process(OpusPsyContext *s, CeltFrame *f, int index)
{
int start_transient_flag = f->transient;
OpusPsyStep **start = &s->steps[index * (1 << s->p.framesize)];
if (f->silence)
return 0;
celt_gauge_psy_weight(s, start, f);
celt_search_for_intensity(s, f);
celt_search_for_dual_stereo(s, f);
celt_search_for_tf(s, start, f);
if (f->transient != start_transient_flag) {
f->blocks = f->transient ? OPUS_BLOCK_SIZE(s->p.framesize)/CELT_OVERLAP : 1;
return 1;
}
return 0;
}
void ff_opus_psy_postencode_update(OpusPsyContext *s, CeltFrame *f)
{
int i, frame_size = OPUS_BLOCK_SIZE(s->p.framesize);
int steps_out = s->p.frames*(frame_size/120);
void *tmp[FF_BUFQUEUE_SIZE];
float ideal_fbits;
for (i = 0; i < steps_out; i++)
memset(s->steps[i], 0, sizeof(OpusPsyStep));
for (i = 0; i < s->max_steps; i++)
tmp[i] = s->steps[i];
for (i = 0; i < s->max_steps; i++) {
const int i_new = i - steps_out;
s->steps[i_new < 0 ? s->max_steps + i_new : i_new] = tmp[i];
}
for (i = steps_out; i < s->buffered_steps; i++)
s->steps[i]->index -= steps_out;
ideal_fbits = s->avctx->bit_rate/(s->avctx->sample_rate/frame_size);
for (i = 0; i < s->p.frames; i++) {
s->avg_is_band += f[i].intensity_stereo;
s->lambda *= ideal_fbits / f[i].framebits;
}
s->avg_is_band /= (s->p.frames + 1);
s->steps_to_process = 0;
s->buffered_steps -= steps_out;
s->total_packets_out += s->p.frames;
s->inflection_points_count = 0;
}
av_cold int ff_opus_psy_init(OpusPsyContext *s, AVCodecContext *avctx,
struct FFBufQueue *bufqueue, OpusEncOptions *options)
{
int i, ch, ret;
s->lambda = 1.0f;
s->options = options;
s->avctx = avctx;
s->bufqueue = bufqueue;
s->max_steps = ceilf(s->options->max_delay_ms/2.5f);
s->bsize_analysis = CELT_BLOCK_960;
s->avg_is_band = CELT_MAX_BANDS - 1;
s->inflection_points_count = 0;
s->inflection_points = av_mallocz(sizeof(*s->inflection_points)*s->max_steps);
if (!s->inflection_points) {
ret = AVERROR(ENOMEM);
goto fail;
}
s->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
if (!s->dsp) {
ret = AVERROR(ENOMEM);
goto fail;
}
for (ch = 0; ch < s->avctx->ch_layout.nb_channels; ch++) {
for (i = 0; i < CELT_MAX_BANDS; i++) {
bessel_init(&s->bfilter_hi[ch][i], 1.0f, 19.0f, 100.0f, 1);
bessel_init(&s->bfilter_lo[ch][i], 1.0f, 20.0f, 100.0f, 0);
}
}
for (i = 0; i < s->max_steps; i++) {
s->steps[i] = av_mallocz(sizeof(OpusPsyStep));
if (!s->steps[i]) {
ret = AVERROR(ENOMEM);
goto fail;
}
}
for (i = 0; i < CELT_BLOCK_NB; i++) {
float tmp;
const int len = OPUS_BLOCK_SIZE(i);
const float scale = 68 << (CELT_BLOCK_NB - 1 - i);
s->window[i] = av_malloc(2*len*sizeof(float));
if (!s->window[i]) {
ret = AVERROR(ENOMEM);
goto fail;
}
generate_window_func(s->window[i], 2*len, WFUNC_SINE, &tmp);
ret = av_tx_init(&s->mdct[i], &s->mdct_fn[i], AV_TX_FLOAT_MDCT,
0, 15 << (i + 3), &scale, 0);
if (ret < 0)
goto fail;
}
return 0;
fail:
av_freep(&s->inflection_points);
av_freep(&s->dsp);
for (i = 0; i < CELT_BLOCK_NB; i++) {
av_tx_uninit(&s->mdct[i]);
av_freep(&s->window[i]);
}
for (i = 0; i < s->max_steps; i++)
av_freep(&s->steps[i]);
return ret;
}
void ff_opus_psy_signal_eof(OpusPsyContext *s)
{
s->eof = 1;
}
av_cold int ff_opus_psy_end(OpusPsyContext *s)
{
int i;
av_freep(&s->inflection_points);
av_freep(&s->dsp);
for (i = 0; i < CELT_BLOCK_NB; i++) {
av_tx_uninit(&s->mdct[i]);
av_freep(&s->window[i]);
}
for (i = 0; i < s->max_steps; i++)
av_freep(&s->steps[i]);
av_log(s->avctx, AV_LOG_INFO, "Average Intensity Stereo band: %0.1f\n", s->avg_is_band);
av_log(s->avctx, AV_LOG_INFO, "Dual Stereo used: %0.2f%%\n", ((float)s->dual_stereo_used/s->total_packets_out)*100.0f);
return 0;
}
+97
View File
@@ -0,0 +1,97 @@
/*
* Opus encoder
* Copyright (c) 2017 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_OPUS_ENC_PSY_H
#define AVCODEC_OPUS_ENC_PSY_H
#include "libavutil/tx.h"
#include "libavutil/mem_internal.h"
#include "enc.h"
#include "celt.h"
#include "enc_utils.h"
/* Each step is 2.5ms */
typedef struct OpusPsyStep {
int index; /* Current index */
int silence;
float energy[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; /* Masking effects included */
float tone[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; /* Tonality */
float stereo[CELT_MAX_BANDS]; /* IS/MS compatibility */
float change_amp[OPUS_MAX_CHANNELS][CELT_MAX_BANDS]; /* Jump over last frame */
float total_change; /* Total change */
float *bands[OPUS_MAX_CHANNELS][CELT_MAX_BANDS];
float coeffs[OPUS_MAX_CHANNELS][OPUS_BLOCK_SIZE(CELT_BLOCK_960)];
} OpusPsyStep;
typedef struct OpusBandExcitation {
float excitation;
float excitation_dist;
float excitation_init;
} OpusBandExcitation;
typedef struct OpusPsyContext {
AVCodecContext *avctx;
AVFloatDSPContext *dsp;
struct FFBufQueue *bufqueue;
OpusEncOptions *options;
OpusBandExcitation ex[OPUS_MAX_CHANNELS][CELT_MAX_BANDS];
FFBesselFilter bfilter_lo[OPUS_MAX_CHANNELS][CELT_MAX_BANDS];
FFBesselFilter bfilter_hi[OPUS_MAX_CHANNELS][CELT_MAX_BANDS];
OpusPsyStep *steps[FF_BUFQUEUE_SIZE + 1];
int max_steps;
float *window[CELT_BLOCK_NB];
AVTXContext *mdct[CELT_BLOCK_NB];
av_tx_fn mdct_fn[CELT_BLOCK_NB];
int bsize_analysis;
DECLARE_ALIGNED(32, float, scratch)[2048];
/* Stats */
float avg_is_band;
int64_t dual_stereo_used;
int64_t total_packets_out;
/* State */
OpusPacketInfo p;
int buffered_steps;
int steps_to_process;
int eof;
float lambda;
int *inflection_points;
int inflection_points_count;
} OpusPsyContext;
int ff_opus_psy_process (OpusPsyContext *s, OpusPacketInfo *p);
void ff_opus_psy_celt_frame_init (OpusPsyContext *s, CeltFrame *f, int index);
int ff_opus_psy_celt_frame_process(OpusPsyContext *s, CeltFrame *f, int index);
void ff_opus_psy_postencode_update (OpusPsyContext *s, CeltFrame *f);
int ff_opus_psy_init(OpusPsyContext *s, AVCodecContext *avctx,
struct FFBufQueue *bufqueue, OpusEncOptions *options);
void ff_opus_psy_signal_eof(OpusPsyContext *s);
int ff_opus_psy_end(OpusPsyContext *s);
#endif /* AVCODEC_OPUS_ENC_PSY_H */
+90
View File
@@ -0,0 +1,90 @@
/*
* Opus encoder
* Copyright (c) 2017 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_OPUS_ENC_UTILS_H
#define AVCODEC_OPUS_ENC_UTILS_H
#include <math.h>
#include <string.h>
#include "opus.h"
typedef struct FFBesselFilter {
float a[3];
float b[2];
float x[3];
float y[3];
} FFBesselFilter;
/* Fills the coefficients, returns 1 if filter will be unstable */
static inline int bessel_reinit(FFBesselFilter *s, float n, float f0, float fs,
int highpass)
{
int unstable;
float c, cfreq, w0, k1, k2;
if (!highpass) {
c = (1.0f/sqrtf(sqrtf(pow(2.0f, 1.0f/n) - 3.0f/4.0f) - 0.5f))/sqrtf(3.0f);
cfreq = c*f0/fs;
unstable = (cfreq <= 0.0f || cfreq >= 1.0f/4.0f);
} else {
c = sqrtf(3.0f)*sqrtf(sqrtf(pow(2.0f, 1.0f/n) - 3.0f/4.0f) - 0.5f);
cfreq = 0.5f - c*f0/fs;
unstable = (cfreq <= 3.0f/8.0f || cfreq >= 1.0f/2.0f);
}
w0 = tanf(M_PI*cfreq);
k1 = 3.0f * w0;
k2 = 3.0f * w0;
s->a[0] = k2/(1.0f + k1 + k2);
s->a[1] = 2.0f * s->a[0];
s->a[2] = s->a[0];
s->b[0] = 2.0f * s->a[0] * (1.0f/k2 - 1.0f);
s->b[1] = 1.0f - (s->a[0] + s->a[1] + s->a[2] + s->b[0]);
if (highpass) {
s->a[1] *= -1;
s->b[0] *= -1;
}
return unstable;
}
static inline int bessel_init(FFBesselFilter *s, float n, float f0, float fs,
int highpass)
{
memset(s, 0, sizeof(FFBesselFilter));
return bessel_reinit(s, n, f0, fs, highpass);
}
static inline float bessel_filter(FFBesselFilter *s, float x)
{
s->x[2] = s->x[1];
s->x[1] = s->x[0];
s->x[0] = x;
s->y[2] = s->y[1];
s->y[1] = s->y[0];
s->y[0] = s->a[0]*s->x[0] + s->a[1]*s->x[1] + s->a[2]*s->x[2] + s->b[0]*s->y[1] + s->b[1]*s->y[2];
return s->y[0];
}
#endif /* AVCODEC_OPUS_ENC_UTILS_H */
+59
View File
@@ -0,0 +1,59 @@
/*
* Opus common header
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_OPUS_OPUS_H
#define AVCODEC_OPUS_OPUS_H
#include <stdint.h>
#define OPUS_MAX_FRAME_SIZE 1275
#define OPUS_MAX_FRAMES 48
#define OPUS_MAX_PACKET_DUR 5760
#define OPUS_TS_HEADER 0x7FE0 // 0x3ff (11 bits)
#define OPUS_TS_MASK 0xFFE0 // top 11 bits
static const uint8_t opus_default_extradata[30] = {
'O', 'p', 'u', 's', 'H', 'e', 'a', 'd',
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
enum OpusMode {
OPUS_MODE_SILK,
OPUS_MODE_HYBRID,
OPUS_MODE_CELT,
OPUS_MODE_NB
};
enum OpusBandwidth {
OPUS_BANDWIDTH_NARROWBAND,
OPUS_BANDWIDTH_MEDIUMBAND,
OPUS_BANDWIDTH_WIDEBAND,
OPUS_BANDWIDTH_SUPERWIDEBAND,
OPUS_BANDWIDTH_FULLBAND,
OPUS_BANDWITH_NB
};
#endif /* AVCODEC_OPUS_OPUS_H */
+468
View File
@@ -0,0 +1,468 @@
/*
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Opus decoder/parser shared code
*/
#include "libavutil/attributes.h"
#include "libavutil/channel_layout.h"
#include "libavutil/error.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/mem.h"
#include "avcodec.h"
#include "internal.h"
#include "mathops.h"
#include "opus.h"
#include "parse.h"
#include "vorbis_data.h"
static const uint16_t opus_frame_duration[32] = {
480, 960, 1920, 2880,
480, 960, 1920, 2880,
480, 960, 1920, 2880,
480, 960,
480, 960,
120, 240, 480, 960,
120, 240, 480, 960,
120, 240, 480, 960,
120, 240, 480, 960,
};
/**
* Read a 1- or 2-byte frame length
*/
static inline int xiph_lacing_16bit(const uint8_t **ptr, const uint8_t *end)
{
int val;
if (*ptr >= end)
return AVERROR_INVALIDDATA;
val = *(*ptr)++;
if (val >= 252) {
if (*ptr >= end)
return AVERROR_INVALIDDATA;
val += 4 * *(*ptr)++;
}
return val;
}
/**
* Read a multi-byte length (used for code 3 packet padding size)
*/
static inline int xiph_lacing_full(const uint8_t **ptr, const uint8_t *end)
{
int val = 0;
int next;
while (1) {
if (*ptr >= end || val > INT_MAX - 254)
return AVERROR_INVALIDDATA;
next = *(*ptr)++;
val += next;
if (next < 255)
break;
else
val--;
}
return val;
}
/**
* Parse Opus packet info from raw packet data
*/
int ff_opus_parse_packet(OpusPacket *pkt, const uint8_t *buf, int buf_size,
int self_delimiting)
{
const uint8_t *ptr = buf;
const uint8_t *end = buf + buf_size;
int padding = 0;
int frame_bytes, i;
if (buf_size < 1)
goto fail;
/* TOC byte */
i = *ptr++;
pkt->code = (i ) & 0x3;
pkt->stereo = (i >> 2) & 0x1;
pkt->config = (i >> 3) & 0x1F;
/* code 2 and code 3 packets have at least 1 byte after the TOC */
if (pkt->code >= 2 && buf_size < 2)
goto fail;
switch (pkt->code) {
case 0:
/* 1 frame */
pkt->frame_count = 1;
pkt->vbr = 0;
if (self_delimiting) {
int len = xiph_lacing_16bit(&ptr, end);
if (len < 0 || len > end - ptr)
goto fail;
end = ptr + len;
buf_size = end - buf;
}
frame_bytes = end - ptr;
if (frame_bytes > OPUS_MAX_FRAME_SIZE)
goto fail;
pkt->frame_offset[0] = ptr - buf;
pkt->frame_size[0] = frame_bytes;
break;
case 1:
/* 2 frames, equal size */
pkt->frame_count = 2;
pkt->vbr = 0;
if (self_delimiting) {
int len = xiph_lacing_16bit(&ptr, end);
if (len < 0 || 2 * len > end - ptr)
goto fail;
end = ptr + 2 * len;
buf_size = end - buf;
}
frame_bytes = end - ptr;
if (frame_bytes & 1 || frame_bytes >> 1 > OPUS_MAX_FRAME_SIZE)
goto fail;
pkt->frame_offset[0] = ptr - buf;
pkt->frame_size[0] = frame_bytes >> 1;
pkt->frame_offset[1] = pkt->frame_offset[0] + pkt->frame_size[0];
pkt->frame_size[1] = frame_bytes >> 1;
break;
case 2:
/* 2 frames, different sizes */
pkt->frame_count = 2;
pkt->vbr = 1;
/* read 1st frame size */
frame_bytes = xiph_lacing_16bit(&ptr, end);
if (frame_bytes < 0)
goto fail;
if (self_delimiting) {
int len = xiph_lacing_16bit(&ptr, end);
if (len < 0 || len + frame_bytes > end - ptr)
goto fail;
end = ptr + frame_bytes + len;
buf_size = end - buf;
}
pkt->frame_offset[0] = ptr - buf;
pkt->frame_size[0] = frame_bytes;
/* calculate 2nd frame size */
frame_bytes = end - ptr - pkt->frame_size[0];
if (frame_bytes < 0 || frame_bytes > OPUS_MAX_FRAME_SIZE)
goto fail;
pkt->frame_offset[1] = pkt->frame_offset[0] + pkt->frame_size[0];
pkt->frame_size[1] = frame_bytes;
break;
case 3:
/* 1 to 48 frames, can be different sizes */
i = *ptr++;
pkt->frame_count = (i ) & 0x3F;
padding = (i >> 6) & 0x01;
pkt->vbr = (i >> 7) & 0x01;
if (pkt->frame_count == 0 || pkt->frame_count > OPUS_MAX_FRAMES)
goto fail;
/* read padding size */
if (padding) {
padding = xiph_lacing_full(&ptr, end);
if (padding < 0)
goto fail;
}
/* read frame sizes */
if (pkt->vbr) {
/* for VBR, all frames except the final one have their size coded
in the bitstream. the last frame size is implicit. */
int total_bytes = 0;
for (i = 0; i < pkt->frame_count - 1; i++) {
frame_bytes = xiph_lacing_16bit(&ptr, end);
if (frame_bytes < 0)
goto fail;
pkt->frame_size[i] = frame_bytes;
total_bytes += frame_bytes;
}
if (self_delimiting) {
int len = xiph_lacing_16bit(&ptr, end);
if (len < 0 || len + total_bytes + padding > end - ptr)
goto fail;
end = ptr + total_bytes + len + padding;
buf_size = end - buf;
}
frame_bytes = end - ptr - padding;
if (total_bytes > frame_bytes)
goto fail;
pkt->frame_offset[0] = ptr - buf;
for (i = 1; i < pkt->frame_count; i++)
pkt->frame_offset[i] = pkt->frame_offset[i-1] + pkt->frame_size[i-1];
pkt->frame_size[pkt->frame_count-1] = frame_bytes - total_bytes;
} else {
/* for CBR, the remaining packet bytes are divided evenly between
the frames */
if (self_delimiting) {
frame_bytes = xiph_lacing_16bit(&ptr, end);
if (frame_bytes < 0 || pkt->frame_count * frame_bytes + padding > end - ptr)
goto fail;
end = ptr + pkt->frame_count * frame_bytes + padding;
buf_size = end - buf;
} else {
frame_bytes = end - ptr - padding;
if (frame_bytes % pkt->frame_count ||
frame_bytes / pkt->frame_count > OPUS_MAX_FRAME_SIZE)
goto fail;
frame_bytes /= pkt->frame_count;
}
pkt->frame_offset[0] = ptr - buf;
pkt->frame_size[0] = frame_bytes;
for (i = 1; i < pkt->frame_count; i++) {
pkt->frame_offset[i] = pkt->frame_offset[i-1] + pkt->frame_size[i-1];
pkt->frame_size[i] = frame_bytes;
}
}
}
pkt->packet_size = buf_size;
pkt->data_size = pkt->packet_size - padding;
/* total packet duration cannot be larger than 120ms */
pkt->frame_duration = opus_frame_duration[pkt->config];
if (pkt->frame_duration * pkt->frame_count > OPUS_MAX_PACKET_DUR)
goto fail;
/* set mode and bandwidth */
if (pkt->config < 12) {
pkt->mode = OPUS_MODE_SILK;
pkt->bandwidth = pkt->config >> 2;
} else if (pkt->config < 16) {
pkt->mode = OPUS_MODE_HYBRID;
pkt->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND + (pkt->config >= 14);
} else {
pkt->mode = OPUS_MODE_CELT;
pkt->bandwidth = (pkt->config - 16) >> 2;
/* skip medium band */
if (pkt->bandwidth)
pkt->bandwidth++;
}
return 0;
fail:
memset(pkt, 0, sizeof(*pkt));
return AVERROR_INVALIDDATA;
}
static int channel_reorder_vorbis(int nb_channels, int channel_idx)
{
return ff_vorbis_channel_layout_offsets[nb_channels - 1][channel_idx];
}
static int channel_reorder_unknown(int nb_channels, int channel_idx)
{
return channel_idx;
}
av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
OpusParseContext *s)
{
static const uint8_t default_channel_map[2] = { 0, 1 };
int (*channel_reorder)(int, int) = channel_reorder_unknown;
int channels = avctx->ch_layout.nb_channels;
const uint8_t *extradata, *channel_map;
int extradata_size;
int version, map_type, streams, stereo_streams, i, j, ret;
AVChannelLayout layout = { 0 };
if (!avctx->extradata) {
if (channels > 2) {
av_log(avctx, AV_LOG_ERROR,
"Multichannel configuration without extradata.\n");
return AVERROR(EINVAL);
}
extradata = opus_default_extradata;
extradata_size = sizeof(opus_default_extradata);
} else {
extradata = avctx->extradata;
extradata_size = avctx->extradata_size;
}
if (extradata_size < 19) {
av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n",
extradata_size);
return AVERROR_INVALIDDATA;
}
version = extradata[8];
if (version > 15) {
avpriv_request_sample(avctx, "Extradata version %d", version);
return AVERROR_PATCHWELCOME;
}
avctx->delay = AV_RL16(extradata + 10);
if (avctx->internal)
avctx->internal->skip_samples = avctx->delay;
channels = avctx->extradata ? extradata[9] : (channels == 1) ? 1 : 2;
if (!channels) {
av_log(avctx, AV_LOG_ERROR, "Zero channel count specified in the extradata\n");
return AVERROR_INVALIDDATA;
}
s->gain_i = AV_RL16(extradata + 16);
map_type = extradata[18];
if (!map_type) {
if (channels > 2) {
av_log(avctx, AV_LOG_ERROR,
"Channel mapping 0 is only specified for up to 2 channels\n");
ret = AVERROR_INVALIDDATA;
goto fail;
}
layout = (channels == 1) ? (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO :
(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
streams = 1;
stereo_streams = channels - 1;
channel_map = default_channel_map;
} else if (map_type == 1 || map_type == 2 || map_type == 255) {
if (extradata_size < 21 + channels) {
av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n",
extradata_size);
ret = AVERROR_INVALIDDATA;
goto fail;
}
streams = extradata[19];
stereo_streams = extradata[20];
if (!streams || stereo_streams > streams ||
streams + stereo_streams > 255) {
av_log(avctx, AV_LOG_ERROR,
"Invalid stream/stereo stream count: %d/%d\n", streams, stereo_streams);
ret = AVERROR_INVALIDDATA;
goto fail;
}
if (map_type == 1) {
if (channels > 8) {
av_log(avctx, AV_LOG_ERROR,
"Channel mapping 1 is only specified for up to 8 channels\n");
ret = AVERROR_INVALIDDATA;
goto fail;
}
av_channel_layout_copy(&layout, &ff_vorbis_ch_layouts[channels - 1]);
channel_reorder = channel_reorder_vorbis;
} else if (map_type == 2) {
int ambisonic_order = ff_sqrt(channels) - 1;
if (channels != ((ambisonic_order + 1) * (ambisonic_order + 1)) &&
channels != ((ambisonic_order + 1) * (ambisonic_order + 1) + 2)) {
av_log(avctx, AV_LOG_ERROR,
"Channel mapping 2 is only specified for channel counts"
" which can be written as (n + 1)^2 or (n + 1)^2 + 2"
" for nonnegative integer n\n");
ret = AVERROR_INVALIDDATA;
goto fail;
}
if (channels > 227) {
av_log(avctx, AV_LOG_ERROR, "Too many channels\n");
ret = AVERROR_INVALIDDATA;
goto fail;
}
layout.order = AV_CHANNEL_ORDER_AMBISONIC;
layout.nb_channels = channels;
if (channels != ((ambisonic_order + 1) * (ambisonic_order + 1)))
layout.u.mask = AV_CH_LAYOUT_STEREO;
} else {
layout.order = AV_CHANNEL_ORDER_UNSPEC;
layout.nb_channels = channels;
}
channel_map = extradata + 21;
} else {
avpriv_request_sample(avctx, "Mapping type %d", map_type);
return AVERROR_PATCHWELCOME;
}
s->channel_maps = av_calloc(channels, sizeof(*s->channel_maps));
if (!s->channel_maps) {
ret = AVERROR(ENOMEM);
goto fail;
}
for (i = 0; i < channels; i++) {
ChannelMap *map = &s->channel_maps[i];
uint8_t idx = channel_map[channel_reorder(channels, i)];
if (idx == 255) {
map->silence = 1;
continue;
} else if (idx >= streams + stereo_streams) {
av_log(avctx, AV_LOG_ERROR,
"Invalid channel map for output channel %d: %d\n", i, idx);
av_freep(&s->channel_maps);
ret = AVERROR_INVALIDDATA;
goto fail;
}
/* check that we did not see this index yet */
map->copy = 0;
for (j = 0; j < i; j++)
if (channel_map[channel_reorder(channels, j)] == idx) {
map->copy = 1;
map->copy_idx = j;
break;
}
if (idx < 2 * stereo_streams) {
map->stream_idx = idx / 2;
map->channel_idx = idx & 1;
} else {
map->stream_idx = idx - stereo_streams;
map->channel_idx = 0;
}
}
ret = av_channel_layout_copy(&avctx->ch_layout, &layout);
if (ret < 0)
goto fail;
s->nb_streams = streams;
s->nb_stereo_streams = stereo_streams;
return 0;
fail:
av_channel_layout_uninit(&layout);
return ret;
}
+77
View File
@@ -0,0 +1,77 @@
/*
* Opus decoder/parser common functions and structures
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_OPUS_PARSE_H
#define AVCODEC_OPUS_PARSE_H
#include <stdint.h>
#include "libavcodec/avcodec.h"
#include "opus.h"
typedef struct OpusPacket {
int packet_size; /**< packet size */
int data_size; /**< size of the useful data -- packet size - padding */
int code; /**< packet code: specifies the frame layout */
int stereo; /**< whether this packet is mono or stereo */
int vbr; /**< vbr flag */
int config; /**< configuration: tells the audio mode,
** bandwidth, and frame duration */
int frame_count; /**< frame count */
int frame_offset[OPUS_MAX_FRAMES]; /**< frame offsets */
int frame_size[OPUS_MAX_FRAMES]; /**< frame sizes */
int frame_duration; /**< frame duration, in samples @ 48kHz */
enum OpusMode mode; /**< mode */
enum OpusBandwidth bandwidth; /**< bandwidth */
} OpusPacket;
// a mapping between an opus stream and an output channel
typedef struct ChannelMap {
int stream_idx;
int channel_idx;
// when a single decoded channel is mapped to multiple output channels, we
// write to the first output directly and copy from it to the others
// this field is set to 1 for those copied output channels
int copy;
// this is the index of the output channel to copy from
int copy_idx;
// this channel is silent
int silence;
} ChannelMap;
typedef struct OpusParseContext {
int nb_streams;
int nb_stereo_streams;
int16_t gain_i;
ChannelMap *channel_maps;
} OpusParseContext;
int ff_opus_parse_packet(OpusPacket *pkt, const uint8_t *buf, int buf_size,
int self_delimited);
int ff_opus_parse_extradata(AVCodecContext *avctx, OpusParseContext *s);
#endif /* AVCODEC_OPUS_PARSE_H */
+221
View File
@@ -0,0 +1,221 @@
/*
* Copyright (c) 2013-2014 Mozilla Corporation
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Opus parser
*
* Determines the duration for each packet.
*/
#include "libavutil/mem.h"
#include "avcodec.h"
#include "bytestream.h"
#include "opus.h"
#include "parse.h"
#include "parser.h"
typedef struct OpusParserContext {
ParseContext pc;
OpusParseContext ctx;
OpusPacket pkt;
int extradata_parsed;
int ts_framing;
} OpusParserContext;
static const uint8_t *parse_opus_ts_header(const uint8_t *start, int *payload_len, int buf_len)
{
const uint8_t *buf = start + 1;
int start_trim_flag, end_trim_flag, control_extension_flag, control_extension_length;
uint8_t flags;
uint64_t payload_len_tmp;
GetByteContext gb;
bytestream2_init(&gb, buf, buf_len);
flags = bytestream2_get_byte(&gb);
start_trim_flag = (flags >> 4) & 1;
end_trim_flag = (flags >> 3) & 1;
control_extension_flag = (flags >> 2) & 1;
payload_len_tmp = *payload_len = 0;
while (bytestream2_peek_byte(&gb) == 0xff)
payload_len_tmp += bytestream2_get_byte(&gb);
payload_len_tmp += bytestream2_get_byte(&gb);
if (start_trim_flag)
bytestream2_skip(&gb, 2);
if (end_trim_flag)
bytestream2_skip(&gb, 2);
if (control_extension_flag) {
control_extension_length = bytestream2_get_byte(&gb);
bytestream2_skip(&gb, control_extension_length);
}
if (bytestream2_tell(&gb) + payload_len_tmp > buf_len)
return NULL;
*payload_len = payload_len_tmp;
return buf + bytestream2_tell(&gb);
}
static int set_frame_duration(AVCodecParserContext *ctx, AVCodecContext *avctx,
const uint8_t *buf, int buf_size)
{
OpusParserContext *s = ctx->priv_data;
if (ff_opus_parse_packet(&s->pkt, buf, buf_size, s->ctx.nb_streams > 1) < 0) {
av_log(avctx, AV_LOG_ERROR, "Error parsing Opus packet header.\n");
return AVERROR_INVALIDDATA;
}
ctx->duration = s->pkt.frame_count * s->pkt.frame_duration;
return 0;
}
/**
* Find the end of the current frame in the bitstream.
* @return the position of the first byte of the next frame, or -1
*/
static int opus_find_frame_end(AVCodecParserContext *ctx, AVCodecContext *avctx,
const uint8_t *buf, int buf_size, int *header_len)
{
OpusParserContext *s = ctx->priv_data;
ParseContext *pc = &s->pc;
int ret, start_found, i = 0, payload_len = 0;
const uint8_t *payload;
uint32_t state;
uint16_t hdr;
*header_len = 0;
if (!buf_size)
return 0;
start_found = pc->frame_start_found;
state = pc->state;
payload = buf;
/* Check if we're using Opus in MPEG-TS framing */
if (!s->ts_framing && buf_size > 2) {
hdr = AV_RB16(buf);
if ((hdr & OPUS_TS_MASK) == OPUS_TS_HEADER)
s->ts_framing = 1;
}
if (s->ts_framing && !start_found) {
for (i = 0; i < buf_size-2; i++) {
state = (state << 8) | payload[i];
if ((state & OPUS_TS_MASK) == OPUS_TS_HEADER) {
payload = parse_opus_ts_header(payload, &payload_len, buf_size - i);
if (!payload) {
av_log(avctx, AV_LOG_ERROR, "Error parsing Ogg TS header.\n");
return AVERROR_INVALIDDATA;
}
*header_len = payload - buf;
start_found = 1;
break;
}
}
}
if (!s->ts_framing)
payload_len = buf_size;
if (payload_len <= buf_size && (!s->ts_framing || start_found)) {
ret = set_frame_duration(ctx, avctx, payload, payload_len);
if (ret < 0) {
pc->frame_start_found = 0;
return AVERROR_INVALIDDATA;
}
}
if (s->ts_framing) {
if (start_found) {
if (payload_len + *header_len <= buf_size) {
pc->frame_start_found = 0;
pc->state = -1;
return payload_len + *header_len;
}
}
pc->frame_start_found = start_found;
pc->state = state;
return END_NOT_FOUND;
}
return buf_size;
}
static int opus_parse(AVCodecParserContext *ctx, AVCodecContext *avctx,
const uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size)
{
OpusParserContext *s = ctx->priv_data;
ParseContext *pc = &s->pc;
int next, header_len = 0;
avctx->sample_rate = 48000;
if (avctx->extradata && !s->extradata_parsed) {
if (ff_opus_parse_extradata(avctx, &s->ctx) < 0) {
av_log(avctx, AV_LOG_ERROR, "Error parsing Ogg extradata.\n");
goto fail;
}
av_freep(&s->ctx.channel_maps);
s->extradata_parsed = 1;
}
if (ctx->flags & PARSER_FLAG_COMPLETE_FRAMES) {
next = buf_size;
if (set_frame_duration(ctx, avctx, buf, buf_size) < 0)
goto fail;
} else {
next = opus_find_frame_end(ctx, avctx, buf, buf_size, &header_len);
if (s->ts_framing && next != AVERROR_INVALIDDATA &&
ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
goto fail;
}
if (next == AVERROR_INVALIDDATA){
goto fail;
}
}
*poutbuf = buf + header_len;
*poutbuf_size = buf_size - header_len;
return next;
fail:
*poutbuf = NULL;
*poutbuf_size = 0;
return buf_size;
}
const AVCodecParser ff_opus_parser = {
.codec_ids = { AV_CODEC_ID_OPUS },
.priv_data_size = sizeof(OpusParserContext),
.parser_parse = opus_parse,
.parser_close = ff_parse_close
};
+930
View File
@@ -0,0 +1,930 @@
/*
* Copyright (c) 2007-2008 CSIRO
* Copyright (c) 2007-2009 Xiph.Org Foundation
* Copyright (c) 2008-2009 Gregory Maxwell
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
* Copyright (c) 2017 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <float.h>
#include "config_components.h"
#include "libavutil/mem.h"
#include "mathops.h"
#include "tab.h"
#include "pvq.h"
#define ROUND_MUL16(a,b) ((MUL16(a, b) + 16384) >> 15)
#define CELT_PVQ_U(n, k) (ff_celt_pvq_u_row[FFMIN(n, k)][FFMAX(n, k)])
#define CELT_PVQ_V(n, k) (CELT_PVQ_U(n, k) + CELT_PVQ_U(n, (k) + 1))
static inline int16_t celt_cos(int16_t x)
{
x = (MUL16(x, x) + 4096) >> 13;
x = (32767-x) + ROUND_MUL16(x, (-7651 + ROUND_MUL16(x, (8277 + ROUND_MUL16(-626, x)))));
return x + 1;
}
static inline int celt_log2tan(int isin, int icos)
{
int lc, ls;
lc = opus_ilog(icos);
ls = opus_ilog(isin);
icos <<= 15 - lc;
isin <<= 15 - ls;
return (ls << 11) - (lc << 11) +
ROUND_MUL16(isin, ROUND_MUL16(isin, -2597) + 7932) -
ROUND_MUL16(icos, ROUND_MUL16(icos, -2597) + 7932);
}
static inline int celt_bits2pulses(const uint8_t *cache, int bits)
{
// TODO: Find the size of cache and make it into an array in the parameters list
int i, low = 0, high;
high = cache[0];
bits--;
for (i = 0; i < 6; i++) {
int center = (low + high + 1) >> 1;
if (cache[center] >= bits)
high = center;
else
low = center;
}
return (bits - (low == 0 ? -1 : cache[low]) <= cache[high] - bits) ? low : high;
}
static inline int celt_pulses2bits(const uint8_t *cache, int pulses)
{
// TODO: Find the size of cache and make it into an array in the parameters list
return (pulses == 0) ? 0 : cache[pulses] + 1;
}
static inline void celt_normalize_residual(const int * restrict iy, float * restrict X,
int N, float g)
{
int i;
for (i = 0; i < N; i++)
X[i] = g * iy[i];
}
static void celt_exp_rotation_impl(float *X, uint32_t len, uint32_t stride,
float c, float s)
{
float *Xptr;
int i;
Xptr = X;
for (i = 0; i < len - stride; i++) {
float x1 = Xptr[0];
float x2 = Xptr[stride];
Xptr[stride] = c * x2 + s * x1;
*Xptr++ = c * x1 - s * x2;
}
Xptr = &X[len - 2 * stride - 1];
for (i = len - 2 * stride - 1; i >= 0; i--) {
float x1 = Xptr[0];
float x2 = Xptr[stride];
Xptr[stride] = c * x2 + s * x1;
*Xptr-- = c * x1 - s * x2;
}
}
static inline void celt_exp_rotation(float *X, uint32_t len,
uint32_t stride, uint32_t K,
enum CeltSpread spread, const int encode)
{
uint32_t stride2 = 0;
float c, s;
float gain, theta;
int i;
if (2*K >= len || spread == CELT_SPREAD_NONE)
return;
gain = (float)len / (len + (20 - 5*spread) * K);
theta = M_PI * gain * gain / 4;
c = cosf(theta);
s = sinf(theta);
if (len >= stride << 3) {
stride2 = 1;
/* This is just a simple (equivalent) way of computing sqrt(len/stride) with rounding.
It's basically incrementing long as (stride2+0.5)^2 < len/stride. */
while ((stride2 * stride2 + stride2) * stride + (stride >> 2) < len)
stride2++;
}
len /= stride;
for (i = 0; i < stride; i++) {
if (encode) {
celt_exp_rotation_impl(X + i * len, len, 1, c, -s);
if (stride2)
celt_exp_rotation_impl(X + i * len, len, stride2, s, -c);
} else {
if (stride2)
celt_exp_rotation_impl(X + i * len, len, stride2, s, c);
celt_exp_rotation_impl(X + i * len, len, 1, c, s);
}
}
}
static inline uint32_t celt_extract_collapse_mask(const int *iy, uint32_t N, uint32_t B)
{
int i, j, N0 = N / B;
uint32_t collapse_mask = 0;
if (B <= 1)
return 1;
for (i = 0; i < B; i++)
for (j = 0; j < N0; j++)
collapse_mask |= (!!iy[i*N0+j]) << i;
return collapse_mask;
}
static inline void celt_stereo_merge(float *X, float *Y, float mid, int N)
{
int i;
float xp = 0, side = 0;
float E[2];
float mid2;
float gain[2];
/* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */
for (i = 0; i < N; i++) {
xp += X[i] * Y[i];
side += Y[i] * Y[i];
}
/* Compensating for the mid normalization */
xp *= mid;
mid2 = mid;
E[0] = mid2 * mid2 + side - 2 * xp;
E[1] = mid2 * mid2 + side + 2 * xp;
if (E[0] < 6e-4f || E[1] < 6e-4f) {
for (i = 0; i < N; i++)
Y[i] = X[i];
return;
}
gain[0] = 1.0f / sqrtf(E[0]);
gain[1] = 1.0f / sqrtf(E[1]);
for (i = 0; i < N; i++) {
float value[2];
/* Apply mid scaling (side is already scaled) */
value[0] = mid * X[i];
value[1] = Y[i];
X[i] = gain[0] * (value[0] - value[1]);
Y[i] = gain[1] * (value[0] + value[1]);
}
}
static void celt_interleave_hadamard(float *tmp, float *X, int N0,
int stride, int hadamard)
{
int i, j, N = N0*stride;
const uint8_t *order = &ff_celt_hadamard_order[hadamard ? stride - 2 : 30];
for (i = 0; i < stride; i++)
for (j = 0; j < N0; j++)
tmp[j*stride+i] = X[order[i]*N0+j];
memcpy(X, tmp, N*sizeof(float));
}
static void celt_deinterleave_hadamard(float *tmp, float *X, int N0,
int stride, int hadamard)
{
int i, j, N = N0*stride;
const uint8_t *order = &ff_celt_hadamard_order[hadamard ? stride - 2 : 30];
for (i = 0; i < stride; i++)
for (j = 0; j < N0; j++)
tmp[order[i]*N0+j] = X[j*stride+i];
memcpy(X, tmp, N*sizeof(float));
}
static void celt_haar1(float *X, int N0, int stride)
{
int i, j;
N0 >>= 1;
for (i = 0; i < stride; i++) {
for (j = 0; j < N0; j++) {
float x0 = X[stride * (2 * j + 0) + i];
float x1 = X[stride * (2 * j + 1) + i];
X[stride * (2 * j + 0) + i] = (x0 + x1) * M_SQRT1_2;
X[stride * (2 * j + 1) + i] = (x0 - x1) * M_SQRT1_2;
}
}
}
static inline int celt_compute_qn(int N, int b, int offset, int pulse_cap,
int stereo)
{
int qn, qb;
int N2 = 2 * N - 1;
if (stereo && N == 2)
N2--;
/* The upper limit ensures that in a stereo split with itheta==16384, we'll
* always have enough bits left over to code at least one pulse in the
* side; otherwise it would collapse, since it doesn't get folded. */
qb = FFMIN3(b - pulse_cap - (4 << 3), (b + N2 * offset) / N2, 8 << 3);
qn = (qb < (1 << 3 >> 1)) ? 1 : ((ff_celt_qn_exp2[qb & 0x7] >> (14 - (qb >> 3))) + 1) >> 1 << 1;
return qn;
}
/* Convert the quantized vector to an index */
static inline uint32_t celt_icwrsi(uint32_t N, uint32_t K, const int *y)
{
int i, idx = 0, sum = 0;
for (i = N - 1; i >= 0; i--) {
const uint32_t i_s = CELT_PVQ_U(N - i, sum + FFABS(y[i]) + 1);
idx += CELT_PVQ_U(N - i, sum) + (y[i] < 0)*i_s;
sum += FFABS(y[i]);
}
return idx;
}
// this code was adapted from libopus
static inline uint64_t celt_cwrsi(uint32_t N, uint32_t K, uint32_t i, int *y)
{
uint64_t norm = 0;
uint32_t q, p;
int s, val;
int k0;
while (N > 2) {
/*Lots of pulses case:*/
if (K >= N) {
const uint32_t *row = ff_celt_pvq_u_row[N];
/* Are the pulses in this dimension negative? */
p = row[K + 1];
s = -(i >= p);
i -= p & s;
/*Count how many pulses were placed in this dimension.*/
k0 = K;
q = row[N];
if (q > i) {
K = N;
do {
p = ff_celt_pvq_u_row[--K][N];
} while (p > i);
} else
for (p = row[K]; p > i; p = row[K])
K--;
i -= p;
val = (k0 - K + s) ^ s;
norm += val * val;
*y++ = val;
} else { /*Lots of dimensions case:*/
/*Are there any pulses in this dimension at all?*/
p = ff_celt_pvq_u_row[K ][N];
q = ff_celt_pvq_u_row[K + 1][N];
if (p <= i && i < q) {
i -= p;
*y++ = 0;
} else {
/*Are the pulses in this dimension negative?*/
s = -(i >= q);
i -= q & s;
/*Count how many pulses were placed in this dimension.*/
k0 = K;
do p = ff_celt_pvq_u_row[--K][N];
while (p > i);
i -= p;
val = (k0 - K + s) ^ s;
norm += val * val;
*y++ = val;
}
}
N--;
}
/* N == 2 */
p = 2 * K + 1;
s = -(i >= p);
i -= p & s;
k0 = K;
K = (i + 1) / 2;
if (K)
i -= 2 * K - 1;
val = (k0 - K + s) ^ s;
norm += val * val;
*y++ = val;
/* N==1 */
s = -i;
val = (K + s) ^ s;
norm += val * val;
*y = val;
return norm;
}
static inline void celt_encode_pulses(OpusRangeCoder *rc, int *y, uint32_t N, uint32_t K)
{
ff_opus_rc_enc_uint(rc, celt_icwrsi(N, K, y), CELT_PVQ_V(N, K));
}
static inline float celt_decode_pulses(OpusRangeCoder *rc, int *y, uint32_t N, uint32_t K)
{
const uint32_t idx = ff_opus_rc_dec_uint(rc, CELT_PVQ_V(N, K));
return celt_cwrsi(N, K, idx, y);
}
#if CONFIG_OPUS_ENCODER
/*
* Faster than libopus's search, operates entirely in the signed domain.
* Slightly worse/better depending on N, K and the input vector.
*/
static float ppp_pvq_search_c(float *X, int *y, int K, int N)
{
int i, y_norm = 0;
float res = 0.0f, xy_norm = 0.0f;
for (i = 0; i < N; i++)
res += FFABS(X[i]);
res = K/(res + FLT_EPSILON);
for (i = 0; i < N; i++) {
y[i] = lrintf(res*X[i]);
y_norm += y[i]*y[i];
xy_norm += y[i]*X[i];
K -= FFABS(y[i]);
}
while (K) {
int max_idx = 0, phase = FFSIGN(K);
float max_num = 0.0f;
float max_den = 1.0f;
y_norm += 1.0f;
for (i = 0; i < N; i++) {
/* If the sum has been overshot and the best place has 0 pulses allocated
* to it, attempting to decrease it further will actually increase the
* sum. Prevent this by disregarding any 0 positions when decrementing. */
const int ca = 1 ^ ((y[i] == 0) & (phase < 0));
const int y_new = y_norm + 2*phase*FFABS(y[i]);
float xy_new = xy_norm + 1*phase*FFABS(X[i]);
xy_new = xy_new * xy_new;
if (ca && (max_den*xy_new) > (y_new*max_num)) {
max_den = y_new;
max_num = xy_new;
max_idx = i;
}
}
K -= phase;
phase *= FFSIGN(X[max_idx]);
xy_norm += 1*phase*X[max_idx];
y_norm += 2*phase*y[max_idx];
y[max_idx] += phase;
}
return (float)y_norm;
}
#endif
static uint32_t celt_alg_quant(OpusRangeCoder *rc, float *X, uint32_t N, uint32_t K,
enum CeltSpread spread, uint32_t blocks, float gain,
CeltPVQ *pvq)
{
int *y = pvq->qcoeff;
celt_exp_rotation(X, N, blocks, K, spread, 1);
gain /= sqrtf(pvq->pvq_search(X, y, K, N));
celt_encode_pulses(rc, y, N, K);
celt_normalize_residual(y, X, N, gain);
celt_exp_rotation(X, N, blocks, K, spread, 0);
return celt_extract_collapse_mask(y, N, blocks);
}
/** Decode pulse vector and combine the result with the pitch vector to produce
the final normalised signal in the current band. */
static uint32_t celt_alg_unquant(OpusRangeCoder *rc, float *X, uint32_t N, uint32_t K,
enum CeltSpread spread, uint32_t blocks, float gain,
CeltPVQ *pvq)
{
int *y = pvq->qcoeff;
gain /= sqrtf(celt_decode_pulses(rc, y, N, K));
celt_normalize_residual(y, X, N, gain);
celt_exp_rotation(X, N, blocks, K, spread, 0);
return celt_extract_collapse_mask(y, N, blocks);
}
static int celt_calc_theta(const float *X, const float *Y, int coupling, int N)
{
int i;
float e[2] = { 0.0f, 0.0f };
if (coupling) { /* Coupling case */
for (i = 0; i < N; i++) {
e[0] += (X[i] + Y[i])*(X[i] + Y[i]);
e[1] += (X[i] - Y[i])*(X[i] - Y[i]);
}
} else {
for (i = 0; i < N; i++) {
e[0] += X[i]*X[i];
e[1] += Y[i]*Y[i];
}
}
return lrintf(32768.0f*atan2f(sqrtf(e[1]), sqrtf(e[0]))/M_PI);
}
static void celt_stereo_is_decouple(float *X, float *Y, float e_l, float e_r, int N)
{
int i;
const float energy_n = 1.0f/(sqrtf(e_l*e_l + e_r*e_r) + FLT_EPSILON);
e_l *= energy_n;
e_r *= energy_n;
for (i = 0; i < N; i++)
X[i] = e_l*X[i] + e_r*Y[i];
}
static void celt_stereo_ms_decouple(float *X, float *Y, int N)
{
int i;
for (i = 0; i < N; i++) {
const float Xret = X[i];
X[i] = (X[i] + Y[i])*M_SQRT1_2;
Y[i] = (Y[i] - Xret)*M_SQRT1_2;
}
}
static av_always_inline uint32_t quant_band_template(CeltPVQ *pvq, CeltFrame *f,
OpusRangeCoder *rc,
const int band, float *X,
float *Y, int N, int b,
uint32_t blocks, float *lowband,
int duration, float *lowband_out,
int level, float gain,
float *lowband_scratch,
int fill, int quant)
{
int i;
const uint8_t *cache;
int stereo = !!Y, split = stereo;
int imid = 0, iside = 0;
uint32_t N0 = N;
int N_B = N / blocks;
int N_B0 = N_B;
int B0 = blocks;
int time_divide = 0;
int recombine = 0;
int inv = 0;
float mid = 0, side = 0;
int longblocks = (B0 == 1);
uint32_t cm = 0;
if (N == 1) {
float *x = X;
for (i = 0; i <= stereo; i++) {
int sign = 0;
if (f->remaining2 >= 1 << 3) {
if (quant) {
sign = x[0] < 0;
ff_opus_rc_put_raw(rc, sign, 1);
} else {
sign = ff_opus_rc_get_raw(rc, 1);
}
f->remaining2 -= 1 << 3;
}
x[0] = 1.0f - 2.0f*sign;
x = Y;
}
if (lowband_out)
lowband_out[0] = X[0];
return 1;
}
if (!stereo && level == 0) {
int tf_change = f->tf_change[band];
int k;
if (tf_change > 0)
recombine = tf_change;
/* Band recombining to increase frequency resolution */
if (lowband &&
(recombine || ((N_B & 1) == 0 && tf_change < 0) || B0 > 1)) {
for (i = 0; i < N; i++)
lowband_scratch[i] = lowband[i];
lowband = lowband_scratch;
}
for (k = 0; k < recombine; k++) {
if (quant || lowband)
celt_haar1(quant ? X : lowband, N >> k, 1 << k);
fill = ff_celt_bit_interleave[fill & 0xF] | ff_celt_bit_interleave[fill >> 4] << 2;
}
blocks >>= recombine;
N_B <<= recombine;
/* Increasing the time resolution */
while ((N_B & 1) == 0 && tf_change < 0) {
if (quant || lowband)
celt_haar1(quant ? X : lowband, N_B, blocks);
fill |= fill << blocks;
blocks <<= 1;
N_B >>= 1;
time_divide++;
tf_change++;
}
B0 = blocks;
N_B0 = N_B;
/* Reorganize the samples in time order instead of frequency order */
if (B0 > 1 && (quant || lowband))
celt_deinterleave_hadamard(pvq->hadamard_tmp, quant ? X : lowband,
N_B >> recombine, B0 << recombine,
longblocks);
}
/* If we need 1.5 more bit than we can produce, split the band in two. */
cache = ff_celt_cache_bits +
ff_celt_cache_index[(duration + 1) * CELT_MAX_BANDS + band];
if (!stereo && duration >= 0 && b > cache[cache[0]] + 12 && N > 2) {
N >>= 1;
Y = X + N;
split = 1;
duration -= 1;
if (blocks == 1)
fill = (fill & 1) | (fill << 1);
blocks = (blocks + 1) >> 1;
}
if (split) {
int qn;
int itheta = quant ? celt_calc_theta(X, Y, stereo, N) : 0;
int mbits, sbits, delta;
int qalloc;
int pulse_cap;
int offset;
int orig_fill;
int tell;
/* Decide on the resolution to give to the split parameter theta */
pulse_cap = ff_celt_log_freq_range[band] + duration * 8;
offset = (pulse_cap >> 1) - (stereo && N == 2 ? CELT_QTHETA_OFFSET_TWOPHASE :
CELT_QTHETA_OFFSET);
qn = (stereo && band >= f->intensity_stereo) ? 1 :
celt_compute_qn(N, b, offset, pulse_cap, stereo);
tell = opus_rc_tell_frac(rc);
if (qn != 1) {
if (quant)
itheta = (itheta*qn + 8192) >> 14;
/* Entropy coding of the angle. We use a uniform pdf for the
* time split, a step for stereo, and a triangular one for the rest. */
if (quant) {
if (stereo && N > 2)
ff_opus_rc_enc_uint_step(rc, itheta, qn / 2);
else if (stereo || B0 > 1)
ff_opus_rc_enc_uint(rc, itheta, qn + 1);
else
ff_opus_rc_enc_uint_tri(rc, itheta, qn);
itheta = itheta * 16384 / qn;
if (stereo) {
if (itheta == 0)
celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band],
f->block[1].lin_energy[band], N);
else
celt_stereo_ms_decouple(X, Y, N);
}
} else {
if (stereo && N > 2)
itheta = ff_opus_rc_dec_uint_step(rc, qn / 2);
else if (stereo || B0 > 1)
itheta = ff_opus_rc_dec_uint(rc, qn+1);
else
itheta = ff_opus_rc_dec_uint_tri(rc, qn);
itheta = itheta * 16384 / qn;
}
} else if (stereo) {
if (quant) {
inv = f->apply_phase_inv ? itheta > 8192 : 0;
if (inv) {
for (i = 0; i < N; i++)
Y[i] *= -1;
}
celt_stereo_is_decouple(X, Y, f->block[0].lin_energy[band],
f->block[1].lin_energy[band], N);
if (b > 2 << 3 && f->remaining2 > 2 << 3) {
ff_opus_rc_enc_log(rc, inv, 2);
} else {
inv = 0;
}
} else {
inv = (b > 2 << 3 && f->remaining2 > 2 << 3) ? ff_opus_rc_dec_log(rc, 2) : 0;
inv = f->apply_phase_inv ? inv : 0;
}
itheta = 0;
}
qalloc = opus_rc_tell_frac(rc) - tell;
b -= qalloc;
orig_fill = fill;
if (itheta == 0) {
imid = 32767;
iside = 0;
fill = av_zero_extend(fill, blocks);
delta = -16384;
} else if (itheta == 16384) {
imid = 0;
iside = 32767;
fill &= ((1 << blocks) - 1) << blocks;
delta = 16384;
} else {
imid = celt_cos(itheta);
iside = celt_cos(16384-itheta);
/* This is the mid vs side allocation that minimizes squared error
in that band. */
delta = ROUND_MUL16((N - 1) << 7, celt_log2tan(iside, imid));
}
mid = imid / 32768.0f;
side = iside / 32768.0f;
/* This is a special case for N=2 that only works for stereo and takes
advantage of the fact that mid and side are orthogonal to encode
the side with just one bit. */
if (N == 2 && stereo) {
int c;
int sign = 0;
float tmp;
float *x2, *y2;
mbits = b;
/* Only need one bit for the side */
sbits = (itheta != 0 && itheta != 16384) ? 1 << 3 : 0;
mbits -= sbits;
c = (itheta > 8192);
f->remaining2 -= qalloc+sbits;
x2 = c ? Y : X;
y2 = c ? X : Y;
if (sbits) {
if (quant) {
sign = x2[0]*y2[1] - x2[1]*y2[0] < 0;
ff_opus_rc_put_raw(rc, sign, 1);
} else {
sign = ff_opus_rc_get_raw(rc, 1);
}
}
sign = 1 - 2 * sign;
/* We use orig_fill here because we want to fold the side, but if
itheta==16384, we'll have cleared the low bits of fill. */
cm = pvq->quant_band(pvq, f, rc, band, x2, NULL, N, mbits, blocks, lowband, duration,
lowband_out, level, gain, lowband_scratch, orig_fill);
/* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
and there's no need to worry about mixing with the other channel. */
y2[0] = -sign * x2[1];
y2[1] = sign * x2[0];
X[0] *= mid;
X[1] *= mid;
Y[0] *= side;
Y[1] *= side;
tmp = X[0];
X[0] = tmp - Y[0];
Y[0] = tmp + Y[0];
tmp = X[1];
X[1] = tmp - Y[1];
Y[1] = tmp + Y[1];
} else {
/* "Normal" split code */
float *next_lowband2 = NULL;
float *next_lowband_out1 = NULL;
int next_level = 0;
int rebalance;
uint32_t cmt;
/* Give more bits to low-energy MDCTs than they would
* otherwise deserve */
if (B0 > 1 && !stereo && (itheta & 0x3fff)) {
if (itheta > 8192)
/* Rough approximation for pre-echo masking */
delta -= delta >> (4 - duration);
else
/* Corresponds to a forward-masking slope of
* 1.5 dB per 10 ms */
delta = FFMIN(0, delta + (N << 3 >> (5 - duration)));
}
mbits = av_clip((b - delta) / 2, 0, b);
sbits = b - mbits;
f->remaining2 -= qalloc;
if (lowband && !stereo)
next_lowband2 = lowband + N; /* >32-bit split case */
/* Only stereo needs to pass on lowband_out.
* Otherwise, it's handled at the end */
if (stereo)
next_lowband_out1 = lowband_out;
else
next_level = level + 1;
rebalance = f->remaining2;
if (mbits >= sbits) {
/* In stereo mode, we do not apply a scaling to the mid
* because we need the normalized mid for folding later */
cm = pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks,
lowband, duration, next_lowband_out1, next_level,
stereo ? 1.0f : (gain * mid), lowband_scratch, fill);
rebalance = mbits - (rebalance - f->remaining2);
if (rebalance > 3 << 3 && itheta != 0)
sbits += rebalance - (3 << 3);
/* For a stereo split, the high bits of fill are always zero,
* so no folding will be done to the side. */
cmt = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks,
next_lowband2, duration, NULL, next_level,
gain * side, NULL, fill >> blocks);
cm |= cmt << ((B0 >> 1) & (stereo - 1));
} else {
/* For a stereo split, the high bits of fill are always zero,
* so no folding will be done to the side. */
cm = pvq->quant_band(pvq, f, rc, band, Y, NULL, N, sbits, blocks,
next_lowband2, duration, NULL, next_level,
gain * side, NULL, fill >> blocks);
cm <<= ((B0 >> 1) & (stereo - 1));
rebalance = sbits - (rebalance - f->remaining2);
if (rebalance > 3 << 3 && itheta != 16384)
mbits += rebalance - (3 << 3);
/* In stereo mode, we do not apply a scaling to the mid because
* we need the normalized mid for folding later */
cm |= pvq->quant_band(pvq, f, rc, band, X, NULL, N, mbits, blocks,
lowband, duration, next_lowband_out1, next_level,
stereo ? 1.0f : (gain * mid), lowband_scratch, fill);
}
}
} else {
/* This is the basic no-split case */
uint32_t q = celt_bits2pulses(cache, b);
uint32_t curr_bits = celt_pulses2bits(cache, q);
f->remaining2 -= curr_bits;
/* Ensures we can never bust the budget */
while (f->remaining2 < 0 && q > 0) {
f->remaining2 += curr_bits;
curr_bits = celt_pulses2bits(cache, --q);
f->remaining2 -= curr_bits;
}
if (q != 0) {
/* Finally do the actual (de)quantization */
if (quant) {
cm = celt_alg_quant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1),
f->spread, blocks, gain, pvq);
} else {
cm = celt_alg_unquant(rc, X, N, (q < 8) ? q : (8 + (q & 7)) << ((q >> 3) - 1),
f->spread, blocks, gain, pvq);
}
} else {
/* If there's no pulse, fill the band anyway */
uint32_t cm_mask = (1 << blocks) - 1;
fill &= cm_mask;
if (fill) {
if (!lowband) {
/* Noise */
for (i = 0; i < N; i++)
X[i] = (((int32_t)celt_rng(f)) >> 20);
cm = cm_mask;
} else {
/* Folded spectrum */
for (i = 0; i < N; i++) {
/* About 48 dB below the "normal" folding level */
X[i] = lowband[i] + (((celt_rng(f)) & 0x8000) ? 1.0f / 256 : -1.0f / 256);
}
cm = fill;
}
celt_renormalize_vector(X, N, gain);
} else {
memset(X, 0, N*sizeof(float));
}
}
}
/* This code is used by the decoder and by the resynthesis-enabled encoder */
if (stereo) {
if (N > 2)
celt_stereo_merge(X, Y, mid, N);
if (inv) {
for (i = 0; i < N; i++)
Y[i] *= -1;
}
} else if (level == 0) {
int k;
/* Undo the sample reorganization going from time order to frequency order */
if (B0 > 1)
celt_interleave_hadamard(pvq->hadamard_tmp, X, N_B >> recombine,
B0 << recombine, longblocks);
/* Undo time-freq changes that we did earlier */
N_B = N_B0;
blocks = B0;
for (k = 0; k < time_divide; k++) {
blocks >>= 1;
N_B <<= 1;
cm |= cm >> blocks;
celt_haar1(X, N_B, blocks);
}
for (k = 0; k < recombine; k++) {
cm = ff_celt_bit_deinterleave[cm];
celt_haar1(X, N0>>k, 1<<k);
}
blocks <<= recombine;
/* Scale output for later folding */
if (lowband_out) {
float n = sqrtf(N0);
for (i = 0; i < N0; i++)
lowband_out[i] = n * X[i];
}
cm = av_zero_extend(cm, blocks);
}
return cm;
}
static QUANT_FN(pvq_decode_band)
{
#if CONFIG_OPUS_DECODER
return quant_band_template(pvq, f, rc, band, X, Y, N, b, blocks, lowband, duration,
lowband_out, level, gain, lowband_scratch, fill, 0);
#else
return 0;
#endif
}
static QUANT_FN(pvq_encode_band)
{
#if CONFIG_OPUS_ENCODER
return quant_band_template(pvq, f, rc, band, X, Y, N, b, blocks, lowband, duration,
lowband_out, level, gain, lowband_scratch, fill, 1);
#else
return 0;
#endif
}
int av_cold ff_celt_pvq_init(CeltPVQ **pvq, int encode)
{
CeltPVQ *s = av_malloc(sizeof(CeltPVQ));
if (!s)
return AVERROR(ENOMEM);
s->quant_band = encode ? pvq_encode_band : pvq_decode_band;
#if CONFIG_OPUS_ENCODER
s->pvq_search = ppp_pvq_search_c;
#if ARCH_X86
ff_celt_pvq_init_x86(s);
#endif
#endif
*pvq = s;
return 0;
}
void av_cold ff_celt_pvq_uninit(CeltPVQ **pvq)
{
av_freep(pvq);
}
+50
View File
@@ -0,0 +1,50 @@
/*
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
* Copyright (c) 2016 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_OPUS_PVQ_H
#define AVCODEC_OPUS_PVQ_H
#include "libavutil/mem_internal.h"
#include "celt.h"
#define QUANT_FN(name) uint32_t (name)(struct CeltPVQ *pvq, CeltFrame *f, \
OpusRangeCoder *rc, const int band, float *X, \
float *Y, int N, int b, uint32_t blocks, \
float *lowband, int duration, \
float *lowband_out, int level, float gain, \
float *lowband_scratch, int fill)
typedef struct CeltPVQ {
DECLARE_ALIGNED(32, int, qcoeff )[256];
DECLARE_ALIGNED(32, float, hadamard_tmp)[256];
float (*pvq_search)(float *X, int *y, int K, int N);
QUANT_FN(*quant_band);
} CeltPVQ;
void ff_celt_pvq_init_x86(struct CeltPVQ *s);
int ff_celt_pvq_init(struct CeltPVQ **pvq, int encode);
void ff_celt_pvq_uninit(struct CeltPVQ **pvq);
#endif /* AVCODEC_OPUS_PVQ_H */
+411
View File
@@ -0,0 +1,411 @@
/*
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
* Copyright (c) 2017 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "rc.h"
#define OPUS_RC_BITS 32
#define OPUS_RC_SYM 8
#define OPUS_RC_CEIL ((1 << OPUS_RC_SYM) - 1)
#define OPUS_RC_TOP (1u << 31)
#define OPUS_RC_BOT (OPUS_RC_TOP >> OPUS_RC_SYM)
#define OPUS_RC_SHIFT (OPUS_RC_BITS - OPUS_RC_SYM - 1)
static av_always_inline void opus_rc_enc_carryout(OpusRangeCoder *rc, int cbuf)
{
const int cb = cbuf >> OPUS_RC_SYM, mb = (OPUS_RC_CEIL + cb) & OPUS_RC_CEIL;
if (cbuf == OPUS_RC_CEIL) {
rc->ext++;
return;
}
rc->rng_cur[0] = rc->rem + cb;
rc->rng_cur += (rc->rem >= 0);
for (; rc->ext > 0; rc->ext--)
*rc->rng_cur++ = mb;
av_assert0(rc->rng_cur < rc->rb.position);
rc->rem = cbuf & OPUS_RC_CEIL; /* Propagate */
}
static av_always_inline void opus_rc_dec_normalize(OpusRangeCoder *rc)
{
while (rc->range <= OPUS_RC_BOT) {
rc->value = ((rc->value << OPUS_RC_SYM) | (get_bits(&rc->gb, OPUS_RC_SYM) ^ OPUS_RC_CEIL)) & (OPUS_RC_TOP - 1);
rc->range <<= OPUS_RC_SYM;
rc->total_bits += OPUS_RC_SYM;
}
}
static av_always_inline void opus_rc_enc_normalize(OpusRangeCoder *rc)
{
while (rc->range <= OPUS_RC_BOT) {
opus_rc_enc_carryout(rc, rc->value >> OPUS_RC_SHIFT);
rc->value = (rc->value << OPUS_RC_SYM) & (OPUS_RC_TOP - 1);
rc->range <<= OPUS_RC_SYM;
rc->total_bits += OPUS_RC_SYM;
}
}
static av_always_inline void opus_rc_dec_update(OpusRangeCoder *rc, uint32_t scale,
uint32_t low, uint32_t high,
uint32_t total)
{
rc->value -= scale * (total - high);
rc->range = low ? scale * (high - low)
: rc->range - scale * (total - high);
opus_rc_dec_normalize(rc);
}
/* Main encoding function, this needs to go fast */
static av_always_inline void opus_rc_enc_update(OpusRangeCoder *rc, uint32_t b, uint32_t p,
uint32_t p_tot, const int ptwo)
{
uint32_t rscaled, cnd = !!b;
if (ptwo) /* Whole function is inlined so hopefully branch is optimized out */
rscaled = rc->range >> ff_log2(p_tot);
else
rscaled = rc->range/p_tot;
rc->value += cnd*(rc->range - rscaled*(p_tot - b));
rc->range = (!cnd)*(rc->range - rscaled*(p_tot - p)) + cnd*rscaled*(p - b);
opus_rc_enc_normalize(rc);
}
uint32_t ff_opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf)
{
unsigned int k, scale, total, symbol, low, high;
total = *cdf++;
scale = rc->range / total;
symbol = rc->value / scale + 1;
symbol = total - FFMIN(symbol, total);
for (k = 0; cdf[k] <= symbol; k++);
high = cdf[k];
low = k ? cdf[k-1] : 0;
opus_rc_dec_update(rc, scale, low, high, total);
return k;
}
void ff_opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf)
{
opus_rc_enc_update(rc, (!!val)*cdf[val], cdf[val + 1], cdf[0], 1);
}
uint32_t ff_opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits)
{
uint32_t k, scale;
scale = rc->range >> bits; // in this case, scale = symbol
if (rc->value >= scale) {
rc->value -= scale;
rc->range -= scale;
k = 0;
} else {
rc->range = scale;
k = 1;
}
opus_rc_dec_normalize(rc);
return k;
}
void ff_opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits)
{
bits = (1 << bits) - 1;
opus_rc_enc_update(rc, (!!val)*bits, bits + !!val, bits + 1, 1);
}
/**
* CELT: read 1-25 raw bits at the end of the frame, backwards byte-wise
*/
uint32_t ff_opus_rc_get_raw(OpusRangeCoder *rc, uint32_t count)
{
uint32_t value = 0;
while (rc->rb.bytes && rc->rb.cachelen < count) {
rc->rb.cacheval |= *--rc->rb.position << rc->rb.cachelen;
rc->rb.cachelen += 8;
rc->rb.bytes--;
}
value = av_zero_extend(rc->rb.cacheval, count);
rc->rb.cacheval >>= count;
rc->rb.cachelen -= count;
rc->total_bits += count;
return value;
}
/**
* CELT: write 0 - 31 bits to the rawbits buffer
*/
void ff_opus_rc_put_raw(OpusRangeCoder *rc, uint32_t val, uint32_t count)
{
const int to_write = FFMIN(32 - rc->rb.cachelen, count);
rc->total_bits += count;
rc->rb.cacheval |= av_zero_extend(val, to_write) << rc->rb.cachelen;
rc->rb.cachelen = (rc->rb.cachelen + to_write) % 32;
if (!rc->rb.cachelen && count) {
AV_WB32((uint8_t *)rc->rb.position, rc->rb.cacheval);
rc->rb.bytes += 4;
rc->rb.position -= 4;
rc->rb.cachelen = count - to_write;
rc->rb.cacheval = av_zero_extend(val >> to_write, rc->rb.cachelen);
av_assert0(rc->rng_cur < rc->rb.position);
}
}
/**
* CELT: read a uniform distribution
*/
uint32_t ff_opus_rc_dec_uint(OpusRangeCoder *rc, uint32_t size)
{
uint32_t bits, k, scale, total;
bits = opus_ilog(size - 1);
total = (bits > 8) ? ((size - 1) >> (bits - 8)) + 1 : size;
scale = rc->range / total;
k = rc->value / scale + 1;
k = total - FFMIN(k, total);
opus_rc_dec_update(rc, scale, k, k + 1, total);
if (bits > 8) {
k = k << (bits - 8) | ff_opus_rc_get_raw(rc, bits - 8);
return FFMIN(k, size - 1);
} else
return k;
}
/**
* CELT: write a uniformly distributed integer
*/
void ff_opus_rc_enc_uint(OpusRangeCoder *rc, uint32_t val, uint32_t size)
{
const int ps = FFMAX(opus_ilog(size - 1) - 8, 0);
opus_rc_enc_update(rc, val >> ps, (val >> ps) + 1, ((size - 1) >> ps) + 1, 0);
ff_opus_rc_put_raw(rc, val, ps);
}
uint32_t ff_opus_rc_dec_uint_step(OpusRangeCoder *rc, int k0)
{
/* Use a probability of 3 up to itheta=8192 and then use 1 after */
uint32_t k, scale, symbol, total = (k0+1)*3 + k0;
scale = rc->range / total;
symbol = rc->value / scale + 1;
symbol = total - FFMIN(symbol, total);
k = (symbol < (k0+1)*3) ? symbol/3 : symbol - (k0+1)*2;
opus_rc_dec_update(rc, scale, (k <= k0) ? 3*(k+0) : (k-1-k0) + 3*(k0+1),
(k <= k0) ? 3*(k+1) : (k-0-k0) + 3*(k0+1), total);
return k;
}
void ff_opus_rc_enc_uint_step(OpusRangeCoder *rc, uint32_t val, int k0)
{
const uint32_t a = val <= k0, b = 2*a + 1;
k0 = (k0 + 1) << 1;
val = b*(val + k0) - 3*a*k0;
opus_rc_enc_update(rc, val, val + b, (k0 << 1) - 1, 0);
}
uint32_t ff_opus_rc_dec_uint_tri(OpusRangeCoder *rc, int qn)
{
uint32_t k, scale, symbol, total, low, center;
total = ((qn>>1) + 1) * ((qn>>1) + 1);
scale = rc->range / total;
center = rc->value / scale + 1;
center = total - FFMIN(center, total);
if (center < total >> 1) {
k = (ff_sqrt(8 * center + 1) - 1) >> 1;
low = k * (k + 1) >> 1;
symbol = k + 1;
} else {
k = (2*(qn + 1) - ff_sqrt(8*(total - center - 1) + 1)) >> 1;
low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1);
symbol = qn + 1 - k;
}
opus_rc_dec_update(rc, scale, low, low + symbol, total);
return k;
}
void ff_opus_rc_enc_uint_tri(OpusRangeCoder *rc, uint32_t k, int qn)
{
uint32_t symbol, low, total;
total = ((qn>>1) + 1) * ((qn>>1) + 1);
if (k <= qn >> 1) {
low = k * (k + 1) >> 1;
symbol = k + 1;
} else {
low = total - ((qn + 1 - k) * (qn + 2 - k) >> 1);
symbol = qn + 1 - k;
}
opus_rc_enc_update(rc, low, low + symbol, total, 0);
}
int ff_opus_rc_dec_laplace(OpusRangeCoder *rc, uint32_t symbol, int decay)
{
/* extends the range coder to model a Laplace distribution */
int value = 0;
uint32_t scale, low = 0, center;
scale = rc->range >> 15;
center = rc->value / scale + 1;
center = (1 << 15) - FFMIN(center, 1 << 15);
if (center >= symbol) {
value++;
low = symbol;
symbol = 1 + ((32768 - 32 - symbol) * (16384-decay) >> 15);
while (symbol > 1 && center >= low + 2 * symbol) {
value++;
symbol *= 2;
low += symbol;
symbol = (((symbol - 2) * decay) >> 15) + 1;
}
if (symbol <= 1) {
int distance = (center - low) >> 1;
value += distance;
low += 2 * distance;
}
if (center < low + symbol)
value *= -1;
else
low += symbol;
}
opus_rc_dec_update(rc, scale, low, FFMIN(low + symbol, 32768), 32768);
return value;
}
void ff_opus_rc_enc_laplace(OpusRangeCoder *rc, int *value, uint32_t symbol, int decay)
{
uint32_t low = symbol;
int i = 1, val = FFABS(*value), pos = *value > 0;
if (!val) {
opus_rc_enc_update(rc, 0, symbol, 1 << 15, 1);
return;
}
symbol = ((32768 - 32 - symbol)*(16384 - decay)) >> 15;
for (; i < val && symbol; i++) {
low += (symbol << 1) + 2;
symbol = (symbol*decay) >> 14;
}
if (symbol) {
low += (++symbol)*pos;
} else {
const int distance = FFMIN(val - i, (((32768 - low) - !pos) >> 1) - 1);
low += pos + (distance << 1);
symbol = FFMIN(1, 32768 - low);
*value = FFSIGN(*value)*(distance + i);
}
opus_rc_enc_update(rc, low, low + symbol, 1 << 15, 1);
}
int ff_opus_rc_dec_init(OpusRangeCoder *rc, const uint8_t *data, int size)
{
int ret = init_get_bits8(&rc->gb, data, size);
if (ret < 0)
return ret;
rc->range = 128;
rc->value = 127 - get_bits(&rc->gb, 7);
rc->total_bits = 9;
opus_rc_dec_normalize(rc);
return 0;
}
void ff_opus_rc_dec_raw_init(OpusRangeCoder *rc, const uint8_t *rightend, uint32_t bytes)
{
rc->rb.position = rightend;
rc->rb.bytes = bytes;
rc->rb.cachelen = 0;
rc->rb.cacheval = 0;
}
void ff_opus_rc_enc_end(OpusRangeCoder *rc, uint8_t *dst, int size)
{
int rng_bytes, bits = OPUS_RC_BITS - opus_ilog(rc->range);
uint32_t mask = (OPUS_RC_TOP - 1) >> bits;
uint32_t end = (rc->value + mask) & ~mask;
if ((end | mask) >= rc->value + rc->range) {
bits++;
mask >>= 1;
end = (rc->value + mask) & ~mask;
}
/* Finish what's left */
while (bits > 0) {
opus_rc_enc_carryout(rc, end >> OPUS_RC_SHIFT);
end = (end << OPUS_RC_SYM) & (OPUS_RC_TOP - 1);
bits -= OPUS_RC_SYM;
}
/* Flush out anything left or marked */
if (rc->rem >= 0 || rc->ext > 0)
opus_rc_enc_carryout(rc, 0);
rng_bytes = rc->rng_cur - rc->buf;
memcpy(dst, rc->buf, rng_bytes);
rc->waste = size*8 - (rc->rb.bytes*8 + rc->rb.cachelen) - rng_bytes*8;
/* Put the rawbits part, if any */
if (rc->rb.bytes || rc->rb.cachelen) {
int i, lap;
uint8_t *rb_src, *rb_dst;
ff_opus_rc_put_raw(rc, 0, 32 - rc->rb.cachelen);
rb_src = rc->buf + OPUS_MAX_FRAME_SIZE + 12 - rc->rb.bytes;
rb_dst = dst + FFMAX(size - rc->rb.bytes, 0);
lap = &dst[rng_bytes] - rb_dst;
for (i = 0; i < lap; i++)
rb_dst[i] |= rb_src[i];
memcpy(&rb_dst[lap], &rb_src[lap], FFMAX(rc->rb.bytes - lap, 0));
}
}
void ff_opus_rc_enc_init(OpusRangeCoder *rc)
{
rc->value = 0;
rc->range = OPUS_RC_TOP;
rc->total_bits = OPUS_RC_BITS + 1;
rc->rem = -1;
rc->ext = 0;
rc->rng_cur = rc->buf;
ff_opus_rc_dec_raw_init(rc, rc->buf + OPUS_MAX_FRAME_SIZE + 8, 0);
}
+127
View File
@@ -0,0 +1,127 @@
/*
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
* Copyright (c) 2017 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_OPUS_RC_H
#define AVCODEC_OPUS_RC_H
#include <stdint.h>
#include "libavcodec/get_bits.h"
#include "opus.h"
#define opus_ilog(i) (av_log2(i) + !!(i))
typedef struct RawBitsContext {
const uint8_t *position;
uint32_t bytes;
uint32_t cachelen;
uint32_t cacheval;
} RawBitsContext;
typedef struct OpusRangeCoder {
GetBitContext gb;
RawBitsContext rb;
uint32_t range;
uint32_t value;
uint32_t total_bits;
/* Encoder */
uint8_t buf[OPUS_MAX_FRAME_SIZE + 12]; /* memcpy vs (memmove + overreading) */
uint8_t *rng_cur; /* Current range coded byte */
int ext; /* Awaiting propagation */
int rem; /* Carryout flag */
/* Encoding stats */
int waste;
} OpusRangeCoder;
/**
* CELT: estimate bits of entropy that have thus far been consumed for the
* current CELT frame, to integer and fractional (1/8th bit) precision
*/
static av_always_inline uint32_t opus_rc_tell(const OpusRangeCoder *rc)
{
return rc->total_bits - av_log2(rc->range) - 1;
}
static av_always_inline uint32_t opus_rc_tell_frac(const OpusRangeCoder *rc)
{
uint32_t i, total_bits, rcbuffer, range;
total_bits = rc->total_bits << 3;
rcbuffer = av_log2(rc->range) + 1;
range = rc->range >> (rcbuffer-16);
for (i = 0; i < 3; i++) {
int bit;
range = range * range >> 15;
bit = range >> 16;
rcbuffer = rcbuffer << 1 | bit;
range >>= bit;
}
return total_bits - rcbuffer;
}
uint32_t ff_opus_rc_dec_cdf(OpusRangeCoder *rc, const uint16_t *cdf);
void ff_opus_rc_enc_cdf(OpusRangeCoder *rc, int val, const uint16_t *cdf);
uint32_t ff_opus_rc_dec_log(OpusRangeCoder *rc, uint32_t bits);
void ff_opus_rc_enc_log(OpusRangeCoder *rc, int val, uint32_t bits);
uint32_t ff_opus_rc_dec_uint_step(OpusRangeCoder *rc, int k0);
void ff_opus_rc_enc_uint_step(OpusRangeCoder *rc, uint32_t val, int k0);
uint32_t ff_opus_rc_dec_uint_tri(OpusRangeCoder *rc, int qn);
void ff_opus_rc_enc_uint_tri(OpusRangeCoder *rc, uint32_t k, int qn);
uint32_t ff_opus_rc_dec_uint(OpusRangeCoder *rc, uint32_t size);
void ff_opus_rc_enc_uint(OpusRangeCoder *rc, uint32_t val, uint32_t size);
uint32_t ff_opus_rc_get_raw(OpusRangeCoder *rc, uint32_t count);
void ff_opus_rc_put_raw(OpusRangeCoder *rc, uint32_t val, uint32_t count);
int ff_opus_rc_dec_laplace(OpusRangeCoder *rc, uint32_t symbol, int decay);
void ff_opus_rc_enc_laplace(OpusRangeCoder *rc, int *value, uint32_t symbol, int decay);
int ff_opus_rc_dec_init(OpusRangeCoder *rc, const uint8_t *data, int size);
void ff_opus_rc_dec_raw_init(OpusRangeCoder *rc, const uint8_t *rightend, uint32_t bytes);
void ff_opus_rc_enc_end(OpusRangeCoder *rc, uint8_t *dst, int size);
void ff_opus_rc_enc_init(OpusRangeCoder *rc);
#define OPUS_RC_CHECKPOINT_UPDATE(rc) \
rc_rollback_bits = opus_rc_tell_frac(rc); \
rc_rollback_ctx = *rc
#define OPUS_RC_CHECKPOINT_SPAWN(rc) \
uint32_t rc_rollback_bits = opus_rc_tell_frac(rc); \
OpusRangeCoder rc_rollback_ctx = *rc \
#define OPUS_RC_CHECKPOINT_BITS(rc) \
(opus_rc_tell_frac(rc) - rc_rollback_bits)
#define OPUS_RC_CHECKPOINT_ROLLBACK(rc) \
memcpy(rc, &rc_rollback_ctx, sizeof(OpusRangeCoder)); \
#endif /* AVCODEC_OPUS_RC_H */
+907
View File
@@ -0,0 +1,907 @@
/*
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Opus SILK decoder
*/
#include <stdint.h>
#include "libavutil/mem.h"
#include "mathops.h"
#include "opus.h"
#include "rc.h"
#include "silk.h"
#include "tab.h"
#define ROUND_MULL(a,b,s) (((MUL64(a, b) >> ((s) - 1)) + 1) >> 1)
typedef struct SilkFrame {
int coded;
int log_gain;
int16_t nlsf[16];
float lpc[16];
float output [2 * SILK_HISTORY];
float lpc_history[2 * SILK_HISTORY];
int primarylag;
int prev_voiced;
} SilkFrame;
struct SilkContext {
void *logctx;
int output_channels;
int midonly;
int subframes;
int sflength;
int flength;
int nlsf_interp_factor;
enum OpusBandwidth bandwidth;
int wb;
SilkFrame frame[2];
float prev_stereo_weights[2];
float stereo_weights[2];
int prev_coded_channels;
};
static inline void silk_stabilize_lsf(int16_t nlsf[16], int order, const uint16_t min_delta[17])
{
int pass, i;
for (pass = 0; pass < 20; pass++) {
int k, min_diff = 0;
for (i = 0; i < order+1; i++) {
int low = i != 0 ? nlsf[i-1] : 0;
int high = i != order ? nlsf[i] : 32768;
int diff = (high - low) - (min_delta[i]);
if (diff < min_diff) {
min_diff = diff;
k = i;
if (pass == 20)
break;
}
}
if (min_diff == 0) /* no issues; stabilized */
return;
/* wiggle one or two LSFs */
if (k == 0) {
/* repel away from lower bound */
nlsf[0] = min_delta[0];
} else if (k == order) {
/* repel away from higher bound */
nlsf[order-1] = 32768 - min_delta[order];
} else {
/* repel away from current position */
int min_center = 0, max_center = 32768, center_val;
/* lower extent */
for (i = 0; i < k; i++)
min_center += min_delta[i];
min_center += min_delta[k] >> 1;
/* upper extent */
for (i = order; i > k; i--)
max_center -= min_delta[i];
max_center -= min_delta[k] >> 1;
/* move apart */
center_val = nlsf[k - 1] + nlsf[k];
center_val = (center_val >> 1) + (center_val & 1); // rounded divide by 2
center_val = FFMIN(max_center, FFMAX(min_center, center_val));
nlsf[k - 1] = center_val - (min_delta[k] >> 1);
nlsf[k] = nlsf[k - 1] + min_delta[k];
}
}
/* resort to the fall-back method, the standard method for LSF stabilization */
/* sort; as the LSFs should be nearly sorted, use insertion sort */
for (i = 1; i < order; i++) {
int j, value = nlsf[i];
for (j = i - 1; j >= 0 && nlsf[j] > value; j--)
nlsf[j + 1] = nlsf[j];
nlsf[j + 1] = value;
}
/* push forwards to increase distance */
if (nlsf[0] < min_delta[0])
nlsf[0] = min_delta[0];
for (i = 1; i < order; i++)
nlsf[i] = FFMAX(nlsf[i], FFMIN(nlsf[i - 1] + min_delta[i], 32767));
/* push backwards to increase distance */
if (nlsf[order-1] > 32768 - min_delta[order])
nlsf[order-1] = 32768 - min_delta[order];
for (i = order-2; i >= 0; i--)
if (nlsf[i] > nlsf[i + 1] - min_delta[i+1])
nlsf[i] = nlsf[i + 1] - min_delta[i+1];
return;
}
static inline int silk_is_lpc_stable(const int16_t lpc[16], int order)
{
int k, j, DC_resp = 0;
int32_t lpc32[2][16]; // Q24
int totalinvgain = 1 << 30; // 1.0 in Q30
int32_t *row = lpc32[0], *prevrow;
/* initialize the first row for the Levinson recursion */
for (k = 0; k < order; k++) {
DC_resp += lpc[k];
row[k] = lpc[k] * 4096;
}
if (DC_resp >= 4096)
return 0;
/* check if prediction gain pushes any coefficients too far */
for (k = order - 1; 1; k--) {
int rc; // Q31; reflection coefficient
int gaindiv; // Q30; inverse of the gain (the divisor)
int gain; // gain for this reflection coefficient
int fbits; // fractional bits used for the gain
int error; // Q29; estimate of the error of our partial estimate of 1/gaindiv
if (FFABS(row[k]) > 16773022)
return 0;
rc = -(row[k] * 128);
gaindiv = (1 << 30) - MULH(rc, rc);
totalinvgain = MULH(totalinvgain, gaindiv) << 2;
if (k == 0)
return (totalinvgain >= 107374);
/* approximate 1.0/gaindiv */
fbits = opus_ilog(gaindiv);
gain = ((1 << 29) - 1) / (gaindiv >> (fbits + 1 - 16)); // Q<fbits-16>
error = (1 << 29) - MULL(gaindiv << (15 + 16 - fbits), gain, 16);
gain = ((gain << 16) + (error * gain >> 13));
/* switch to the next row of the LPC coefficients */
prevrow = row;
row = lpc32[k & 1];
for (j = 0; j < k; j++) {
int x = av_sat_sub32(prevrow[j], ROUND_MULL(prevrow[k - j - 1], rc, 31));
int64_t tmp = ROUND_MULL(x, gain, fbits);
/* per RFC 8251 section 6, if this calculation overflows, the filter
is considered unstable. */
if (tmp < INT32_MIN || tmp > INT32_MAX)
return 0;
row[j] = (int32_t)tmp;
}
}
}
static void silk_lsp2poly(const int32_t lsp[/* 2 * half_order - 1 */],
int32_t pol[/* half_order + 1 */], int half_order)
{
int i, j;
pol[0] = 65536; // 1.0 in Q16
pol[1] = -lsp[0];
for (i = 1; i < half_order; i++) {
pol[i + 1] = pol[i - 1] * 2 - ROUND_MULL(lsp[2 * i], pol[i], 16);
for (j = i; j > 1; j--)
pol[j] += pol[j - 2] - ROUND_MULL(lsp[2 * i], pol[j - 1], 16);
pol[1] -= lsp[2 * i];
}
}
static void silk_lsf2lpc(const int16_t nlsf[16], float lpcf[16], int order)
{
int i, k;
int32_t lsp[16]; // Q17; 2*cos(LSF)
int32_t p[9], q[9]; // Q16
int32_t lpc32[16]; // Q17
int16_t lpc[16]; // Q12
/* convert the LSFs to LSPs, i.e. 2*cos(LSF) */
for (k = 0; k < order; k++) {
int index = nlsf[k] >> 8;
int offset = nlsf[k] & 255;
int k2 = (order == 10) ? ff_silk_lsf_ordering_nbmb[k] : ff_silk_lsf_ordering_wb[k];
/* interpolate and round */
lsp[k2] = ff_silk_cosine[index] * 256;
lsp[k2] += (ff_silk_cosine[index + 1] - ff_silk_cosine[index]) * offset;
lsp[k2] = (lsp[k2] + 4) >> 3;
}
silk_lsp2poly(lsp , p, order >> 1);
silk_lsp2poly(lsp + 1, q, order >> 1);
/* reconstruct A(z) */
for (k = 0; k < order>>1; k++) {
int32_t p_tmp = p[k + 1] + p[k];
int32_t q_tmp = q[k + 1] - q[k];
lpc32[k] = -q_tmp - p_tmp;
lpc32[order-k-1] = q_tmp - p_tmp;
}
/* limit the range of the LPC coefficients to each fit within an int16_t */
for (i = 0; i < 10; i++) {
int j;
unsigned int maxabs = 0;
for (j = 0, k = 0; j < order; j++) {
unsigned int x = FFABS(lpc32[k]);
if (x > maxabs) {
maxabs = x; // Q17
k = j;
}
}
maxabs = (maxabs + 16) >> 5; // convert to Q12
if (maxabs > 32767) {
/* perform bandwidth expansion */
unsigned int chirp, chirp_base; // Q16
maxabs = FFMIN(maxabs, 163838); // anything above this overflows chirp's numerator
chirp_base = chirp = 65470 - ((maxabs - 32767) << 14) / ((maxabs * (k+1)) >> 2);
for (k = 0; k < order; k++) {
lpc32[k] = ROUND_MULL(lpc32[k], chirp, 16);
chirp = (chirp_base * chirp + 32768) >> 16;
}
} else break;
}
if (i == 10) {
/* time's up: just clamp */
for (k = 0; k < order; k++) {
int x = (lpc32[k] + 16) >> 5;
lpc[k] = av_clip_int16(x);
lpc32[k] = lpc[k] << 5; // shortcut mandated by the spec; drops lower 5 bits
}
} else {
for (k = 0; k < order; k++)
lpc[k] = (lpc32[k] + 16) >> 5;
}
/* if the prediction gain causes the LPC filter to become unstable,
apply further bandwidth expansion on the Q17 coefficients */
for (i = 1; i <= 16 && !silk_is_lpc_stable(lpc, order); i++) {
unsigned int chirp, chirp_base;
chirp_base = chirp = 65536 - (1 << i);
for (k = 0; k < order; k++) {
lpc32[k] = ROUND_MULL(lpc32[k], chirp, 16);
lpc[k] = (lpc32[k] + 16) >> 5;
chirp = (chirp_base * chirp + 32768) >> 16;
}
}
for (i = 0; i < order; i++)
lpcf[i] = lpc[i] / 4096.0f;
}
static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame,
OpusRangeCoder *rc,
float lpc_leadin[16], float lpc[16],
int *lpc_order, int *has_lpc_leadin, int voiced)
{
int i;
int order; // order of the LP polynomial; 10 for NB/MB and 16 for WB
int8_t lsf_i1, lsf_i2[16]; // stage-1 and stage-2 codebook indices
int16_t lsf_res[16]; // residual as a Q10 value
int16_t nlsf[16]; // Q15
*lpc_order = order = s->wb ? 16 : 10;
/* obtain LSF stage-1 and stage-2 indices */
lsf_i1 = ff_opus_rc_dec_cdf(rc, ff_silk_model_lsf_s1[s->wb][voiced]);
for (i = 0; i < order; i++) {
int index = s->wb ? ff_silk_lsf_s2_model_sel_wb [lsf_i1][i] :
ff_silk_lsf_s2_model_sel_nbmb[lsf_i1][i];
lsf_i2[i] = ff_opus_rc_dec_cdf(rc, ff_silk_model_lsf_s2[index]) - 4;
if (lsf_i2[i] == -4)
lsf_i2[i] -= ff_opus_rc_dec_cdf(rc, ff_silk_model_lsf_s2_ext);
else if (lsf_i2[i] == 4)
lsf_i2[i] += ff_opus_rc_dec_cdf(rc, ff_silk_model_lsf_s2_ext);
}
/* reverse the backwards-prediction step */
for (i = order - 1; i >= 0; i--) {
int qstep = s->wb ? 9830 : 11796;
lsf_res[i] = lsf_i2[i] * 1024;
if (lsf_i2[i] < 0) lsf_res[i] += 102;
else if (lsf_i2[i] > 0) lsf_res[i] -= 102;
lsf_res[i] = (lsf_res[i] * qstep) >> 16;
if (i + 1 < order) {
int weight = s->wb ? ff_silk_lsf_pred_weights_wb [ff_silk_lsf_weight_sel_wb [lsf_i1][i]][i] :
ff_silk_lsf_pred_weights_nbmb[ff_silk_lsf_weight_sel_nbmb[lsf_i1][i]][i];
lsf_res[i] += (lsf_res[i+1] * weight) >> 8;
}
}
/* reconstruct the NLSF coefficients from the supplied indices */
for (i = 0; i < order; i++) {
const uint8_t * codebook = s->wb ? ff_silk_lsf_codebook_wb [lsf_i1] :
ff_silk_lsf_codebook_nbmb[lsf_i1];
int cur, prev, next, weight_sq, weight, ipart, fpart, y, value;
/* find the weight of the residual */
/* TODO: precompute */
cur = codebook[i];
prev = i ? codebook[i - 1] : 0;
next = i + 1 < order ? codebook[i + 1] : 256;
weight_sq = (1024 / (cur - prev) + 1024 / (next - cur)) << 16;
/* approximate square-root with mandated fixed-point arithmetic */
ipart = opus_ilog(weight_sq);
fpart = (weight_sq >> (ipart-8)) & 127;
y = ((ipart & 1) ? 32768 : 46214) >> ((32 - ipart)>>1);
weight = y + ((213 * fpart * y) >> 16);
value = cur * 128 + (lsf_res[i] * 16384) / weight;
nlsf[i] = av_clip_uintp2(value, 15);
}
/* stabilize the NLSF coefficients */
silk_stabilize_lsf(nlsf, order, s->wb ? ff_silk_lsf_min_spacing_wb :
ff_silk_lsf_min_spacing_nbmb);
/* produce an interpolation for the first 2 subframes, */
/* and then convert both sets of NLSFs to LPC coefficients */
*has_lpc_leadin = 0;
if (s->subframes == 4) {
int offset = ff_opus_rc_dec_cdf(rc, ff_silk_model_lsf_interpolation_offset);
if (offset != 4 && frame->coded) {
*has_lpc_leadin = 1;
if (offset != 0) {
int16_t nlsf_leadin[16];
for (i = 0; i < order; i++)
nlsf_leadin[i] = frame->nlsf[i] +
((nlsf[i] - frame->nlsf[i]) * offset >> 2);
silk_lsf2lpc(nlsf_leadin, lpc_leadin, order);
} else /* avoid re-computation for a (roughly) 1-in-4 occurrence */
memcpy(lpc_leadin, frame->lpc, 16 * sizeof(float));
} else
offset = 4;
s->nlsf_interp_factor = offset;
silk_lsf2lpc(nlsf, lpc, order);
} else {
s->nlsf_interp_factor = 4;
silk_lsf2lpc(nlsf, lpc, order);
}
memcpy(frame->nlsf, nlsf, order * sizeof(nlsf[0]));
memcpy(frame->lpc, lpc, order * sizeof(lpc[0]));
}
static inline void silk_count_children(OpusRangeCoder *rc, int model, int32_t total,
int32_t child[2])
{
if (total != 0) {
child[0] = ff_opus_rc_dec_cdf(rc,
ff_silk_model_pulse_location[model] + (((total - 1 + 5) * (total - 1)) >> 1));
child[1] = total - child[0];
} else {
child[0] = 0;
child[1] = 0;
}
}
static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc,
float* excitationf,
int qoffset_high, int active, int voiced)
{
int i;
uint32_t seed;
int shellblocks;
int ratelevel;
uint8_t pulsecount[20]; // total pulses in each shell block
uint8_t lsbcount[20] = {0}; // raw lsbits defined for each pulse in each shell block
int32_t excitation[320]; // Q23
/* excitation parameters */
seed = ff_opus_rc_dec_cdf(rc, ff_silk_model_lcg_seed);
shellblocks = ff_silk_shell_blocks[s->bandwidth][s->subframes >> 2];
ratelevel = ff_opus_rc_dec_cdf(rc, ff_silk_model_exc_rate[voiced]);
for (i = 0; i < shellblocks; i++) {
pulsecount[i] = ff_opus_rc_dec_cdf(rc, ff_silk_model_pulse_count[ratelevel]);
if (pulsecount[i] == 17) {
while (pulsecount[i] == 17 && ++lsbcount[i] != 10)
pulsecount[i] = ff_opus_rc_dec_cdf(rc, ff_silk_model_pulse_count[9]);
if (lsbcount[i] == 10)
pulsecount[i] = ff_opus_rc_dec_cdf(rc, ff_silk_model_pulse_count[10]);
}
}
/* decode pulse locations using PVQ */
for (i = 0; i < shellblocks; i++) {
if (pulsecount[i] != 0) {
int a, b, c, d;
int32_t * location = excitation + 16*i;
int32_t branch[4][2];
branch[0][0] = pulsecount[i];
/* unrolled tail recursion */
for (a = 0; a < 1; a++) {
silk_count_children(rc, 0, branch[0][a], branch[1]);
for (b = 0; b < 2; b++) {
silk_count_children(rc, 1, branch[1][b], branch[2]);
for (c = 0; c < 2; c++) {
silk_count_children(rc, 2, branch[2][c], branch[3]);
for (d = 0; d < 2; d++) {
silk_count_children(rc, 3, branch[3][d], location);
location += 2;
}
}
}
}
} else
memset(excitation + 16*i, 0, 16*sizeof(int32_t));
}
/* decode least significant bits */
for (i = 0; i < shellblocks << 4; i++) {
int bit;
for (bit = 0; bit < lsbcount[i >> 4]; bit++)
excitation[i] = (excitation[i] << 1) |
ff_opus_rc_dec_cdf(rc, ff_silk_model_excitation_lsb);
}
/* decode signs */
for (i = 0; i < shellblocks << 4; i++) {
if (excitation[i] != 0) {
int sign = ff_opus_rc_dec_cdf(rc, ff_silk_model_excitation_sign[active +
voiced][qoffset_high][FFMIN(pulsecount[i >> 4], 6)]);
if (sign == 0)
excitation[i] *= -1;
}
}
/* assemble the excitation */
for (i = 0; i < shellblocks << 4; i++) {
int value = excitation[i];
excitation[i] = value * 256 | ff_silk_quant_offset[voiced][qoffset_high];
if (value < 0) excitation[i] += 20;
else if (value > 0) excitation[i] -= 20;
/* invert samples pseudorandomly */
seed = 196314165 * seed + 907633515;
if (seed & 0x80000000)
excitation[i] *= -1;
seed += value;
excitationf[i] = excitation[i] / 8388608.0f;
}
}
/** Maximum residual history according to 4.2.7.6.1 */
#define SILK_MAX_LAG (288 + LTP_ORDER / 2)
/** Order of the LTP filter */
#define LTP_ORDER 5
static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
int frame_num, int channel, int coded_channels,
int active, int active1, int redundant)
{
/* per frame */
int voiced; // combines with active to indicate inactive, active, or active+voiced
int qoffset_high;
int order; // order of the LPC coefficients
float lpc_leadin[16], lpc_body[16], residual[SILK_MAX_LAG + SILK_HISTORY];
int has_lpc_leadin;
float ltpscale;
/* per subframe */
struct {
float gain;
int pitchlag;
float ltptaps[5];
} sf[4];
SilkFrame * const frame = s->frame + channel;
int i;
/* obtain stereo weights */
if (coded_channels == 2 && channel == 0) {
int n, wi[2], ws[2], w[2];
n = ff_opus_rc_dec_cdf(rc, ff_silk_model_stereo_s1);
wi[0] = ff_opus_rc_dec_cdf(rc, ff_silk_model_stereo_s2) + 3 * (n / 5);
ws[0] = ff_opus_rc_dec_cdf(rc, ff_silk_model_stereo_s3);
wi[1] = ff_opus_rc_dec_cdf(rc, ff_silk_model_stereo_s2) + 3 * (n % 5);
ws[1] = ff_opus_rc_dec_cdf(rc, ff_silk_model_stereo_s3);
for (i = 0; i < 2; i++)
w[i] = ff_silk_stereo_weights[wi[i]] +
(((ff_silk_stereo_weights[wi[i] + 1] - ff_silk_stereo_weights[wi[i]]) * 6554) >> 16)
* (ws[i]*2 + 1);
s->stereo_weights[0] = (w[0] - w[1]) / 8192.0;
s->stereo_weights[1] = w[1] / 8192.0;
/* and read the mid-only flag */
s->midonly = active1 ? 0 : ff_opus_rc_dec_cdf(rc, ff_silk_model_mid_only);
}
/* obtain frame type */
if (!active) {
qoffset_high = ff_opus_rc_dec_cdf(rc, ff_silk_model_frame_type_inactive);
voiced = 0;
} else {
int type = ff_opus_rc_dec_cdf(rc, ff_silk_model_frame_type_active);
qoffset_high = type & 1;
voiced = type >> 1;
}
/* obtain subframe quantization gains */
for (i = 0; i < s->subframes; i++) {
int log_gain; //Q7
int ipart, fpart, lingain;
if (i == 0 && (frame_num == 0 || !frame->coded)) {
/* gain is coded absolute */
int x = ff_opus_rc_dec_cdf(rc, ff_silk_model_gain_highbits[active + voiced]);
log_gain = (x<<3) | ff_opus_rc_dec_cdf(rc, ff_silk_model_gain_lowbits);
if (frame->coded)
log_gain = FFMAX(log_gain, frame->log_gain - 16);
} else {
/* gain is coded relative */
int delta_gain = ff_opus_rc_dec_cdf(rc, ff_silk_model_gain_delta);
log_gain = av_clip_uintp2(FFMAX((delta_gain<<1) - 16,
frame->log_gain + delta_gain - 4), 6);
}
frame->log_gain = log_gain;
/* approximate 2**(x/128) with a Q7 (i.e. non-integer) input */
log_gain = (log_gain * 0x1D1C71 >> 16) + 2090;
ipart = log_gain >> 7;
fpart = log_gain & 127;
lingain = (1 << ipart) + ((-174 * fpart * (128-fpart) >>16) + fpart) * ((1<<ipart) >> 7);
sf[i].gain = lingain / 65536.0f;
}
/* obtain LPC filter coefficients */
silk_decode_lpc(s, frame, rc, lpc_leadin, lpc_body, &order, &has_lpc_leadin, voiced);
/* obtain pitch lags, if this is a voiced frame */
if (voiced) {
int lag_absolute = (!frame_num || !frame->prev_voiced);
int primarylag; // primary pitch lag for the entire SILK frame
int ltpfilter;
const int8_t * offsets;
if (!lag_absolute) {
int delta = ff_opus_rc_dec_cdf(rc, ff_silk_model_pitch_delta);
if (delta)
primarylag = frame->primarylag + delta - 9;
else
lag_absolute = 1;
}
if (lag_absolute) {
/* primary lag is coded absolute */
int highbits, lowbits;
static const uint16_t * const model[] = {
ff_silk_model_pitch_lowbits_nb, ff_silk_model_pitch_lowbits_mb,
ff_silk_model_pitch_lowbits_wb
};
highbits = ff_opus_rc_dec_cdf(rc, ff_silk_model_pitch_highbits);
lowbits = ff_opus_rc_dec_cdf(rc, model[s->bandwidth]);
primarylag = ff_silk_pitch_min_lag[s->bandwidth] +
highbits*ff_silk_pitch_scale[s->bandwidth] + lowbits;
}
frame->primarylag = primarylag;
if (s->subframes == 2)
offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
? ff_silk_pitch_offset_nb10ms[ff_opus_rc_dec_cdf(rc,
ff_silk_model_pitch_contour_nb10ms)]
: ff_silk_pitch_offset_mbwb10ms[ff_opus_rc_dec_cdf(rc,
ff_silk_model_pitch_contour_mbwb10ms)];
else
offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
? ff_silk_pitch_offset_nb20ms[ff_opus_rc_dec_cdf(rc,
ff_silk_model_pitch_contour_nb20ms)]
: ff_silk_pitch_offset_mbwb20ms[ff_opus_rc_dec_cdf(rc,
ff_silk_model_pitch_contour_mbwb20ms)];
for (i = 0; i < s->subframes; i++)
sf[i].pitchlag = av_clip(primarylag + offsets[i],
ff_silk_pitch_min_lag[s->bandwidth],
ff_silk_pitch_max_lag[s->bandwidth]);
/* obtain LTP filter coefficients */
ltpfilter = ff_opus_rc_dec_cdf(rc, ff_silk_model_ltp_filter);
for (i = 0; i < s->subframes; i++) {
int index, j;
static const uint16_t * const filter_sel[] = {
ff_silk_model_ltp_filter0_sel, ff_silk_model_ltp_filter1_sel,
ff_silk_model_ltp_filter2_sel
};
static const int8_t (* const filter_taps[])[5] = {
ff_silk_ltp_filter0_taps, ff_silk_ltp_filter1_taps, ff_silk_ltp_filter2_taps
};
index = ff_opus_rc_dec_cdf(rc, filter_sel[ltpfilter]);
for (j = 0; j < 5; j++)
sf[i].ltptaps[j] = filter_taps[ltpfilter][index][j] / 128.0f;
}
}
/* obtain LTP scale factor */
if (voiced && frame_num == 0)
ltpscale = ff_silk_ltp_scale_factor[ff_opus_rc_dec_cdf(rc,
ff_silk_model_ltp_scale_index)] / 16384.0f;
else ltpscale = 15565.0f/16384.0f;
/* generate the excitation signal for the entire frame */
silk_decode_excitation(s, rc, residual + SILK_MAX_LAG, qoffset_high,
active, voiced);
/* skip synthesising the output if we do not need it */
// TODO: implement error recovery
if (s->output_channels == channel || redundant)
return;
/* generate the output signal */
for (i = 0; i < s->subframes; i++) {
const float * lpc_coeff = (i < 2 && has_lpc_leadin) ? lpc_leadin : lpc_body;
float *dst = frame->output + SILK_HISTORY + i * s->sflength;
float *resptr = residual + SILK_MAX_LAG + i * s->sflength;
float *lpc = frame->lpc_history + SILK_HISTORY + i * s->sflength;
float sum;
int j, k;
if (voiced) {
int out_end;
float scale;
if (i < 2 || s->nlsf_interp_factor == 4) {
out_end = -i * s->sflength;
scale = ltpscale;
} else {
out_end = -(i - 2) * s->sflength;
scale = 1.0f;
}
/* when the LPC coefficients change, a re-whitening filter is used */
/* to produce a residual that accounts for the change */
for (j = - sf[i].pitchlag - LTP_ORDER/2; j < out_end; j++) {
sum = dst[j];
for (k = 0; k < order; k++)
sum -= lpc_coeff[k] * dst[j - k - 1];
resptr[j] = av_clipf(sum, -1.0f, 1.0f) * scale / sf[i].gain;
}
if (out_end) {
float rescale = sf[i-1].gain / sf[i].gain;
for (j = out_end; j < 0; j++)
resptr[j] *= rescale;
}
/* LTP synthesis */
for (j = 0; j < s->sflength; j++) {
sum = resptr[j];
for (k = 0; k < LTP_ORDER; k++)
sum += sf[i].ltptaps[k] * resptr[j - sf[i].pitchlag + LTP_ORDER/2 - k];
resptr[j] = sum;
}
}
/* LPC synthesis */
for (j = 0; j < s->sflength; j++) {
sum = resptr[j] * sf[i].gain;
for (k = 1; k <= order; k++)
sum += lpc_coeff[k - 1] * lpc[j - k];
lpc[j] = sum;
dst[j] = av_clipf(sum, -1.0f, 1.0f);
}
}
frame->prev_voiced = voiced;
memmove(frame->lpc_history, frame->lpc_history + s->flength, SILK_HISTORY * sizeof(float));
memmove(frame->output, frame->output + s->flength, SILK_HISTORY * sizeof(float));
frame->coded = 1;
}
static void silk_unmix_ms(SilkContext *s, float *l, float *r)
{
float *mid = s->frame[0].output + SILK_HISTORY - s->flength;
float *side = s->frame[1].output + SILK_HISTORY - s->flength;
float w0_prev = s->prev_stereo_weights[0];
float w1_prev = s->prev_stereo_weights[1];
float w0 = s->stereo_weights[0];
float w1 = s->stereo_weights[1];
int n1 = ff_silk_stereo_interp_len[s->bandwidth];
int i;
for (i = 0; i < n1; i++) {
float interp0 = w0_prev + i * (w0 - w0_prev) / n1;
float interp1 = w1_prev + i * (w1 - w1_prev) / n1;
float p0 = 0.25 * (mid[i - 2] + 2 * mid[i - 1] + mid[i]);
l[i] = av_clipf((1 + interp1) * mid[i - 1] + side[i - 1] + interp0 * p0, -1.0, 1.0);
r[i] = av_clipf((1 - interp1) * mid[i - 1] - side[i - 1] - interp0 * p0, -1.0, 1.0);
}
for (; i < s->flength; i++) {
float p0 = 0.25 * (mid[i - 2] + 2 * mid[i - 1] + mid[i]);
l[i] = av_clipf((1 + w1) * mid[i - 1] + side[i - 1] + w0 * p0, -1.0, 1.0);
r[i] = av_clipf((1 - w1) * mid[i - 1] - side[i - 1] - w0 * p0, -1.0, 1.0);
}
memcpy(s->prev_stereo_weights, s->stereo_weights, sizeof(s->stereo_weights));
}
static void silk_flush_frame(SilkFrame *frame)
{
if (!frame->coded)
return;
memset(frame->output, 0, sizeof(frame->output));
memset(frame->lpc_history, 0, sizeof(frame->lpc_history));
memset(frame->lpc, 0, sizeof(frame->lpc));
memset(frame->nlsf, 0, sizeof(frame->nlsf));
frame->log_gain = 0;
frame->primarylag = 0;
frame->prev_voiced = 0;
frame->coded = 0;
}
int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
float *output[2],
enum OpusBandwidth bandwidth,
int coded_channels,
int duration_ms)
{
int active[2][6], redundancy[2];
int nb_frames, i, j;
if (bandwidth > OPUS_BANDWIDTH_WIDEBAND ||
coded_channels > 2 || duration_ms > 60) {
av_log(s->logctx, AV_LOG_ERROR, "Invalid parameters passed "
"to the SILK decoder.\n");
return AVERROR(EINVAL);
}
nb_frames = 1 + (duration_ms > 20) + (duration_ms > 40);
s->subframes = duration_ms / nb_frames / 5; // 5ms subframes
s->sflength = 20 * (bandwidth + 2);
s->flength = s->sflength * s->subframes;
s->bandwidth = bandwidth;
s->wb = bandwidth == OPUS_BANDWIDTH_WIDEBAND;
/* make sure to flush the side channel when switching from mono to stereo */
if (coded_channels > s->prev_coded_channels)
silk_flush_frame(&s->frame[1]);
s->prev_coded_channels = coded_channels;
/* read the LP-layer header bits */
for (i = 0; i < coded_channels; i++) {
for (j = 0; j < nb_frames; j++)
active[i][j] = ff_opus_rc_dec_log(rc, 1);
redundancy[i] = ff_opus_rc_dec_log(rc, 1);
}
/* read the per-frame LBRR flags */
for (i = 0; i < coded_channels; i++)
if (redundancy[i] && duration_ms > 20) {
redundancy[i] = ff_opus_rc_dec_cdf(rc, duration_ms == 40 ?
ff_silk_model_lbrr_flags_40 : ff_silk_model_lbrr_flags_60);
}
/* decode the LBRR frames */
for (i = 0; i < nb_frames; i++) {
for (j = 0; j < coded_channels; j++)
if (redundancy[j] & (1 << i)) {
int active1 = (j == 0 && !(redundancy[1] & (1 << i))) ? 0 : 1;
silk_decode_frame(s, rc, i, j, coded_channels, 1, active1, 1);
}
s->midonly = 0;
}
for (i = 0; i < nb_frames; i++) {
for (j = 0; j < coded_channels && !s->midonly; j++) {
int active1 = coded_channels > 1 ? active[1][i] : 0;
silk_decode_frame(s, rc, i, j, coded_channels, active[j][i], active1, 0);
}
/* reset the side channel if it is not coded */
if (s->midonly && s->frame[1].coded)
silk_flush_frame(&s->frame[1]);
if (coded_channels == 1 || s->output_channels == 1) {
for (j = 0; j < s->output_channels; j++) {
memcpy(output[j] + i * s->flength,
s->frame[0].output + SILK_HISTORY - s->flength - 2,
s->flength * sizeof(float));
}
} else {
silk_unmix_ms(s, output[0] + i * s->flength, output[1] + i * s->flength);
}
s->midonly = 0;
}
return nb_frames * s->flength;
}
void ff_silk_free(SilkContext **ps)
{
av_freep(ps);
}
void ff_silk_flush(SilkContext *s)
{
silk_flush_frame(&s->frame[0]);
silk_flush_frame(&s->frame[1]);
memset(s->prev_stereo_weights, 0, sizeof(s->prev_stereo_weights));
}
int ff_silk_init(void *logctx, SilkContext **ps, int output_channels)
{
SilkContext *s;
if (output_channels != 1 && output_channels != 2) {
av_log(logctx, AV_LOG_ERROR, "Invalid number of output channels: %d\n",
output_channels);
return AVERROR(EINVAL);
}
s = av_mallocz(sizeof(*s));
if (!s)
return AVERROR(ENOMEM);
s->logctx = logctx;
s->output_channels = output_channels;
ff_silk_flush(s);
*ps = s;
return 0;
}
+47
View File
@@ -0,0 +1,47 @@
/*
* Opus Silk functions/definitions
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_OPUS_SILK_H
#define AVCODEC_OPUS_SILK_H
#include "opus.h"
#include "rc.h"
#define SILK_HISTORY 322
#define SILK_MAX_LPC 16
typedef struct SilkContext SilkContext;
int ff_silk_init(void *logctx, SilkContext **ps, int output_channels);
void ff_silk_free(SilkContext **ps);
void ff_silk_flush(SilkContext *s);
/**
* Decode the LP layer of one Opus frame (which may correspond to several SILK
* frames).
*/
int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
float *output[2],
enum OpusBandwidth bandwidth, int coded_channels,
int duration_ms);
#endif /* AVCODEC_OPUS_SILK_H */
File diff suppressed because it is too large Load Diff
+169
View File
@@ -0,0 +1,169 @@
/*
* Copyright (c) 2012 Andrew D'Addesio
* Copyright (c) 2013-2014 Mozilla Corporation
* Copyright (c) 2016 Rostislav Pehlivanov <atomnuker@gmail.com>
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVCODEC_OPUS_TAB_H
#define AVCODEC_OPUS_TAB_H
#include <stdint.h>
#include "libavutil/attributes_internal.h"
FF_VISIBILITY_PUSH_HIDDEN
extern const uint8_t ff_celt_band_end[];
extern const uint8_t ff_opus_default_coupled_streams[];
extern const uint16_t ff_silk_model_lbrr_flags_40[];
extern const uint16_t ff_silk_model_lbrr_flags_60[];
extern const uint16_t ff_silk_model_stereo_s1[];
extern const uint16_t ff_silk_model_stereo_s2[];
extern const uint16_t ff_silk_model_stereo_s3[];
extern const uint16_t ff_silk_model_mid_only[];
extern const uint16_t ff_silk_model_frame_type_inactive[];
extern const uint16_t ff_silk_model_frame_type_active[];
extern const uint16_t ff_silk_model_gain_highbits[3][9];
extern const uint16_t ff_silk_model_gain_lowbits[];
extern const uint16_t ff_silk_model_gain_delta[];
extern const uint16_t ff_silk_model_lsf_s1[2][2][33];
extern const uint16_t ff_silk_model_lsf_s2[32][10];
extern const uint16_t ff_silk_model_lsf_s2_ext[];
extern const uint16_t ff_silk_model_lsf_interpolation_offset[];
extern const uint16_t ff_silk_model_pitch_highbits[];
#define ff_silk_model_pitch_lowbits_nb ff_silk_model_lcg_seed
extern const uint16_t ff_silk_model_pitch_lowbits_mb[];
#define ff_silk_model_pitch_lowbits_wb ff_silk_model_gain_lowbits
extern const uint16_t ff_silk_model_pitch_delta[];
extern const uint16_t ff_silk_model_pitch_contour_nb10ms[];
extern const uint16_t ff_silk_model_pitch_contour_nb20ms[];
extern const uint16_t ff_silk_model_pitch_contour_mbwb10ms[];
extern const uint16_t ff_silk_model_pitch_contour_mbwb20ms[];
extern const uint16_t ff_silk_model_ltp_filter[];
extern const uint16_t ff_silk_model_ltp_filter0_sel[];
extern const uint16_t ff_silk_model_ltp_filter1_sel[];
extern const uint16_t ff_silk_model_ltp_filter2_sel[];
extern const uint16_t ff_silk_model_ltp_scale_index[];
extern const uint16_t ff_silk_model_lcg_seed[];
extern const uint16_t ff_silk_model_exc_rate[2][10];
extern const uint16_t ff_silk_model_pulse_count[11][19];
extern const uint16_t ff_silk_model_pulse_location[4][168];
extern const uint16_t ff_silk_model_excitation_lsb[];
extern const uint16_t ff_silk_model_excitation_sign[3][2][7][3];
extern const int16_t ff_silk_stereo_weights[];
extern const uint8_t ff_silk_lsf_s2_model_sel_nbmb[32][10];
extern const uint8_t ff_silk_lsf_s2_model_sel_wb[32][16];
extern const uint8_t ff_silk_lsf_pred_weights_nbmb[2][9];
extern const uint8_t ff_silk_lsf_pred_weights_wb[2][15];
extern const uint8_t ff_silk_lsf_weight_sel_nbmb[32][9];
extern const uint8_t ff_silk_lsf_weight_sel_wb[32][15];
extern const uint8_t ff_silk_lsf_codebook_nbmb[32][10];
extern const uint8_t ff_silk_lsf_codebook_wb[32][16];
extern const uint16_t ff_silk_lsf_min_spacing_nbmb[];
extern const uint16_t ff_silk_lsf_min_spacing_wb[];
extern const uint8_t ff_silk_lsf_ordering_nbmb[];
extern const uint8_t ff_silk_lsf_ordering_wb[];
extern const int16_t ff_silk_cosine[];
extern const uint16_t ff_silk_pitch_scale[];
extern const uint16_t ff_silk_pitch_min_lag[];
extern const uint16_t ff_silk_pitch_max_lag[];
extern const int8_t ff_silk_pitch_offset_nb10ms[3][2];
extern const int8_t ff_silk_pitch_offset_nb20ms[11][4];
extern const int8_t ff_silk_pitch_offset_mbwb10ms[12][2];
extern const int8_t ff_silk_pitch_offset_mbwb20ms[34][4];
extern const int8_t ff_silk_ltp_filter0_taps[8][5];
extern const int8_t ff_silk_ltp_filter1_taps[16][5];
extern const int8_t ff_silk_ltp_filter2_taps[32][5];
extern const uint16_t ff_silk_ltp_scale_factor[];
extern const uint8_t ff_silk_shell_blocks[3][2];
extern const uint8_t ff_silk_quant_offset[2][2];
extern const int ff_silk_stereo_interp_len[3];
extern const uint16_t ff_celt_model_tapset[];
extern const uint16_t ff_celt_model_spread[];
extern const uint16_t ff_celt_model_alloc_trim[];
#define ff_celt_model_energy_small ff_celt_model_tapset
extern const uint8_t ff_celt_freq_bands[];
extern const uint8_t ff_celt_freq_range[];
extern const uint8_t ff_celt_log_freq_range[];
extern const int8_t ff_celt_tf_select[4][2][2][2];
extern const float ff_celt_mean_energy[];
extern const float ff_celt_alpha_coef[];
extern const float ff_celt_beta_coef[];
extern const uint8_t ff_celt_coarse_energy_dist[4][2][42];
extern const uint8_t ff_celt_static_alloc[11][21];
extern const uint8_t ff_celt_static_caps[4][2][21];
extern const uint8_t ff_celt_cache_bits[392];
extern const int16_t ff_celt_cache_index[105];
extern const uint8_t ff_celt_log2_frac[];
extern const uint8_t ff_celt_bit_interleave[];
extern const uint8_t ff_celt_bit_deinterleave[];
extern const uint8_t ff_celt_hadamard_order[];
extern const uint16_t ff_celt_qn_exp2[];
extern const float ff_celt_postfilter_taps[3][3];
extern const float ff_celt_window2[120];
extern const float ff_celt_window_padded[];
static const float *const ff_celt_window = &ff_celt_window_padded[8];
extern const float ff_opus_deemph_weights[];
extern const uint32_t * const ff_celt_pvq_u_row[15];
FF_VISIBILITY_POP_HIDDEN
#endif /* AVCODEC_OPUS_TAB_H */