FfmpegDecoderPlugin.cxx 19.8 KB
Newer Older
1
/*
2
 * Copyright 2003-2016 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 "lib/ffmpeg/Time.hxx"
24
#include "config.h"
25
#include "FfmpegDecoderPlugin.hxx"
26
#include "lib/ffmpeg/Domain.hxx"
27
#include "lib/ffmpeg/Error.hxx"
28
#include "lib/ffmpeg/LogError.hxx"
29
#include "lib/ffmpeg/Init.hxx"
30
#include "lib/ffmpeg/Buffer.hxx"
31
#include "../DecoderAPI.hxx"
32
#include "FfmpegMetaData.hxx"
33
#include "FfmpegIo.hxx"
34
#include "pcm/Interleave.hxx"
35
#include "tag/TagBuilder.hxx"
36
#include "tag/TagHandler.hxx"
37 38
#include "tag/ReplayGain.hxx"
#include "tag/MixRamp.hxx"
Max Kellermann's avatar
Max Kellermann committed
39
#include "input/InputStream.hxx"
40
#include "CheckAudioFormat.hxx"
41
#include "util/ConstBuffer.hxx"
42
#include "util/Error.hxx"
43
#include "LogV.hxx"
44 45

extern "C" {
46 47 48
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
49
#include <libavutil/avutil.h>
50 51 52 53

#if LIBAVUTIL_VERSION_MAJOR >= 53
#include <libavutil/frame.h>
#endif
54
}
55

56 57 58
#include <assert.h>
#include <string.h>

59 60
static AVFormatContext *
FfmpegOpenInput(AVIOContext *pb,
61 62
		const char *filename,
		AVInputFormat *fmt)
63 64
{
	AVFormatContext *context = avformat_alloc_context();
65
	if (context == nullptr)
66
		return nullptr;
67 68

	context->pb = pb;
69 70 71

	avformat_open_input(&context, filename, fmt, nullptr);
	return context;
72 73
}

74
static bool
75
ffmpeg_init(gcc_unused const ConfigBlock &block)
76
{
77
	FfmpegInit();
78
	return true;
79 80
}

81
gcc_pure
82
static int
83
ffmpeg_find_audio_stream(const AVFormatContext &format_context)
84
{
85 86
	for (unsigned i = 0; i < format_context.nb_streams; ++i)
		if (format_context.streams[i]->codec->codec_type ==
87
		    AVMEDIA_TYPE_AUDIO)
88 89 90 91 92
			return i;

	return -1;
}

93 94 95 96 97 98
/**
 * 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.
 */
99
static constexpr int64_t
100 101
start_time_fallback(const AVStream &stream)
{
102
	return FfmpegTimestampFallback(stream.start_time, 0);
103 104
}

105
/**
106
 * Copy PCM data from a non-empty AVFrame to an interleaved buffer.
107
 */
108
static ConstBuffer<void>
109 110
copy_interleave_frame(const AVCodecContext &codec_context,
		      const AVFrame &frame,
111 112
		      FfmpegBuffer &global_buffer,
		      Error &error)
113
{
114 115
	assert(frame.nb_samples > 0);

116 117 118
	int plane_size;
	const int data_size =
		av_samples_get_buffer_size(&plane_size,
119 120 121
					   codec_context.channels,
					   frame.nb_samples,
					   codec_context.sample_fmt, 1);
122 123 124 125 126
	assert(data_size != 0);
	if (data_size < 0) {
		SetFfmpegError(error, data_size);
		return 0;
	}
127

128
	void *output_buffer;
129 130
	if (av_sample_fmt_is_planar(codec_context.sample_fmt) &&
	    codec_context.channels > 1) {
131 132
		output_buffer = global_buffer.GetT<uint8_t>(data_size);
		if (output_buffer == nullptr) {
133
			/* Not enough memory - shouldn't happen */
134 135 136
			error.SetErrno(ENOMEM);
			return 0;
		}
137

138 139 140 141 142
		PcmInterleave(output_buffer,
			      ConstBuffer<const void *>((const void *const*)frame.extended_data,
							codec_context.channels),
			      frame.nb_samples,
			      av_get_bytes_per_sample(codec_context.sample_fmt));
143
	} else {
144
		output_buffer = frame.extended_data[0];
145 146
	}

147
	return { output_buffer, (size_t)data_size };
148 149
}

