OpusEncoderPlugin.cxx 10.1 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright (C) 2003-2014 The Music Player Daemon Project
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
 * http://www.musicpd.org
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "config.h"
#include "OpusEncoderPlugin.hxx"
22
#include "OggStream.hxx"
23
#include "OggSerial.hxx"
24
#include "../EncoderAPI.hxx"
25
#include "AudioFormat.hxx"
26
#include "config/ConfigError.hxx"
27
#include "util/Alloc.hxx"
28 29
#include "util/Error.hxx"
#include "util/Domain.hxx"
30
#include "system/ByteOrder.hxx"
31 32 33 34 35

#include <opus.h>
#include <ogg/ogg.h>

#include <assert.h>
36
#include <stdlib.h>
37 38 39

struct opus_encoder {
	/** the base class */
40
	Encoder encoder;
41 42 43 44 45 46 47 48 49

	/* configuration */

	opus_int32 bitrate;
	int complexity;
	int signal;

	/* runtime information */

50
	AudioFormat audio_format;
51 52 53 54 55 56 57 58 59 60

	size_t frame_size;

	size_t buffer_frames, buffer_size, buffer_position;
	uint8_t *buffer;

	OpusEncoder *enc;

	unsigned char buffer2[1275 * 3 + 7];

61
	OggStream stream;
62

63 64
	int lookahead;

65
	ogg_int64_t packetno;
66 67

	ogg_int64_t granulepos;
68

69
	opus_encoder():encoder(opus_encoder_plugin) {}
70 71
};

72
static constexpr Domain opus_encoder_domain("opus_encoder");
73 74 75

static bool
opus_encoder_configure(struct opus_encoder *encoder,
76
		       const config_param &param, Error &error)
77
{
78
	const char *value = param.GetBlockValue("bitrate", "auto");
79 80 81 82 83 84 85 86 87
	if (strcmp(value, "auto") == 0)
		encoder->bitrate = OPUS_AUTO;
	else if (strcmp(value, "max") == 0)
		encoder->bitrate = OPUS_BITRATE_MAX;
	else {
		char *endptr;
		encoder->bitrate = strtoul(value, &endptr, 10);
		if (endptr == value || *endptr != 0 ||
		    encoder->bitrate < 500 || encoder->bitrate > 512000) {
88
			error.Set(config_domain, "Invalid bit rate");
89 90 91 92
			return false;
		}
	}

93
	encoder->complexity = param.GetBlockValue("complexity", 10u);
94
	if (encoder->complexity > 10) {
95
		error.Format(config_domain, "Invalid complexity");
96 97 98
		return false;
	}

99
	value = param.GetBlockValue("signal", "auto");
100
	if (strcmp(value, "auto") == 0)
101
		encoder->signal = OPUS_AUTO;
102
	else if (strcmp(value, "voice") == 0)
103
		encoder->signal = OPUS_SIGNAL_VOICE;
104
	else if (strcmp(value, "music") == 0)
105
		encoder->signal = OPUS_SIGNAL_MUSIC;
106
	else {
107
		error.Format(config_domain, "Invalid signal");
108 109 110 111 112 113
		return false;
	}

	return true;
}

114
static Encoder *
115
opus_encoder_init(const config_param &param, Error &error)
116
{
117
	opus_encoder *encoder = new opus_encoder();
118 119 120 121

	/* load configuration from "param" */
	if (!opus_encoder_configure(encoder, param, error)) {
		/* configuration has failed, roll back and return error */
122
		delete encoder;
123
		return nullptr;
124 125 126 127 128 129
	}

	return &encoder->encoder;
}

static void
130
opus_encoder_finish(Encoder *_encoder)
131 132 133 134 135
{
	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;

	/* the real libopus cleanup was already performed by
	   opus_encoder_close(), so no real work here */
136
	delete encoder;
137 138 139
}

static bool
140
opus_encoder_open(Encoder *_encoder,
141
		  AudioFormat &audio_format,
142
		  Error &error)
