|
|
|
@ -4,6 +4,7 @@
|
|
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
|
|
extern "C" {
|
|
|
|
|
#ifndef HAVE_LIBSWRESAMPLE
|
|
|
|
@ -15,6 +16,8 @@ AVAudioResampleContext * swr_alloc_set_opts( AVAudioResampleContext *avr, int64_
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#include <components/vfs/manager.hpp>
|
|
|
|
|
|
|
|
|
|
namespace MWSound
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
@ -27,8 +30,10 @@ int FFmpeg_Decoder::readPacket(void *user_data, uint8_t *buf, int buf_size)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Ogre::DataStreamPtr stream = static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
|
|
|
|
return stream->read(buf, buf_size);
|
|
|
|
|
std::istream& stream = *static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
|
|
|
|
stream.read((char*)buf, buf_size);
|
|
|
|
|
stream.clear();
|
|
|
|
|
return stream.gcount();
|
|
|
|
|
}
|
|
|
|
|
catch (std::exception& )
|
|
|
|
|
{
|
|
|
|
@ -36,36 +41,36 @@ int FFmpeg_Decoder::readPacket(void *user_data, uint8_t *buf, int buf_size)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int FFmpeg_Decoder::writePacket(void *user_data, uint8_t *buf, int buf_size)
|
|
|
|
|
int FFmpeg_Decoder::writePacket(void *, uint8_t *, int)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Ogre::DataStreamPtr stream = static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
|
|
|
|
return stream->write(buf, buf_size);
|
|
|
|
|
}
|
|
|
|
|
catch (std::exception& )
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error("can't write to read-only stream");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int64_t FFmpeg_Decoder::seek(void *user_data, int64_t offset, int whence)
|
|
|
|
|
{
|
|
|
|
|
Ogre::DataStreamPtr stream = static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
|
|
|
|
std::istream& stream = *static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
|
|
|
|
|
|
|
|
|
|
whence &= ~AVSEEK_FORCE;
|
|
|
|
|
|
|
|
|
|
if(whence == AVSEEK_SIZE)
|
|
|
|
|
return stream->size();
|
|
|
|
|
{
|
|
|
|
|
size_t prev = stream.tellg();
|
|
|
|
|
stream.seekg(0, std::ios_base::end);
|
|
|
|
|
size_t size = stream.tellg();
|
|
|
|
|
stream.seekg(prev, std::ios_base::beg);
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(whence == SEEK_SET)
|
|
|
|
|
stream->seek(static_cast<size_t>(offset));
|
|
|
|
|
stream.seekg(offset, std::ios_base::beg);
|
|
|
|
|
else if(whence == SEEK_CUR)
|
|
|
|
|
stream->seek(static_cast<size_t>(stream->tell()+offset));
|
|
|
|
|
stream.seekg(offset, std::ios_base::cur);
|
|
|
|
|
else if(whence == SEEK_END)
|
|
|
|
|
stream->seek(static_cast<size_t>(stream->size()+offset));
|
|
|
|
|
stream.seekg(offset, std::ios_base::end);
|
|
|
|
|
else
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
return stream->tell();
|
|
|
|
|
return stream.tellg();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -186,7 +191,7 @@ size_t FFmpeg_Decoder::readAVAudioData(void *data, size_t length)
|
|
|
|
|
void FFmpeg_Decoder::open(const std::string &fname)
|
|
|
|
|
{
|
|
|
|
|
close();
|
|
|
|
|
mDataStream = mResourceMgr.openResource(fname);
|
|
|
|
|
mDataStream = mResourceMgr->get(fname);
|
|
|
|
|
|
|
|
|
|
if((mFormatCtx=avformat_alloc_context()) == NULL)
|
|
|
|
|
fail("Failed to allocate context");
|
|
|
|
@ -289,7 +294,7 @@ void FFmpeg_Decoder::close()
|
|
|
|
|
avformat_close_input(&mFormatCtx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mDataStream.setNull();
|
|
|
|
|
mDataStream.reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string FFmpeg_Decoder::getName()
|
|
|
|
@ -409,8 +414,9 @@ size_t FFmpeg_Decoder::getSampleOffset()
|
|
|
|
|
return (int)(mNextPts*(*mStream)->codec->sample_rate) - delay;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FFmpeg_Decoder::FFmpeg_Decoder()
|
|
|
|
|
: mFormatCtx(NULL)
|
|
|
|
|
FFmpeg_Decoder::FFmpeg_Decoder(const VFS::Manager* vfs)
|
|
|
|
|
: Sound_Decoder(vfs)
|
|
|
|
|
, mFormatCtx(NULL)
|
|
|
|
|
, mStream(NULL)
|
|
|
|
|
, mFrame(NULL)
|
|
|
|
|
, mFrameSize(0)
|
|
|
|
|