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 */ | |
52 | VorbisParseContext vp; /**< parse context to get durations */ | |
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 | ||
190 | return 0; | |
191 | } | |
192 | ||
193 | static av_cold int libvorbis_encode_init(AVCodecContext *avctx) | |
194 | { | |
195 | LibvorbisEncContext *s = avctx->priv_data; | |
196 | ogg_packet header, header_comm, header_code; | |
197 | uint8_t *p; | |
198 | unsigned int offset; | |
199 | int ret; | |
200 | ||
201 | vorbis_info_init(&s->vi); | |
202 | if ((ret = libvorbis_setup(&s->vi, avctx))) { | |
203 | av_log(avctx, AV_LOG_ERROR, "encoder setup failed\n"); | |
204 | goto error; | |
205 | } | |
206 | if ((ret = vorbis_analysis_init(&s->vd, &s->vi))) { | |
207 | av_log(avctx, AV_LOG_ERROR, "analysis init failed\n"); | |
208 | ret = vorbis_error_to_averror(ret); | |
209 | goto error; | |
210 | } | |
211 | s->dsp_initialized = 1; | |
212 | if ((ret = vorbis_block_init(&s->vd, &s->vb))) { | |
213 | av_log(avctx, AV_LOG_ERROR, "dsp init failed\n"); | |
214 | ret = vorbis_error_to_averror(ret); | |
215 | goto error; | |
216 | } | |
217 | ||
218 | vorbis_comment_init(&s->vc); | |
219 | if (!(avctx->flags & CODEC_FLAG_BITEXACT)) | |
220 | vorbis_comment_add_tag(&s->vc, "encoder", LIBAVCODEC_IDENT); | |
221 | ||
222 | if ((ret = vorbis_analysis_headerout(&s->vd, &s->vc, &header, &header_comm, | |
223 | &header_code))) { | |
224 | ret = vorbis_error_to_averror(ret); | |
225 | goto error; | |
226 | } | |
227 | ||
228 | avctx->extradata_size = 1 + xiph_len(header.bytes) + | |
229 | xiph_len(header_comm.bytes) + | |
230 | header_code.bytes; | |
231 | p = avctx->extradata = av_malloc(avctx->extradata_size + | |
232 | FF_INPUT_BUFFER_PADDING_SIZE); | |
233 | if (!p) { | |
234 | ret = AVERROR(ENOMEM); | |
235 | goto error; | |
236 | } | |
237 | p[0] = 2; | |
238 | offset = 1; | |
239 | offset += av_xiphlacing(&p[offset], header.bytes); | |
240 | offset += av_xiphlacing(&p[offset], header_comm.bytes); | |
241 | memcpy(&p[offset], header.packet, header.bytes); | |
242 | offset += header.bytes; | |
243 | memcpy(&p[offset], header_comm.packet, header_comm.bytes); | |
244 | offset += header_comm.bytes; | |
245 | memcpy(&p[offset], header_code.packet, header_code.bytes); | |
246 | offset += header_code.bytes; | |
247 | av_assert0(offset == avctx->extradata_size); | |
248 | ||
249 | if ((ret = avpriv_vorbis_parse_extradata(avctx, &s->vp)) < 0) { | |
250 | av_log(avctx, AV_LOG_ERROR, "invalid extradata\n"); | |
251 | return ret; | |
252 | } | |
253 | ||
254 | vorbis_comment_clear(&s->vc); | |
255 | ||
256 | avctx->frame_size = LIBVORBIS_FRAME_SIZE; | |
257 | ff_af_queue_init(avctx, &s->afq); | |
258 | ||
259 | s->pkt_fifo = av_fifo_alloc(BUFFER_SIZE); | |
260 | if (!s->pkt_fifo) { | |
261 | ret = AVERROR(ENOMEM); | |
262 | goto error; | |
263 | } | |
264 | ||
265 | return 0; | |
266 | error: | |
267 | libvorbis_encode_close(avctx); | |
268 | return ret; | |
269 | } | |
270 | ||
271 | static int libvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, | |
272 | const AVFrame *frame, int *got_packet_ptr) | |
273 | { | |
274 | LibvorbisEncContext *s = avctx->priv_data; | |
275 | ogg_packet op; | |
276 | int ret, duration; | |
277 | ||
278 | /* send samples to libvorbis */ | |
279 | if (frame) { | |
280 | const int samples = frame->nb_samples; | |
281 | float **buffer; | |
282 | int c, channels = s->vi.channels; | |
283 | ||
284 | buffer = vorbis_analysis_buffer(&s->vd, samples); | |
285 | for (c = 0; c < channels; c++) { | |
286 | int co = (channels > 8) ? c : | |
287 | ff_vorbis_encoding_channel_layout_offsets[channels - 1][c]; | |
288 | memcpy(buffer[c], frame->extended_data[co], | |
289 | samples * sizeof(*buffer[c])); | |
290 | } | |
291 | if ((ret = vorbis_analysis_wrote(&s->vd, samples)) < 0) { | |
292 | av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n"); | |
293 | return vorbis_error_to_averror(ret); | |
294 | } | |
295 | if ((ret = ff_af_queue_add(&s->afq, frame)) < 0) | |
296 | return ret; | |
297 | } else { | |
298 | if (!s->eof && s->afq.frame_alloc) | |
299 | if ((ret = vorbis_analysis_wrote(&s->vd, 0)) < 0) { | |
300 | av_log(avctx, AV_LOG_ERROR, "error in vorbis_analysis_wrote()\n"); | |
301 | return vorbis_error_to_averror(ret); | |
302 | } | |
303 | s->eof = 1; | |
304 | } | |
305 | ||
306 | /* retrieve available packets from libvorbis */ | |
307 | while ((ret = vorbis_analysis_blockout(&s->vd, &s->vb)) == 1) { | |
308 | if ((ret = vorbis_analysis(&s->vb, NULL)) < 0) | |
309 | break; | |
310 | if ((ret = vorbis_bitrate_addblock(&s->vb)) < 0) | |
311 | break; | |
312 | ||
313 | /* add any available packets to the output packet buffer */ | |
314 | while ((ret = vorbis_bitrate_flushpacket(&s->vd, &op)) == 1) { | |
315 | if (av_fifo_space(s->pkt_fifo) < sizeof(ogg_packet) + op.bytes) { | |
316 | av_log(avctx, AV_LOG_ERROR, "packet buffer is too small\n"); | |
317 | return AVERROR_BUG; | |
318 | } | |
319 | av_fifo_generic_write(s->pkt_fifo, &op, sizeof(ogg_packet), NULL); | |
320 | av_fifo_generic_write(s->pkt_fifo, op.packet, op.bytes, NULL); | |
321 | } | |
322 | if (ret < 0) { | |
323 | av_log(avctx, AV_LOG_ERROR, "error getting available packets\n"); | |
324 | break; | |
325 | } | |
326 | } | |
327 | if (ret < 0) { | |
328 | av_log(avctx, AV_LOG_ERROR, "error getting available packets\n"); | |
329 | return vorbis_error_to_averror(ret); | |
330 | } | |
331 | ||
332 | /* check for available packets */ | |
333 | if (av_fifo_size(s->pkt_fifo) < sizeof(ogg_packet)) | |
334 | return 0; | |
335 | ||
336 | av_fifo_generic_read(s->pkt_fifo, &op, sizeof(ogg_packet), NULL); | |
337 | ||
338 | if ((ret = ff_alloc_packet2(avctx, avpkt, op.bytes)) < 0) | |
339 | return ret; | |
340 | av_fifo_generic_read(s->pkt_fifo, avpkt->data, op.bytes, NULL); | |
341 | ||
342 | avpkt->pts = ff_samples_to_time_base(avctx, op.granulepos); | |
343 | ||
344 | duration = avpriv_vorbis_parse_frame(&s->vp, avpkt->data, avpkt->size); | |
345 | if (duration > 0) { | |
346 | /* we do not know encoder delay until we get the first packet from | |
347 | * libvorbis, so we have to update the AudioFrameQueue counts */ | |
348 | if (!avctx->delay && s->afq.frames) { | |
349 | avctx->delay = duration; | |
350 | av_assert0(!s->afq.remaining_delay); | |
351 | s->afq.frames->duration += duration; | |
352 | if (s->afq.frames->pts != AV_NOPTS_VALUE) | |
353 | s->afq.frames->pts -= duration; | |
354 | s->afq.remaining_samples += duration; | |
355 | } | |
356 | ff_af_queue_remove(&s->afq, duration, &avpkt->pts, &avpkt->duration); | |
357 | } | |
358 | ||
359 | *got_packet_ptr = 1; | |
360 | return 0; | |
361 | } | |
362 | ||
363 | AVCodec ff_libvorbis_encoder = { | |
364 | .name = "libvorbis", | |
365 | .long_name = NULL_IF_CONFIG_SMALL("libvorbis"), | |
366 | .type = AVMEDIA_TYPE_AUDIO, | |
367 | .id = AV_CODEC_ID_VORBIS, | |
368 | .priv_data_size = sizeof(LibvorbisEncContext), | |
369 | .init = libvorbis_encode_init, | |
370 | .encode2 = libvorbis_encode_frame, | |
371 | .close = libvorbis_encode_close, | |
372 | .capabilities = CODEC_CAP_DELAY, | |
373 | .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, | |
374 | AV_SAMPLE_FMT_NONE }, | |
375 | .priv_class = &vorbis_class, | |
376 | .defaults = defaults, | |
377 | }; |