1 /* 2 ** Copyright 2004, Marcus Overhagen. All rights reserved. 3 ** Distributed under the terms of the OpenBeOS License. 4 */ 5 6 7 #include <Path.h> 8 #include <image.h> 9 #include <string.h> 10 11 #include "PluginManager.h" 12 #include "DataExchange.h" 13 #include "debug.h" 14 15 PluginManager _plugin_manager; 16 17 18 status_t 19 _CreateReader(Reader **reader, int32 *streamCount, media_file_format *mff, BDataIO *source) 20 { 21 TRACE("_CreateReader enter\n"); 22 23 BPositionIO *seekable_source = dynamic_cast<BPositionIO *>(source); 24 if (seekable_source == 0) { 25 printf("_CreateReader: non-seekable sources not supported yet\n"); 26 return B_ERROR; 27 } 28 29 // get list of available readers from, the server 30 server_get_readers_request request; 31 server_get_readers_reply reply; 32 if (B_OK != QueryServer(SERVER_GET_READERS, &request, sizeof(request), &reply, sizeof(reply))) { 33 printf("_CreateReader: can't get list of readers\n"); 34 return B_ERROR; 35 } 36 37 // try each reader by calling it's Sniff function... 38 for (int32 i = 0; i < reply.count; i++) { 39 entry_ref ref = reply.ref[i]; 40 MediaPlugin *plugin = _plugin_manager.GetPlugin(ref); 41 if (!plugin) { 42 printf("_CreateReader: GetPlugin failed\n"); 43 return B_ERROR; 44 } 45 46 ReaderPlugin *readerPlugin = dynamic_cast<ReaderPlugin *>(plugin); 47 if (!readerPlugin) { 48 printf("_CreateReader: dynamic_cast failed\n"); 49 return B_ERROR; 50 } 51 52 *reader = readerPlugin->NewReader(); 53 if (! *reader) { 54 printf("_CreateReader: NewReader failed\n"); 55 return B_ERROR; 56 } 57 58 seekable_source->Seek(0, SEEK_SET); 59 (*reader)->Setup(seekable_source); 60 61 if (B_OK == (*reader)->Sniff(streamCount)) { 62 TRACE("_CreateReader: Sniff success (%ld stream(s))\n", *streamCount); 63 (*reader)->GetFileFormatInfo(mff); 64 return B_OK; 65 } 66 67 // _DestroyReader(*reader); 68 delete *reader; 69 _plugin_manager.PutPlugin(plugin); 70 } 71 72 TRACE("_CreateReader leave\n"); 73 return B_MEDIA_NO_HANDLER; 74 } 75 76 77 status_t 78 _CreateDecoder(Decoder **_decoder, const media_format &format) 79 { 80 TRACE("_CreateDecoder enter\n"); 81 82 // get decoder for this format from the server 83 server_get_decoder_for_format_request request; 84 server_get_decoder_for_format_reply reply; 85 request.format = format; 86 if (B_OK != QueryServer(SERVER_GET_DECODER_FOR_FORMAT, &request, sizeof(request), &reply, sizeof(reply))) { 87 printf("_CreateReader: can't get decoder for format\n"); 88 return B_ERROR; 89 } 90 91 MediaPlugin *plugin = _plugin_manager.GetPlugin(reply.ref); 92 if (!plugin) { 93 printf("_CreateDecoder: GetPlugin failed\n"); 94 return B_ERROR; 95 } 96 97 DecoderPlugin *decoderPlugin = dynamic_cast<DecoderPlugin *>(plugin); 98 if (!decoderPlugin) { 99 printf("_CreateDecoder: dynamic_cast failed\n"); 100 return B_ERROR; 101 } 102 103 *_decoder = decoderPlugin->NewDecoder(0); 104 if (*_decoder == NULL) { 105 printf("_CreateDecoder: NewDecoder() failed\n"); 106 return B_ERROR; 107 } 108 109 TRACE("_CreateDecoder leave\n"); 110 111 return B_OK; 112 } 113 114 115 void 116 _DestroyReader(Reader *reader) 117 { 118 // ToDo: must call put plugin 119 delete reader; 120 } 121 122 123 void 124 _DestroyDecoder(Decoder *decoder) 125 { 126 // ToDo: must call put plugin 127 delete decoder; 128 } 129 130 131 // #pragma mark - 132 133 134 PluginManager::PluginManager() 135 { 136 CALLED(); 137 fLocker = new BLocker; 138 fPluginList = new List<plugin_info>; 139 } 140 141 142 PluginManager::~PluginManager() 143 { 144 CALLED(); 145 while (!fPluginList->IsEmpty()) { 146 plugin_info *info; 147 fPluginList->Get(fPluginList->CountItems() - 1, &info); 148 printf("PluginManager: Error, unloading PlugIn %s with usecount %d\n", info->name, info->usecount); 149 delete info->plugin; 150 unload_add_on(info->image); 151 fPluginList->Remove(fPluginList->CountItems() - 1); 152 } 153 delete fLocker; 154 } 155 156 157 MediaPlugin * 158 PluginManager::GetPlugin(const entry_ref &ref) 159 { 160 fLocker->Lock(); 161 162 MediaPlugin *plugin; 163 plugin_info *pinfo; 164 plugin_info info; 165 166 for (fPluginList->Rewind(); fPluginList->GetNext(&pinfo); ) { 167 if (0 == strcmp(ref.name, pinfo->name)) { 168 plugin = pinfo->plugin; 169 pinfo->usecount++; 170 fLocker->Unlock(); 171 return plugin; 172 } 173 } 174 175 if (!LoadPlugin(ref, &info.plugin, &info.image)) { 176 printf("PluginManager: Error, loading PlugIn %s failed\n", ref.name); 177 fLocker->Unlock(); 178 return 0; 179 } 180 181 strcpy(info.name, ref.name); 182 info.usecount = 1; 183 fPluginList->Insert(info); 184 185 TRACE("PluginManager: PlugIn %s loaded\n", ref.name); 186 187 plugin = info.plugin; 188 189 fLocker->Unlock(); 190 return plugin; 191 } 192 193 194 void 195 PluginManager::PutPlugin(MediaPlugin *plugin) 196 { 197 fLocker->Lock(); 198 199 plugin_info *pinfo; 200 201 for (fPluginList->Rewind(); fPluginList->GetNext(&pinfo); ) { 202 if (plugin == pinfo->plugin) { 203 pinfo->usecount--; 204 if (pinfo->usecount == 0) { 205 delete pinfo->plugin; 206 unload_add_on(pinfo->image); 207 } 208 fPluginList->RemoveCurrent(); 209 fLocker->Unlock(); 210 return; 211 } 212 } 213 214 printf("PluginManager: Error, can't put PlugIn %p\n", plugin); 215 216 fLocker->Unlock(); 217 } 218 219 220 bool 221 PluginManager::LoadPlugin(const entry_ref &ref, MediaPlugin **plugin, image_id *image) 222 { 223 BPath p(&ref); 224 225 TRACE("PluginManager: LoadPlugin trying to load %s\n", p.Path()); 226 227 image_id id; 228 id = load_add_on(p.Path()); 229 if (id < 0) 230 return false; 231 232 MediaPlugin *(*instantiate_plugin_func)(); 233 234 if (get_image_symbol(id, "instantiate_plugin", B_SYMBOL_TYPE_TEXT, (void**)&instantiate_plugin_func) < B_OK) { 235 printf("PluginManager: Error, LoadPlugin can't find instantiate_plugin in %s\n", p.Path()); 236 unload_add_on(id); 237 return false; 238 } 239 240 MediaPlugin *pl; 241 242 pl = (*instantiate_plugin_func)(); 243 if (pl == 0) { 244 printf("PluginManager: Error, LoadPlugin instantiate_plugin in %s returned 0\n", p.Path()); 245 unload_add_on(id); 246 return false; 247 } 248 249 *plugin = pl; 250 *image = id; 251 return true; 252 } 253