Restore exception throwing to the decoder

pull/359/head
Chris Robinson 7 years ago
parent 06ae61479a
commit 08e947319a

@ -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();
try
{
mDataStream = mResourceMgr->get(fname);
mDataStream = mResourceMgr->get(fname);
if((mFormatCtx=avformat_alloc_context()) == NULL)
throw std::runtime_error("Failed to allocate context");
if((mFormatCtx=avformat_alloc_context()) == NULL)
throw std::runtime_error("Failed to allocate context");
try
{
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)
{
ChannelConfig chans;
SampleType type;
if(decoder->getInfo(&srate, &chans, &type))
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
{
format = getALFormat(chans, type);
if(format) decoder->readAll(data);
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;
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…
Cancel
Save