FfmpegDecoderPlugin.cxx 18.4 KB
Newer Older
1
/*
Max Kellermann's avatar
Max Kellermann committed
2
 * Copyright (C) 2003-2014 The Music Player Daemon Project
3
 * http://www.musicpd.org
4 5 6 7 8 9 10 11 12 13
 *
 * 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.
14 15 16 17
 *
 * 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.
18 19
 */

20 21 22
/* necessary because libavutil/common.h uses UINT64_C */
#define __STDC_CONSTANT_MACROS

23
#include "config.h"
24
#include "FfmpegDecoderPlugin.hxx"
25
#include "lib/ffmpeg/Domain.hxx"
26
#include "../DecoderAPI.hxx"
27
#include "FfmpegMetaData.hxx"
28
#include "tag/TagHandler.hxx"
Max Kellermann's avatar
Max Kellermann committed
29
#include "input/InputStream.hxx"
30
#include "CheckAudioFormat.hxx"
31
#include "util/Error.hxx"
32 33
#include "util/Domain.hxx"
#include "LogV.hxx"
34 35

extern "C" {
36 37 38
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
39
#include <libavutil/avutil.h>
40
#include <libavutil/log.h>
41
#include <libavutil/mathematics.h>
42 43 44 45

#if LIBAVUTIL_VERSION_MAJOR >= 53
#include <libavutil/frame.h>
#endif
46
}
47

48 49 50
#include <assert.h>
#include <string.h>

51 52 53 54 55
/* suppress the ffmpeg compatibility macro */
#ifdef SampleFormat
#undef SampleFormat
#endif

56 57
static LogLevel
import_ffmpeg_level(int level)
58 59
{
	if (level <= AV_LOG_FATAL)
60
		return LogLevel::ERROR;
61

62 63
	if (level <= AV_LOG_WARNING)
		return LogLevel::WARNING;
64 65

	if (level <= AV_LOG_INFO)
66
		return LogLevel::INFO;
67

68
	return LogLevel::DEBUG;
69 70 71
}

static void
72
mpd_ffmpeg_log_callback(gcc_unused void *ptr, int level,
73 74
			const char *fmt, va_list vl)
{
75
	const AVClass * cls = nullptr;
76

77
	if (ptr != nullptr)
78 79
		cls = *(const AVClass *const*)ptr;

80
	if (cls != nullptr) {
81 82 83
		char domain[64];
		snprintf(domain, sizeof(domain), "%s/%s",
			 ffmpeg_domain.GetName(), cls->item_name(ptr));
84 85
		const Domain d(domain);
		LogFormatV(d, import_ffmpeg_level(level), fmt, vl);
86
	}
87 88
}

89
struct AvioStream {
90
	Decoder *const decoder;
91
	InputStream &input;
92

93
	AVIOContext *io;
94

95
	unsigned char buffer[8192];
96

97
	AvioStream(Decoder *_decoder, InputStream &_input)
98 99 100 101 102 103 104 105
		:decoder(_decoder), input(_input), io(nullptr) {}

	~AvioStream() {
		if (io != nullptr)
			av_free(io);
	}

	bool Open();
106
};
107

108 109
static int
mpd_ffmpeg_stream_read(void *opaque, uint8_t *buf, int size)
110
{
111
	AvioStream *stream = (AvioStream *)opaque;
112

113 114
	return decoder_read(stream->decoder, stream->input,
			    (void *)buf, size);
115 116
}

117 118
static int64_t
mpd_ffmpeg_stream_seek(void *opaque, int64_t pos, int whence)
119
{
120
	AvioStream *stream = (AvioStream *)opaque;
121

122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
	switch (whence) {
	case SEEK_SET:
		break;

	case SEEK_CUR:
		pos += stream->input.GetOffset();
		break;

	case SEEK_END:
		if (!stream->input.KnownSize())
			return -1;

		pos += stream->input.GetSize();
		break;

	case AVSEEK_SIZE:
138 139 140
		if (!stream->input.KnownSize())
			return -1;

141
		return stream->input.GetSize();
142

143 144 145 146 147
	default:
		return -1;
	}

	if (!stream->input.LockSeek(pos, IgnoreError()))
148 149
		return -1;

150
	return stream->input.GetOffset();
151 152
}

153 154
bool
AvioStream::Open()
155
{
156 157 158
	io = avio_alloc_context(buffer, sizeof(buffer),
				false, this,
				mpd_ffmpeg_stream_read, nullptr,
159
				input.IsSeekable()
160 161
				? mpd_ffmpeg_stream_seek : nullptr);
	return io != nullptr;
162 163
}

