1 /*
2  * Copyright 2003-2021 The Music Player Daemon Project
3  * http://www.musicpd.org
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #include "OpusEncoderPlugin.hxx"
21 #include "OggEncoder.hxx"
22 #include "pcm/AudioFormat.hxx"
23 #include "util/ByteOrder.hxx"
24 #include "util/StringUtil.hxx"
25 
26 #include <opus.h>
27 #include <ogg/ogg.h>
28 
29 #include <cassert>
30 #include <stdexcept>
31 
32 #include <stdlib.h>
33 
34 namespace {
35 
36 class OpusEncoder final : public OggEncoder {
37 	const AudioFormat audio_format;
38 
39 	const size_t frame_size;
40 
41 	const size_t buffer_frames, buffer_size;
42 	size_t buffer_position = 0;
43 	uint8_t *const buffer;
44 
45 	::OpusEncoder *const enc;
46 
47 	unsigned char buffer2[1275 * 3 + 7];
48 
49 	int lookahead;
50 
51 	ogg_int64_t packetno = 0;
52 
53 	ogg_int64_t granulepos = 0;
54 
55 public:
56 	OpusEncoder(AudioFormat &_audio_format, ::OpusEncoder *_enc, bool _chaining);
57 	~OpusEncoder() noexcept override;
58 
59 	OpusEncoder(const OpusEncoder &) = delete;
60 	OpusEncoder &operator=(const OpusEncoder &) = delete;
61 
62 	/* virtual methods from class Encoder */
63 	void End() override;
64 	void Write(const void *data, size_t length) override;
65 
66 	void PreTag() override;
67 	void SendTag(const Tag &tag) override;
68 
69 private:
70 	void DoEncode(bool eos);
71 	void WriteSilence(unsigned fill_frames);
72 
73 	void GenerateHeaders(const Tag *tag) noexcept;
74 	void GenerateHead() noexcept;
75 	void GenerateTags(const Tag *tag) noexcept;
76 };
77 
78 class PreparedOpusEncoder final : public PreparedEncoder {
79 	opus_int32 bitrate;
80 	int complexity;
81 	int signal;
82 	int packet_loss;
83 	int vbr;
84 	int vbr_constraint;
85 	const bool chaining;
86 
87 public:
88 	explicit PreparedOpusEncoder(const ConfigBlock &block);
89 
90 	/* virtual methods from class PreparedEncoder */
91 	Encoder *Open(AudioFormat &audio_format) override;
92 
GetMimeType() const93 	[[nodiscard]] const char *GetMimeType() const noexcept override {
94 		return "audio/ogg";
95 	}
96 };
97 
PreparedOpusEncoder(const ConfigBlock & block)98 PreparedOpusEncoder::PreparedOpusEncoder(const ConfigBlock &block)
99 	:chaining(block.GetBlockValue("opustags", false))
100 {
101 	const char *value = block.GetBlockValue("bitrate", "auto");
102 	if (strcmp(value, "auto") == 0)
103 		bitrate = OPUS_AUTO;
104 	else if (strcmp(value, "max") == 0)
105 		bitrate = OPUS_BITRATE_MAX;
106 	else {
107 		char *endptr;
108 		bitrate = strtoul(value, &endptr, 10);
109 		if (endptr == value || *endptr != 0 ||
110 		    bitrate < 500 || bitrate > 512000)
111 			throw std::runtime_error("Invalid bit rate");
112 	}
113 
114 	complexity = block.GetBlockValue("complexity", 10U);
115 	if (complexity > 10)
116 		throw std::runtime_error("Invalid complexity");
117 
118 	value = block.GetBlockValue("signal", "auto");
119 	if (strcmp(value, "auto") == 0)
120 		signal = OPUS_AUTO;
121 	else if (strcmp(value, "voice") == 0)
122 		signal = OPUS_SIGNAL_VOICE;
123 	else if (strcmp(value, "music") == 0)
124 		signal = OPUS_SIGNAL_MUSIC;
125 	else
126 		throw std::runtime_error("Invalid signal");
127 
128 	value = block.GetBlockValue("vbr", "yes");
129 	if (strcmp(value, "yes") == 0) {
130 		vbr = 1U;
131 		vbr_constraint = 0U;
132 	} else if (strcmp(value, "no") == 0) {
133 		vbr = 0U;
134 		vbr_constraint = 0U;
135 	} else if (strcmp(value, "constrained") == 0) {
136 		vbr = 1U;
137 		vbr_constraint = 1U;
138 	} else
139 		throw std::runtime_error("Invalid vbr");
140 
141 	packet_loss = block.GetBlockValue("packet_loss", 0U);
142 	if (packet_loss > 100)
143 		throw std::runtime_error("Invalid packet loss");
144 }
145 
146 PreparedEncoder *
opus_encoder_init(const ConfigBlock & block)147 opus_encoder_init(const ConfigBlock &block)
148 {
149 	return new PreparedOpusEncoder(block);
150 }
151 
OpusEncoder(AudioFormat & _audio_format,::OpusEncoder * _enc,bool _chaining)152 OpusEncoder::OpusEncoder(AudioFormat &_audio_format, ::OpusEncoder *_enc, bool _chaining)
153 	:OggEncoder(_chaining),
154 	 audio_format(_audio_format),
155 	 frame_size(_audio_format.GetFrameSize()),
156 	 buffer_frames(_audio_format.sample_rate / 50),
157 	 buffer_size(frame_size * buffer_frames),
158 	 buffer(new uint8_t[buffer_size]),
159 	 enc(_enc)
160 {
161 	opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&lookahead));
162 	GenerateHeaders(nullptr);
163 }
164 
165 Encoder *
Open(AudioFormat & audio_format)166 PreparedOpusEncoder::Open(AudioFormat &audio_format)
167 {
168 	/* libopus supports only 48 kHz */
169 	audio_format.sample_rate = 48000;
170 
171 	if (audio_format.channels > 2)
172 		audio_format.channels = 1;
173 
174 	switch (audio_format.format) {
175 	case SampleFormat::S16:
176 	case SampleFormat::FLOAT:
177 		break;
178 
179 	case SampleFormat::S8:
180 		audio_format.format = SampleFormat::S16;
181 		break;
182 
183 	default:
184 		audio_format.format = SampleFormat::FLOAT;
185 		break;
186 	}
187 
188 	int error_code;
189 	auto *enc = opus_encoder_create(audio_format.sample_rate,
190 					audio_format.channels,
191 					OPUS_APPLICATION_AUDIO,
192 					&error_code);
193 	if (enc == nullptr)
194 		throw std::runtime_error(opus_strerror(error_code));
195 
196 	opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate));
197 	opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
198 	opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal));
199 	opus_encoder_ctl(enc, OPUS_SET_VBR(vbr));
200 	opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(vbr_constraint));
201 	opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss));
202 
203 	return new OpusEncoder(audio_format, enc, chaining);
204 }
205 
~OpusEncoder()206 OpusEncoder::~OpusEncoder() noexcept
207 {
208 	delete[] buffer;
209 	opus_encoder_destroy(enc);
210 }
211 
212 void
DoEncode(bool eos)213 OpusEncoder::DoEncode(bool eos)
214 {
215 	assert(buffer_position == buffer_size || eos);
216 
217 	opus_int32 result =
218 		audio_format.format == SampleFormat::S16
219 		? opus_encode(enc,
220 		              (const opus_int16 *)buffer,
221 		              buffer_frames,
222 		              buffer2,
223 		              sizeof(buffer2))
224 		: opus_encode_float(enc,
225 		                    (const float *)buffer,
226 		                    buffer_frames,
227 		                    buffer2,
228 		                    sizeof(buffer2));
229 	if (result < 0)
230 		throw std::runtime_error("Opus encoder error");
231 
232 	granulepos += buffer_position / frame_size;
233 
234 	ogg_packet packet;
235 	packet.packet = buffer2;
236 	packet.bytes = result;
237 	packet.b_o_s = false;
238 	packet.e_o_s = eos;
239 	packet.granulepos = granulepos;
240 	packet.packetno = packetno++;
241 	stream.PacketIn(packet);
242 
243 	buffer_position = 0;
244 }
245 
246 void
End()247 OpusEncoder::End()
248 {
249 	memset(buffer + buffer_position, 0,
250 	       buffer_size - buffer_position);
251 	DoEncode(true);
252 	Flush();
253 }
254 
255 void
WriteSilence(unsigned fill_frames)256 OpusEncoder::WriteSilence(unsigned fill_frames)
257 {
258 	size_t fill_bytes = fill_frames * frame_size;
259 
260 	while (fill_bytes > 0) {
261 		size_t nbytes = buffer_size - buffer_position;
262 		if (nbytes > fill_bytes)
263 			nbytes = fill_bytes;
264 
265 		memset(buffer + buffer_position, 0, nbytes);
266 		buffer_position += nbytes;
267 		fill_bytes -= nbytes;
268 
269 		if (buffer_position == buffer_size)
270 			DoEncode(false);
271 	}
272 }
273 
274 void
Write(const void * _data,size_t length)275 OpusEncoder::Write(const void *_data, size_t length)
276 {
277 	const auto *data = (const uint8_t *)_data;
278 
279 	if (lookahead > 0) {
280 		/* generate some silence at the beginning of the
281 		   stream */
282 
283 		assert(buffer_position == 0);
284 
285 		WriteSilence(lookahead);
286 		lookahead = 0;
287 	}
288 
289 	while (length > 0) {
290 		size_t nbytes = buffer_size - buffer_position;
291 		if (nbytes > length)
292 			nbytes = length;
293 
294 		memcpy(buffer + buffer_position, data, nbytes);
295 		data += nbytes;
296 		length -= nbytes;
297 		buffer_position += nbytes;
298 
299 		if (buffer_position == buffer_size)
300 			DoEncode(false);
301 	}
302 }
303 
304 void
GenerateHeaders(const Tag * tag)305 OpusEncoder::GenerateHeaders(const Tag *tag) noexcept
306 {
307 	GenerateHead();
308 	GenerateTags(tag);
309 }
310 
311 void
GenerateHead()312 OpusEncoder::GenerateHead() noexcept
313 {
314 	unsigned char header[19];
315 	memcpy(header, "OpusHead", 8);
316 	header[8] = 1;
317 	header[9] = audio_format.channels;
318 	*(uint16_t *)(header + 10) = ToLE16(lookahead);
319 	*(uint32_t *)(header + 12) = ToLE32(audio_format.sample_rate);
320 	header[16] = 0;
321 	header[17] = 0;
322 	header[18] = 0;
323 
324 	ogg_packet packet;
325 	packet.packet = header;
326 	packet.bytes = sizeof(header);
327 	packet.b_o_s = true;
328 	packet.e_o_s = false;
329 	packet.granulepos = 0;
330 	packet.packetno = packetno++;
331 	stream.PacketIn(packet);
332 	// flush not needed because libogg autoflushes on b_o_s flag
333 }
334 
335 void
GenerateTags(const Tag * tag)336 OpusEncoder::GenerateTags(const Tag *tag) noexcept
337 {
338 	const char *version = opus_get_version_string();
339 	size_t version_length = strlen(version);
340 
341 	// len("OpusTags") + 4 byte version length + len(version) + 4 byte tag count
342 	size_t comments_size = 8 + 4 + version_length + 4;
343 	uint32_t tag_count = 0;
344 	if (tag) {
345 		for (const auto &item: *tag) {
346 			++tag_count;
347 			// 4 byte length + len(tagname) + len('=') + len(value)
348 			comments_size += 4 + strlen(tag_item_names[item.type]) + 1 + strlen(item.value);
349 		}
350 	}
351 
352 	auto *comments = new unsigned char[comments_size];
353 	unsigned char *p = comments;
354 
355 	memcpy(comments, "OpusTags", 8);
356 	*(uint32_t *)(comments + 8) = ToLE32(version_length);
357 	p += 12;
358 
359 	memcpy(p, version, version_length);
360 	p += version_length;
361 
362 	tag_count = ToLE32(tag_count);
363 	memcpy(p, &tag_count, 4);
364 	p += 4;
365 
366 	if (tag) {
367 		for (const auto &item: *tag) {
368 			size_t tag_name_len = strlen(tag_item_names[item.type]);
369 			size_t tag_val_len = strlen(item.value);
370 			uint32_t tag_len_le = ToLE32(tag_name_len + 1 + tag_val_len);
371 
372 			memcpy(p, &tag_len_le, 4);
373 			p += 4;
374 
375 			ToUpperASCII((char *)p, tag_item_names[item.type], tag_name_len + 1);
376 			p += tag_name_len;
377 
378 			*p++ = '=';
379 
380 			memcpy(p, item.value, tag_val_len);
381 			p += tag_val_len;
382 		}
383 	}
384 	assert(comments + comments_size == p);
385 
386 	ogg_packet packet;
387 	packet.packet = comments;
388 	packet.bytes = comments_size;
389 	packet.b_o_s = false;
390 	packet.e_o_s = false;
391 	packet.granulepos = 0;
392 	packet.packetno = packetno++;
393 	stream.PacketIn(packet);
394 	Flush();
395 
396 	delete[] comments;
397 }
398 
399 void
PreTag()400 OpusEncoder::PreTag()
401 {
402 	End();
403 	packetno = 0;
404 	granulepos = 0; // not really required, but useful to prevent wraparound
405 	opus_encoder_ctl(enc, OPUS_RESET_STATE);
406 }
407 
408 void
SendTag(const Tag & tag)409 OpusEncoder::SendTag(const Tag &tag)
410 {
411 	stream.Reinitialize(GenerateSerial());
412 	opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&lookahead));
413 	GenerateHeaders(&tag);
414 }
415 
416 } // namespace
417 
418 const EncoderPlugin opus_encoder_plugin = {
419 	"opus",
420 	opus_encoder_init,
421 };
422