A couple more ffmpeg decoder bug fixes -- wma files seem to be decoding properly on macOS (and likely Linux) now.

This commit is contained in:
casey langen 2018-12-27 13:40:27 -08:00
parent e3a3da754e
commit 39b068fc52
5 changed files with 68 additions and 27 deletions

View File

@ -258,7 +258,16 @@ static class Environment: public IEnvironment {
namespace musik { namespace core { namespace plugin { namespace musik { namespace core { namespace plugin {
void InstallDependencies(IMessageQueue* messageQueue, IPlaybackService* playback, ILibraryPtr library) { void InitDebug() {
/* debug */
PluginFactory::Instance().QueryFunction<SetDebug>(
"SetDebug",
[](musik::core::sdk::IPlugin* plugin, SetDebug func) {
func(&debugger);
});
}
void InitPlayback(IMessageQueue* messageQueue, IPlaybackService* playback, ILibraryPtr library) {
/* preferences */ /* preferences */
Preferences::LoadPluginPreferences(); Preferences::LoadPluginPreferences();
@ -292,16 +301,9 @@ namespace musik { namespace core { namespace plugin {
[](musik::core::sdk::IPlugin* plugin, SetEnvironment func) { [](musik::core::sdk::IPlugin* plugin, SetEnvironment func) {
func(&environment); func(&environment);
}); });
/* debug */
PluginFactory::Instance().QueryFunction<SetDebug>(
"SetDebug",
[](musik::core::sdk::IPlugin* plugin, SetDebug func) {
func(&debugger);
});
} }
void UninstallDependencies() { void Deinit() {
/* preferences */ /* preferences */
Preferences::SavePluginPreferences(); Preferences::SavePluginPreferences();

View File

@ -40,11 +40,13 @@
namespace musik { namespace core { namespace plugin { namespace musik { namespace core { namespace plugin {
void InstallDependencies( void InitDebug();
void InitPlayback(
musik::core::runtime::IMessageQueue* messageQueue, musik::core::runtime::IMessageQueue* messageQueue,
musik::core::sdk::IPlaybackService* playback, musik::core::sdk::IPlaybackService* playback,
musik::core::ILibraryPtr library); musik::core::ILibraryPtr library);
void UninstallDependencies(); void Deinit();
} } } } } }

View File

@ -124,6 +124,7 @@ int main(int argc, char* argv[]) {
auto fileLogger = new musik::debug::SimpleFileBackend(); auto fileLogger = new musik::debug::SimpleFileBackend();
auto consoleLogger = new ConsoleLogger(Window::MessageQueue()); auto consoleLogger = new ConsoleLogger(Window::MessageQueue());
musik::debug::Start({ fileLogger, consoleLogger }); musik::debug::Start({ fileLogger, consoleLogger });
musik::core::plugin::InitDebug();
ILibraryPtr library = LibraryFactory::Default(); ILibraryPtr library = LibraryFactory::Default();
library->SetMessageQueue(Window::MessageQueue()); library->SetMessageQueue(Window::MessageQueue());
@ -137,7 +138,7 @@ int main(int argc, char* argv[]) {
GlobalHotkeys globalHotkeys(playback, library); GlobalHotkeys globalHotkeys(playback, library);
Window::SetNavigationKeys(Hotkeys::NavigationKeys()); Window::SetNavigationKeys(Hotkeys::NavigationKeys());
musik::core::plugin::InstallDependencies( musik::core::plugin::InitPlayback(
&Window::MessageQueue(), &playback, library); &Window::MessageQueue(), &playback, library);
#ifdef WIN32 #ifdef WIN32
@ -223,7 +224,7 @@ int main(int argc, char* argv[]) {
} }
musik::core::audio::vis::HideSelectedVisualizer(); musik::core::audio::vis::HideSelectedVisualizer();
musik::core::plugin::UninstallDependencies(); musik::core::plugin::Deinit();
LibraryFactory::Instance().Shutdown(); LibraryFactory::Instance().Shutdown();

View File

@ -238,6 +238,7 @@ int main(int argc, char** argv) {
srand((unsigned int) time(0)); srand((unsigned int) time(0));
debug::Start(); debug::Start();
plugin::InitDebug();
EvMessageQueue messageQueue; EvMessageQueue messageQueue;
auto library = LibraryFactory::Default(); auto library = LibraryFactory::Default();
@ -246,7 +247,7 @@ int main(int argc, char** argv) {
{ {
PlaybackService playback(messageQueue, library); PlaybackService playback(messageQueue, library);
plugin::InstallDependencies(&messageQueue, &playback, library); plugin::InitPlayback(&messageQueue, &playback, library);
auto prefs = Preferences::ForComponent(prefs::components::Settings); auto prefs = Preferences::ForComponent(prefs::components::Settings);
if (prefs->GetBool(prefs::keys::SyncOnStartup, true)) { if (prefs->GetBool(prefs::keys::SyncOnStartup, true)) {
@ -258,5 +259,7 @@ int main(int argc, char** argv) {
library->Indexer()->Stop(); library->Indexer()->Stop();
} }
plugin::Deinit();
remove(LOCKFILE); remove(LOCKFILE);
} }

View File

@ -62,6 +62,13 @@ static std::string getAvError(int errnum) {
return std::string(buffer); return std::string(buffer);
} }
static void logAvError(const std::string& method, int errnum) {
if (errnum != 0) {
std::string err = method + "() failed: " + getAvError(errnum);
::debug->Warning(TAG, err.c_str());
}
}
static int readCallback(void* opaque, uint8_t* buffer, int bufferSize) { static int readCallback(void* opaque, uint8_t* buffer, int bufferSize) {
FfmpegDecoder* decoder = static_cast<FfmpegDecoder*>(opaque); FfmpegDecoder* decoder = static_cast<FfmpegDecoder*>(opaque);
if (decoder && decoder->Stream()) { if (decoder && decoder->Stream()) {
@ -92,6 +99,13 @@ static int64_t seekCallback(void* opaque, int64_t offset, int whence) {
case SEEK_END: case SEEK_END:
stream->SetPosition(stream->Length() - 1); stream->SetPosition(stream->Length() - 1);
break; break;
default:
debug->Error(TAG, "unknown seek type!");
break;
}
if (stream->Position() >= stream->Length()) {
return -1;
} }
return stream->Position(); return stream->Position();
@ -152,9 +166,9 @@ bool FfmpegDecoder::GetBuffer(IBuffer *buffer) {
buffer->SetChannels((long) this->channels); buffer->SetChannels((long) this->channels);
buffer->SetSamples(0); buffer->SetSamples(0);
int readFrameResult = av_read_frame(this->formatContext, &this->packet); int errnum = av_read_frame(this->formatContext, &this->packet);
if (!readFrameResult) { if (!errnum) {
int frameDecoded = 0; int frameDecoded = 0;
avcodec_decode_audio4( avcodec_decode_audio4(
@ -171,6 +185,20 @@ bool FfmpegDecoder::GetBuffer(IBuffer *buffer) {
auto inFormat = this->codecContext->sample_fmt; auto inFormat = this->codecContext->sample_fmt;
auto inLayout = this->codecContext->channel_layout; auto inLayout = this->codecContext->channel_layout;
if (inLayout == 0) {
/* in some cases it seems the input channel layout cannot be detected.
for this case, we configure it manually so the resampler is happy. */
switch (channels) {
case 1: inLayout = AV_CH_LAYOUT_MONO; break;
case 2: inLayout = AV_CH_LAYOUT_STEREO; break;
case 3: inLayout = AV_CH_LAYOUT_2POINT1; break;
case 4: inLayout = AV_CH_LAYOUT_3POINT1; break;
case 5: inLayout = AV_CH_LAYOUT_4POINT1; break;
case 6: inLayout = AV_CH_LAYOUT_5POINT1; break;
default: inLayout = AV_CH_LAYOUT_STEREO_DOWNMIX; break;
}
}
int decodedSize = av_samples_get_buffer_size( int decodedSize = av_samples_get_buffer_size(
nullptr, channels, samples, inFormat, 1); nullptr, channels, samples, inFormat, 1);
@ -192,7 +220,9 @@ bool FfmpegDecoder::GetBuffer(IBuffer *buffer) {
0, 0,
nullptr); nullptr);
swr_init(this->resampler); if ((errnum = swr_init(this->resampler)) != 0) {
logAvError("swr_init", errnum);
}
} }
uint8_t* outData = (uint8_t*) buffer->BufferPointer(); uint8_t* outData = (uint8_t*) buffer->BufferPointer();
@ -201,9 +231,15 @@ bool FfmpegDecoder::GetBuffer(IBuffer *buffer) {
int convertedSamplesPerChannel = swr_convert( int convertedSamplesPerChannel = swr_convert(
this->resampler, &outData, samples, inData, samples); this->resampler, &outData, samples, inData, samples);
/* actual buffer size, based on resampler output. should be the same if (convertedSamplesPerChannel < 0) {
as the preferred size... */ logAvError("swr_convert", convertedSamplesPerChannel);
buffer->SetSamples(convertedSamplesPerChannel * this->channels); buffer->SetSamples(0);
}
else {
/* actual buffer size, based on resampler output. should be the same
as the preferred size... */
buffer->SetSamples(convertedSamplesPerChannel * this->channels);
}
} }
} }
else { else {
@ -214,11 +250,7 @@ bool FfmpegDecoder::GetBuffer(IBuffer *buffer) {
return true; return true;
} }
else { else {
std::string err = logAvError("av_read_frame", errnum);
"av_read_frame() failed: " +
getAvError(readFrameResult);
::debug->Warning(TAG, err.c_str());
} }
} }
@ -276,7 +308,8 @@ bool FfmpegDecoder::Open(musik::core::sdk::IDataStream *stream) {
this->formatContext->flags = AVFMT_FLAG_CUSTOM_IO; this->formatContext->flags = AVFMT_FLAG_CUSTOM_IO;
unsigned char probe[PROBE_SIZE]; unsigned char probe[PROBE_SIZE];
size_t count = stream->Read(probe, PROBE_SIZE); memset(probe, 0, PROBE_SIZE);
size_t count = stream->Read(probe, PROBE_SIZE - AVPROBE_PADDING_SIZE);
stream->SetPosition(0); stream->SetPosition(0);
AVProbeData probeData = { 0 }; AVProbeData probeData = { 0 };
@ -298,7 +331,7 @@ bool FfmpegDecoder::Open(musik::core::sdk::IDataStream *stream) {
} }
if (this->streamId != -1) { if (this->streamId != -1) {
::debug->Info(TAG, "found audio!"); ::debug->Info(TAG, "found audio stream!");
this->codecContext = this->formatContext->streams[this->streamId]->codec; this->codecContext = this->formatContext->streams[this->streamId]->codec;
if (codecContext) { if (codecContext) {
this->codecContext->request_sample_fmt = AV_SAMPLE_FMT_FLT; this->codecContext->request_sample_fmt = AV_SAMPLE_FMT_FLT;