164 165 166 167 168 169 170 171 172 173 174
/**
 * API compatibility wrapper for av_open_input_stream() and
 * avformat_open_input().
 */
static int
mpd_ffmpeg_open_input(AVFormatContext **ic_ptr,
		      AVIOContext *pb,
		      const char *filename,
		      AVInputFormat *fmt)
{
	AVFormatContext *context = avformat_alloc_context();
175
	if (context == nullptr)
176 177 178 179
		return AVERROR(ENOMEM);

	context->pb = pb;
	*ic_ptr = context;
180
	return avformat_open_input(ic_ptr, filename, fmt, nullptr);
181 182
}

183
static bool
184
ffmpeg_init(gcc_unused const config_param &param)
185
{
186 187
	av_log_set_callback(mpd_ffmpeg_log_callback);

188
	av_register_all();
189
	return true;
190 191
}

192 193 194 195 196
static int
ffmpeg_find_audio_stream(const AVFormatContext *format_context)
{
	for (unsigned i = 0; i < format_context->nb_streams; ++i)
		if (format_context->streams[i]->codec->codec_type ==
197
		    AVMEDIA_TYPE_AUDIO)
198 199 200 201 202
			return i;

	return -1;
}

203
gcc_const
204 205 206 207 208
static double
time_from_ffmpeg(int64_t t, const AVRational time_base)
{
	assert(t != (int64_t)AV_NOPTS_VALUE);

209 210
	return (double)av_rescale_q(t, time_base, (AVRational){1, 1024})
		/ (double)1024;
211 212
}

213 214 215 216 217 218 219
template<typename Ratio>
static constexpr AVRational
RatioToAVRational()
{
	return { Ratio::num, Ratio::den };
}

220
gcc_const
221
static int64_t
222
time_to_ffmpeg(SongTime t, const AVRational time_base)
223
{
224 225
	return av_rescale_q(t.count(),
			    RatioToAVRational<SongTime::period>(),
226 227 228
			    time_base);
}

229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251
/**
 * Replace #AV_NOPTS_VALUE with the given fallback.
 */
static constexpr int64_t
timestamp_fallback(int64_t t, int64_t fallback)
{
	return gcc_likely(t != int64_t(AV_NOPTS_VALUE))
		? t
		: fallback;
}

/**
 * Accessor for AVStream::start_time that replaces AV_NOPTS_VALUE with
 * zero.  We can't use AV_NOPTS_VALUE in calculations, and we simply
 * assume that the stream's start time is zero, which appears to be
 * the best way out of that situation.
 */
static int64_t
start_time_fallback(const AVStream &stream)
{
	return timestamp_fallback(stream.start_time, 0);
}

252
static void
253 254 255
copy_interleave_frame2(uint8_t *dest, uint8_t **src,
		       unsigned nframes, unsigned nchannels,
		       unsigned sample_size)
256
{
257 258 259 260 261 262
	for (unsigned frame = 0; frame < nframes; ++frame) {
		for (unsigned channel = 0; channel < nchannels; ++channel) {
			memcpy(dest, src[channel] + frame * sample_size,
			       sample_size);
			dest += sample_size;
		}
263 264 265
	}
}

266 267 268 269 270 271
/**
 * Copy PCM data from a AVFrame to an interleaved buffer.
 */
static int
copy_interleave_frame(const AVCodecContext *codec_context,
		      const AVFrame *frame,
272 273
		      uint8_t **output_buffer,
		      uint8_t **global_buffer, int *global_buffer_size)
274 275 276 277 278 279 280
{
	int plane_size;
	const int data_size =
		av_samples_get_buffer_size(&plane_size,
					   codec_context->channels,
					   frame->nb_samples,
					   codec_context->sample_fmt, 1);
281 282 283
	if (data_size <= 0)
		return data_size;

284 285
	if (av_sample_fmt_is_planar(codec_context->sample_fmt) &&
	    codec_context->channels > 1) {
286 287 288 289 290 291 292 293 294 295 296 297
		if(*global_buffer_size < data_size) {
			av_freep(global_buffer);

			*global_buffer = (uint8_t*)av_malloc(data_size);

			if (!*global_buffer)
				/* Not enough memory - shouldn't happen */
				return AVERROR(ENOMEM);
			*global_buffer_size = data_size;
		}
		*output_buffer = *global_buffer;
		copy_interleave_frame2(*output_buffer, frame->extended_data,
298 299 300
				       frame->nb_samples,
				       codec_context->channels,
				       av_get_bytes_per_sample(codec_context->sample_fmt));
301
	} else {
302
		*output_buffer = frame->extended_data[0];
303 304 305 306 307
	}

	return data_size;
}

