Author: stippi Date: 2010-08-24 19:46:11 +0200 (Tue, 24 Aug 2010) New Revision: 38338 Changeset: http://dev.haiku-os.org/changeset/38338 Modified: haiku/trunk/src/servers/media/AddOnManager.cpp haiku/trunk/src/servers/media/AddOnManager.h Log: * When unregistering plugins, decoders specifically, we need to remove its globally registered formats from the FormatManager. * When searching decoders for a given format, we need to search by add-on directory, since the decoder list will not stay sorted once some have been removed or added after the initial add-on scan. These fixes make it finally possible to rebuild media plugins and have the media_server pick up the changes without needing a restart. Modified: haiku/trunk/src/servers/media/AddOnManager.cpp =================================================================== --- haiku/trunk/src/servers/media/AddOnManager.cpp 2010-08-24 17:43:13 UTC (rev 38337) +++ haiku/trunk/src/servers/media/AddOnManager.cpp 2010-08-24 17:46:11 UTC (rev 38338) @@ -57,6 +57,13 @@ }; +static const directory_which sDirectories[] = { + B_USER_ADDONS_DIRECTORY, + B_COMMON_ADDONS_DIRECTORY, + B_BEOS_ADDONS_DIRECTORY, +}; + + // #pragma mark - @@ -112,21 +119,20 @@ printf("AddOnManager::GetDecoderForFormat: searching decoder for encoding " "%ld\n", format.Encoding()); - decoder_info* info; - for (fDecoderList.Rewind(); fDecoderList.GetNext(&info);) { - media_format* decoderFormat; - for (info->formats.Rewind(); info->formats.GetNext(&decoderFormat);) { - // check if the decoder matches the supplied format - if (!decoderFormat->Matches(&format)) - continue; + // Since the list of decoders is unsorted, we need to search for + // an decoder by add-on directory, in order to maintain the shadowing + // of system add-ons by user add-ons, in case they offer decorders + // for the same format. - printf("AddOnManager::GetDecoderForFormat: found decoder %s for " - "encoding %ld\n", info->ref.name, decoderFormat->Encoding()); - - *_decoderRef = info->ref; - return B_OK; + BPath path; + for (uint i = 0; i < sizeof(sDirectories) / sizeof(directory_which); i++) { + if (find_directory(sDirectories[i], &path) == B_OK + && path.Append("media/plugins") == B_OK) { + if (_FindDecoder(format, path, _decoderRef)) + return B_OK; } } + return B_ENTRY_NOT_FOUND; } @@ -268,12 +274,6 @@ } }; - const directory_which directories[] = { - B_USER_ADDONS_DIRECTORY, - B_COMMON_ADDONS_DIRECTORY, - B_BEOS_ADDONS_DIRECTORY, - }; - fAddOnMonitorHandler = new CodecHandler(this); fAddOnMonitor = new AddOnMonitor(fAddOnMonitorHandler); @@ -293,11 +293,11 @@ node_ref nref; BDirectory directory; BPath path; - for (uint i = 0 ; i < sizeof(directories) / sizeof(directory_which) ; i++) { + for (uint i = 0; i < sizeof(sDirectories) / sizeof(directory_which); i++) { if (disableUserAddOns && i <= 1) continue; - if (find_directory(directories[i], &path) == B_OK + if (find_directory(sDirectories[i], &path) == B_OK && path.Append("media/plugins") == B_OK && directory.SetTo(path.Path()) == B_OK && directory.GetNodeRef(&nref) == B_OK) { @@ -384,6 +384,11 @@ for (fDecoderList.Rewind(); fDecoderList.GetNext(&decoderInfo);) { if (decoderInfo->ref == ref) { printf("removing decoder '%s'\n", decoderInfo->ref.name); + media_format* format; + for (decoderInfo->formats.Rewind(); + decoderInfo->formats.GetNext(&format);) { + gFormatManager->RemoveFormat(*format); + } fDecoderList.RemoveCurrent(); break; } @@ -561,3 +566,36 @@ } +bool +AddOnManager::_FindDecoder(const media_format& format, const BPath& path, + xfer_entry_ref* _decoderRef) +{ + node_ref nref; + BDirectory directory; + if (directory.SetTo(path.Path()) != B_OK + || directory.GetNodeRef(&nref) != B_OK) { + return B_ERROR; + } + + decoder_info* info; + for (fDecoderList.Rewind(); fDecoderList.GetNext(&info);) { + if (info->ref.directory != nref.node) + continue; + + media_format* decoderFormat; + for (info->formats.Rewind(); info->formats.GetNext(&decoderFormat);) { + // check if the decoder matches the supplied format + if (!decoderFormat->Matches(&format)) + continue; + + printf("AddOnManager::GetDecoderForFormat: found decoder %s/%s " + "for encoding %ld\n", path.Path(), info->ref.name, + decoderFormat->Encoding()); + + *_decoderRef = info->ref; + return true; + } + } + return false; +} + Modified: haiku/trunk/src/servers/media/AddOnManager.h =================================================================== --- haiku/trunk/src/servers/media/AddOnManager.h 2010-08-24 17:43:13 UTC (rev 38337) +++ haiku/trunk/src/servers/media/AddOnManager.h 2010-08-24 17:46:11 UTC (rev 38338) @@ -69,6 +69,10 @@ void _RegisterEncoder(EncoderPlugin* encoder, const entry_ref& ref); + bool _FindDecoder(const media_format& format, + const BPath& path, + xfer_entry_ref* _decoderRef); + private: struct reader_info { entry_ref ref;