150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
/**
 * Convert AVPacket::pts to a stream-relative time stamp (still in
 * AVStream::time_base units).  Returns a negative value on error.
 */
gcc_pure
static int64_t
StreamRelativePts(const AVPacket &packet, const AVStream &stream)
{
	auto pts = packet.pts;
	if (pts < 0 || pts == int64_t(AV_NOPTS_VALUE))
		return -1;

	auto start = start_time_fallback(stream);
	return pts - start;
}

166 167 168 169 170 171 172 173 174 175 176 177
/**
 * Convert a non-negative stream-relative time stamp in
 * AVStream::time_base units to a PCM frame number.
 */
gcc_pure
static uint64_t
PtsToPcmFrame(uint64_t pts, const AVStream &stream,
	      const AVCodecContext &codec_context)
{
	return av_rescale_q(pts, stream.time_base, codec_context.time_base);
}

178 179 180
/**
 * Decode an #AVPacket and send the resulting PCM data to the decoder
 * API.
Max Kellermann's avatar
Max Kellermann committed
181
 *
182 183 184
 * @param min_frame skip all data before this PCM frame number; this
 * is used after seeking to skip data in an AVPacket until the exact
 * desired time stamp has been reached
185
 */
186
static DecoderCommand
187
ffmpeg_send_packet(Decoder &decoder, InputStream &is,
188
		   AVPacket &&packet,
189 190 191
		   AVCodecContext &codec_context,
		   const AVStream &stream,
		   AVFrame &frame,
192
		   uint64_t min_frame, size_t pcm_frame_size,
193
		   FfmpegBuffer &buffer)
194
{
195 196
	size_t skip_bytes = 0;

Max Kellermann's avatar
Max Kellermann committed
197
	const auto pts = StreamRelativePts(packet, stream);
198
	if (pts >= 0) {
199
		if (min_frame > 0) {
Max Kellermann's avatar
Max Kellermann committed
200 201
			auto cur_frame = PtsToPcmFrame(pts, stream,
						       codec_context);
202 203 204
			if (cur_frame < min_frame)
				skip_bytes = pcm_frame_size * (min_frame - cur_frame);
		} else
205
			decoder_timestamp(decoder,
Max Kellermann's avatar
Max Kellermann committed
206
					  FfmpegTimeToDouble(pts,
207
							     stream.time_base));
208
	}
209

210 211
	Error error;

212
	DecoderCommand cmd = DecoderCommand::NONE;
213
	while (packet.size > 0 && cmd == DecoderCommand::NONE) {
214
		int got_frame = 0;
215 216
		int len = avcodec_decode_audio4(&codec_context,
						&frame, &got_frame,
217
						&packet);
218 219
		if (len < 0) {
			/* if error, we skip the frame */
220
			LogFfmpegError(len, "decoding failed, frame skipped");
221 222 223
			break;
		}

224 225
		packet.data += len;
		packet.size -= len;
226

227
		if (!got_frame || frame.nb_samples <= 0)
228 229
			continue;

230
		auto output_buffer =
231
			copy_interleave_frame(codec_context, frame,
232
					      buffer, error);
233
		if (output_buffer.IsNull()) {
234 235
			/* this must be a serious error,
			   e.g. OOM */
236
			LogError(error);
237 238 239
			return DecoderCommand::STOP;
		}

240
		if (skip_bytes > 0) {
Max Kellermann's avatar
Max Kellermann committed
241 242
			if (skip_bytes >= output_buffer.size) {
				skip_bytes -= output_buffer.size;
243 244 245
				continue;
			}

Max Kellermann's avatar
Max Kellermann committed
246 247 248
			output_buffer.data =
				(const uint8_t *)output_buffer.data + skip_bytes;
			output_buffer.size -= skip_bytes;
249 250 251
			skip_bytes = 0;
		}

252
		cmd = decoder_data(decoder, is,
253
				   output_buffer.data, output_buffer.size,
254
				   codec_context.bit_rate / 1000);
255
	}
256
	return cmd;
257 258
}