308
static DecoderCommand
309
ffmpeg_send_packet(Decoder &decoder, InputStream &is,
310
		   const AVPacket *packet,
311
		   AVCodecContext *codec_context,
312
		   const AVStream *stream,
313 314
		   AVFrame *frame,
		   uint8_t **buffer, int *buffer_size)
315
{
316
	if (packet->pts >= 0 && packet->pts != (int64_t)AV_NOPTS_VALUE)
317
		decoder_timestamp(decoder,
318
				  time_from_ffmpeg(packet->pts - start_time_fallback(*stream),
319
				  stream->time_base));
320

321
	AVPacket packet2 = *packet;
322

323
	uint8_t *output_buffer;
324

325 326
	DecoderCommand cmd = DecoderCommand::NONE;
	while (packet2.size > 0 && cmd == DecoderCommand::NONE) {
327
		int audio_size = 0;
328 329
		int got_frame = 0;
		int len = avcodec_decode_audio4(codec_context,
330
						frame, &got_frame,
331 332 333
						&packet2);
		if (len >= 0 && got_frame) {
			audio_size = copy_interleave_frame(codec_context,
334
							   frame,
335 336
							   &output_buffer,
							   buffer, buffer_size);
337 338
			if (audio_size < 0)
				len = audio_size;
339
		}
340 341 342

		if (len < 0) {
			/* if error, we skip the frame */
343 344
			LogDefault(ffmpeg_domain,
				   "decoding failed, frame skipped");
345 346 347
			break;
		}

348 349
		packet2.data += len;
		packet2.size -= len;
350

351
		if (audio_size <= 0)
352
			continue;
353

354
		cmd = decoder_data(decoder, is,
355
				   output_buffer, audio_size,
356
				   codec_context->bit_rate / 1000);
357
	}
358
	return cmd;
359 360
}

361
gcc_const
362
static SampleFormat
363
ffmpeg_sample_format(enum AVSampleFormat sample_fmt)
364
{
365
	switch (sample_fmt) {
366
	case AV_SAMPLE_FMT_S16:
367
	case AV_SAMPLE_FMT_S16P:
368
		return SampleFormat::S16;
369

370
	case AV_SAMPLE_FMT_S32:
371
	case AV_SAMPLE_FMT_S32P:
372
		return SampleFormat::S32;
373

374
	case AV_SAMPLE_FMT_FLTP:
375
		return SampleFormat::FLOAT;
376

377
	default:
378 379 380 381 382 383
		break;
	}

	char buffer[64];
	const char *name = av_get_sample_fmt_string(buffer, sizeof(buffer),
						    sample_fmt);
384
	if (name != nullptr)
385 386 387
		FormatError(ffmpeg_domain,
			    "Unsupported libavcodec SampleFormat value: %s (%d)",
			    name, sample_fmt);
388
	else
389 390 391
		FormatError(ffmpeg_domain,
			    "Unsupported libavcodec SampleFormat value: %d",
			    sample_fmt);
392
	return SampleFormat::UNDEFINED;
393 394
}

395
static AVInputFormat *
396
ffmpeg_probe(Decoder *decoder, InputStream &is)
397 398 399 400 401 402
{
	enum {
		BUFFER_SIZE = 16384,
		PADDING = 16,
	};

403
	unsigned char buffer[BUFFER_SIZE];
404
	size_t nbytes = decoder_read(decoder, is, buffer, BUFFER_SIZE);
405
	if (nbytes <= PADDING || !is.LockRewind(IgnoreError()))
406
		return nullptr;
407 408 409 410 411 412 413

	/* some ffmpeg parsers (e.g. ac3_parser.c) read a few bytes
	   beyond the declared buffer limit, which makes valgrind
	   angry; this workaround removes some padding from the buffer
	   size */
	nbytes -= PADDING;

414
	AVProbeData avpd;
415 416 417 418 419 420

	/* new versions of ffmpeg may add new attributes, and leaving
	   them uninitialized may crash; hopefully, zero-initializing
	   everything we don't know is ok */
	memset(&avpd, 0, sizeof(avpd));

421 422
	avpd.buf = buffer;
	avpd.buf_size = nbytes;
423
	avpd.filename = is.GetURI();
424

425 426 427 428 429 430 431
#ifdef AVPROBE_SCORE_MIME
	/* this attribute was added in libav/ffmpeg version 11, but
	   unfortunately it's "uint8_t" instead of "char", and it's
	   not "const" - wtf? */
	avpd.mime_type = (uint8_t *)const_cast<char *>(is.GetMimeType());
#endif

432
	return av_probe_input_format(&avpd, true);
433 434
}