143 144 145 146
{
	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;

	/* libopus supports only 48 kHz */
147
	audio_format.sample_rate = 48000;
148

149 150
	if (audio_format.channels > 2)
		audio_format.channels = 1;
151

152 153 154
	switch (audio_format.format) {
	case SampleFormat::S16:
	case SampleFormat::FLOAT:
155 156
		break;

157 158
	case SampleFormat::S8:
		audio_format.format = SampleFormat::S16;
159 160 161
		break;

	default:
162
		audio_format.format = SampleFormat::FLOAT;
163 164 165
		break;
	}

166 167
	encoder->audio_format = audio_format;
	encoder->frame_size = audio_format.GetFrameSize();
168

169
	int error_code;
170 171
	encoder->enc = opus_encoder_create(audio_format.sample_rate,
					   audio_format.channels,
172
					   OPUS_APPLICATION_AUDIO,
173
					   &error_code);
174
	if (encoder->enc == nullptr) {
175 176
		error.Set(opus_encoder_domain, error_code,
			  opus_strerror(error_code));
177 178 179 180 181 182 183 184
		return false;
	}

	opus_encoder_ctl(encoder->enc, OPUS_SET_BITRATE(encoder->bitrate));
	opus_encoder_ctl(encoder->enc,
			 OPUS_SET_COMPLEXITY(encoder->complexity));
	opus_encoder_ctl(encoder->enc, OPUS_SET_SIGNAL(encoder->signal));

185 186
	opus_encoder_ctl(encoder->enc, OPUS_GET_LOOKAHEAD(&encoder->lookahead));

187
	encoder->buffer_frames = audio_format.sample_rate / 50;
188 189
	encoder->buffer_size = encoder->frame_size * encoder->buffer_frames;
	encoder->buffer_position = 0;
190
	encoder->buffer = (unsigned char *)xalloc(encoder->buffer_size);
191

192
	encoder->stream.Initialize(GenerateOggSerial());
193 194 195 196 197 198
	encoder->packetno = 0;

	return true;
}

static void
199
opus_encoder_close(Encoder *_encoder)
200 201 202
{
	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;

203
	encoder->stream.Deinitialize();
204
	free(encoder->buffer);
205 206 207 208 209
	opus_encoder_destroy(encoder->enc);
}

static bool
opus_encoder_do_encode(struct opus_encoder *encoder, bool eos,
210
		       Error &error)
211 212 213 214
{
	assert(encoder->buffer_position == encoder->buffer_size);

	opus_int32 result =
215
		encoder->audio_format.format == SampleFormat::S16
216 217 218 219 220 221 222 223 224 225 226
		? opus_encode(encoder->enc,
			      (const opus_int16 *)encoder->buffer,
			      encoder->buffer_frames,
			      encoder->buffer2,
			      sizeof(encoder->buffer2))
		: opus_encode_float(encoder->enc,
				    (const float *)encoder->buffer,
				    encoder->buffer_frames,
				    encoder->buffer2,
				    sizeof(encoder->buffer2));
	if (result < 0) {
227
		error.Set(opus_encoder_domain, "Opus encoder error");
228 229 230
		return false;
	}

231 232
	encoder->granulepos += encoder->buffer_frames;

233 234 235 236 237
	ogg_packet packet;
	packet.packet = encoder->buffer2;
	packet.bytes = result;
	packet.b_o_s = false;
	packet.e_o_s = eos;
238
	packet.granulepos = encoder->granulepos;
239
	packet.packetno = encoder->packetno++;
240
	encoder->stream.PacketIn(packet);
241 242 243 244 245 246 247

	encoder->buffer_position = 0;

	return true;
}

static bool
248
opus_encoder_end(Encoder *_encoder, Error &error)
249 250 251
{
	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;

252
	encoder->stream.Flush();
253 254 255 256 257

	memset(encoder->buffer + encoder->buffer_position, 0,
	       encoder->buffer_size - encoder->buffer_position);
	encoder->buffer_position = encoder->buffer_size;

258
	return opus_encoder_do_encode(encoder, true, error);
259 260 261
}

static bool
262
opus_encoder_flush(Encoder *_encoder, gcc_unused Error &error)
263 264 265
{
	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;

266
	encoder->stream.Flush();
267 268 269
	return true;
}

270 271
static bool
opus_encoder_write_silence(struct opus_encoder *encoder, unsigned fill_frames,
272
			   Error &error)
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
{
	size_t fill_bytes = fill_frames * encoder->frame_size;

	while (fill_bytes > 0) {
		size_t nbytes =
			encoder->buffer_size - encoder->buffer_position;
		if (nbytes > fill_bytes)
			nbytes = fill_bytes;

		memset(encoder->buffer + encoder->buffer_position,
		       0, nbytes);
		encoder->buffer_position += nbytes;
		fill_bytes -= nbytes;

		if (encoder->buffer_position == encoder->buffer_size &&
288
		    !opus_encoder_do_encode(encoder, false, error))
289 290 291 292 293 294
			return false;
	}

	return true;
}