259
gcc_const
260
static SampleFormat
261
ffmpeg_sample_format(enum AVSampleFormat sample_fmt)
262
{
263
	switch (sample_fmt) {
264
	case AV_SAMPLE_FMT_S16:
265
	case AV_SAMPLE_FMT_S16P:
266
		return SampleFormat::S16;
267

268
	case AV_SAMPLE_FMT_S32:
269
	case AV_SAMPLE_FMT_S32P:
270
		return SampleFormat::S32;
271

272
	case AV_SAMPLE_FMT_FLT:
273
	case AV_SAMPLE_FMT_FLTP:
274
		return SampleFormat::FLOAT;
275

276
	default:
277 278 279 280 281 282
		break;
	}

	char buffer[64];
	const char *name = av_get_sample_fmt_string(buffer, sizeof(buffer),
						    sample_fmt);
283
	if (name != nullptr)
284 285 286
		FormatError(ffmpeg_domain,
			    "Unsupported libavcodec SampleFormat value: %s (%d)",
			    name, sample_fmt);
287
	else
288 289 290
		FormatError(ffmpeg_domain,
			    "Unsupported libavcodec SampleFormat value: %d",
			    sample_fmt);
291
	return SampleFormat::UNDEFINED;
292 293
}

294
static AVInputFormat *
295
ffmpeg_probe(Decoder *decoder, InputStream &is)
296
{
297 298
	constexpr size_t BUFFER_SIZE = 16384;
	constexpr size_t PADDING = 16;
299

300
	unsigned char buffer[BUFFER_SIZE];
301
	size_t nbytes = decoder_read(decoder, is, buffer, BUFFER_SIZE);
302
	if (nbytes <= PADDING || !is.LockRewind(IgnoreError()))
303
		return nullptr;
304 305 306 307 308 309 310

	/* 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;

311
	AVProbeData avpd;
312 313 314 315 316 317

	/* 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));

318 319
	avpd.buf = buffer;
	avpd.buf_size = nbytes;
320
	avpd.filename = is.GetURI();
321

322
#ifdef AVPROBE_SCORE_MIME
323
#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(56, 5, 1)
324 325 326 327
	/* 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());
328 329 330 331
#else
	/* API problem fixed in FFmpeg 2.5 */
	avpd.mime_type = is.GetMimeType();
#endif
332 333
#endif

334
	return av_probe_input_format(&avpd, true);
335 336
}

337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
static void
FfmpegParseMetaData(AVDictionary &dict, ReplayGainInfo &rg, MixRampInfo &mr)
{
	AVDictionaryEntry *i = nullptr;

	while ((i = av_dict_get(&dict, "", i,
				AV_DICT_IGNORE_SUFFIX)) != nullptr) {
		const char *name = i->key;
		const char *value = i->value;

		if (!ParseReplayGainTag(rg, name, value))
			ParseMixRampTag(mr, name, value);
	}
}

static void
FfmpegParseMetaData(const AVStream &stream,
		    ReplayGainInfo &rg, MixRampInfo &mr)
{
	FfmpegParseMetaData(*stream.metadata, rg, mr);
}

static void
FfmpegParseMetaData(const AVFormatContext &format_context, int audio_stream,
		    ReplayGainInfo &rg, MixRampInfo &mr)
{
363
	assert(audio_stream >= 0);
364

365 366
	FfmpegParseMetaData(*format_context.metadata, rg, mr);
	FfmpegParseMetaData(*format_context.streams[audio_stream],
367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
				    rg, mr);
}

static void
FfmpegParseMetaData(Decoder &decoder,
		    const AVFormatContext &format_context, int audio_stream)
{
	ReplayGainInfo rg;
	rg.Clear();

	MixRampInfo mr;
	mr.Clear();

	FfmpegParseMetaData(format_context, audio_stream, rg, mr);

	if (rg.IsDefined())
		decoder_replay_gain(decoder, &rg);

	if (mr.IsDefined())
		decoder_mixramp(decoder, std::move(mr));
}

389 390
static void
FfmpegScanMetadata(const AVStream &stream,
391
		   const TagHandler &handler, void *handler_ctx)
392
{
393
	FfmpegScanDictionary(stream.metadata, handler, handler_ctx);
394 395 396 397
}

static void
FfmpegScanMetadata(const AVFormatContext &format_context, int audio_stream,
398
		   const TagHandler &handler, void *handler_ctx)