435
static void
436
ffmpeg_decode(Decoder &decoder, InputStream &input)
437
{
438
	AVInputFormat *input_format = ffmpeg_probe(&decoder, input);
439
	if (input_format == nullptr)
440 441
		return;

442 443
	FormatDebug(ffmpeg_domain, "detected input format '%s' (%s)",
		    input_format->name, input_format->long_name);
444

445
	AvioStream stream(&decoder, input);
446
	if (!stream.Open()) {
447
		LogError(ffmpeg_domain, "Failed to open stream");
448 449 450
		return;
	}

451
	//ffmpeg works with ours "fileops" helper
452
	AVFormatContext *format_context = nullptr;
453
	if (mpd_ffmpeg_open_input(&format_context, stream.io,
454
				  input.GetURI(),
455
				  input_format) != 0) {
456
		LogError(ffmpeg_domain, "Open failed");
457 458 459
		return;
	}

460
	const int find_result =
461
		avformat_find_stream_info(format_context, nullptr);
462
	if (find_result < 0) {
463
		LogError(ffmpeg_domain, "Couldn't find stream info");
464
		avformat_close_input(&format_context);
465 466
		return;
	}
467

468
	int audio_stream = ffmpeg_find_audio_stream(format_context);
469
	if (audio_stream == -1) {
470
		LogError(ffmpeg_domain, "No audio stream inside");
471
		avformat_close_input(&format_context);
472 473
		return;
	}
474

475 476 477
	AVStream *av_stream = format_context->streams[audio_stream];

	AVCodecContext *codec_context = av_stream->codec;
478 479 480 481 482 483 484 485

#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 25, 0)
	const AVCodecDescriptor *codec_descriptor =
		avcodec_descriptor_get(codec_context->codec_id);
	if (codec_descriptor != nullptr)
		FormatDebug(ffmpeg_domain, "codec '%s'",
			    codec_descriptor->name);
#else
486
	if (codec_context->codec_name[0] != 0)
487 488
		FormatDebug(ffmpeg_domain, "codec '%s'",
			    codec_context->codec_name);
489
#endif
490

491
	AVCodec *codec = avcodec_find_decoder(codec_context->codec_id);
492 493

	if (!codec) {
494
		LogError(ffmpeg_domain, "Unsupported audio codec");
495
		avformat_close_input(&format_context);
496 497 498
		return;
	}

499
	const SampleFormat sample_format =
500
		ffmpeg_sample_format(codec_context->sample_fmt);
501 502 503
	if (sample_format == SampleFormat::UNDEFINED) {
		// (error message already done by ffmpeg_sample_format())
		avformat_close_input(&format_context);
504
		return;
505
	}
506

507
	Error error;
508 509
	AudioFormat audio_format;
	if (!audio_format_init_checked(audio_format,
510
				       codec_context->sample_rate,
511
				       sample_format,
512
				       codec_context->channels, error)) {
513
		LogError(error);
514
		avformat_close_input(&format_context);
515 516 517 518 519 520 521 522
		return;
	}

	/* the audio format must be read from AVCodecContext by now,
	   because avcodec_open() has been demonstrated to fill bogus
	   values into AVCodecContext.channels - a change that will be
	   reverted later by avcodec_decode_audio3() */

523
	const int open_result = avcodec_open2(codec_context, codec, nullptr);
524
	if (open_result < 0) {
525
		LogError(ffmpeg_domain, "Could not open codec");
526
		avformat_close_input(&format_context);
527
		return;
528 529
	}

530 531 532 533 534
	const SignedSongTime total_time =
		format_context->duration != (int64_t)AV_NOPTS_VALUE
		? SignedSongTime::FromScale<uint64_t>(format_context->duration,
						      AV_TIME_BASE)
		: SignedSongTime::Negative();
535

536
	decoder_initialized(decoder, audio_format,
537
			    input.IsSeekable(), total_time);
538

539 540 541
#if LIBAVUTIL_VERSION_MAJOR >= 53
	AVFrame *frame = av_frame_alloc();
#else
542
	AVFrame *frame = avcodec_alloc_frame();
543
#endif
544
	if (!frame) {
545
		LogError(ffmpeg_domain, "Could not allocate frame");
546 547 548 549
		avformat_close_input(&format_context);
		return;
	}

550
	uint8_t *interleaved_buffer = nullptr;
551 552
	int interleaved_buffer_size = 0;

553
	DecoderCommand cmd;
554
	do {
555
		AVPacket packet;
Max Kellermann's avatar
Max Kellermann committed
556
		if (av_read_frame(format_context, &packet) < 0)
557 558 559
			/* end of file */
			break;

560 561
		if (packet.stream_index == audio_stream)
			cmd = ffmpeg_send_packet(decoder, input,
Max Kellermann's avatar
Max Kellermann committed
562
						 &packet, codec_context,
563
						 av_stream,
564 565
						 frame,
						 &interleaved_buffer, &interleaved_buffer_size);
566 567 568 569
		else
			cmd = decoder_get_command(decoder);

		av_free_packet(&packet);
570

571
		if (cmd == DecoderCommand::SEEK) {
572
			int64_t where =
573
				time_to_ffmpeg(decoder_seek_time(decoder),
574
					       av_stream->time_base) +
575
				start_time_fallback(*av_stream);
576

577
			if (av_seek_frame(format_context, audio_stream, where,
578
					  AVSEEK_FLAG_ANY) < 0)
579
				decoder_seek_error(decoder);
580 581
			else {
				avcodec_flush_buffers(codec_context);
582
				decoder_command_finished(decoder);
583
			}
584
		}
585
	} while (cmd != DecoderCommand::STOP);
586

587 588 589
#if LIBAVUTIL_VERSION_MAJOR >= 53
	av_frame_free(&frame);
#elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 28, 0)
590 591 592 593
	avcodec_free_frame(&frame);
#else
	av_freep(&frame);
#endif
594
	av_freep(&interleaved_buffer);
595

596
	avcodec_close(codec_context);
597
	avformat_close_input(&format_context);
598 599
}