295
static bool
296
opus_encoder_write(Encoder *_encoder,
297
		   const void *_data, size_t length,
298
		   Error &error)
299 300 301 302
{
	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;
	const uint8_t *data = (const uint8_t *)_data;

303 304 305 306 307 308 309
	if (encoder->lookahead > 0) {
		/* generate some silence at the beginning of the
		   stream */

		assert(encoder->buffer_position == 0);

		if (!opus_encoder_write_silence(encoder, encoder->lookahead,
310
						error))
311 312 313 314 315
			return false;

		encoder->lookahead = 0;
	}

316 317 318 319 320 321 322 323 324 325 326 327 328
	while (length > 0) {
		size_t nbytes =
			encoder->buffer_size - encoder->buffer_position;
		if (nbytes > length)
			nbytes = length;

		memcpy(encoder->buffer + encoder->buffer_position,
		       data, nbytes);
		data += nbytes;
		length -= nbytes;
		encoder->buffer_position += nbytes;

		if (encoder->buffer_position == encoder->buffer_size &&
329
		    !opus_encoder_do_encode(encoder, false, error))
330 331 332 333 334 335 336 337 338 339 340 341 342
			return false;
	}

	return true;
}

static void
opus_encoder_generate_head(struct opus_encoder *encoder)
{
	unsigned char header[19];
	memcpy(header, "OpusHead", 8);
	header[8] = 1;
	header[9] = encoder->audio_format.channels;
343
	*(uint16_t *)(header + 10) = ToLE16(encoder->lookahead);
344
	*(uint32_t *)(header + 12) =
345
		ToLE32(encoder->audio_format.sample_rate);
346 347 348 349 350 351 352 353 354 355 356
	header[16] = 0;
	header[17] = 0;
	header[18] = 0;

	ogg_packet packet;
	packet.packet = header;
	packet.bytes = 19;
	packet.b_o_s = true;
	packet.e_o_s = false;
	packet.granulepos = 0;
	packet.packetno = encoder->packetno++;
357 358
	encoder->stream.PacketIn(packet);
	encoder->stream.Flush();
359 360 361 362 363 364 365 366 367
}

static void
opus_encoder_generate_tags(struct opus_encoder *encoder)
{
	const char *version = opus_get_version_string();
	size_t version_length = strlen(version);

	size_t comments_size = 8 + 4 + version_length + 4;
368
	unsigned char *comments = (unsigned char *)xalloc(comments_size);
369
	memcpy(comments, "OpusTags", 8);
370
	*(uint32_t *)(comments + 8) = ToLE32(version_length);
371
	memcpy(comments + 12, version, version_length);
372
	*(uint32_t *)(comments + 12 + version_length) = ToLE32(0);
373 374 375 376 377 378 379 380

	ogg_packet packet;
	packet.packet = comments;
	packet.bytes = comments_size;
	packet.b_o_s = false;
	packet.e_o_s = false;
	packet.granulepos = 0;
	packet.packetno = encoder->packetno++;
381 382
	encoder->stream.PacketIn(packet);
	encoder->stream.Flush();
383

384
	free(comments);
385 386 387
}

static size_t
388
opus_encoder_read(Encoder *_encoder, void *dest, size_t length)
389 390 391 392 393 394 395 396
{
	struct opus_encoder *encoder = (struct opus_encoder *)_encoder;

	if (encoder->packetno == 0)
		opus_encoder_generate_head(encoder);
	else if (encoder->packetno == 1)
		opus_encoder_generate_tags(encoder);

397
	return encoder->stream.PageOut(dest, length);
398 399 400
}

static const char *
401
opus_encoder_get_mime_type(gcc_unused Encoder *_encoder)
402 403 404 405
{
	return  "audio/ogg";
}

406
const EncoderPlugin opus_encoder_plugin = {
407 408 409 410 411 412 413 414 415 416 417 418 419
	"opus",
	opus_encoder_init,
	opus_encoder_finish,
	opus_encoder_open,
	opus_encoder_close,
	opus_encoder_end,
	opus_encoder_flush,
	nullptr,
	nullptr,
	opus_encoder_write,
	opus_encoder_read,
	opus_encoder_get_mime_type,
};