399
{
400 401
	assert(audio_stream >= 0);

402
	FfmpegScanDictionary(format_context.metadata, handler, handler_ctx);
403 404
	FfmpegScanMetadata(*format_context.streams[audio_stream],
			   handler, handler_ctx);
405 406
}

407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(56, 1, 0)

static void
FfmpegScanTag(const AVFormatContext &format_context, int audio_stream,
	      TagBuilder &tag)
{
	FfmpegScanMetadata(format_context, audio_stream,
			   full_tag_handler, &tag);
}

/**
 * Check if a new stream tag was received and pass it to
 * decoder_tag().
 */
static void
FfmpegCheckTag(Decoder &decoder, InputStream &is,
	       AVFormatContext &format_context, int audio_stream)
{
	AVStream &stream = *format_context.streams[audio_stream];
	if ((stream.event_flags & AVSTREAM_EVENT_FLAG_METADATA_UPDATED) == 0)
		/* no new metadata */
		return;

	/* clear the flag */
	stream.event_flags &= ~AVSTREAM_EVENT_FLAG_METADATA_UPDATED;

	TagBuilder tag;
	FfmpegScanTag(format_context, audio_stream, tag);
	if (!tag.IsEmpty())
		decoder_tag(decoder, is, tag.Commit());
}

#endif

441
static void
442 443
FfmpegDecode(Decoder &decoder, InputStream &input,
	     AVFormatContext &format_context)
444
{
445
	const int find_result =
446
		avformat_find_stream_info(&format_context, nullptr);
447
	if (find_result < 0) {
448
		LogError(ffmpeg_domain, "Couldn't find stream info");
449 450
		return;
	}
451

452
	int audio_stream = ffmpeg_find_audio_stream(format_context);
453
	if (audio_stream == -1) {
454
		LogError(ffmpeg_domain, "No audio stream inside");
455 456
		return;
	}
457

458
	AVStream &av_stream = *format_context.streams[audio_stream];
459

460
	AVCodecContext &codec_context = *av_stream.codec;
461 462 463

#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 25, 0)
	const AVCodecDescriptor *codec_descriptor =
464
		avcodec_descriptor_get(codec_context.codec_id);
465 466 467 468
	if (codec_descriptor != nullptr)
		FormatDebug(ffmpeg_domain, "codec '%s'",
			    codec_descriptor->name);
#else
469
	if (codec_context.codec_name[0] != 0)
470
		FormatDebug(ffmpeg_domain, "codec '%s'",
471
			    codec_context.codec_name);
472
#endif
473

474
	AVCodec *codec = avcodec_find_decoder(codec_context.codec_id);
475 476

	if (!codec) {
477
		LogError(ffmpeg_domain, "Unsupported audio codec");
478 479 480
		return;
	}

481
	const SampleFormat sample_format =
482
		ffmpeg_sample_format(codec_context.sample_fmt);
483 484
	if (sample_format == SampleFormat::UNDEFINED) {
		// (error message already done by ffmpeg_sample_format())
485
		return;
486
	}
487

488
	Error error;
489 490
	AudioFormat audio_format;
	if (!audio_format_init_checked(audio_format,
491
				       codec_context.sample_rate,
492
				       sample_format,
493
				       codec_context.channels, error)) {
494
		LogError(error);
495 496 497 498 499 500 501 502
		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() */

503
	const int open_result = avcodec_open2(&codec_context, codec, nullptr);
504
	if (open_result < 0) {
505
		LogError(ffmpeg_domain, "Could not open codec");
506
		return;
507 508
	}

509
	const SignedSongTime total_time =
510
		FromFfmpegTimeChecked(av_stream.duration, av_stream.time_base);
511

512
	decoder_initialized(decoder, audio_format,
513
			    input.IsSeekable(), total_time);
514

515
	FfmpegParseMetaData(decoder, format_context, audio_stream);
516

517 518 519
#if LIBAVUTIL_VERSION_MAJOR >= 53
	AVFrame *frame = av_frame_alloc();
#else
520
	AVFrame *frame = avcodec_alloc_frame();
521
#endif
522
	if (!frame) {
523
		LogError(ffmpeg_domain, "Could not allocate frame");
524 525 526
		return;
	}

527
	FfmpegBuffer interleaved_buffer;
528

529 530
	uint64_t min_frame = 0;

531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
	DecoderCommand cmd = decoder_get_command(decoder);
	while (cmd != DecoderCommand::STOP) {
		if (cmd == DecoderCommand::SEEK) {
			int64_t where =
				ToFfmpegTime(decoder_seek_time(decoder),
					     av_stream.time_base) +
				start_time_fallback(av_stream);

			/* AVSEEK_FLAG_BACKWARD asks FFmpeg to seek to
			   the packet boundary before the seek time
			   stamp, not after */
			if (av_seek_frame(&format_context, audio_stream, where,
					  AVSEEK_FLAG_ANY|AVSEEK_FLAG_BACKWARD) < 0)
				decoder_seek_error(decoder);
			else {
				avcodec_flush_buffers(&codec_context);
				min_frame = decoder_seek_where_frame(decoder);
				decoder_command_finished(decoder);
			}
		}

552
		AVPacket packet;
553
		if (av_read_frame(&format_context, &packet) < 0)
554 555 556
			/* end of file */
			break;

557
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(56, 1, 0)
558
		FfmpegCheckTag(decoder, input, format_context, audio_stream);
559 560
#endif

561
		if (packet.stream_index == audio_stream) {
562
			cmd = ffmpeg_send_packet(decoder, input,
563
						 std::move(packet),
Max Kellermann's avatar
Max Kellermann committed
564
						 codec_context,
565
						 av_stream,
566
						 *frame,
567
						 min_frame, audio_format.GetFrameSize(),
568
						 interleaved_buffer);
569 570
			min_frame = 0;
		} else
571 572
			cmd = decoder_get_command(decoder);

573 574 575
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 25, 100)
		av_packet_unref(&packet);
#else
576
		av_free_packet(&packet);
577
#endif
578
	}
579

580 581 582
#if LIBAVUTIL_VERSION_MAJOR >= 53
	av_frame_free(&frame);
#elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(54, 28, 0)
583 584
	avcodec_free_frame(&frame);
#else
585
	av_free(frame);
586 587
#endif

588
	avcodec_close(&codec_context);
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606
}

