Compare commits

...

4 Commits

Author SHA1 Message Date
Andreas Rheinhardt 4c8a6631ad fftools/ffmpeg_filter: Fix check
Fixes Coverity issues #1596529, #1596531.
Introduced in 8e35e33d42.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-04-27 17:00:12 +02:00
Andreas Rheinhardt 67c7c44c79 avcodec/vp8: Return error on error
Regression since e1ba00ac8f.

Reviewed-by: Ronald S. Bultje <rsbultje@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2024-04-27 16:55:00 +02:00
Lynne 3390693bfb
aacdec: avoid generating unused code when either implementation is disabled
Minor optimization to remove extra branches.
We need to include the header for xHE anyway, which is float-only.
2024-04-27 11:12:12 +02:00
Lynne 134dba9544
opusdsp: add ability to modify deemphasis constant
xHE-AAC relies on the same postfilter mechanism
that Opus uses to improve clarity (albeit with a steeper
deemphasis filter).

The code to apply it is identical, it's still just a
simple IIR low-pass filter. This commit makes it possible
to use alternative constants.
2024-04-27 11:12:07 +02:00
14 changed files with 76 additions and 54 deletions

View File

@ -862,7 +862,7 @@ int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost,
ofp->fps.vsync_method = opts->vsync_method;
ofp->fps.framerate = ost->frame_rate;
ofp->fps.framerate_max = ost->max_frame_rate;
ofp->fps.framerate_supported = ost->force_fps && opts->enc ?
ofp->fps.framerate_supported = ost->force_fps || !opts->enc ?
NULL : opts->enc->supported_framerates;
// reduce frame rate for mpeg4 to be within the spec limits

View File

