libopusdec.c
Go to the documentation of this file.
1 /*
2  * Opus decoder using libopus
3  * Copyright (c) 2012 Nicolas George
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include <opus.h>
23 #include <opus_multistream.h>
24 
25 #include "libavutil/avassert.h"
26 #include "libavutil/intreadwrite.h"
27 #include "avcodec.h"
28 #include "internal.h"
29 #include "vorbis.h"
30 #include "mathops.h"
31 #include "libopus.h"
32 
34  OpusMSDecoder *dec;
35  int pre_skip;
36 #ifndef OPUS_SET_GAIN
37  union { int i; double d; } gain;
38 #endif
39 };
40 
41 #define OPUS_HEAD_SIZE 19
42 
44 {
45  struct libopus_context *opus = avc->priv_data;
46  int ret, channel_map = 0, gain_db = 0, nb_streams, nb_coupled;
47  uint8_t mapping_arr[8] = { 0, 1 }, *mapping;
48 
49  avc->sample_rate = 48000;
52  avc->channel_layout = avc->channels > 8 ? 0 :
54 
55  if (avc->extradata_size >= OPUS_HEAD_SIZE) {
56  opus->pre_skip = AV_RL16(avc->extradata + 10);
57  gain_db = sign_extend(AV_RL16(avc->extradata + 16), 16);
58  channel_map = AV_RL8 (avc->extradata + 18);
59  }
60  if (avc->extradata_size >= OPUS_HEAD_SIZE + 2 + avc->channels) {
61  nb_streams = avc->extradata[OPUS_HEAD_SIZE + 0];
62  nb_coupled = avc->extradata[OPUS_HEAD_SIZE + 1];
63  if (nb_streams + nb_coupled != avc->channels)
64  av_log(avc, AV_LOG_WARNING, "Inconsistent channel mapping.\n");
65  mapping = avc->extradata + OPUS_HEAD_SIZE + 2;
66  } else {
67  if (avc->channels > 2 || channel_map) {
68  av_log(avc, AV_LOG_ERROR,
69  "No channel mapping for %d channels.\n", avc->channels);
70  return AVERROR(EINVAL);
71  }
72  nb_streams = 1;
73  nb_coupled = avc->channels > 1;
74  mapping = mapping_arr;
75  }
76 
77  if (avc->channels > 2 && avc->channels <= 8) {
78  const uint8_t *vorbis_offset = ff_vorbis_channel_layout_offsets[avc->channels - 1];
79  int ch;
80 
81  /* Remap channels from vorbis order to ffmpeg order */
82  for (ch = 0; ch < avc->channels; ch++)
83  mapping_arr[ch] = mapping[vorbis_offset[ch]];
84  mapping = mapping_arr;
85  }
86 
87  opus->dec = opus_multistream_decoder_create(avc->sample_rate, avc->channels,
88  nb_streams, nb_coupled,
89  mapping, &ret);
90  if (!opus->dec) {
91  av_log(avc, AV_LOG_ERROR, "Unable to create decoder: %s\n",
92  opus_strerror(ret));
93  return ff_opus_error_to_averror(ret);
94  }
95 
96 #ifdef OPUS_SET_GAIN
97  ret = opus_multistream_decoder_ctl(opus->dec, OPUS_SET_GAIN(gain_db));
98  if (ret != OPUS_OK)
99  av_log(avc, AV_LOG_WARNING, "Failed to set gain: %s\n",
100  opus_strerror(ret));
101 #else
102  {
103  double gain_lin = pow(10, gain_db / (20.0 * 256));
104  if (avc->sample_fmt == AV_SAMPLE_FMT_FLT)
105  opus->gain.d = gain_lin;
106  else
107  opus->gain.i = FFMIN(gain_lin * 65536, INT_MAX);
108  }
109 #endif
110 
111  avc->internal->skip_samples = opus->pre_skip;
112  avc->delay = 3840; /* Decoder delay (in samples) at 48kHz */
113 
114  return 0;
115 }
116 
118 {
119  struct libopus_context *opus = avc->priv_data;
120 
121  opus_multistream_decoder_destroy(opus->dec);
122  return 0;
123 }
124 
125 #define MAX_FRAME_SIZE (960 * 6)
126 
127 static int libopus_decode(AVCodecContext *avc, void *data,
128  int *got_frame_ptr, AVPacket *pkt)
129 {
130  struct libopus_context *opus = avc->priv_data;
131  AVFrame *frame = data;
132  int ret, nb_samples;
133 
134  frame->nb_samples = MAX_FRAME_SIZE;
135  if ((ret = ff_get_buffer(avc, frame, 0)) < 0)
136  return ret;
137 
138  if (avc->sample_fmt == AV_SAMPLE_FMT_S16)
139  nb_samples = opus_multistream_decode(opus->dec, pkt->data, pkt->size,
140  (opus_int16 *)frame->data[0],
141  frame->nb_samples, 0);
142  else
143  nb_samples = opus_multistream_decode_float(opus->dec, pkt->data, pkt->size,
144  (float *)frame->data[0],
145  frame->nb_samples, 0);
146 
147  if (nb_samples < 0) {
148  av_log(avc, AV_LOG_ERROR, "Decoding error: %s\n",
149  opus_strerror(nb_samples));
150  return ff_opus_error_to_averror(nb_samples);
151  }
152 
153 #ifndef OPUS_SET_GAIN
154  {
155  int i = avc->channels * nb_samples;
156  if (avc->sample_fmt == AV_SAMPLE_FMT_FLT) {
157  float *pcm = (float *)frame->data[0];
158  for (; i > 0; i--, pcm++)
159  *pcm = av_clipf(*pcm * opus->gain.d, -1, 1);
160  } else {
161  int16_t *pcm = (int16_t *)frame->data[0];
162  for (; i > 0; i--, pcm++)
163  *pcm = av_clip_int16(((int64_t)opus->gain.i * *pcm) >> 16);
164  }
165  }
166 #endif
167 
168  frame->nb_samples = nb_samples;
169  *got_frame_ptr = 1;
170 
171  return pkt->size;
172 }
173 
174 static void libopus_flush(AVCodecContext *avc)
175 {
176  struct libopus_context *opus = avc->priv_data;
177 
178  opus_multistream_decoder_ctl(opus->dec, OPUS_RESET_STATE);
179  /* The stream can have been extracted by a tool that is not Opus-aware.
180  Therefore, any packet can become the first of the stream. */
181  avc->internal->skip_samples = opus->pre_skip;
182 }
183 
185  .name = "libopus",
186  .type = AVMEDIA_TYPE_AUDIO,
187  .id = AV_CODEC_ID_OPUS,
188  .priv_data_size = sizeof(struct libopus_context),
189  .init = libopus_decode_init,
190  .close = libopus_decode_close,
191  .decode = libopus_decode,
192  .flush = libopus_flush,
193  .capabilities = CODEC_CAP_DR1,
194  .long_name = NULL_IF_CONFIG_SMALL("libopus Opus"),
195  .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
198 };
static int libopus_decode(AVCodecContext *avc, void *data, int *got_frame_ptr, AVPacket *pkt)
Definition: libopusdec.c:127
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
#define AV_RL16
signed 16 bits
Definition: samplefmt.h:52
AVCodec ff_libopus_decoder
Definition: libopusdec.c:184
int ff_opus_error_to_averror(int err)
Definition: libopus.c:28
enum AVSampleFormat sample_fmt
audio sample format
uint8_t
#define av_cold
Definition: attributes.h:78
static AVPacket pkt
Definition: demuxing.c:56
#define MAX_FRAME_SIZE
Definition: libopusdec.c:125
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
uint8_t * data
frame
Definition: stft.m:14
#define AV_RL8(x)
Definition: intreadwrite.h:390
OpusMSDecoder * dec
Definition: libopusdec.c:34
enum AVSampleFormat request_sample_fmt
desired sample format
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Spectrum Plot time data
simple assert() macros that are a bit more flexible than ISO C assert().
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
external API header
uint64_t channel_layout
Audio channel layout.
#define FFMIN(a, b)
Definition: common.h:58
ret
Definition: avfilter.c:821
static av_cold int libopus_decode_init(AVCodecContext *avc)
Definition: libopusdec.c:43
Harmonics mapping(fx) Xmag(ploc)
union libopus_context::@66 gain
int sample_rate
samples per second
main external API structure.
const uint64_t ff_vorbis_channel_layouts[9]
Definition: vorbis_data.c:47
static void libopus_flush(AVCodecContext *avc)
Definition: libopusdec.c:174
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
int skip_samples
Number of audio samples to skip at the start of the next decoded frame.
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
#define OPUS_HEAD_SIZE
Definition: libopusdec.c:41
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:123
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
common internal api header.
AVSampleFormat
Audio Sample Formats.
Definition: samplefmt.h:49
int channels
number of audio channels
struct AVCodecInternal * internal
Private context used for internal data.
static av_cold int libopus_decode_close(AVCodecContext *avc)
Definition: libopusdec.c:117
const uint8_t ff_vorbis_channel_layout_offsets[8][8]
Definition: vorbis_data.c:25
This structure stores compressed data.
int delay
Codec delay.
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:127
for(j=16;j >0;--j)