static void
ffmpeg_decode(Decoder &decoder, InputStream &input)
{
	AVInputFormat *input_format = ffmpeg_probe(&decoder, input);
	if (input_format == nullptr)
		return;

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

	AvioStream stream(&decoder, input);
	if (!stream.Open()) {
		LogError(ffmpeg_domain, "Failed to open stream");
		return;
	}

607 608 609
	AVFormatContext *format_context =
		FfmpegOpenInput(stream.io, input.GetURI(), input_format);
	if (format_context == nullptr) {
610 611 612 613 614
		LogError(ffmpeg_domain, "Open failed");
		return;
	}

	FfmpegDecode(decoder, input, *format_context);
615
	avformat_close_input(&format_context);
616 617
}

618 619
static bool
FfmpegScanStream(AVFormatContext &format_context,
620
		 const TagHandler &handler, void *handler_ctx)
621 622 623 624 625 626
{
	const int find_result =
		avformat_find_stream_info(&format_context, nullptr);
	if (find_result < 0)
		return false;

627 628 629 630
	const int audio_stream = ffmpeg_find_audio_stream(format_context);
	if (audio_stream < 0)
		return false;

631 632
	const AVStream &stream = *format_context.streams[audio_stream];
	if (stream.duration != (int64_t)AV_NOPTS_VALUE)
633
		tag_handler_invoke_duration(handler, handler_ctx,
634 635
					    FromFfmpegTime(stream.duration,
							   stream.time_base));
636

637
	FfmpegScanMetadata(format_context, audio_stream, handler, handler_ctx);
638 639 640 641

	return true;
}

642
static bool
643
ffmpeg_scan_stream(InputStream &is,
644
		   const TagHandler &handler, void *handler_ctx)
645
{
646 647
	AVInputFormat *input_format = ffmpeg_probe(nullptr, is);
	if (input_format == nullptr)
648
		return false;
649

650 651
	AvioStream stream(nullptr, is);
	if (!stream.Open())
652
		return false;
653

654 655 656
	AVFormatContext *f =
		FfmpegOpenInput(stream.io, is.GetURI(), input_format);
	if (f == nullptr)
657
		return false;
658

659
	bool result = FfmpegScanStream(*f, handler, handler_ctx);
660
	avformat_close_input(&f);
661
	return result;
662 663 664
}