@ -33,6 +33,8 @@
* for which we need this to be defined for them to work as expected. */
#define USE_FIXED 1
#include "config_components.h"
#include <limits.h>
#include <stddef.h>
@ -1312,9 +1314,9 @@ static void decode_ltp(AACDecContext *ac, LongTermPrediction *ltp,
int sfb;
ltp->lag = get_bits(gb, 11);
if (ac->is_fixed)
if (CONFIG_AAC_FIXED_DECODER && ac->is_fixed)
ltp->coef_fixed = Q30(ff_ltp_coef[get_bits(gb, 3)]);
else
else if (CONFIG_AAC_DECODER)
ltp->coef = ff_ltp_coef[get_bits(gb, 3)];
for (sfb = 0; sfb < FFMIN(max_sfb, MAX_LTP_LONG_SFB); sfb++)
@ -1623,9 +1625,9 @@ static int decode_tns(AACDecContext *ac, TemporalNoiseShaping *tns,
tmp2_idx = 2 * coef_compress + coef_res;
for (i = 0; i < tns->order[w][filt]; i++) {
if (ac->is_fixed)
if (CONFIG_AAC_FIXED_DECODER && ac->is_fixed)
tns->coef_fixed[w][filt][i] = Q31(ff_tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)]);
else
else if (CONFIG_AAC_DECODER)
tns->coef[w][filt][i] = ff_tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)];
}
}
@ -1974,9 +1976,9 @@ static int decode_extension_payload(AACDecContext *ac, GetBitContext *gb, int cn
ac->avctx->profile = AV_PROFILE_AAC_HE;
}
if (ac->is_fixed)
if (CONFIG_AAC_FIXED_DECODER && ac->is_fixed)
res = ff_aac_sbr_decode_extension_fixed(ac, che, gb, crc_flag, cnt, elem_type);
else
else if (CONFIG_AAC_DECODER)
res = ff_aac_sbr_decode_extension(ac, che, gb, crc_flag, cnt, elem_type);
@ -2087,11 +2089,11 @@ static void spectral_to_sample(AACDecContext *ac, int samples)
ac->dsp.update_ltp(ac, &che->ch[1]);
}
if (ac->oc[1].m4ac.sbr > 0) {
if (ac->is_fixed)
if (CONFIG_AAC_FIXED_DECODER && ac->is_fixed)
ff_aac_sbr_apply_fixed(ac, che, type,
(void *)che->ch[0].output,
(void *)che->ch[1].output);
else
else if (CONFIG_AAC_DECODER)
ff_aac_sbr_apply(ac, che, type,
(void *)che->ch[0].output,
(void *)che->ch[1].output);
@ -2550,6 +2552,7 @@ static const AVClass decoder_class = {
.version = LIBAVUTIL_VERSION_INT,
};
#if CONFIG_AAC_DECODER
const FFCodec ff_aac_decoder = {
.p.name = "aac",
CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),
@ -2569,7 +2572,9 @@ const FFCodec ff_aac_decoder = {
.flush = flush,
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
};
#endif
#if CONFIG_AAC_FIXED_DECODER
const FFCodec ff_aac_fixed_decoder = {
.p.name = "aac_fixed",
CODEC_LONG_NAME("AAC (Advanced Audio Coding)"),
@ -2589,3 +2594,4 @@ const FFCodec ff_aac_fixed_decoder = {
.p.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
.flush = flush,
};
#endif

View File

@ -23,7 +23,7 @@
#include "libavcodec/opusdsp.h"
void ff_opus_postfilter_neon(float *data, int period, float *gains, int len);
float ff_opus_deemphasis_neon(float *out, float *in, float coeff, int len);
float ff_opus_deemphasis_neon(float *out, float *in, float coeff, const float *weights, int len);
av_cold void ff_opus_dsp_init_aarch64(OpusDSP *ctx)
{

View File

@ -18,29 +18,11 @@
#include "libavutil/aarch64/asm.S"
// 0.85..^1 0.85..^2 0.85..^3 0.85..^4
const tab_st, align=4
.word 0x3f599a00, 0x3f38f671, 0x3f1d382a, 0x3f05a32f
endconst
const tab_x0, align=4
.word 0x0, 0x3f599a00, 0x3f38f671, 0x3f1d382a
endconst
const tab_x1, align=4
.word 0x0, 0x0, 0x3f599a00, 0x3f38f671
endconst
const tab_x2, align=4
.word 0x0, 0x0, 0x0, 0x3f599a00
endconst
function ff_opus_deemphasis_neon, export=1
movrel x4, tab_st
ld1 {v4.4s}, [x4]
movrel x4, tab_x0
ld1 {v5.4s}, [x4]
movrel x4, tab_x1
ld1 {v6.4s}, [x4]
movrel x4, tab_x2
ld1 {v7.4s}, [x4]
ld1 {v4.4s}, [x2], #16
ld1 {v5.4s}, [x2], #16
ld1 {v6.4s}, [x2], #16
ld1 {v7.4s}, [x2]
fmul v0.4s, v4.4s, v0.s[0]
@ -63,7 +45,7 @@ function ff_opus_deemphasis_neon, export=1
st1 {v1.4s, v2.4s}, [x0], #32
fmul v0.4s, v4.4s, v2.s[3]
subs w2, w2, #8
subs w3, w3, #8
b.gt 1b
mov s0, v2.s[3]

View File

@ -460,7 +460,9 @@ int ff_celt_decode_frame(CeltFrame *f, OpusRangeCoder *rc,
/* deemphasis */
block->emph_coeff = f->opusdsp.deemphasis(output[i],
&block->buf[1024 - frame_size],
block->emph_coeff, frame_size);
block->emph_coeff,
ff_opus_deemph_weights,
frame_size);
}
if (channels == 1)
@ -516,7 +518,7 @@ void ff_celt_flush(CeltFrame *f)
* 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 / CELT_EMPH_COEFF;
block->emph_coeff = 0.0f / ff_opus_deemph_weights[0];
}
f->seed = 0;

View File

@ -18,6 +18,7 @@
#include "config.h"
#include "libavutil/attributes.h"
#include "libavutil/mem_internal.h"
#include "opusdsp.h"
static void postfilter_c(float *data, int period, float *gains, int len)
@ -43,10 +44,11 @@ static void postfilter_c(float *data, int period, float *gains, int len)
}
}
static float deemphasis_c(float *y, float *x, float coeff, int len)
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*CELT_EMPH_COEFF;
coeff = y[i] = x[i] + coeff*c;
return coeff;
}

View File

@ -19,11 +19,9 @@
#ifndef AVCODEC_OPUSDSP_H
#define AVCODEC_OPUSDSP_H
#define CELT_EMPH_COEFF 0.8500061035f
typedef struct OpusDSP {
void (*postfilter)(float *data, int period, float *gains, int len);
float (*deemphasis)(float *out, float *in, float coeff, int len);
float (*deemphasis)(float *out, float *in, float coeff, const float *weights, int len);
} OpusDSP;
void ff_opus_dsp_init(OpusDSP *ctx);

View File

@ -164,6 +164,7 @@ 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++) {
@ -172,7 +173,7 @@ static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f)
for (int i = 0; i < CELT_OVERLAP; i++) {
float sample = b->overlap[i];
b->overlap[i] = sample - m;
m = sample * CELT_EMPH_COEFF;
m = sample * c;
}
b->emph_coeff = m;
}
@ -185,7 +186,7 @@ static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f)
for (int i = 0; i < subframesize; i++) {
float sample = b->samples[sf*subframesize + i];
b->samples[sf*subframesize + i] = sample - m;
m = sample * CELT_EMPH_COEFF;
m = sample * c;
}
if (sf != (subframes - 1))
b->emph_coeff = m;

View File

