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