diff --git a/src/servers/media/AddOnManager.cpp b/src/servers/media/AddOnManager.cpp index 4a01c52624..577ffc2f55 100644 --- a/src/servers/media/AddOnManager.cpp +++ b/src/servers/media/AddOnManager.cpp @@ -5,6 +5,7 @@ * Authors: * Marcus Overhagen * Axel Dörfler + * Stephan Aßmus */ @@ -13,20 +14,21 @@ #include #include -#include -#include -#include -#include #include +#include +#include +#include #include +#include #include #include +#include "debug.h" +#include "media_server.h" + #include "FormatManager.h" #include "MetaFormat.h" -#include "media_server.h" -#include "debug.h" // #pragma mark - ImageLoader @@ -60,7 +62,8 @@ private: AddOnManager::AddOnManager() : - fLock("add-on manager") + fLock("add-on manager"), + fNextWriterFormatFamilyID(0) { } @@ -73,7 +76,7 @@ AddOnManager::~AddOnManager() void AddOnManager::LoadState() { - RegisterAddOns(); + _RegisterAddOns(); } @@ -90,8 +93,9 @@ AddOnManager::GetDecoderForFormat(xfer_entry_ref* _decoderRef, if ((format.type == B_MEDIA_ENCODED_VIDEO || format.type == B_MEDIA_ENCODED_AUDIO || format.type == B_MEDIA_MULTISTREAM) - && format.Encoding() == 0) + && format.Encoding() == 0) { return B_MEDIA_BAD_FORMAT; + } if (format.type == B_MEDIA_NO_TYPE || format.type == B_MEDIA_UNKNOWN_TYPE) return B_MEDIA_BAD_FORMAT; @@ -137,7 +141,76 @@ AddOnManager::GetReaders(xfer_entry_ref* outRefs, int32* outCount, status_t -AddOnManager::RegisterAddOn(BEntry& entry) +AddOnManager::GetEncoderForFormat(xfer_entry_ref* _encoderRef, + const media_format& format) +{ + if ((format.type == B_MEDIA_ENCODED_VIDEO + || format.type == B_MEDIA_ENCODED_AUDIO + || format.type == B_MEDIA_MULTISTREAM) + && format.Encoding() == 0) { + return B_MEDIA_BAD_FORMAT; + } + if (format.type == B_MEDIA_NO_TYPE || format.type == B_MEDIA_UNKNOWN_TYPE) + return B_MEDIA_BAD_FORMAT; + + BAutolock locker(fLock); + + printf("AddOnManager::GetEncoderForFormat: searching encoder for encoding " + "%ld\n", format.Encoding()); + + encoder_info* info; + for (fEncoderList.Rewind(); fEncoderList.GetNext(&info);) { + media_format* encoderFormat; + for (info->formats.Rewind(); info->formats.GetNext(&encoderFormat);) { + // check if the encoder matches the supplied format + if (!encoderFormat->Matches(&format)) + continue; + + printf("AddOnManager::GetEncoderForFormat: found encoder %s for " + "encoding %ld\n", info->ref.name, encoderFormat->Encoding()); + + *_encoderRef = info->ref; + return B_OK; + } + } + return B_ENTRY_NOT_FOUND; +} + + +status_t +AddOnManager::GetWriter(xfer_entry_ref* _ref, const media_file_format& format) +{ + BAutolock locker(fLock); + + writer_info* info; + for (fWriterList.Rewind(); fWriterList.GetNext(&info);) { + media_file_format* fileFormat; + for (info->fileFormats.Rewind(); + info->fileFormats.GetNext(&fileFormat);) { + // Check if the writer matches the supplied file format + // TODO: There must be a trick here which makes all this + // much simpler and probably lets us create a Writer client + // side... + if (fileFormat->id.internal_id != format.id.internal_id) + continue; + + printf("AddOnManager::GetWriter: found writer %s for " + "file format %s\n", info->ref.name, format.pretty_name); + + *_ref = info->ref; + return B_OK; + } + } + + return B_ERROR; +} + + +// #pragma mark - + + +status_t +AddOnManager::_RegisterAddOn(BEntry& entry) { BPath path(&entry); @@ -146,7 +219,7 @@ AddOnManager::RegisterAddOn(BEntry& entry) if (status < B_OK) return status; - printf("AddOnManager::RegisterAddOn(): trying to load \"%s\"\n", + printf("AddOnManager::_RegisterAddOn(): trying to load \"%s\"\n", path.Path()); ImageLoader loader(path); @@ -157,27 +230,35 @@ AddOnManager::RegisterAddOn(BEntry& entry) if (get_image_symbol(loader.Image(), "instantiate_plugin", B_SYMBOL_TYPE_TEXT, (void**)&instantiate_plugin_func) < B_OK) { - printf("AddOnManager::RegisterAddOn(): can't find instantiate_plugin " + printf("AddOnManager::_RegisterAddOn(): can't find instantiate_plugin " "in \"%s\"\n", path.Path()); return B_BAD_TYPE; } MediaPlugin* plugin = (*instantiate_plugin_func)(); if (plugin == NULL) { - printf("AddOnManager::RegisterAddOn(): instantiate_plugin in \"%s\" " + printf("AddOnManager::_RegisterAddOn(): instantiate_plugin in \"%s\" " "returned NULL\n", path.Path()); return B_ERROR; } - // ToDo: remove any old formats describing this add-on!! + // TODO: Remove any old formats describing this add-on!! ReaderPlugin* reader = dynamic_cast(plugin); if (reader != NULL) - RegisterReader(reader, ref); + _RegisterReader(reader, ref); DecoderPlugin* decoder = dynamic_cast(plugin); if (decoder != NULL) - RegisterDecoder(decoder, ref); + _RegisterDecoder(decoder, ref); + + WriterPlugin* writer = dynamic_cast(plugin); + if (writer != NULL) + _RegisterWriter(writer, ref); + + EncoderPlugin* encoder = dynamic_cast(plugin); + if (encoder != NULL) + _RegisterEncoder(encoder, ref); delete plugin; @@ -186,7 +267,7 @@ AddOnManager::RegisterAddOn(BEntry& entry) void -AddOnManager::RegisterAddOns() +AddOnManager::_RegisterAddOns() { class CodecHandler : public AddOnMonitorHandler { private: @@ -209,7 +290,7 @@ AddOnManager::RegisterAddOns() entryInfo->dir_nref.node, entryInfo->name, &ref); BEntry entry(&ref, false); if (entry.InitCheck() == B_OK) - fManager->RegisterAddOn(entry); + fManager->_RegisterAddOn(entry); } virtual void AddOnDisabled(const add_on_entry_info* entryInfo) @@ -261,7 +342,7 @@ AddOnManager::RegisterAddOns() void -AddOnManager::RegisterReader(ReaderPlugin* reader, const entry_ref& ref) +AddOnManager::_RegisterReader(ReaderPlugin* reader, const entry_ref& ref) { BAutolock locker(fLock); @@ -273,7 +354,7 @@ AddOnManager::RegisterReader(ReaderPlugin* reader, const entry_ref& ref) } } - printf("AddOnManager::RegisterReader, name %s\n", ref.name); + printf("AddOnManager::_RegisterReader, name %s\n", ref.name); reader_info info; info.ref = ref; @@ -283,7 +364,7 @@ AddOnManager::RegisterReader(ReaderPlugin* reader, const entry_ref& ref) void -AddOnManager::RegisterDecoder(DecoderPlugin* plugin, const entry_ref& ref) +AddOnManager::_RegisterDecoder(DecoderPlugin* plugin, const entry_ref& ref) { BAutolock locker(fLock); @@ -295,22 +376,96 @@ AddOnManager::RegisterDecoder(DecoderPlugin* plugin, const entry_ref& ref) } } - printf("AddOnManager::RegisterDecoder, name %s\n", ref.name); + printf("AddOnManager::_RegisterDecoder, name %s\n", ref.name); decoder_info info; info.ref = ref; media_format* formats = 0; size_t count = 0; - if (plugin->GetSupportedFormats(&formats,&count) != B_OK) { - printf("AddOnManager::RegisterDecoder(): plugin->GetSupportedFormats" + if (plugin->GetSupportedFormats(&formats, &count) != B_OK) { + printf("AddOnManager::_RegisterDecoder(): plugin->GetSupportedFormats" "(...) failed!\n"); return; } - for (uint i = 0 ; i < count ; i++) { + for (uint i = 0 ; i < count ; i++) info.formats.Insert(formats[i]); - } + fDecoderList.Insert(info); } +void +AddOnManager::_RegisterWriter(WriterPlugin* writer, const entry_ref& ref) +{ + BAutolock locker(fLock); + + writer_info* pinfo; + for (fWriterList.Rewind(); fWriterList.GetNext(&pinfo);) { + if (!strcmp(pinfo->ref.name, ref.name)) { + // we already know this writer + return; + } + } + + printf("AddOnManager::_RegisterWriter, name %s\n", ref.name); + + writer_info info; + info.ref = ref; + + // Get list of support media_file_formats... + media_file_format* fileFormats = NULL; + size_t count = 0; + if (writer->GetSupportedFileFormats(&fileFormats, &count) != B_OK) { + printf("AddOnManager::_RegisterWriter(): " + "plugin->GetSupportedFileFormats(...) failed!\n"); + return; + } + for (uint i = 0 ; i < count ; i++) { + // Generate a proper ID before inserting this format, this encodes + // the specific plugin in the media_file_format. + media_file_format fileFormat = fileFormats[i]; + fileFormat.id.node = ref.directory; + fileFormat.id.device = ref.device; + fileFormat.id.internal_id = fNextWriterFormatFamilyID++; + + info.fileFormats.Insert(fileFormat); + } + + fWriterList.Insert(info); +} + + +void +AddOnManager::_RegisterEncoder(EncoderPlugin* plugin, const entry_ref& ref) +{ + BAutolock locker(fLock); + + encoder_info* pinfo; + for (fEncoderList.Rewind(); fEncoderList.GetNext(&pinfo);) { + if (!strcmp(pinfo->ref.name, ref.name)) { + // we already know this encoder + return; + } + } + + printf("AddOnManager::_RegisterEncoder, name %s\n", ref.name); + + encoder_info info; + info.ref = ref; + + // Get list of support media_formats... + media_format* formats = NULL; + size_t count = 0; + if (plugin->GetSupportedFormats(&formats, &count) != B_OK) { + printf("AddOnManager::_RegisterEncoder(): plugin->GetSupportedFormats" + "(...) failed!\n"); + return; + } + for (uint i = 0 ; i < count ; i++) + info.formats.Insert(formats[i]); + + fEncoderList.Insert(info); +} + + diff --git a/src/servers/media/AddOnManager.h b/src/servers/media/AddOnManager.h index a90f6eaff6..3b80bb4c11 100644 --- a/src/servers/media/AddOnManager.h +++ b/src/servers/media/AddOnManager.h @@ -5,6 +5,7 @@ * Authors: * Marcus Overhagen * Axel Dörfler + * Stephan Aßmus */ #ifndef _ADD_ON_MANAGER_H #define _ADD_ON_MANAGER_H @@ -15,13 +16,15 @@ */ -#include "ReaderPlugin.h" -#include "DecoderPlugin.h" #include "DataExchange.h" #include "TList.h" #include "AddOnMonitor.h" #include "AddOnMonitorHandler.h" +#include "DecoderPlugin.h" +#include "EncoderPlugin.h" +#include "ReaderPlugin.h" +#include "WriterPlugin.h" class AddOnManager { @@ -38,13 +41,24 @@ public: status_t GetReaders(xfer_entry_ref* _ref, int32* _count, int32 maxCount); -private: - status_t RegisterAddOn(BEntry& entry); - void RegisterAddOns(); + status_t GetEncoderForFormat(xfer_entry_ref* _ref, + const media_format& format); - void RegisterReader(ReaderPlugin* reader, + status_t GetWriter(xfer_entry_ref* _ref, + const media_file_format& format); + +private: + status_t _RegisterAddOn(BEntry& entry); + void _RegisterAddOns(); + + void _RegisterReader(ReaderPlugin* reader, const entry_ref& ref); - void RegisterDecoder(DecoderPlugin* decoder, + void _RegisterDecoder(DecoderPlugin* decoder, + const entry_ref& ref); + + void _RegisterWriter(WriterPlugin* writer, + const entry_ref& ref); + void _RegisterEncoder(EncoderPlugin* encoder, const entry_ref& ref); private: @@ -53,6 +67,7 @@ private: }; struct writer_info { entry_ref ref; + List fileFormats; }; struct decoder_info { entry_ref ref; @@ -60,6 +75,7 @@ private: }; struct encoder_info { entry_ref ref; + List formats; }; BLocker fLock; @@ -68,7 +84,7 @@ private: List fDecoderList; List fEncoderList; - decoder_info* fCurrentDecoder; + uint32 fNextWriterFormatFamilyID; AddOnMonitorHandler* fHandler; AddOnMonitor* fAddOnMonitor; diff --git a/src/servers/media/media_server.cpp b/src/servers/media/media_server.cpp index 129579b8da..bedb3df204 100644 --- a/src/servers/media/media_server.cpp +++ b/src/servers/media/media_server.cpp @@ -886,6 +886,28 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size) break; } + case SERVER_GET_WRITER_FOR_FORMAT_FAMILY: + { + const server_get_writer_request *request + = reinterpret_cast(data); + server_get_writer_reply reply; + rv = gAddOnManager->GetWriter(&reply.ref, request->file_format); + request->SendReply(rv, &reply, sizeof(reply)); + break; + } + + case SERVER_GET_ENCODER_FOR_FORMAT: + { + const server_get_encoder_for_format_request *request + = reinterpret_cast< + const server_get_encoder_for_format_request *>(data); + server_get_encoder_for_format_reply reply; + rv = gAddOnManager->GetEncoderForFormat(&reply.ref, + request->format); + request->SendReply(rv, &reply, sizeof(reply)); + break; + } + default: printf("media_server: received unknown message code %#08lx\n", code);