600
//no tag reading in ffmpeg, check if playable
601
static bool
602
ffmpeg_scan_stream(InputStream &is,
603
		   const struct tag_handler *handler, void *handler_ctx)
604
{
605 606
	AVInputFormat *input_format = ffmpeg_probe(nullptr, is);
	if (input_format == nullptr)
607
		return false;
608

609 610
	AvioStream stream(nullptr, is);
	if (!stream.Open())
611
		return false;
612

613
	AVFormatContext *f = nullptr;
614
	if (mpd_ffmpeg_open_input(&f, stream.io, is.GetURI(),
615
				  input_format) != 0)
616
		return false;
617

618
	const int find_result =
619
		avformat_find_stream_info(f, nullptr);
620 621
	if (find_result < 0) {
		avformat_close_input(&f);
622
		return false;
623 624
	}

625 626 627 628 629 630
	if (f->duration != (int64_t)AV_NOPTS_VALUE) {
		const auto duration =
			SongTime::FromScale<uint64_t>(f->duration,
						      AV_TIME_BASE);
		tag_handler_invoke_duration(handler, handler_ctx, duration);
	}
631

632
	ffmpeg_scan_dictionary(f->metadata, handler, handler_ctx);
633 634
	int idx = ffmpeg_find_audio_stream(f);
	if (idx >= 0)
635 636
		ffmpeg_scan_dictionary(f->streams[idx]->metadata,
				       handler, handler_ctx);
637

638
	avformat_close_input(&f);
639
	return true;
640 641 642
}

/**
643 644 645 646
 * A list of extensions found for the formats supported by ffmpeg.
 * This list is current as of 02-23-09; To find out if there are more
 * supported formats, check the ffmpeg changelog since this date for
 * more formats.
647
 */
