2 * Copyright 2004-2010, Marcus Overhagen. All rights reserved.
3 * Distributed under the terms of the OpenBeOS License.
10 #include "AddOnManager.h"
11 #include "PluginManager.h"
12 #include "DataExchange.h"
16 PluginManager gPluginManager
;
19 // #pragma mark - Readers/Decoders
23 PluginManager::CreateReader(Reader
** reader
, int32
* streamCount
,
24 media_file_format
* mff
, BDataIO
* source
)
26 TRACE("PluginManager::CreateReader enter\n");
28 BPositionIO
*seekable_source
= dynamic_cast<BPositionIO
*>(source
);
29 if (seekable_source
== 0) {
30 printf("PluginManager::CreateReader: non-seekable sources not "
35 // get list of available readers from the server
36 entry_ref refs
[MAX_READERS
];
39 status_t ret
= AddOnManager::GetInstance()->GetReaders(refs
, &count
,
42 printf("PluginManager::CreateReader: can't get list of readers: %s\n",
47 // try each reader by calling it's Sniff function...
48 for (int32 i
= 0; i
< count
; i
++) {
49 entry_ref ref
= refs
[i
];
50 MediaPlugin
* plugin
= GetPlugin(ref
);
52 printf("PluginManager::CreateReader: GetPlugin failed\n");
56 ReaderPlugin
* readerPlugin
= dynamic_cast<ReaderPlugin
*>(plugin
);
57 if (readerPlugin
== NULL
) {
58 printf("PluginManager::CreateReader: dynamic_cast failed\n");
63 *reader
= readerPlugin
->NewReader();
64 if (*reader
== NULL
) {
65 printf("PluginManager::CreateReader: NewReader failed\n");
70 seekable_source
->Seek(0, SEEK_SET
);
71 (*reader
)->Setup(seekable_source
);
72 (*reader
)->fMediaPlugin
= plugin
;
74 if ((*reader
)->Sniff(streamCount
) == B_OK
) {
75 TRACE("PluginManager::CreateReader: Sniff success "
76 "(%ld stream(s))\n", *streamCount
);
77 (*reader
)->GetFileFormatInfo(mff
);
81 DestroyReader(*reader
);
85 TRACE("PluginManager::CreateReader leave\n");
86 return B_MEDIA_NO_HANDLER
;
91 PluginManager::DestroyReader(Reader
* reader
)
94 TRACE("PluginManager::DestroyReader(%p (plugin: %p))\n", reader
,
95 reader
->fMediaPlugin
);
96 // NOTE: We have to put the plug-in after deleting the reader,
97 // since otherwise we may actually unload the code for the
99 MediaPlugin
* plugin
= reader
->fMediaPlugin
;
107 PluginManager::CreateDecoder(Decoder
** _decoder
, const media_format
& format
)
109 TRACE("PluginManager::CreateDecoder enter\n");
111 // get decoder for this format
113 status_t ret
= AddOnManager::GetInstance()->GetDecoderForFormat(
116 printf("PluginManager::CreateDecoder: can't get decoder for format: "
117 "%s\n", strerror(ret
));
121 MediaPlugin
* plugin
= GetPlugin(ref
);
122 if (plugin
== NULL
) {
123 printf("PluginManager::CreateDecoder: GetPlugin failed\n");
127 DecoderPlugin
* decoderPlugin
= dynamic_cast<DecoderPlugin
*>(plugin
);
128 if (decoderPlugin
== NULL
) {
129 printf("PluginManager::CreateDecoder: dynamic_cast failed\n");
134 // TODO: In theory, one DecoderPlugin could support multiple Decoders,
135 // but this is not yet handled (passing "0" as index/ID).
136 *_decoder
= decoderPlugin
->NewDecoder(0);
137 if (*_decoder
== NULL
) {
138 printf("PluginManager::CreateDecoder: NewDecoder() failed\n");
142 TRACE(" created decoder: %p\n", *_decoder
);
143 (*_decoder
)->fMediaPlugin
= plugin
;
145 TRACE("PluginManager::CreateDecoder leave\n");
152 PluginManager::CreateDecoder(Decoder
** decoder
, const media_codec_info
& mci
)
155 debugger("not implemented");
161 PluginManager::GetDecoderInfo(Decoder
* decoder
, media_codec_info
* _info
) const
166 decoder
->GetCodecInfo(_info
);
169 // out_info->sub_id =
175 PluginManager::DestroyDecoder(Decoder
* decoder
)
177 if (decoder
!= NULL
) {
178 TRACE("PluginManager::DestroyDecoder(%p, plugin: %p)\n", decoder
,
179 decoder
->fMediaPlugin
);
180 // NOTE: We have to put the plug-in after deleting the decoder,
181 // since otherwise we may actually unload the code for the
183 MediaPlugin
* plugin
= decoder
->fMediaPlugin
;
190 // #pragma mark - Writers/Encoders
194 PluginManager::CreateWriter(Writer
** writer
, const media_file_format
& mff
,
197 TRACE("PluginManager::CreateWriter enter\n");
199 // Get the Writer responsible for this media_file_format from the server.
201 status_t ret
= AddOnManager::GetInstance()->GetWriter(&ref
,
204 printf("PluginManager::CreateWriter: can't get writer for file "
205 "family: %s\n", strerror(ret
));
209 MediaPlugin
* plugin
= GetPlugin(ref
);
210 if (plugin
== NULL
) {
211 printf("PluginManager::CreateWriter: GetPlugin failed\n");
215 WriterPlugin
* writerPlugin
= dynamic_cast<WriterPlugin
*>(plugin
);
216 if (writerPlugin
== NULL
) {
217 printf("PluginManager::CreateWriter: dynamic_cast failed\n");
222 *writer
= writerPlugin
->NewWriter();
223 if (*writer
== NULL
) {
224 printf("PluginManager::CreateWriter: NewWriter failed\n");
229 (*writer
)->Setup(target
);
230 (*writer
)->fMediaPlugin
= plugin
;
232 TRACE("PluginManager::CreateWriter leave\n");
238 PluginManager::DestroyWriter(Writer
* writer
)
240 if (writer
!= NULL
) {
241 TRACE("PluginManager::DestroyWriter(%p (plugin: %p))\n", writer
,
242 writer
->fMediaPlugin
);
243 // NOTE: We have to put the plug-in after deleting the writer,
244 // since otherwise we may actually unload the code for the
246 MediaPlugin
* plugin
= writer
->fMediaPlugin
;
254 PluginManager::CreateEncoder(Encoder
** _encoder
,
255 const media_codec_info
* codecInfo
, uint32 flags
)
257 TRACE("PluginManager::CreateEncoder enter\n");
259 // Get encoder for this codec info from the server
261 status_t ret
= AddOnManager::GetInstance()->GetEncoder(&ref
,
264 printf("PluginManager::CreateEncoder: can't get encoder for codec %s: "
265 "%s\n", codecInfo
->pretty_name
, strerror(ret
));
269 MediaPlugin
* plugin
= GetPlugin(ref
);
271 printf("PluginManager::CreateEncoder: GetPlugin failed\n");
275 EncoderPlugin
* encoderPlugin
= dynamic_cast<EncoderPlugin
*>(plugin
);
276 if (encoderPlugin
== NULL
) {
277 printf("PluginManager::CreateEncoder: dynamic_cast failed\n");
282 *_encoder
= encoderPlugin
->NewEncoder(*codecInfo
);
283 if (*_encoder
== NULL
) {
284 printf("PluginManager::CreateEncoder: NewEncoder() failed\n");
288 TRACE(" created encoder: %p\n", *_encoder
);
289 (*_encoder
)->fMediaPlugin
= plugin
;
291 TRACE("PluginManager::CreateEncoder leave\n");
298 PluginManager::DestroyEncoder(Encoder
* encoder
)
300 if (encoder
!= NULL
) {
301 TRACE("PluginManager::DestroyEncoder(%p, plugin: %p)\n", encoder
,
302 encoder
->fMediaPlugin
);
303 // NOTE: We have to put the plug-in after deleting the encoder,
304 // since otherwise we may actually unload the code for the
306 MediaPlugin
* plugin
= encoder
->fMediaPlugin
;
316 PluginManager::PluginManager()
319 fLocker("media plugin manager")
325 PluginManager::~PluginManager()
328 for (int i
= fPluginList
.CountItems() - 1; i
>= 0; i
--) {
329 plugin_info
* info
= NULL
;
330 fPluginList
.Get(i
, &info
);
331 TRACE("PluginManager: Error, unloading PlugIn %s with usecount "
332 "%d\n", info
->name
, info
->usecount
);
334 unload_add_on(info
->image
);
340 PluginManager::GetPlugin(const entry_ref
& ref
)
342 TRACE("PluginManager::GetPlugin(%s)\n", ref
.name
);
349 for (fPluginList
.Rewind(); fPluginList
.GetNext(&pinfo
); ) {
350 if (0 == strcmp(ref
.name
, pinfo
->name
)) {
351 plugin
= pinfo
->plugin
;
353 TRACE(" found existing plugin: %p\n", pinfo
->plugin
);
359 if (_LoadPlugin(ref
, &info
.plugin
, &info
.image
) < B_OK
) {
360 printf("PluginManager: Error, loading PlugIn %s failed\n", ref
.name
);
365 strcpy(info
.name
, ref
.name
);
367 fPluginList
.Insert(info
);
369 TRACE("PluginManager: PlugIn %s loaded\n", ref
.name
);
371 plugin
= info
.plugin
;
372 TRACE(" loaded plugin: %p\n", plugin
);
380 PluginManager::PutPlugin(MediaPlugin
* plugin
)
382 TRACE("PluginManager::PutPlugin()\n");
387 for (fPluginList
.Rewind(); fPluginList
.GetNext(&pinfo
); ) {
388 if (plugin
== pinfo
->plugin
) {
390 if (pinfo
->usecount
== 0) {
391 TRACE(" deleting %p\n", pinfo
->plugin
);
392 delete pinfo
->plugin
;
393 TRACE(" unloading add-on: %ld\n\n", pinfo
->image
);
394 unload_add_on(pinfo
->image
);
395 fPluginList
.RemoveCurrent();
402 printf("PluginManager: Error, can't put PlugIn %p\n", plugin
);
409 PluginManager::_LoadPlugin(const entry_ref
& ref
, MediaPlugin
** plugin
,
414 TRACE("PluginManager: _LoadPlugin trying to load %s\n", p
.Path());
417 id
= load_add_on(p
.Path());
419 printf("PluginManager: Error, load_add_on(): %s\n", strerror(id
));
423 MediaPlugin
* (*instantiate_plugin_func
)();
425 if (get_image_symbol(id
, "instantiate_plugin", B_SYMBOL_TYPE_TEXT
,
426 (void**)&instantiate_plugin_func
) < B_OK
) {
427 printf("PluginManager: Error, _LoadPlugin can't find "
428 "instantiate_plugin in %s\n", p
.Path());
435 pl
= (*instantiate_plugin_func
)();
437 printf("PluginManager: Error, _LoadPlugin instantiate_plugin in %s "
438 "returned NULL\n", p
.Path());