/**
665 666 667 668
 * 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.
669
 */
Max Kellermann's avatar
Max Kellermann committed
670
static const char *const ffmpeg_suffixes[] = {
671 672 673 674 675
	"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",
676 677 678
	"gsm", "gxf", "iss", "m1v", "m2v", "m2t", "m2ts",
	"m4a", "m4b", "m4v",
	"mad",
679 680 681
	"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",
682
	"ogx", "oma", "ogg", "omg", "opus", "psp", "pva", "qcp", "qt", "r3d", "ra",
683
	"ram", "rl2", "rm", "rmvb", "roq", "rpl", "rvc", "shn", "smk", "snd",
684
	"sol", "son", "spx", "str", "swf", "tak", "tgi", "tgq", "tgv", "thp", "ts",
685
	"tsp", "tta", "xa", "xvid", "uv", "uv2", "vb", "vid", "vob", "voc",
686 687
	"vp6", "vmd", "wav", "webm", "wma", "wmv", "wsaud", "wsvga", "wv",
	"wve",
688
	nullptr
689 690
};

Max Kellermann's avatar
Max Kellermann committed
691
static const char *const ffmpeg_mime_types[] = {
692
	"application/flv",
693
	"application/m4a",
694 695 696 697 698
	"application/mp4",
	"application/octet-stream",
	"application/ogg",
	"application/x-ms-wmz",
	"application/x-ms-wmd",
699
	"application/x-ogg",
700 701 702 703 704
	"application/x-shockwave-flash",
	"application/x-shorten",
	"audio/8svx",
	"audio/16sv",
	"audio/aac",
705
	"audio/aacp",
706
	"audio/ac3",
707
	"audio/aiff"
708 709 710
	"audio/amr",
	"audio/basic",
	"audio/flac",
711 712
	"audio/m4a",
	"audio/mp4",
713 714 715
	"audio/mpeg",
	"audio/musepack",
	"audio/ogg",
716
	"audio/opus",
717 718
	"audio/qcelp",
	"audio/vorbis",
719
	"audio/vorbis+ogg",
720 721 722 723 724 725 726 727 728 729 730 731
	"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",
732
	"audio/x-matroska",
733 734
	"audio/x-monkeys-audio",
	"audio/x-mpeg",
735 736
	"audio/x-ms-wma",
	"audio/x-ms-wax",
737
	"audio/x-musepack",
738 739 740
	"audio/x-ogg",
	"audio/x-vorbis",
	"audio/x-vorbis+ogg",
741 742 743 744
	"audio/x-pn-realaudio",
	"audio/x-pn-multirate-realaudio",
	"audio/x-speex",
	"audio/x-tta"
745
	"audio/x-voc",
746 747 748 749 750 751 752 753
	"audio/x-wav",
	"audio/x-wma",
	"audio/x-wv",
	"video/anim",
	"video/quicktime",
	"video/msvideo",
	"video/ogg",
	"video/theora",
754
	"video/webm",
755 756 757 758 759 760 761
	"video/x-dv",
	"video/x-flv",
	"video/x-matroska",
	"video/x-mjpeg",
	"video/x-mpeg",
	"video/x-ms-asf",
	"video/x-msvideo",
762 763 764 765
	"video/x-ms-wmv",
	"video/x-ms-wvx",
	"video/x-ms-wm",
	"video/x-ms-wmx",
766 767 768 769 770 771
	"video/x-nut",
	"video/x-pva",
	"video/x-theora",
	"video/x-vid",
	"video/x-wmv",
	"video/x-xvid",
772 773 774 775 776 777

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

778
	nullptr
779 780
};

781
const struct DecoderPlugin ffmpeg_decoder_plugin = {
782 783 784 785 786 787 788 789 790 791
	"ffmpeg",
	ffmpeg_init,
	nullptr,
	ffmpeg_decode,
	nullptr,
	nullptr,
	ffmpeg_scan_stream,
	nullptr,
	ffmpeg_suffixes,
	ffmpeg_mime_types
792
};