forked from mirror/openmw-tes3mp
Restore exception throwing to the decoder
This commit is contained in:
parent
06ae61479a
commit
08e947319a
5 changed files with 56 additions and 73 deletions
|
@ -176,16 +176,16 @@ size_t FFmpeg_Decoder::readAVAudioData(void *data, size_t length)
|
|||
return dec;
|
||||
}
|
||||
|
||||
bool FFmpeg_Decoder::open(const std::string &fname)
|
||||
void FFmpeg_Decoder::open(const std::string &fname)
|
||||
{
|
||||
close();
|
||||
mDataStream = mResourceMgr->get(fname);
|
||||
|
||||
if((mFormatCtx=avformat_alloc_context()) == NULL)
|
||||
throw std::runtime_error("Failed to allocate context");
|
||||
|
||||
try
|
||||
{
|
||||
mDataStream = mResourceMgr->get(fname);
|
||||
|
||||
if((mFormatCtx=avformat_alloc_context()) == NULL)
|
||||
throw std::runtime_error("Failed to allocate context");
|
||||
|
||||
mFormatCtx->pb = avio_alloc_context(NULL, 0, 0, this, readPacket, writePacket, seek);
|
||||
if(!mFormatCtx->pb || avformat_open_input(&mFormatCtx, fname.c_str(), NULL, NULL) != 0)
|
||||
{
|
||||
|
@ -250,16 +250,8 @@ bool FFmpeg_Decoder::open(const std::string &fname)
|
|||
mOutputChannelLayout = (*mStream)->codec->channel_layout;
|
||||
if(mOutputChannelLayout == 0)
|
||||
mOutputChannelLayout = av_get_default_channel_layout((*mStream)->codec->channels);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
std::cerr<< "Could not open audio file: "<<e.what() <<std::endl;
|
||||
}
|
||||
|
||||
if(mFormatCtx)
|
||||
{
|
||||
catch(...) {
|
||||
if(mStream)
|
||||
avcodec_close((*mStream)->codec);
|
||||
mStream = NULL;
|
||||
|
@ -273,8 +265,8 @@ bool FFmpeg_Decoder::open(const std::string &fname)
|
|||
mFormatCtx->pb = NULL;
|
||||
|
||||
avformat_close_input(&mFormatCtx);
|
||||
throw;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FFmpeg_Decoder::close()
|
||||
|
@ -316,13 +308,10 @@ std::string FFmpeg_Decoder::getName()
|
|||
return mFormatCtx->filename;
|
||||
}
|
||||
|
||||
bool FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type)
|
||||
void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type)
|
||||
{
|
||||
if(!mStream)
|
||||
{
|
||||
std::cerr<< "No audio stream info" <<std::endl;
|
||||
return false;
|
||||
}
|
||||
throw std::runtime_error("No audio stream info");
|
||||
|
||||
if(mOutputSampleFormat == AV_SAMPLE_FMT_U8)
|
||||
*type = SampleType_UInt8;
|
||||
|
@ -330,6 +319,11 @@ bool FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *
|
|||
*type = SampleType_Int16;
|
||||
else if(mOutputSampleFormat == AV_SAMPLE_FMT_FLT)
|
||||
*type = SampleType_Float32;
|
||||
else
|
||||
{
|
||||
mOutputSampleFormat = AV_SAMPLE_FMT_S16;
|
||||
*type = SampleType_Int16;
|
||||
}
|
||||
|
||||
if(mOutputChannelLayout == AV_CH_LAYOUT_MONO)
|
||||
*chans = ChannelConfig_Mono;
|
||||
|
@ -378,18 +372,10 @@ bool FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *
|
|||
0, // logging level offset
|
||||
NULL); // log context
|
||||
if(!mSwr)
|
||||
{
|
||||
std::cerr<< "Couldn't allocate SwrContext" <<std::endl;
|
||||
return false;
|
||||
}
|
||||
throw std::runtime_error("Couldn't allocate SwrContext");
|
||||
if(swr_init(mSwr) < 0)
|
||||
{
|
||||
std::cerr<< "Couldn't initialize SwrContext" <<std::endl;
|
||||
return false;
|
||||
}
|
||||
throw std::runtime_error("Couldn't initialize SwrContext");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t FFmpeg_Decoder::read(char *buffer, size_t bytes)
|
||||
|
|
|
@ -66,11 +66,11 @@ namespace MWSound
|
|||
bool getAVAudioData();
|
||||
size_t readAVAudioData(void *data, size_t length);
|
||||
|
||||
bool open(const std::string &fname) override;
|
||||
void open(const std::string &fname) override;
|
||||
void close() override;
|
||||
|
||||
std::string getName() override;
|
||||
bool getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) override;
|
||||
void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) override;
|
||||
|
||||
size_t read(char *buffer, size_t bytes) override;
|
||||
void readAll(std::vector<char> &output) override;
|
||||
|
|
|
@ -27,10 +27,10 @@ namespace MWSound
|
|||
private:
|
||||
MWSound::MovieAudioDecoder* mDecoder;
|
||||
|
||||
bool open(const std::string &fname) override;
|
||||
void open(const std::string &fname) override;
|
||||
void close() override;
|
||||
std::string getName() override;
|
||||
bool getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) override;
|
||||
void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) override;
|
||||
size_t read(char *buffer, size_t bytes) override;
|
||||
size_t getSampleOffset() override;
|
||||
};
|
||||
|
@ -98,9 +98,9 @@ namespace MWSound
|
|||
};
|
||||
|
||||
|
||||
bool MWSoundDecoderBridge::open(const std::string &fname)
|
||||
void MWSoundDecoderBridge::open(const std::string &fname)
|
||||
{
|
||||
return false;
|
||||
throw std::runtime_error("Method not implemented");
|
||||
}
|
||||
void MWSoundDecoderBridge::close() {}
|
||||
|
||||
|
@ -109,7 +109,7 @@ namespace MWSound
|
|||
return mDecoder->getStreamName();
|
||||
}
|
||||
|
||||
bool MWSoundDecoderBridge::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type)
|
||||
void MWSoundDecoderBridge::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type)
|
||||
{
|
||||
*samplerate = mDecoder->getOutputSampleRate();
|
||||
|
||||
|
@ -125,10 +125,8 @@ namespace MWSound
|
|||
else if (outputChannelLayout == AV_CH_LAYOUT_QUAD)
|
||||
*chans = ChannelConfig_Quad;
|
||||
else
|
||||
{
|
||||
std::cerr<< "Unsupported channel layout: "<<outputChannelLayout <<std::endl;
|
||||
return false;
|
||||
}
|
||||
throw std::runtime_error("Unsupported channel layout: "+
|
||||
std::to_string(outputChannelLayout));
|
||||
|
||||
AVSampleFormat outputSampleFormat = mDecoder->getOutputSampleFormat();
|
||||
if (outputSampleFormat == AV_SAMPLE_FMT_U8)
|
||||
|
@ -141,11 +139,8 @@ namespace MWSound
|
|||
{
|
||||
char str[1024];
|
||||
av_get_sample_fmt_string(str, sizeof(str), outputSampleFormat);
|
||||
std::cerr<< "Unsupported sample format: "<<str <<std::endl;
|
||||
return false;
|
||||
throw std::runtime_error(std::string("Unsupported sample format: ")+str);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t MWSoundDecoderBridge::read(char *buffer, size_t bytes)
|
||||
|
|
|
@ -411,10 +411,14 @@ bool OpenAL_SoundStream::init(bool getLoudnessData)
|
|||
ChannelConfig chans;
|
||||
SampleType type;
|
||||
|
||||
if(!mDecoder->getInfo(&mSampleRate, &chans, &type))
|
||||
try {
|
||||
mDecoder->getInfo(&mSampleRate, &chans, &type);
|
||||
mFormat = getALFormat(chans, type);
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
std::cerr<< "Failed to get stream info: "<<e.what() <<std::endl;
|
||||
return false;
|
||||
mFormat = getALFormat(chans, type);
|
||||
if(!mFormat) return false;
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
|
@ -946,35 +950,33 @@ std::pair<Sound_Handle,size_t> OpenAL_Output::loadSound(const std::string &fname
|
|||
{
|
||||
getALError();
|
||||
|
||||
DecoderPtr decoder = mManager.getDecoder();
|
||||
// Workaround: Bethesda at some point converted some of the files to mp3, but the references were kept as .wav.
|
||||
bool succeeded;
|
||||
if(decoder->mResourceMgr->exists(fname))
|
||||
succeeded = decoder->open(fname);
|
||||
else
|
||||
{
|
||||
std::string file = fname;
|
||||
std::string::size_type pos = file.rfind('.');
|
||||
if(pos != std::string::npos)
|
||||
file = file.substr(0, pos)+".mp3";
|
||||
succeeded = decoder->open(file);
|
||||
}
|
||||
|
||||
std::vector<char> data;
|
||||
ALenum format;
|
||||
int srate;
|
||||
|
||||
if(succeeded)
|
||||
{
|
||||
try {
|
||||
DecoderPtr decoder = mManager.getDecoder();
|
||||
// Workaround: Bethesda at some point converted some of the files to mp3, but the references were kept as .wav.
|
||||
if(decoder->mResourceMgr->exists(fname))
|
||||
decoder->open(fname);
|
||||
else
|
||||
{
|
||||
std::string file = fname;
|
||||
std::string::size_type pos = file.rfind('.');
|
||||
if(pos != std::string::npos)
|
||||
file = file.substr(0, pos)+".mp3";
|
||||
decoder->open(file);
|
||||
}
|
||||
|
||||
ChannelConfig chans;
|
||||
SampleType type;
|
||||
if(decoder->getInfo(&srate, &chans, &type))
|
||||
{
|
||||
format = getALFormat(chans, type);
|
||||
if(format) decoder->readAll(data);
|
||||
}
|
||||
decoder->getInfo(&srate, &chans, &type);
|
||||
format = getALFormat(chans, type);
|
||||
if(format) decoder->readAll(data);
|
||||
}
|
||||
catch(std::exception &e) {
|
||||
std::cerr<< "Failed to load audio from "<<fname<<": "<<e.what() <<std::endl;
|
||||
}
|
||||
decoder->close();
|
||||
|
||||
if(data.empty())
|
||||
{
|
||||
|
|
|
@ -34,11 +34,11 @@ namespace MWSound
|
|||
{
|
||||
const VFS::Manager* mResourceMgr;
|
||||
|
||||
virtual bool open(const std::string &fname) = 0;
|
||||
virtual void open(const std::string &fname) = 0;
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual std::string getName() = 0;
|
||||
virtual bool getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) = 0;
|
||||
virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) = 0;
|
||||
|
||||
virtual size_t read(char *buffer, size_t bytes) = 0;
|
||||
virtual void readAll(std::vector<char> &output);
|
||||
|
|
Loading…
Reference in a new issue