diff --git a/headers/private/media/DecoderPlugin.h b/headers/private/media/DecoderPlugin.h index f5078594fa..648d9eeed1 100644 --- a/headers/private/media/DecoderPlugin.h +++ b/headers/private/media/DecoderPlugin.h @@ -9,53 +9,75 @@ class AddOnManager; namespace BPrivate { namespace media { +class PluginManager; + class ChunkProvider { public: - virtual ~ChunkProvider() {}; - virtual status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader) = 0; + virtual ~ChunkProvider() {}; + virtual status_t GetNextChunk(const void** chunkBuffer, + size_t* chunkSize, + media_header* mediaHeader) = 0; }; -class Decoder -{ +class Decoder { public: - Decoder(); - virtual ~Decoder(); + Decoder(); + virtual ~Decoder(); - virtual void GetCodecInfo(media_codec_info *codecInfo) = 0; + virtual void GetCodecInfo(media_codec_info* codecInfo) = 0; - // Setup get's called with the info data from Reader::GetStreamInfo - virtual status_t Setup(media_format *ioEncodedFormat, const void *infoBuffer, size_t infoSize) = 0; + // Setup get's called with the info data from Reader::GetStreamInfo + virtual status_t Setup(media_format* ioEncodedFormat, + const void* infoBuffer, + size_t infoSize) = 0; - virtual status_t NegotiateOutputFormat(media_format *ioDecodedFormat) = 0; + virtual status_t NegotiateOutputFormat( + media_format* ioDecodedFormat) = 0; - virtual status_t Seek(uint32 seekTo, - int64 seekFrame, int64 *frame, - bigtime_t seekTime, bigtime_t *time) = 0; + virtual status_t Seek(uint32 seekTo, int64 seekFrame, + int64* frame, bigtime_t seekTime, + bigtime_t* time) = 0; - virtual status_t Decode(void *buffer, int64 *frameCount, - media_header *mediaHeader, media_decode_info *info = 0) = 0; + virtual status_t Decode(void* buffer, int64* frameCount, + media_header* mediaHeader, + media_decode_info* info = 0) = 0; - status_t GetNextChunk(const void **chunkBuffer, size_t *chunkSize, - media_header *mediaHeader); + status_t GetNextChunk(const void** chunkBuffer, + size_t* chunkSize, + media_header* mediaHeader); + + void SetChunkProvider(ChunkProvider* provider); + + virtual status_t Perform(perform_code code, void* data); - void SetChunkProvider(ChunkProvider *provider); private: - ChunkProvider * fChunkProvider; + virtual void _ReservedDecoder1(); + virtual void _ReservedDecoder2(); + virtual void _ReservedDecoder3(); + virtual void _ReservedDecoder4(); + virtual void _ReservedDecoder5(); + + ChunkProvider* fChunkProvider; + + // needed for plug-in reference count management + friend class PluginManager; + MediaPlugin* fMediaPlugin; + + uint32 fReserved[5]; }; -class DecoderPlugin : public virtual MediaPlugin -{ - public: - DecoderPlugin(); +class DecoderPlugin : public virtual MediaPlugin { +public: + DecoderPlugin(); - virtual Decoder *NewDecoder(uint index) = 0; - virtual status_t GetSupportedFormats(media_format ** formats, size_t * count) = 0; + virtual Decoder* NewDecoder(uint index) = 0; + virtual status_t GetSupportedFormats(media_format** formats, + size_t * count) = 0; }; } } // namespace BPrivate::media using namespace BPrivate::media; -#endif +#endif // _DECODER_PLUGIN_H diff --git a/headers/private/media/PluginManager.h b/headers/private/media/PluginManager.h index f9667985a1..aefb19155b 100644 --- a/headers/private/media/PluginManager.h +++ b/headers/private/media/PluginManager.h @@ -36,6 +36,15 @@ private: int usecount; MediaPlugin *plugin; image_id image; + + plugin_info& operator=(const plugin_info& other) + { + strcpy(name, other.name); + usecount = other.usecount; + plugin = other.plugin; + image = other.image; + return *this; + } }; List *fPluginList; diff --git a/headers/private/media/ReaderPlugin.h b/headers/private/media/ReaderPlugin.h index cf29423f6a..248108d4fb 100644 --- a/headers/private/media/ReaderPlugin.h +++ b/headers/private/media/ReaderPlugin.h @@ -6,6 +6,8 @@ namespace BPrivate { namespace media { +class PluginManager; + enum { B_MEDIA_SEEK_TO_TIME = 0x10000, B_MEDIA_SEEK_TO_FRAME = 0x20000 @@ -41,12 +43,26 @@ public: media_header* mediaHeader) = 0; BDataIO* Source() const; - + + virtual status_t Perform(perform_code code, void* data); + private: + virtual void _ReservedReader1(); + virtual void _ReservedReader2(); + virtual void _ReservedReader3(); + virtual void _ReservedReader4(); + virtual void _ReservedReader5(); + public: // XXX for test programs only void Setup(BDataIO* source); BDataIO* fSource; + + // needed for plug-in reference count management + friend class PluginManager; + MediaPlugin* fMediaPlugin; + + uint32 fReserved[5]; }; diff --git a/src/kits/media/DecoderPlugin.cpp b/src/kits/media/DecoderPlugin.cpp index f85feffb9c..e3b8a0e915 100644 --- a/src/kits/media/DecoderPlugin.cpp +++ b/src/kits/media/DecoderPlugin.cpp @@ -1,18 +1,20 @@ /* -** Copyright 2004, Marcus Overhagen. All rights reserved. -** Distributed under the terms of the OpenBeOS License. -*/ - + * Copyright 2004, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ #include "DecoderPlugin.h" -#include #include #include +#include + Decoder::Decoder() - : fChunkProvider(NULL) + : + fChunkProvider(NULL), + fMediaPlugin(NULL) { } @@ -39,6 +41,18 @@ Decoder::SetChunkProvider(ChunkProvider *provider) } +status_t +Decoder::Perform(perform_code code, void* _data) +{ + return B_OK; +} + +void Decoder::_ReservedDecoder1() {} +void Decoder::_ReservedDecoder2() {} +void Decoder::_ReservedDecoder3() {} +void Decoder::_ReservedDecoder4() {} +void Decoder::_ReservedDecoder5() {} + // #pragma mark - diff --git a/src/kits/media/PluginManager.cpp b/src/kits/media/PluginManager.cpp index 4332460fad..007511ddbc 100644 --- a/src/kits/media/PluginManager.cpp +++ b/src/kits/media/PluginManager.cpp @@ -49,7 +49,7 @@ PluginManager::CreateReader(Reader **reader, int32 *streamCount, return B_ERROR; } - ReaderPlugin *readerPlugin = dynamic_cast(plugin); + ReaderPlugin *readerPlugin = dynamic_cast(plugin); if (!readerPlugin) { printf("PluginManager::CreateReader: dynamic_cast failed\n"); PutPlugin(plugin); @@ -57,7 +57,7 @@ PluginManager::CreateReader(Reader **reader, int32 *streamCount, } *reader = readerPlugin->NewReader(); - if (! *reader) { + if (*reader == NULL) { printf("PluginManager::CreateReader: NewReader failed\n"); PutPlugin(plugin); return B_ERROR; @@ -65,6 +65,7 @@ PluginManager::CreateReader(Reader **reader, int32 *streamCount, seekable_source->Seek(0, SEEK_SET); (*reader)->Setup(seekable_source); + (*reader)->fMediaPlugin = plugin; if ((*reader)->Sniff(streamCount) == B_OK) { TRACE("PluginManager::CreateReader: Sniff success " @@ -73,9 +74,7 @@ PluginManager::CreateReader(Reader **reader, int32 *streamCount, return B_OK; } - // _DestroyReader(*reader); - delete *reader; - PutPlugin(plugin); + DestroyReader(*reader); } TRACE("PluginManager::CreateReader leave\n"); @@ -84,10 +83,18 @@ PluginManager::CreateReader(Reader **reader, int32 *streamCount, void -PluginManager::DestroyReader(Reader *reader) +PluginManager::DestroyReader(Reader* reader) { - // ToDo: must call put plugin - delete reader; + if (reader != NULL) { + TRACE("PluginManager::DestroyReader(%p (plugin: %p))\n", reader, + reader->fMediaPlugin); + // NOTE: We have to put the plug-in after deleting the reader, + // since otherwise we may actually unload the code for the + // destructor... + MediaPlugin* plugin = reader->fMediaPlugin; + delete reader; + PutPlugin(plugin); + } } @@ -108,7 +115,7 @@ PluginManager::CreateDecoder(Decoder **_decoder, const media_format &format) return ret; } - MediaPlugin *plugin = GetPlugin(reply.ref); + MediaPlugin* plugin = GetPlugin(reply.ref); if (!plugin) { printf("PluginManager::CreateDecoder: GetPlugin failed\n"); return B_ERROR; @@ -127,6 +134,8 @@ PluginManager::CreateDecoder(Decoder **_decoder, const media_format &format) PutPlugin(plugin); return B_ERROR; } + TRACE(" created decoder: %p\n", *_decoder); + (*_decoder)->fMediaPlugin = plugin; TRACE("PluginManager::CreateDecoder leave\n"); @@ -161,8 +170,16 @@ PluginManager::GetDecoderInfo(Decoder *decoder, void PluginManager::DestroyDecoder(Decoder *decoder) { - // ToDo: must call put plugin - delete decoder; + if (decoder != NULL) { + TRACE("PluginManager::DestroyDecoder(%p, plugin: %p)\n", decoder, + decoder->fMediaPlugin); + // NOTE: We have to put the plug-in after deleting the decoder, + // since otherwise we may actually unload the code for the + // destructor... + MediaPlugin* plugin = decoder->fMediaPlugin; + delete decoder; + PutPlugin(plugin); + } } @@ -180,14 +197,13 @@ PluginManager::PluginManager() PluginManager::~PluginManager() { CALLED(); - while (!fPluginList->IsEmpty()) { + for (int i = fPluginList->CountItems() - 1; i >= 0; i--) { plugin_info *info = NULL; - fPluginList->Get(fPluginList->CountItems() - 1, &info); + fPluginList->Get(i, &info); printf("PluginManager: Error, unloading PlugIn %s with usecount " "%d\n", info->name, info->usecount); delete info->plugin; unload_add_on(info->image); - fPluginList->Remove(fPluginList->CountItems() - 1); } delete fLocker; } @@ -196,6 +212,7 @@ PluginManager::~PluginManager() MediaPlugin * PluginManager::GetPlugin(const entry_ref &ref) { + TRACE("PluginManager::GetPlugin(%s)\n", ref.name); fLocker->Lock(); MediaPlugin *plugin; @@ -206,6 +223,7 @@ PluginManager::GetPlugin(const entry_ref &ref) if (0 == strcmp(ref.name, pinfo->name)) { plugin = pinfo->plugin; pinfo->usecount++; + TRACE(" found existing plugin: %p\n", pinfo->plugin); fLocker->Unlock(); return plugin; } @@ -224,6 +242,7 @@ PluginManager::GetPlugin(const entry_ref &ref) TRACE("PluginManager: PlugIn %s loaded\n", ref.name); plugin = info.plugin; + TRACE(" loaded plugin: %p\n", plugin); fLocker->Unlock(); return plugin; @@ -231,8 +250,9 @@ PluginManager::GetPlugin(const entry_ref &ref) void -PluginManager::PutPlugin(MediaPlugin *plugin) +PluginManager::PutPlugin(MediaPlugin* plugin) { + TRACE("PluginManager::PutPlugin()\n"); fLocker->Lock(); plugin_info *pinfo; @@ -241,7 +261,9 @@ PluginManager::PutPlugin(MediaPlugin *plugin) if (plugin == pinfo->plugin) { pinfo->usecount--; if (pinfo->usecount == 0) { + TRACE(" deleting %p\n", pinfo->plugin); delete pinfo->plugin; + TRACE(" unloading add-on: %ld\n\n", pinfo->image); unload_add_on(pinfo->image); fPluginList->RemoveCurrent(); } @@ -266,6 +288,7 @@ PluginManager::LoadPlugin(const entry_ref &ref, MediaPlugin **plugin, image_id id; id = load_add_on(p.Path()); + TRACE(" loaded add-on: %ld\n", id); if (id < 0) return B_ERROR; diff --git a/src/kits/media/ReaderPlugin.cpp b/src/kits/media/ReaderPlugin.cpp index 44ad4137d1..40148d0cd2 100644 --- a/src/kits/media/ReaderPlugin.cpp +++ b/src/kits/media/ReaderPlugin.cpp @@ -1,8 +1,17 @@ +/* + * Copyright 2004, Marcus Overhagen. All rights reserved. + * Distributed under the terms of the MIT License. + */ + #include "ReaderPlugin.h" +#include + Reader::Reader() - : fSource(0) + : + fSource(0), + fMediaPlugin(NULL) { } @@ -38,3 +47,17 @@ Reader::Setup(BDataIO *source) { fSource = source; } + + +status_t +Reader::Perform(perform_code code, void* _data) +{ + return B_OK; +} + +void Reader::_ReservedReader1() {} +void Reader::_ReservedReader2() {} +void Reader::_ReservedReader3() {} +void Reader::_ReservedReader4() {} +void Reader::_ReservedReader5() {} +