Commit | Line | Data |
---|---|---|
2ba45a60 DM |
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/fifo.h" | |
25 | #include "libavutil/opt.h" | |
26 | #include "avcodec.h" | |
27 | #include "audio_frame_queue.h" | |
28 | #include "internal.h" | |
29 | #include "vorbis.h" | |
30 | #include "vorbis_parser.h" | |
31 | ||
32 | ||
33 | /* Number of samples the user should send in each call. | |
34 | * This value is used because it is the LCD of all possible frame sizes, so | |
35 | * an output packet will always start at the same point as one of the input | |
36 | * packets. | |
37 | */ | |
38 | #define LIBVORBIS_FRAME_SIZE 64 | |
39 | ||
40 | #define BUFFER_SIZE (1024 * 64) | |
41 | ||
42 | typedef struct LibvorbisEncContext { | |
43 | AVClass *av_class; /**< class for AVOptions */ | |
44 | vorbis_info vi; /**< vorbis_info used during init */ | |
45 | vorbis_dsp_state vd; /**< DSP state used for analysis */ | |
46 | vorbis_block vb; /**< vorbis_block used for analysis */ | |
47 | AVFifoBuffer *pkt_fifo; /**< output packet buffer */ | |
48 | int eof; /**< end-of-file flag */ | |
49 | int dsp_initialized; /**< vd has been initialized */ | |
50 | vorbis_comment vc; /**< VorbisComment info */ | |
51 | double iblock; /**< impulse block bias option */ | |
f6fa7814 | 52 | AVVorbisParseContext *vp; /**< parse context to get durations */ |
2ba45a60 DM |
53 | AudioFrameQueue afq; /**< frame queue for timestamps */ |
54 | } LibvorbisEncContext; | |
55 | ||
56 | static const AVOption options[] = { | |
57 | { "iblock", "Sets the impulse block bias", offsetof(LibvorbisEncContext, iblock), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -15, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, | |
58 | { NULL } | |
59 | }; | |
60 | ||
61 | static const AVCodecDefault defaults[] = { | |
62 | { "b", "0" }, | |
63 | { NULL }, | |
64 | }; | |
65 | ||
66 | static const AVClass vorbis_class = { | |
67 | .class_name = "libvorbis", | |
68 | .item_name = av_default_item_name, | |
69 | .option = options, | |
70 | .version = LIBAVUTIL_VERSION_INT, | |
71 | }; | |
72 | ||
73 | static int vorbis_error_to_averror(int ov_err) | |
74 | { | |
75 | switch (ov_err) { | |
76 | case OV_EFAULT: return AVERROR_BUG; | |
77 | case OV_EINVAL: return AVERROR(EINVAL); | |
78 | case OV_EIMPL: return AVERROR(EINVAL); | |
79 | default: return AVERROR_UNKNOWN; | |
80 | } | |
81 | } | |
82 | ||
83 | static av_cold int libvorbis_setup(vorbis_info *vi, AVCodecContext *avctx) | |
84 | { | |
85 | LibvorbisEncContext *s = avctx->priv_data; | |
86 | double cfreq; | |
87 | int ret; | |
88 | ||
89 | if (avctx->flags & CODEC_FLAG_QSCALE || !avctx->bit_rate) { | |
90 | /* variable bitrate | |
91 | * NOTE: we use the oggenc range of -1 to 10 for global_quality for | |
92 | * user convenience, but libvorbis uses -0.1 to 1.0. | |
93 | */ | |
94 | float q = avctx->global_quality / (float)FF_QP2LAMBDA; | |
95 | /* default to 3 if the user did not set quality or bitrate */ | |
96 | if (!(avctx->flags & CODEC_FLAG_QSCALE)) | |
97 | q = 3.0; | |
98 | if ((ret = vorbis_encode_setup_vbr(vi, avctx->channels, | |
99 | avctx->sample_rate, | |
100 | q / 10.0))) | |
101 | goto error; | |
102 | } else { | |
103 | int minrate = avctx->rc_min_rate > 0 ? avctx->rc_min_rate : -1; | |
104 | int maxrate = avctx->rc_max_rate > 0 ? avctx->rc_max_rate : -1; | |
105 | ||
106 | /* average bitrate */ | |
107 | if ((ret = vorbis_encode_setup_managed(vi, avctx->channels, | |
108 | avctx->sample_rate, maxrate, | |
109 | avctx->bit_rate, minrate))) | |
110 | goto error; | |
111 | ||
112 | /* variable bitrate by estimate, disable slow rate management */ | |
113 | if (minrate == -1 && maxrate == -1) | |
114 | if ((ret = vorbis_encode_ctl(vi, OV_ECTL_RATEMANAGE2_SET, NULL))) | |
115 | goto error; /* should not happen */ | |
116 | } | |
117 | ||
118 | /* cutoff frequency */ | |
119 | if (avctx->cutoff > 0) { | |
120 | cfreq = avctx->cutoff / 1000.0; | |
121 | if ((ret = vorbis_encode_ctl(vi, OV_ECTL_LOWPASS_SET, &cfreq))) | |
122 | goto error; /* should not happen */ | |
123 | } | |
124 | ||
125 | /* impulse block bias */ | |
126 | if (s->iblock) { | |
127 | if ((ret = vorbis_encode_ctl(vi, OV_ECTL_IBLOCK_SET, &s->iblock))) | |
128 | goto error; | |
129 | } | |
130 | ||
131 | if (avctx->channels == 3 && | |
132 | avctx->channel_layout != (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER) || | |
133 | avctx->channels == 4 && | |
134 | avctx->channel_layout != AV_CH_LAYOUT_2_2 && | |
135 | avctx->channel_layout != AV_CH_LAYOUT_QUAD || | |
136 | avctx->channels == 5 && | |
137 | avctx->channel_layout != AV_CH_LAYOUT_5POINT0 && | |
138 | avctx->channel_layout != AV_CH_LAYOUT_5POINT0_BACK || | |
139 | avctx->channels == 6 && | |
140 | avctx->channel_layout != AV_CH_LAYOUT_5POINT1 && | |
141 | avctx->channel_layout != AV_CH_LAYOUT_5POINT1_BACK || | |
142 | avctx->channels == 7 && | |
143 | avctx->channel_layout != (AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER) || | |
144 | avctx->channels == 8 && | |
145 | avctx->channel_layout != AV_CH_LAYOUT_7POINT1) { | |
146 | if (avctx->channel_layout) { | |
147 | char name[32]; | |
148 | av_get_channel_layout_string(name, sizeof(name), avctx->channels, | |
149 | avctx->channel_layout); | |
150 | av_log(avctx, AV_LOG_ERROR, "%s not supported by Vorbis: " | |
151 | "output stream will have incorrect " | |
152 | "channel layout.\n", name); | |
153 | } else { | |
154 | av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The encoder " | |
155 | "will use Vorbis channel layout for " | |
156 | "%d channels.\n", avctx->channels); | |
157 | } | |
158 | } | |
159 | ||
160 | if ((ret = vorbis_encode_setup_init(vi))) | |
161 | goto error; | |
162 | ||
163 | return 0; | |
164 | error: | |
165 | return vorbis_error_to_averror(ret); | |
166 | } | |
167 | ||
168 | /* How many bytes are needed for a buffer of length 'l' */ | |
169 | static int xiph_len(int l) | |
170 | { | |
171 | return 1 + l / 255 + l; | |
172 | } | |
173 | ||
174 | static av_cold int libvorbis_encode_close(AVCodecContext *avctx) | |
175 | { | |
176 | LibvorbisEncContext *s = avctx->priv_data; | |
177 | ||
178 | /* notify vorbisenc this is EOF */ | |
179 | if (s->dsp_initialized) | |
180 | vorbis_analysis_wrote(&s->vd, 0); | |
181 | ||
182 | vorbis_block_clear(&s->vb); | |
183 | vorbis_dsp_clear(&s->vd); | |
184 | vorbis_info_clear(&s->vi); | |
185 | ||
186 | av_fifo_freep(&s->pkt_fifo); | |
187 | ff_af_queue_close(&s->afq); | |
188 | av_freep(&avctx->extradata); | |
189 | ||
f6fa7814 DM |
190 | av_vorbis_parse_free(&s->vp); |
191 | ||
2ba45a60 DM |
192 | return 0; |
193 | } | |
194 | ||
195 | static av_cold int libvorbis_encode_init(AVCodecContext *avctx) | |
196 | { | |
197 | LibvorbisEncContext *s = avctx->priv_data; | |
198 | ogg_packet header, header_comm, header_code; | |
199 | uint8_t *p; | |
200 | unsigned int offset; | |
201 | int ret; | |
202 | ||
203 | vorbis_info_init(&s->vi); | |
204 | if ((ret = libvorbis_setup(&s->vi, avctx))) { | |
205 | av_log(avctx, AV_LOG_ERROR, "encoder setup failed\n"); | |
206 | goto error; | |
207 | } | |
208 | if ((ret = vorbis_analysis_init(&s->vd, &s->vi))) { | |
209 | av_log(avctx, AV_LOG_ERROR, "analysis init failed\n"); | |
210 | ret = vorbis_error_to_averror(ret); | |
211 | goto error; | |
212 | } | |
213 | s->dsp_initialized = 1; | |
214 | if ((ret = vorbis_block_init(&s->vd, &s->vb))) { | |
215 | av_log(avctx, AV_LOG_ERROR, "dsp init failed\n"); | |
216 | ret = vorbis_error_to_averror(ret); | |
217 | goto error; | |
218 | } | |
219 | ||
220 | vorbis_comment_init(&s->vc); | |
221 | if (!(avctx->flags & CODEC_FLAG_BITEXACT)) | |
222 | vorbis_comment_add_tag(&s->vc, "encoder", LIBAVCODEC_IDENT); | |
223 | ||
224 | if ((ret = vorbis_analysis_headerout(&s->vd, &s->vc, &header, &header_comm, | |
225 | &header_code))) { | |
226 | ret = vorbis_error_to_averror(ret); | |
227 | goto error; | |
228 | } | |
229 | ||
230 | avctx->extradata_size = 1 + xiph_len(header.bytes) + | |
231 | xiph_len(header_comm.bytes) + | |
232 | header_code.bytes; | |
233 | p = avctx->extradata = av_malloc(avctx->extradata_size + | |
234 | FF_INPUT_BUFFER_PADDING_SIZE); | |
235 | if (!p) { | |
236 | ret = AVERROR(ENOMEM); | |
237 | goto error; | |
238 | } | |
239 | p[0] = 2; | |
240 | offset = 1; | |
241 | offset += av_xiphlacing(&p[offset], header.bytes); | |
242 | offset += av_xiphlacing(&p[offset], header_comm.bytes); | |
243 | memcpy(&p[offset], header.packet, header.bytes); | |
244 | offset += header.bytes; | |
245 | memcpy(&p[offset], header_comm.packet, header_comm.bytes); | |
246 | offset += header_comm.bytes; | |
247 | memcpy(&p[offset], header_code.packet, header_code.bytes); | |
248 | offset += header_code.bytes; | |
249 | av_assert0(offset == avctx->extradata_size); | |
250 | ||
f6fa7814 DM |
251 | s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size); |
252 | if (!s->vp) { | |
2ba45a60 DM |
253 | av_log(avctx, AV_LOG_ERROR, "invalid extradata\n"); |
254 | return ret; | |
255 | } | |
256 | ||
257 | vorbis_comment_clear(&s->vc); | |
258 | ||
259 | avctx->frame_size = LIBVORBIS_FRAME_SIZE; | |
260 | ff_af_queue_init(avctx, &s->afq); | |
261 | ||
262 | s->pkt_fifo = av_fifo_alloc(BUFFER_SIZE); | |
263 | if (!s->pkt_fifo) { | |
264 | ret = AVERROR(ENOMEM); | |
265 | goto error; | |
266 | } | |
267 | ||
268 | return 0; | |
269 | error: | |
270 | libvorbis_encode_close(avctx); | |
271 | return ret; | |
272 | } | |
273 | ||
274 | static int libvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, | |
275 | const AVFrame *frame, int *got_packet_ptr) | |
276 | { | |
277 | LibvorbisEncContext *s = avctx->priv_data; | |
278 | ogg_packet op; | |
279 | int ret, duration; | |
280 | ||
281 | /* send samples to libvorbis */ | |
282 | if (frame) { | |
283 | const int samples = frame->nb_samples; | |
284 | float **buffer; | |
285 | int c, channels = s->vi.channels; | |
286 | ||
287 | buffer = vorbis_analysis_buffer(&s->vd, samples); | |
288 | for (c = 0; c < channels; c++) { | |
289 | int co = (channels > 8) ? c : | |
290 | ff_vorbis_encoding_channel_layout_offsets[channels - 1][c]; | |
291 | memcpy(buffer[c], frame->extended_data[co], | |
292 | samples * sizeof(*buffer[c])); | |
293 | } | |
294 | if ((ret = vorbis_analysis_wrote(&s->vd, samples)) < 0) { | |
295 | av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n"); | |
296 | return vorbis_error_to_averror(ret); | |
297 | } | |
298 | if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) | |
299 | return ret; | |
300 | } else { | |
301 | if (!s->eof && s->afq.frame_alloc) | |
302 | if ((ret = vorbis_analysis_wrote(&s->vd, 0)) < 0) { | |
303 | av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n"); | |
304 | return vorbis_error_to_averror(ret); | |
305 | } | |
306 | s->eof = 1; | |
307 | } | |
308 | ||
309 | /* retrieve available packets from libvorbis */ | |
310 | while ((ret = vorbis_analysis_blockout(&s->vd, &s->vb)) == 1) { | |
311 | if ((ret = vorbis_analysis(&s->vb, NULL)) < 0) | |
312 | break; | |
313 | if ((ret = vorbis_bitrate_addblock(&s->vb)) < 0) | |
314 | break; | |
315 | ||
316 | /* add any available packets to the output packet buffer */ | |
317 | while ((ret = vorbis_bitrate_flushpacket(&s->vd, &op)) == 1) { | |
318 | if (av_fifo_space(s->pkt_fifo) < sizeof(ogg_packet) + op.bytes) { | |
319 | av_log(avctx, AV_LOG_ERROR, "packet buffer is too small\n"); | |
320 | return AVERROR_BUG; | |
321 | } | |
322 | av_fifo_generic_write(s->pkt_fifo, &op, sizeof(ogg_packet), NULL); | |
323 | av_fifo_generic_write(s->pkt_fifo, op.packet, op.bytes, NULL); | |
324 | } | |
325 | if (ret < 0) { | |
326 | av_log(avctx, AV_LOG_ERROR, "error getting available packets\n"); | |
327 | break; | |
328 | } | |
329 | } | |
330 | if (ret < 0) { | |
331 | av_log(avctx, AV_LOG_ERROR, "error getting available packets\n"); | |
332 | return vorbis_error_to_averror(ret); | |
333 | } | |
334 | ||
335 | /* check for available packets */ | |
336 | if (av_fifo_size(s->pkt_fifo) < sizeof(ogg_packet)) | |
337 | return 0; | |
338 | ||
339 | av_fifo_generic_read(s->pkt_fifo, &op, sizeof(ogg_packet), NULL); | |
340 | ||
341 | if ((ret = ff_alloc_packet2(avctx, avpkt, op.bytes)) < 0) | |
342 | return ret; | |
343 | av_fifo_generic_read(s->pkt_fifo, avpkt->data, op.bytes, NULL); | |
344 | ||
345 | avpkt->pts = ff_samples_to_time_base(avctx, op.granulepos); | |
346 | ||
f6fa7814 | 347 | duration = av_vorbis_parse_frame(s->vp, avpkt->data, avpkt->size); |
2ba45a60 DM |
348 | if (duration > 0) { |
349 | /* we do not know encoder delay until we get the first packet from | |
350 | * libvorbis, so we have to update the AudioFrameQueue counts */ | |
f6fa7814 DM |
351 | if (!avctx->initial_padding && s->afq.frames) { |
352 | avctx->initial_padding = duration; | |
2ba45a60 DM |
353 | av_assert0(!s->afq.remaining_delay); |
354 | s->afq.frames->duration += duration; | |
355 | if (s->afq.frames->pts != AV_NOPTS_VALUE) | |
356 | s->afq.frames->pts -= duration; | |
357 | s->afq.remaining_samples += duration; | |
358 | } | |
359 | ff_af_queue_remove(&s->afq, duration, &avpkt->pts, &avpkt->duration); | |
360 | } | |
361 | ||
362 | *got_packet_ptr = 1; | |
363 | return 0; | |
364 | } | |
365 | ||
366 | AVCodec ff_libvorbis_encoder = { | |
367 | .name = "libvorbis", | |
368 | .long_name = NULL_IF_CONFIG_SMALL("libvorbis"), | |
369 | .type = AVMEDIA_TYPE_AUDIO, | |
370 | .id = AV_CODEC_ID_VORBIS, | |
371 | .priv_data_size = sizeof(LibvorbisEncContext), | |
372 | .init = libvorbis_encode_init, | |
373 | .encode2 = libvorbis_encode_frame, | |
374 | .close = libvorbis_encode_close, | |
f6fa7814 | 375 | .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME, |
2ba45a60 DM |
376 | .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, |
377 | AV_SAMPLE_FMT_NONE }, | |
378 | .priv_class = &vorbis_class, | |
379 | .defaults = defaults, | |
380 | }; |