From df97049647a82f4da4f4fa0faacb8cb2ab5a96ac Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 19 Dec 2014 10:35:10 +0100 Subject: [PATCH] decoder/ffmpeg: move struct AvioStream to FfmpegIo.hxx --- Makefile.am | 2 + src/decoder/plugins/FfmpegDecoderPlugin.cxx | 85 +---------------- src/decoder/plugins/FfmpegIo.cxx | 100 ++++++++++++++++++++ src/decoder/plugins/FfmpegIo.hxx | 48 ++++++++++ 4 files changed, 151 insertions(+), 84 deletions(-) create mode 100644 src/decoder/plugins/FfmpegIo.cxx create mode 100644 src/decoder/plugins/FfmpegIo.hxx diff --git a/Makefile.am b/Makefile.am index 15a66c113..1ca69db07 100644 --- a/Makefile.am +++ b/Makefile.am @@ -983,6 +983,8 @@ endif if HAVE_FFMPEG libdecoder_a_SOURCES += \ + src/decoder/plugins/FfmpegIo.cxx \ + src/decoder/plugins/FfmpegIo.hxx \ src/decoder/plugins/FfmpegMetaData.cxx \ src/decoder/plugins/FfmpegMetaData.hxx \ src/decoder/plugins/FfmpegDecoderPlugin.cxx \ diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index 53e3c74be..a3419d0ac 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/TagHandler.hxx" #include "input/InputStream.hxx" #include "CheckAudioFormat.hxx" @@ -85,90 +86,6 @@ mpd_ffmpeg_log_callback(gcc_unused void *ptr, int level, } } -struct AvioStream { - Decoder *const decoder; - InputStream &input; - - AVIOContext *io; - - AvioStream(Decoder *_decoder, InputStream &_input) - :decoder(_decoder), input(_input), io(nullptr) {} - - ~AvioStream() { - if (io != nullptr) { - av_free(io->buffer); - 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() -{ - constexpr size_t BUFFER_SIZE = 8192; - auto buffer = (unsigned char *)av_malloc(BUFFER_SIZE); - if (buffer == nullptr) - return false; - - io = avio_alloc_context(buffer, BUFFER_SIZE, - false, this, - mpd_ffmpeg_stream_read, nullptr, - input.IsSeekable() - ? mpd_ffmpeg_stream_seek : nullptr); - /* If avio_alloc_context() fails, who frees the buffer? The - libavformat API documentation does not specify this, it - only says that AVIOContext.buffer must be freed in the end, - however no AVIOContext exists in that failure code path. */ - 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..5f8452c68 --- /dev/null +++ b/src/decoder/plugins/FfmpegIo.cxx @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2003-2016 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() +{ + if (io != nullptr) { + av_free(io->buffer); + 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() +{ + constexpr size_t BUFFER_SIZE = 8192; + auto buffer = (unsigned char *)av_malloc(BUFFER_SIZE); + if (buffer == nullptr) + return false; + + io = avio_alloc_context(buffer, BUFFER_SIZE, + false, this, + mpd_ffmpeg_stream_read, nullptr, + input.IsSeekable() + ? mpd_ffmpeg_stream_seek : nullptr); + /* If avio_alloc_context() fails, who frees the buffer? The + libavformat API documentation does not specify this, it + only says that AVIOContext.buffer must be freed in the end, + however no AVIOContext exists in that failure code path. */ + return io != nullptr; +} diff --git a/src/decoder/plugins/FfmpegIo.hxx b/src/decoder/plugins/FfmpegIo.hxx new file mode 100644 index 000000000..7c400de89 --- /dev/null +++ b/src/decoder/plugins/FfmpegIo.hxx @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2003-2016 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 + +class InputStream; +struct Decoder; + +struct AvioStream { + Decoder *const decoder; + InputStream &input; + + AVIOContext *io; + + AvioStream(Decoder *_decoder, InputStream &_input) + :decoder(_decoder), input(_input), io(nullptr) {} + + ~AvioStream(); + + bool Open(); +}; + +#endif