@ -1159,3 +1159,31 @@ const uint32_t * const ff_celt_pvq_u_row[15] = {
celt_pvq_u + 1207, celt_pvq_u + 1226, celt_pvq_u + 1240,
celt_pvq_u + 1248, celt_pvq_u + 1254, celt_pvq_u + 1257
};
/* Deemphasis constant (alpha_p), as specified in RFC6716 as 0.8500061035.
* libopus uses a slighly rounded constant, set to 0.85 exactly,
* to simplify its fixed-point version, but it's not significant to impact
* compliance. */
#define CELT_EMPH_COEFF 0.8500061035f
DECLARE_ALIGNED(16, const float, ff_opus_deemph_weights)[] = {
CELT_EMPH_COEFF,
CELT_EMPH_COEFF*CELT_EMPH_COEFF,
CELT_EMPH_COEFF*CELT_EMPH_COEFF*CELT_EMPH_COEFF,
CELT_EMPH_COEFF*CELT_EMPH_COEFF*CELT_EMPH_COEFF*CELT_EMPH_COEFF,
0,
CELT_EMPH_COEFF,
CELT_EMPH_COEFF*CELT_EMPH_COEFF,
CELT_EMPH_COEFF*CELT_EMPH_COEFF*CELT_EMPH_COEFF,
0,
0,
CELT_EMPH_COEFF,
CELT_EMPH_COEFF*CELT_EMPH_COEFF,
0,
0,
0,
CELT_EMPH_COEFF,
};

View File

@ -161,6 +161,8 @@ 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

View File

@ -107,8 +107,11 @@ static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
ref ? AV_GET_BUFFER_FLAG_REF : 0);
if (ret < 0)
return ret;
if (!(f->seg_map = ff_refstruct_allocz(s->mb_width * s->mb_height)))
f->seg_map = ff_refstruct_allocz(s->mb_width * s->mb_height);
if (!f->seg_map) {
ret = AVERROR(ENOMEM);
goto fail;
}
ret = ff_hwaccel_frame_priv_alloc(s->avctx, &f->hwaccel_picture_private);
if (ret < 0)
goto fail;

View File

@ -22,16 +22,13 @@
SECTION_RODATA
; 0.85..^1 0.85..^2 0.85..^3 0.85..^4
tab_st: dd 0x3f599a00, 0x3f38f671, 0x3f1d382a, 0x3f05a32f
SECTION .text
INIT_XMM fma3
%if UNIX64
cglobal opus_deemphasis, 3, 3, 8, out, in, len
cglobal opus_deemphasis, 4, 4, 8, out, in, weights, len
%else
cglobal opus_deemphasis, 4, 4, 8, out, in, coeff, len
cglobal opus_deemphasis, 5, 5, 8, out, in, coeff, weights, len
%endif
%if ARCH_X86_32
VBROADCASTSS m0, coeffm
@ -41,7 +38,7 @@ cglobal opus_deemphasis, 4, 4, 8, out, in, coeff, len
shufps m0, m0, 0
%endif
movaps m4, [tab_st]
movaps m4, [weightsq]
VBROADCASTSS m5, m4
shufps m6, m4, m4, q1111
shufps m7, m4, m4, q2222

View File

@ -23,7 +23,7 @@
#include "libavcodec/opusdsp.h"
void ff_opus_postfilter_fma3(float *data, int period, float *gains, int len);
float ff_opus_deemphasis_fma3(float *out, float *in, float coeff, int len);
float ff_opus_deemphasis_fma3(float *out, float *in, float coeff, const float *weights, int len);
av_cold void ff_opus_dsp_init_x86(OpusDSP *ctx)
{

View File

@ -19,6 +19,7 @@
#include "libavutil/mem_internal.h"
#include "libavcodec/opusdsp.h"
#include "libavcodec/opustab.h"
#include "checkasm.h"
@ -69,17 +70,17 @@ static void test_deemphasis(void)
LOCAL_ALIGNED(16, float, dst1, [FFALIGN(MAX_SIZE, 4)]);
float coeff0 = (float)rnd() / (UINT_MAX >> 5) - 16.0f, coeff1 = coeff0;
declare_func_float(float, float *out, float *in, float coeff, int len);
declare_func_float(float, float *out, float *in, float coeff, const float *weights, int len);
randomize_float(src, MAX_SIZE);
coeff0 = call_ref(dst0, src, coeff0, MAX_SIZE);
coeff1 = call_new(dst1, src, coeff1, MAX_SIZE);
coeff0 = call_ref(dst0, src, coeff0, ff_opus_deemph_weights, MAX_SIZE);
coeff1 = call_new(dst1, src, coeff1, ff_opus_deemph_weights, MAX_SIZE);
if (!float_near_abs_eps(coeff0, coeff1, EPS) ||
!float_near_abs_eps_array(dst0, dst1, EPS, MAX_SIZE))
fail();
bench_new(dst1, src, coeff1, MAX_SIZE);
bench_new(dst1, src, coeff1, ff_opus_deemph_weights, MAX_SIZE);
}
void checkasm_check_opusdsp(void)