Bug Summary

File:root/firefox-clang/media/ffvpx/libavcodec/libvorbisenc.c
Warning:line 208, column 10
Although the value stored to 'ret' is used in the enclosing expression, the value is never actually read from 'ret'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name libvorbisenc.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -include libavutil_visibility.h -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D HAVE_AV_CONFIG_H -D ASSERT_LEVEL=2 -I /root/firefox-clang/media/ffvpx/libavcodec -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/media/ffvpx/libavcodec -I /root/firefox-clang/modules/fdlibm/inexact-math-override -I /root/firefox-clang/third_party/khronos/vulkan-headers/include -I /root/firefox-clang/media/mozva -I /root/firefox-clang/media/libopus/include -I /root/firefox-clang/media/libvorbis -I /root/firefox-clang/media/libvpx -I /root/firefox-clang/media/ffvpx -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=tautological-type-limit-compare -Wno-range-loop-analysis -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-unknown-warning-option -Wno-character-conversion -Wno-parentheses -Wno-pointer-sign -Wno-sign-compare -Wno-switch -Wno-type-limits -Wno-unused-function -Wno-deprecated-declarations -Wno-absolute-value -Wno-incompatible-pointer-types -Wno-string-conversion -Wno-visibility -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-09-01-224014-2642839-1 -x c /root/firefox-clang/media/ffvpx/libavcodec/libvorbisenc.c
1/*
2 * Copyright (c) 2002 Mark Hills <mark@pogo.org.uk>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <vorbis/vorbisenc.h>
22
23#include "libavutil/avassert.h"
24#include "libavutil/channel_layout.h"
25#include "libavutil/fifo.h"
26#include "libavutil/intreadwrite.h"
27#include "libavutil/mem.h"
28#include "libavutil/opt.h"
29#include "avcodec.h"
30#include "audio_frame_queue.h"
31#include "codec_internal.h"
32#include "encode.h"
33#include "version.h"
34#include "vorbis_parser.h"
35
36
37/* Number of samples the user should send in each call.
38 * This value is used because it is the LCD of all possible frame sizes, so
39 * an output packet will always start at the same point as one of the input
40 * packets.
41 */
42#define LIBVORBIS_FRAME_SIZE64 64
43
44#define BUFFER_SIZE(1024 * 64) (1024 * 64)
45
46typedef struct LibvorbisEncContext {
47 AVClass *av_class; /**< class for AVOptions */
48 vorbis_info vi; /**< vorbis_info used during init */
49 vorbis_dsp_state vd; /**< DSP state used for analysis */
50 vorbis_block vb; /**< vorbis_block used for analysis */
51 AVFifo *pkt_fifo; /**< output packet buffer */
52 int eof; /**< end-of-file flag */
53 int dsp_initialized; /**< vd has been initialized */
54 vorbis_comment vc; /**< VorbisComment info */
55 double iblock; /**< impulse block bias option */
56 AVVorbisParseContext *vp; /**< parse context to get durations */
57 AudioFrameQueue afq; /**< frame queue for timestamps */
58} LibvorbisEncContext;
59
60static const AVOption options[] = {
61 { "iblock", "Sets the impulse block bias", offsetof(LibvorbisEncContext, iblock)__builtin_offsetof(LibvorbisEncContext, iblock), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -15, 0, AV_OPT_FLAG_AUDIO_PARAM(1 << 3) | AV_OPT_FLAG_ENCODING_PARAM(1 << 0) },
62 { NULL((void*)0) }
63};
64
65static const FFCodecDefault defaults[] = {
66 { "b", "0" },
67 { NULL((void*)0) },
68};
69
70static const AVClass vorbis_class = {
71 .class_name = "libvorbis",
72 .item_name = av_default_item_name,
73 .option = options,
74 .version = LIBAVUTIL_VERSION_INT((60)<<16 | (29)<<8 | (100)),
75};
76
77static const uint8_t vorbis_encoding_channel_layout_offsets[8][8] = {
78 { 0 },
79 { 0, 1 },
80 { 0, 2, 1 },
81 { 0, 1, 2, 3 },
82 { 0, 2, 1, 3, 4 },
83 { 0, 2, 1, 4, 5, 3 },
84 { 0, 2, 1, 5, 6, 4, 3 },
85 { 0, 2, 1, 6, 7, 4, 5, 3 },
86};
87
88static int vorbis_error_to_averror(int ov_err)
89{
90 switch (ov_err) {
91 case OV_EFAULT-129: return AVERROR_BUG(-(int)(('B') | (('U') << 8) | (('G') << 16) | ((
unsigned)('!') << 24)))
;
92 case OV_EINVAL-131: return AVERROR(EINVAL)(-(22));
93 case OV_EIMPL-130: return AVERROR(EINVAL)(-(22));
94 default: return AVERROR_UNKNOWN(-(int)(('U') | (('N') << 8) | (('K') << 16) | ((
unsigned)('N') << 24)))
;
95 }
96}
97
98static av_cold__attribute__((cold)) int libvorbis_setup(vorbis_info *vi, AVCodecContext *avctx)
99{
100 LibvorbisEncContext *s = avctx->priv_data;
101 int channels = avctx->ch_layout.nb_channels;
102 double cfreq;
103 int ret;
104
105 if (avctx->flags & AV_CODEC_FLAG_QSCALE(1 << 1) || !avctx->bit_rate) {
106 /* variable bitrate
107 * NOTE: we use the oggenc range of -1 to 10 for global_quality for
108 * user convenience, but libvorbis uses -0.1 to 1.0.
109 */
110 float q = avctx->global_quality / (float)FF_QP2LAMBDA118;
111 /* default to 3 if the user did not set quality or bitrate */
112 if (!(avctx->flags & AV_CODEC_FLAG_QSCALE(1 << 1)))
113 q = 3.0;
114 if ((ret = vorbis_encode_setup_vbr(vi, channels,
115 avctx->sample_rate,
116 q / 10.0)))
117 goto error;
118 } else {
119 int minrate = avctx->rc_min_rate > 0 ? avctx->rc_min_rate : -1;
120 int maxrate = avctx->rc_max_rate > 0 ? avctx->rc_max_rate : -1;
121
122 /* average bitrate */
123 if ((ret = vorbis_encode_setup_managed(vi, channels,
124 avctx->sample_rate, maxrate,
125 avctx->bit_rate, minrate)))
126 goto error;
127
128 /* variable bitrate by estimate, disable slow rate management */
129 if (minrate == -1 && maxrate == -1)
130 if ((ret = vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET0x15, NULL((void*)0))))
131 goto error; /* should not happen */
132 }
133
134 /* cutoff frequency */
135 if (avctx->cutoff > 0) {
136 cfreq = avctx->cutoff / 1000.0;
137 if ((ret = vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET0x21, &cfreq)))
138 goto error; /* should not happen */
139 }
140
141 /* impulse block bias */
142 if (s->iblock) {
143 if ((ret = vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET0x31, &s->iblock)))
144 goto error;
145 }
146
147 if ((channels == 3 &&
148 av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_SURROUND{ AV_CHANNEL_ORDER_NATIVE, (3), { (((1ULL << AV_CHAN_FRONT_LEFT
)|(1ULL << AV_CHAN_FRONT_RIGHT ))|(1ULL << AV_CHAN_FRONT_CENTER
)) }, ((void*)0) }
)) ||
149 (channels == 4 &&
150 av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_2_2{ AV_CHANNEL_ORDER_NATIVE, (4), { (((1ULL << AV_CHAN_FRONT_LEFT
)|(1ULL << AV_CHAN_FRONT_RIGHT ))|(1ULL << AV_CHAN_SIDE_LEFT
)|(1ULL << AV_CHAN_SIDE_RIGHT )) }, ((void*)0) }
) &&
151 av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD{ AV_CHANNEL_ORDER_NATIVE, (4), { (((1ULL << AV_CHAN_FRONT_LEFT
)|(1ULL << AV_CHAN_FRONT_RIGHT ))|(1ULL << AV_CHAN_BACK_LEFT
)|(1ULL << AV_CHAN_BACK_RIGHT )) }, ((void*)0) }
)) ||
152 (channels == 5 &&
153 av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0{ AV_CHANNEL_ORDER_NATIVE, (5), { ((((1ULL << AV_CHAN_FRONT_LEFT
)|(1ULL << AV_CHAN_FRONT_RIGHT ))|(1ULL << AV_CHAN_FRONT_CENTER
))|(1ULL << AV_CHAN_SIDE_LEFT )|(1ULL << AV_CHAN_SIDE_RIGHT
)) }, ((void*)0) }
) &&
154 av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0_BACK{ AV_CHANNEL_ORDER_NATIVE, (5), { ((((1ULL << AV_CHAN_FRONT_LEFT
)|(1ULL << AV_CHAN_FRONT_RIGHT ))|(1ULL << AV_CHAN_FRONT_CENTER
))|(1ULL << AV_CHAN_BACK_LEFT )|(1ULL << AV_CHAN_BACK_RIGHT
)) }, ((void*)0) }
)) ||
155 (channels == 6 &&
156 av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1{ AV_CHANNEL_ORDER_NATIVE, (6), { (((((1ULL << AV_CHAN_FRONT_LEFT
)|(1ULL << AV_CHAN_FRONT_RIGHT ))|(1ULL << AV_CHAN_FRONT_CENTER
))|(1ULL << AV_CHAN_SIDE_LEFT )|(1ULL << AV_CHAN_SIDE_RIGHT
))|(1ULL << AV_CHAN_LOW_FREQUENCY )) }, ((void*)0) }
) &&
157 av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK{ AV_CHANNEL_ORDER_NATIVE, (6), { (((((1ULL << AV_CHAN_FRONT_LEFT
)|(1ULL << AV_CHAN_FRONT_RIGHT ))|(1ULL << AV_CHAN_FRONT_CENTER
))|(1ULL << AV_CHAN_BACK_LEFT )|(1ULL << AV_CHAN_BACK_RIGHT
))|(1ULL << AV_CHAN_LOW_FREQUENCY )) }, ((void*)0) }
)) ||
158 (channels == 7 &&
159 av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_6POINT1{ AV_CHANNEL_ORDER_NATIVE, (7), { ((((((1ULL << AV_CHAN_FRONT_LEFT
)|(1ULL << AV_CHAN_FRONT_RIGHT ))|(1ULL << AV_CHAN_FRONT_CENTER
))|(1ULL << AV_CHAN_SIDE_LEFT )|(1ULL << AV_CHAN_SIDE_RIGHT
))|(1ULL << AV_CHAN_LOW_FREQUENCY ))|(1ULL << AV_CHAN_BACK_CENTER
)) }, ((void*)0) }
)) ||
160 (channels == 8 &&
161 av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_7POINT1{ AV_CHANNEL_ORDER_NATIVE, (8), { ((((((1ULL << AV_CHAN_FRONT_LEFT
)|(1ULL << AV_CHAN_FRONT_RIGHT ))|(1ULL << AV_CHAN_FRONT_CENTER
))|(1ULL << AV_CHAN_SIDE_LEFT )|(1ULL << AV_CHAN_SIDE_RIGHT
))|(1ULL << AV_CHAN_LOW_FREQUENCY ))|(1ULL << AV_CHAN_BACK_LEFT
)|(1ULL << AV_CHAN_BACK_RIGHT )) }, ((void*)0) }
))) {
162 if (avctx->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
163 char name[32];
164 av_channel_layout_describe(&avctx->ch_layout, name, sizeof(name));
165 av_log(avctx, AV_LOG_ERROR16, "%s not supported by Vorbis: "
166 "output stream will have incorrect "
167 "channel layout.\n", name);
168 } else {
169 av_log(avctx, AV_LOG_WARNING24, "No channel layout specified. The encoder "
170 "will use Vorbis channel layout for "
171 "%d channels.\n", channels);
172 }
173 }
174
175 if ((ret = vorbis_encode_setup_init(vi)))
176 goto error;
177
178 return 0;
179error:
180 return vorbis_error_to_averror(ret);
181}
182
183static av_cold__attribute__((cold)) int libvorbis_get_priming_samples(vorbis_info *vi, AVCodecContext *avctx)
184{
185 LibvorbisEncContext *s = avctx->priv_data;
186 vorbis_dsp_state vd;
187 vorbis_block vb;
188 ogg_packet op;
189 int ret;
190
191 if ((ret = vorbis_analysis_init(&vd, vi))) {
192 av_log(avctx, AV_LOG_ERROR16, "analysis init failed\n");
193 return vorbis_error_to_averror(ret);
194 }
195 if ((ret = vorbis_block_init(&vd, &vb))) {
196 av_log(avctx, AV_LOG_ERROR16, "dsp init failed\n");
197 vorbis_dsp_clear(&vd);
198 return vorbis_error_to_averror(ret);
199 }
200
201 if ((ret = vorbis_analysis_wrote(&vd, 0)) < 0) {
202 av_log(avctx, AV_LOG_ERROR16, "error in vorbis_analysis_wrote() during init\n");
203 ret = vorbis_error_to_averror(ret);
204 goto error;
205 }
206
207 /* retrieve available packets from libvorbis */
208 if ((ret = vorbis_analysis_blockout(&vd, &vb)) == 1) {
Although the value stored to 'ret' is used in the enclosing expression, the value is never actually read from 'ret'
209 if ((ret = vorbis_analysis(&vb, NULL((void*)0))) < 0) {
210 av_log(avctx, AV_LOG_ERROR16, "error in vorbis_analysis_blockout() during init\n");
211 ret = vorbis_error_to_averror(ret);
212 goto error;
213 }
214 if ((ret = vorbis_bitrate_addblock(&vb)) < 0) {
215 av_log(avctx, AV_LOG_ERROR16, "error in vorbis_bitrate_addblock() during init\n");
216 ret = vorbis_error_to_averror(ret);
217 goto error;
218 }
219
220 /* add any available packets to the output packet buffer */
221 ret = vorbis_bitrate_flushpacket(&vd, &op);
222 if (ret < 0) {
223 av_log(avctx, AV_LOG_ERROR16, "error in vorbis_bitrate_flushpacket() during init\n");
224 ret = vorbis_error_to_averror(ret);
225 goto error;
226 }
227 }
228
229 avctx->initial_padding = av_vorbis_parse_frame(s->vp, op.packet, op.bytes);
230
231 ret = 0;
232error:
233 vorbis_block_clear(&vb);
234 vorbis_dsp_clear(&vd);
235
236 return ret;
237}
238
239/* How many bytes are needed for a buffer of length 'l' */
240static int xiph_len(int l)
241{
242 return 1 + l / 255 + l;
243}
244
245static av_cold__attribute__((cold)) int libvorbis_encode_close(AVCodecContext *avctx)
246{
247 LibvorbisEncContext *s = avctx->priv_data;
248
249 /* notify vorbisenc this is EOF */
250 if (s->dsp_initialized)
251 vorbis_analysis_wrote(&s->vd, 0);
252
253 vorbis_block_clear(&s->vb);
254 vorbis_dsp_clear(&s->vd);
255 vorbis_info_clear(&s->vi);
256
257 av_fifo_freep2(&s->pkt_fifo);
258 ff_af_queue_close(&s->afq);
259
260 av_vorbis_parse_free(&s->vp);
261
262 return 0;
263}
264
265static av_cold__attribute__((cold)) int libvorbis_encode_init(AVCodecContext *avctx)
266{
267 LibvorbisEncContext *s = avctx->priv_data;
268 ogg_packet header, header_comm, header_code;
269 uint8_t *p;
270 unsigned int offset;
271 int ret;
272
273 vorbis_info_init(&s->vi);
274 if ((ret = libvorbis_setup(&s->vi, avctx))) {
275 av_log(avctx, AV_LOG_ERROR16, "encoder setup failed\n");
276 goto error;
277 }
278 if ((ret = vorbis_analysis_init(&s->vd, &s->vi))) {
279 av_log(avctx, AV_LOG_ERROR16, "analysis init failed\n");
280 ret = vorbis_error_to_averror(ret);
281 goto error;
282 }
283 s->dsp_initialized = 1;
284 if ((ret = vorbis_block_init(&s->vd, &s->vb))) {
285 av_log(avctx, AV_LOG_ERROR16, "dsp init failed\n");
286 ret = vorbis_error_to_averror(ret);
287 goto error;
288 }
289
290 vorbis_comment_init(&s->vc);
291 if (!(avctx->flags & AV_CODEC_FLAG_BITEXACT(1 << 23)))
292 vorbis_comment_add_tag(&s->vc, "encoder", LIBAVCODEC_IDENT"Lavc" "62.29.101");
293
294 if ((ret = vorbis_analysis_headerout(&s->vd, &s->vc, &header, &header_comm,
295 &header_code))) {
296 ret = vorbis_error_to_averror(ret);
297 goto error;
298 }
299
300 avctx->extradata_size = 1 + xiph_len(header.bytes) +
301 xiph_len(header_comm.bytes) +
302 header_code.bytes;
303 p = avctx->extradata = av_malloc(avctx->extradata_size +
304 AV_INPUT_BUFFER_PADDING_SIZE64);
305 if (!p) {
306 ret = AVERROR(ENOMEM)(-(12));
307 goto error;
308 }
309 p[0] = 2;
310 offset = 1;
311 offset += av_xiphlacing(&p[offset], header.bytes);
312 offset += av_xiphlacing(&p[offset], header_comm.bytes);
313 memcpy(&p[offset], header.packet, header.bytes);
314 offset += header.bytes;
315 memcpy(&p[offset], header_comm.packet, header_comm.bytes);
316 offset += header_comm.bytes;
317 memcpy(&p[offset], header_code.packet, header_code.bytes);
318 offset += header_code.bytes;
319 av_assert0(offset == avctx->extradata_size)do { if (!(offset == avctx->extradata_size)) { av_log(((void
*)0), 0, "Assertion %s failed at %s:%d\n", "offset == avctx->extradata_size"
, "/root/firefox-clang/media/ffvpx/libavcodec/libvorbisenc.c"
, 319); abort(); } } while (0)
;
320
321 s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size);
322 if (!s->vp) {
323 av_log(avctx, AV_LOG_ERROR16, "invalid extradata\n");
324 return ret;
325 }
326
327 vorbis_comment_clear(&s->vc);
328
329 if ((ret = libvorbis_get_priming_samples(&s->vi, avctx)))
330 return ret;
331
332 avctx->frame_size = LIBVORBIS_FRAME_SIZE64;
333 ff_af_queue_init(avctx, &s->afq);
334
335 s->pkt_fifo = av_fifo_alloc2(BUFFER_SIZE(1024 * 64), 1, 0);
336 if (!s->pkt_fifo) {
337 ret = AVERROR(ENOMEM)(-(12));
338 goto error;
339 }
340
341 return 0;
342error:
343 libvorbis_encode_close(avctx);
344 return ret;
345}
346
347static int libvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
348 const AVFrame *frame, int *got_packet_ptr)
349{
350 LibvorbisEncContext *s = avctx->priv_data;
351 ogg_packet op;
352 int ret, duration;
353
354 /* send samples to libvorbis */
355 if (frame) {
356 const int samples = frame->nb_samples;
357 float **buffer;
358 int c, channels = s->vi.channels;
359
360 buffer = vorbis_analysis_buffer(&s->vd, samples);
361 for (c = 0; c < channels; c++) {
362 int co = (channels > 8) ? c :
363 vorbis_encoding_channel_layout_offsets[channels - 1][c];
364 memcpy(buffer[c], frame->extended_data[co],
365 samples * sizeof(*buffer[c]));
366 }
367 if ((ret = vorbis_analysis_wrote(&s->vd, samples)) < 0) {
368 av_log(avctx, AV_LOG_ERROR16, "error in vorbis_analysis_wrote()\n");
369 return vorbis_error_to_averror(ret);
370 }
371 if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
372 return ret;
373 } else {
374 if (!s->eof && s->afq.frame_alloc)
375 if ((ret = vorbis_analysis_wrote(&s->vd, 0)) < 0) {
376 av_log(avctx, AV_LOG_ERROR16, "error in vorbis_analysis_wrote()\n");
377 return vorbis_error_to_averror(ret);
378 }
379 s->eof = 1;
380 }
381
382 /* retrieve available packets from libvorbis */
383 while ((ret = vorbis_analysis_blockout(&s->vd, &s->vb)) == 1) {
384 if ((ret = vorbis_analysis(&s->vb, NULL((void*)0))) < 0)
385 break;
386 if ((ret = vorbis_bitrate_addblock(&s->vb)) < 0)
387 break;
388
389 /* add any available packets to the output packet buffer */
390 while ((ret = vorbis_bitrate_flushpacket(&s->vd, &op)) == 1) {
391 if (av_fifo_can_write(s->pkt_fifo) < sizeof(ogg_packet) + op.bytes) {
392 av_log(avctx, AV_LOG_ERROR16, "packet buffer is too small\n");
393 return AVERROR_BUG(-(int)(('B') | (('U') << 8) | (('G') << 16) | ((
unsigned)('!') << 24)))
;
394 }
395 av_fifo_write(s->pkt_fifo, &op, sizeof(ogg_packet));
396 av_fifo_write(s->pkt_fifo, op.packet, op.bytes);
397 }
398 if (ret < 0) {
399 av_log(avctx, AV_LOG_ERROR16, "error getting available packets\n");
400 break;
401 }
402 }
403 if (ret < 0) {
404 av_log(avctx, AV_LOG_ERROR16, "error getting available packets\n");
405 return vorbis_error_to_averror(ret);
406 }
407
408 /* Read an available packet if possible */
409 if (av_fifo_read(s->pkt_fifo, &op, sizeof(ogg_packet)) < 0)
410 return 0;
411
412 if ((ret = ff_get_encode_buffer(avctx, avpkt, op.bytes, 0)) < 0)
413 return ret;
414 av_fifo_read(s->pkt_fifo, avpkt->data, op.bytes);
415
416 avpkt->pts = ff_samples_to_time_base(avctx, op.granulepos);
417
418 duration = av_vorbis_parse_frame(s->vp, avpkt->data, avpkt->size);
419 if (duration > 0) {
420 int discard_padding;
421
422 ff_af_queue_remove(&s->afq, duration, &avpkt->pts, &avpkt->duration);
423
424 discard_padding = duration - ff_samples_from_time_base(avctx, avpkt->duration);
425 if (discard_padding > 0) {
426 uint8_t *side_data = av_packet_new_side_data(avpkt,
427 AV_PKT_DATA_SKIP_SAMPLES,
428 10);
429 if (!side_data)
430 return AVERROR(ENOMEM)(-(12));
431 AV_WL32(side_data + 4, discard_padding)((((union unaligned_32 *) (side_data + 4))->l) = (discard_padding
))
;
432 }
433 }
434
435 *got_packet_ptr = 1;
436 return 0;
437}
438
439const FFCodec ff_libvorbis_encoder = {
440 .p.name = "libvorbis",
441 CODEC_LONG_NAME("libvorbis").p.long_name = "libvorbis",
442 .p.type = AVMEDIA_TYPE_AUDIO,
443 .p.id = AV_CODEC_ID_VORBIS,
444 .p.capabilities = AV_CODEC_CAP_DR1(1 << 1) | AV_CODEC_CAP_DELAY(1 << 5) |
445 AV_CODEC_CAP_SMALL_LAST_FRAME(1 << 6),
446 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE(1 << 0),
447 .priv_data_size = sizeof(LibvorbisEncContext),
448 .init = libvorbis_encode_init,
449 FF_CODEC_ENCODE_CB(libvorbis_encode_frame).is_decoder = 0, .cb_type = FF_CODEC_CB_TYPE_ENCODE, .cb.encode
= (libvorbis_encode_frame)
,
450 .close = libvorbis_encode_close,
451 CODEC_SAMPLEFMTS(AV_SAMPLE_FMT_FLTP)GCC diagnostic push GCC diagnostic ignored "-Wdeprecated-declarations"
.p.sample_fmts = ((((const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP
, AV_SAMPLE_FMT_NONE }))) GCC diagnostic pop
,
452 .p.priv_class = &vorbis_class,
453 .defaults = defaults,
454 .p.wrapper_name = "libvorbis",
455};