summaryrefslogtreecommitdiff
path: root/libavcodec/opusdec.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-10-03 20:48:09 +0200
committerAndreas Rheinhardt <andreas.rheinhardt@outlook.com>2022-10-05 02:04:41 +0200
commit4fc2531fff112836026aad2bdaf128c9d15a72e3 (patch)
tree9e33638c4af0c03e5880bcca60a3d806cea7b788 /libavcodec/opusdec.c
parent6658028482cf3bda2a05ae7a9bf183c81f75d4bd (diff)
avcodec/opus: Move stuff shared by decoder and parser to a new file
opus.h (which is used by all the Opus code) currently includes several structures only used by the parser and the decoder; several elements of OpusContext are even only used by the decoder. This commit therefore moves the part of OpusContext that is shared between these two components (and used by ff_opus_parse_extradata()) out into a new structure and moves all the other accompanying structures and functions to a new header, opus_parse.h; the functions itself are also moved to a new file, opus_parse.c. (This also allows to remove several spurious dependencies of the Opus parser and encoder.) Reviewed-by: Lynne <dev@lynne.ee> Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
Diffstat (limited to 'libavcodec/opusdec.c')
-rw-r--r--libavcodec/opusdec.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/libavcodec/opusdec.c b/libavcodec/opusdec.c
index 87a86b6b47..e26ca0b2c3 100644
--- a/libavcodec/opusdec.c
+++ b/libavcodec/opusdec.c
@@ -38,6 +38,8 @@
#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_internal.h"
#include "libavutil/opt.h"
@@ -50,6 +52,7 @@
#include "opus.h"
#include "opustab.h"
#include "opus_celt.h"
+#include "opus_parse.h"
static const uint16_t silk_frame_duration_ms[16] = {
10, 20, 40, 60,
@@ -110,6 +113,18 @@ typedef struct OpusStreamContext {
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)
@@ -469,7 +484,7 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame,
int i, ret;
/* calculate the number of delayed samples */
- for (i = 0; i < c->nb_streams; i++) {
+ for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];
s->out[0] =
s->out[1] = NULL;
@@ -480,7 +495,7 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame,
/* 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->nb_streams > 1);
+ 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;
@@ -504,13 +519,13 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame,
frame->nb_samples = 0;
for (i = 0; i < avctx->ch_layout.nb_channels; i++) {
- ChannelMap *map = &c->channel_maps[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 (i = 0; i < c->nb_streams; i++) {
+ 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);
@@ -542,11 +557,11 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame,
}
/* decode each sub-packet */
- for (i = 0; i < c->nb_streams; i++) {
+ 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->nb_streams - 1);
+ 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;
@@ -572,7 +587,7 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame,
}
/* buffer the extra samples */
- for (i = 0; i < c->nb_streams; i++) {
+ 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) {
@@ -587,7 +602,7 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame,
}
for (i = 0; i < avctx->ch_layout.nb_channels; i++) {
- ChannelMap *map = &c->channel_maps[i];
+ ChannelMap *map = &c->p.channel_maps[i];
/* handle copied channels */
if (map->copy) {
@@ -598,7 +613,7 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame,
memset(frame->extended_data[i], 0, frame->linesize[0]);
}
- if (c->gain_i && decoded_samples > 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));
@@ -614,9 +629,8 @@ static int opus_decode_packet(AVCodecContext *avctx, AVFrame *frame,
static av_cold void opus_decode_flush(AVCodecContext *ctx)
{
OpusContext *c = ctx->priv_data;
- int i;
- for (i = 0; i < c->nb_streams; i++) {
+ for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];
memset(&s->packet, 0, sizeof(s->packet));
@@ -635,9 +649,8 @@ static av_cold void opus_decode_flush(AVCodecContext *ctx)
static av_cold int opus_decode_close(AVCodecContext *avctx)
{
OpusContext *c = avctx->priv_data;
- int i;
- for (i = 0; i < c->nb_streams; i++) {
+ for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];
ff_silk_free(&s->silk);
@@ -653,9 +666,9 @@ static av_cold int opus_decode_close(AVCodecContext *avctx)
av_freep(&c->streams);
- c->nb_streams = 0;
+ c->p.nb_streams = 0;
- av_freep(&c->channel_maps);
+ av_freep(&c->p.channel_maps);
av_freep(&c->fdsp);
return 0;
@@ -664,7 +677,7 @@ static av_cold int opus_decode_close(AVCodecContext *avctx)
static av_cold int opus_decode_init(AVCodecContext *avctx)
{
OpusContext *c = avctx->priv_data;
- int ret, i, j;
+ int ret;
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
avctx->sample_rate = 48000;
@@ -674,26 +687,28 @@ static av_cold int opus_decode_init(AVCodecContext *avctx)
return AVERROR(ENOMEM);
/* find out the channel configuration */
- ret = ff_opus_parse_extradata(avctx, c);
+ 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->nb_streams, sizeof(*c->streams));
+ c->streams = av_calloc(c->p.nb_streams, sizeof(*c->streams));
if (!c->streams) {
- c->nb_streams = 0;
+ c->p.nb_streams = 0;
return AVERROR(ENOMEM);
}
- for (i = 0; i < c->nb_streams; i++) {
+ for (int i = 0; i < c->p.nb_streams; i++) {
OpusStreamContext *s = &c->streams[i];
AVChannelLayout layout;
- s->output_channels = (i < c->nb_stereo_streams) ? 2 : 1;
+ s->output_channels = (i < c->p.nb_stereo_streams) ? 2 : 1;
s->avctx = avctx;
- for (j = 0; j < s->output_channels; j++) {
+ 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];