diff options
Diffstat (limited to 'src/decoder')
-rw-r--r-- | src/decoder/plugins/FfmpegDecoderPlugin.cxx | 75 | ||||
-rw-r--r-- | src/decoder/plugins/FfmpegIo.cxx | 88 | ||||
-rw-r--r-- | src/decoder/plugins/FfmpegIo.hxx | 50 |
3 files changed, 139 insertions, 74 deletions
diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index 6ddb16d1d..0c809c18e 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -29,6 +29,7 @@ #include "lib/ffmpeg/Buffer.hxx" #include "../DecoderAPI.hxx" #include "FfmpegMetaData.hxx" +#include "FfmpegIo.hxx" #include "tag/TagBuilder.hxx" #include "tag/TagHandler.hxx" #include "tag/ReplayGain.hxx" @@ -88,80 +89,6 @@ mpd_ffmpeg_log_callback(gcc_unused void *ptr, int level, } } -struct AvioStream { - Decoder *const decoder; - InputStream &input; - - AVIOContext *io; - - unsigned char buffer[8192]; - - AvioStream(Decoder *_decoder, InputStream &_input) - :decoder(_decoder), input(_input), io(nullptr) {} - - ~AvioStream() { - av_free(io); - } - - bool Open(); -}; - -static int -mpd_ffmpeg_stream_read(void *opaque, uint8_t *buf, int size) -{ - AvioStream *stream = (AvioStream *)opaque; - - return decoder_read(stream->decoder, stream->input, - (void *)buf, size); -} - -static int64_t -mpd_ffmpeg_stream_seek(void *opaque, int64_t pos, int whence) -{ - AvioStream *stream = (AvioStream *)opaque; - - 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: - if (!stream->input.KnownSize()) - return -1; - - return stream->input.GetSize(); - - default: - return -1; - } - - if (!stream->input.LockSeek(pos, IgnoreError())) - return -1; - - return stream->input.GetOffset(); -} - -bool -AvioStream::Open() -{ - io = avio_alloc_context(buffer, sizeof(buffer), - false, this, - mpd_ffmpeg_stream_read, nullptr, - input.IsSeekable() - ? mpd_ffmpeg_stream_seek : nullptr); - return io != nullptr; -} - /** * API compatibility wrapper for av_open_input_stream() and * avformat_open_input(). diff --git a/src/decoder/plugins/FfmpegIo.cxx b/src/decoder/plugins/FfmpegIo.cxx new file mode 100644 index 000000000..12df15bb2 --- /dev/null +++ b/src/decoder/plugins/FfmpegIo.cxx @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * 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. + */ + +/* necessary because libavutil/common.h uses UINT64_C */ +#define __STDC_CONSTANT_MACROS + +#include "config.h" +#include "FfmpegIo.hxx" +#include "../DecoderAPI.hxx" +#include "input/InputStream.hxx" +#include "util/Error.hxx" + +AvioStream::~AvioStream() +{ + av_free(io); +} + +static int +mpd_ffmpeg_stream_read(void *opaque, uint8_t *buf, int size) +{ + AvioStream *stream = (AvioStream *)opaque; + + return decoder_read(stream->decoder, stream->input, + (void *)buf, size); +} + +static int64_t +mpd_ffmpeg_stream_seek(void *opaque, int64_t pos, int whence) +{ + AvioStream *stream = (AvioStream *)opaque; + + 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: + if (!stream->input.KnownSize()) + return -1; + + return stream->input.GetSize(); + + default: + return -1; + } + + if (!stream->input.LockSeek(pos, IgnoreError())) + return -1; + + return stream->input.GetOffset(); +} + +bool +AvioStream::Open() +{ + io = avio_alloc_context(buffer, sizeof(buffer), + false, this, + mpd_ffmpeg_stream_read, nullptr, + input.IsSeekable() + ? mpd_ffmpeg_stream_seek : nullptr); + return io != nullptr; +} diff --git a/src/decoder/plugins/FfmpegIo.hxx b/src/decoder/plugins/FfmpegIo.hxx new file mode 100644 index 000000000..1b154faa9 --- /dev/null +++ b/src/decoder/plugins/FfmpegIo.hxx @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * 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. + */ + +#ifndef MPD_FFMPEG_IO_HXX +#define MPD_FFMPEG_IO_HXX + +#include "check.h" + +extern "C" { +#include "libavformat/avio.h" +} + +#include <stdint.h> + +class InputStream; +struct Decoder; + +struct AvioStream { + Decoder *const decoder; + InputStream &input; + + AVIOContext *io; + + uint8_t buffer[8192]; + + AvioStream(Decoder *_decoder, InputStream &_input) + :decoder(_decoder), input(_input), io(nullptr) {} + + ~AvioStream(); + + bool Open(); +}; + +#endif |