Max Kellermann's avatar
Max Kellermann committed
648
static const char *const ffmpeg_suffixes[] = {
649 650 651 652 653
	"16sv", "3g2", "3gp", "4xm", "8svx", "aa3", "aac", "ac3", "afc", "aif",
	"aifc", "aiff", "al", "alaw", "amr", "anim", "apc", "ape", "asf",
	"atrac", "au", "aud", "avi", "avm2", "avs", "bap", "bfi", "c93", "cak",
	"cin", "cmv", "cpk", "daud", "dct", "divx", "dts", "dv", "dvd", "dxa",
	"eac3", "film", "flac", "flc", "fli", "fll", "flx", "flv", "g726",
654 655 656
	"gsm", "gxf", "iss", "m1v", "m2v", "m2t", "m2ts",
	"m4a", "m4b", "m4v",
	"mad",
657 658 659 660 661 662 663
	"mj2", "mjpeg", "mjpg", "mka", "mkv", "mlp", "mm", "mmf", "mov", "mp+",
	"mp1", "mp2", "mp3", "mp4", "mpc", "mpeg", "mpg", "mpga", "mpp", "mpu",
	"mve", "mvi", "mxf", "nc", "nsv", "nut", "nuv", "oga", "ogm", "ogv",
	"ogx", "oma", "ogg", "omg", "psp", "pva", "qcp", "qt", "r3d", "ra",
	"ram", "rl2", "rm", "rmvb", "roq", "rpl", "rvc", "shn", "smk", "snd",
	"sol", "son", "spx", "str", "swf", "tgi", "tgq", "tgv", "thp", "ts",
	"tsp", "tta", "xa", "xvid", "uv", "uv2", "vb", "vid", "vob", "voc",
664 665
	"vp6", "vmd", "wav", "webm", "wma", "wmv", "wsaud", "wsvga", "wv",
	"wve",
666
	nullptr
667 668
};

Max Kellermann's avatar
Max Kellermann committed
669
static const char *const ffmpeg_mime_types[] = {
670
	"application/flv",
671
	"application/m4a",
672 673 674 675 676
	"application/mp4",
	"application/octet-stream",
	"application/ogg",
	"application/x-ms-wmz",
	"application/x-ms-wmd",
677
	"application/x-ogg",
678 679 680 681 682 683
	"application/x-shockwave-flash",
	"application/x-shorten",
	"audio/8svx",
	"audio/16sv",
	"audio/aac",
	"audio/ac3",
684
	"audio/aiff"
685 686 687
	"audio/amr",
	"audio/basic",
	"audio/flac",
688 689
	"audio/m4a",
	"audio/mp4",
690 691 692 693 694
	"audio/mpeg",
	"audio/musepack",
	"audio/ogg",
	"audio/qcelp",
	"audio/vorbis",
695
	"audio/vorbis+ogg",
696 697 698 699 700 701 702 703 704 705 706 707
	"audio/x-8svx",
	"audio/x-16sv",
	"audio/x-aac",
	"audio/x-ac3",
	"audio/x-aiff"
	"audio/x-alaw",
	"audio/x-au",
	"audio/x-dca",
	"audio/x-eac3",
	"audio/x-flac",
	"audio/x-gsm",
	"audio/x-mace",
708
	"audio/x-matroska",
709 710
	"audio/x-monkeys-audio",
	"audio/x-mpeg",
711 712
	"audio/x-ms-wma",
	"audio/x-ms-wax",
713
	"audio/x-musepack",
714 715 716
	"audio/x-ogg",
	"audio/x-vorbis",
	"audio/x-vorbis+ogg",
717 718 719 720
	"audio/x-pn-realaudio",
	"audio/x-pn-multirate-realaudio",
	"audio/x-speex",
	"audio/x-tta"
721
	"audio/x-voc",
722 723 724 725 726 727 728 729
	"audio/x-wav",
	"audio/x-wma",
	"audio/x-wv",
	"video/anim",
	"video/quicktime",
	"video/msvideo",
	"video/ogg",
	"video/theora",
730
	"video/webm",
731 732 733 734 735 736 737
	"video/x-dv",
	"video/x-flv",
	"video/x-matroska",
	"video/x-mjpeg",
	"video/x-mpeg",
	"video/x-ms-asf",
	"video/x-msvideo",
738 739 740 741
	"video/x-ms-wmv",
	"video/x-ms-wvx",
	"video/x-ms-wm",
	"video/x-ms-wmx",
742 743 744 745 746 747
	"video/x-nut",
	"video/x-pva",
	"video/x-theora",
	"video/x-vid",
	"video/x-wmv",
	"video/x-xvid",
748 749 750 751 752 753

	/* special value for the "ffmpeg" input plugin: all streams by
	   the "ffmpeg" input plugin shall be decoded by this
	   plugin */
	"audio/x-mpd-ffmpeg",

754
	nullptr
755 756
};

757
const struct DecoderPlugin ffmpeg_decoder_plugin = {
758 759 760 761 762 763 764 765 766 767
	"ffmpeg",
	ffmpeg_init,
	nullptr,
	ffmpeg_decode,
	nullptr,
	nullptr,
	ffmpeg_scan_stream,
	nullptr,
	ffmpeg_suffixes,
	ffmpeg_mime_types
768
};