mirror of
https://github.com/clangen/musikcube.git
synced 2025-04-10 21:44:30 +00:00
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:
parent
e3a3da754e
commit
39b068fc52
@ -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();
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
|
||||||
} } }
|
} } }
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user